当前位置: 首页 > news >正文

CMakeLists.txt 中一些最常见和核心的命令

文章目录

    • 核心命令
      • 1 cmake_minimum_required()
      • 2 project()
      • 3 add_executable()
      • 4 add_library()
      • 5 target_link_libraries()
    • 管理源文件和头文件
      • 1 set()
      • 2 aux_source_directory()
      • 3 target_include_directories()
    • 控制编译和链接
      • 1 target_compile_definitions()
      • 2 target_compile_options()
      • 3 find_package()
    • 流程控制和信息输出
      • 1 if()/elseif()/else()/endif()
      • 2 message()
      • 3 add_subdirectory()


核心命令

这些是构建任何 C++ 项目几乎都必须用到的基础命令。

1 cmake_minimum_required()

  • 用处: 指定构建该项目所需的 CMake 最低版本。如果用户使用的 CMake 版本低于这个要求,将会报错。这确保了项目构建脚本的兼容性,避免了因使用过时的 CMake 命令而导致的错误。
  • 示例:
    # 要求 CMake 版本至少为 3.10
    cmake_minimum_required(VERSION 3.10)
    

2 project()

  • 用处: 定义项目名称,并可以指定项目版本、描述和支持的语言。这个命令应该在 cmake_minimum_required() 之后立即调用。
  • 示例:
    # 定义项目名称为 "MyAwesomeApp"
    project(MyAwesomeApp VERSION 1.0.0DESCRIPTION "A very awesome application"LANGUAGES CXX) # CXX 代表 C++
    

3 add_executable()

  • 用处: 使用指定的源文件来生成一个可执行文件。
  • 语法: add_executable(<可执行文件名> <源文件1> [源文件2] …)
  • 示例:
    # 使用 main.cpp 和 utils.cpp 生成一个名为 "app" 的可执行文件
    add_executable(app main.cpp utils.cpp)
    

4 add_library()

  • 用处: 使用指定的源文件来生成一个库文件。库可以是静态库(STATIC)、共享库/动态库(SHARED)或仅用于组织代码的接口库(INTERFACE)。
  • 语法: add_library(<库名> [STATIC | SHARED | INTERFACE] <源文件1> …)
  • 示例:
    # 创建一个名为 "myutils" 的静态库
    add_library(myutils STATIC utils.cpp)# 创建一个名为 "sharedlib" 的共享库
    add_library(sharedlib SHARED lib_source.cpp)
    

5 target_link_libraries()

  • 用处: 将一个或多个库链接到指定的目标(可执行文件或另一个库)。这是管理依赖关系的核心命令。
  • 语法: target_link_libraries(<目标名> [PUBLIC | PRIVATE | INTERFACE] <库1> [<库2>] …)
    • PRIVATE: 依赖项仅对当前目标内部可见。
    • PUBLIC: 依赖项对当前目标和链接到当前目标的其他目标都可见。
    • INTERFACE: 依赖项仅对链接到当前目标的其他目标可见。
  • 示例:
    # 将 myutils 库链接到 app 可执行文件
    # app 的代码可以直接使用 myutils 中定义的函数
    target_link_libraries(app PRIVATE myutils)
    

管理源文件和头文件

这些命令帮助你更好地组织和管理项目的文件。

1 set()

  • 用处: 创建或修改一个 CMake 变量。这是 CMake 中最通用的命令之一,用于存储源文件列表、路径、编译选项等。
  • 示例:
    # 将一系列源文件存入变量 SRC_FILES
    set(SRC_FILESmain.cppsrc/player.cppsrc/enemy.cpp
    )# 使用变量创建可执行文件
    add_executable(game ${SRC_FILES})
    

2 aux_source_directory()

  • 用处: 查找指定目录下的所有源文件,并将它们存入一个变量。注意:官方不推荐使用此命令,因为它不会在添加新文件时自动触发 CMake 重新运行,容易导致新文件未被编译。但对于快速原型或简单项目,它仍然很方便。
  • 示例:
    # 查找 src 目录下的所有源文件并存入 DIR_SRCS 变量
    aux_source_directory(src DIR_SRCS)# 将这些源文件添加到可执行文件中
    add_executable(app main.cpp ${DIR_SRCS})
    

3 target_include_directories()

  • 用处: 为一个目标指定头文件搜索路径。当你的源文件 #include "my_header.h"时,编译器会到这里指定的目录中去查找。
  • 语法: target_include_directories(<目标名> [PUBLIC | PRIVATE | INTERFACE] <路径1> …)
  • 示例:
    # 为 "app" 添加 "include" 目录作为头文件搜索路径
    # 这样在 app 的源文件中就可以 #include "my_header.h" 而不是 #include "include/my_header.h"
    target_include_directories(app PRIVATE include)
    

控制编译和链接

这些命令提供了对编译和链接过程的精细控制。

1 target_compile_definitions()

  • 用处: 为目标添加预处理器宏定义,等同于在编译命令中添加 -D 选项。
  • 示例:
    # 为 app 添加 DEBUG=1 和 VERSION="1.0" 两个宏定义
    target_compile_definitions(app PRIVATE DEBUG=1 VERSION="1.0")
    

