当前位置: 首页 > 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.dtcms.com/a/290087.html

相关文章:

  • GC9118S低压单通道全桥驱动器芯片详解
  • Effective Modern C++ 条款15:尽可能的使用constexpr
  • 17 BTLO 蓝队靶场 Pretium 解题记录
  • Windows GCC修改链接脚本文件实现section块存储函数
  • LVS 集群技术基础
  • docker--挂载
  • Docker安装Elasticsearch 7.17.0和Kibana 7.17.0并配置基础安全
  • 悬镜安全将受邀参加2025开放原子开源生态大会
  • Curtain e-locker 易锁防泄密:无需网络隔离,实现安全与效率并存
  • 量子生成对抗网络:量子计算与生成模型的融合革命
  • uni-api交互反馈组件(showToast)的用法
  • 宝塔面板Nginx报错: IP+端口可以直接从访问,反向代理之后就504了 Gateway Time-out
  • 农村供水智慧化管理系统:从精准监测到智能调度,破解农村用水安全与效率难题
  • MySQL 事务死锁排查:从日志分析到解决实战
  • 某日在某个月份中不存在导致软件出现异常的问题排查(判断闰年以及月份中的天数,附完整源码)
  • 低代码平台能否完全取代传统前端开发
  • Bun v1.2.19发布,node_modules隔离,sql比node快6倍
  • MySQL:表的增删查改
  • 【跨国数仓迁移最佳实践2】MaxCompute SQL执行引擎对复杂类型处理全面重构,保障客户从BigQuery平滑迁移
  • VUE如何设置语音
  • 【实践篇】基于.venv 的 ComfyUI 环境同配置迁移:pyvenv.cfg 路径修改法
  • leetcode-sql-627变更性别
  • 植物根茎切片图像处理与分析系统开发
  • 【大模型】结构化提示词:让AI高效完成复杂任务的“编程语言”
  • 虚拟机扩展磁盘容量后扩展分区大小
  • 部署 Zabbix 企业级分布式监控
  • 【图像处理基石】什么是相机的内外参数?
  • 在Windows Server 2012 R2中安装与配置IIS服务并部署mssql靶机教程
  • 在Web API 开发中践行Security by Default原则
  • 【操作篇】群晖NAS用root权限直接访问系统分区文件