2 target_compile_options()

  • 用处: 为目标添加特定的编译选项,例如警告等级、优化级别或特定的语言标准。
  • 示例:
    # 为 app 开启所有警告,并使用 C++17 标准进行编译
    target_compile_options(app PRIVATE -Wall -Wextra -std=c++17)
    

3 find_package()

  • 用处: 查找并加载外部库的配置。这是使用第三方库(如 Boost, Qt, OpenCV)的标准方式。成功找到后,它会创建一些变量,如 _INCLUDE_DIRS 和 _LIBRARIES,供后续使用。
  • 示例:
    # 查找 Boost 库的 1.67 或更高版本,并要求必须找到 Components(组件) a aio 和 thread
    find_package(Boost 1.67 REQUIRED COMPONENTS system thread)# 如果找到了 Boost
    if(Boost_FOUND)# 添加 Boost 的头文件路径target_include_directories(app PRIVATE ${Boost_INCLUDE_DIRS})# 链接 Boost 的库target_link_libraries(app PRIVATE ${Boost_LIBRARIES})
    endif()
    

流程控制和信息输出

1 if()/elseif()/else()/endif()

  • 用处: 提供条件判断逻辑,可以根据不同的平台、编译选项或变量值执行不同的 CMake 命令。
  • 示例:
    # 根据操作系统设置不同的宏
    if(WIN32)target_compile_definitions(app PRIVATE OS_WINDOWS)
    elseif(APPLE)target_compile_definitions(app PRIVATE OS_MACOS)
    else()target_compile_definitions(app PRIVATE OS_LINUX)
    endif()
    

2 message()

  • 用处: 在 CMake 配置阶段向终端输出信息,常用于调试或显示状态信息。
  • 模式:
    • STATUS: 常规状态信息。
    • WARNING: 警告信息。
    • FATAL_ERROR: 严重错误,会终止 CMake 的执行。
  • 示例:
    # 输出 C++ 编译器的路径
    message(STATUS "CXX compiler is: ${CMAKE_CXX_COMPILER}")# 如果未找到 Boost,则输出错误并停止
    if(NOT Boost_FOUND)message(FATAL_ERROR "Boost library is not found!")
    endif()
    

3 add_subdirectory()

  • 用处: 添加一个子目录到构建系统中。CMake 会进入该子目录并执行其下的 CMakeLists.txt 文件。这对于组织大型、多模块的项目至关重要。
  • 示例:
    假设项目结构如下:
    .
    ├── CMakeLists.txt
    ├── main.cpp
    └── math_lib/├── CMakeLists.txt└── src/└── add.cpp
    
    顶层 CMakeLists.txt:
    cmake_minimum_required(VERSION 3.10)
    project(MainApp CXX)# 添加 math_lib 子目录,CMake会去执行 math_lib/CMakeLists.txt
    add_subdirectory(math_lib)add_executable(app main.cpp)# 链接子目录中创建的库
    target_link_libraries(app PRIVATE math)
    
    math_lib/CMakeLists.txt:
    # 创建一个名为 "math" 的库
    add_library(math src/add.cpp)# 将 "math" 库的头文件目录暴露出去,以便上层目标可以使用
    target_include_directories(math PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
    

希望这份总结能帮助你快速上手 CMake!

http://www.lryc.cn/news/595506.html

相关文章:

  • 三大工厂设计模式
  • Oracle自治事务——从问题到实践的深度解析
  • mcu中的调试接口是什么?
  • 阿里思想学习-如何优化大事务提交
  • JAVA后端开发—— JWT(JSON Web Token)实践
  • c语言----文件操作
  • 上海RISC-V峰会-香山开源RISC-V CPU随想随记
  • 软件测试 —— A / 入门
  • 从0开始学习R语言--Day53--AFT模型
  • react-window 大数据列表和表格数据渲染组件之虚拟滚动
  • Spring关于依赖注入的几种方式和Spring配置文件的标签
  • 面试总结第54天微服务开始
  • Spring处理器和Bean的生命周期
  • 线程池与ThreadPoolExecutor源码解析(上)
  • 暴力破解练习
  • Pandas - JSON格式数据操作实践
  • AV1平滑缓冲区
  • iostat的使用说明
  • MongoDB 查询时区问题
  • GUI简介
  • Kafka 如何优雅实现 Varint 和 ZigZag 编码
  • 【每天一个知识点】非参聚类(Nonparametric Clustering)
  • 期权到期会对大盘有什么影响?
  • 如何用 Z.ai 生成PPT,一句话生成整套演示文档
  • 【操作篇】群晖NAS用root权限直接访问系统分区文件
  • 圆柱电池自动分选机:全流程自动化检测的革新之路
  • 83、形式化方法
  • 淘宝获取商品分类接口操作指南
  • MySQL介绍和MySQL包安装
  • accelerate 在Pycham中执行的设置方法