CMake几个命令顺序

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


在 CMake 中,target_include_directoriestarget_link_directoriesadd_librarytarget_link_libraries 的使用存在明确的先后顺序 ,核心原则是:先创建目标(add_library),再配置目标的属性(target_include_directoriestarget_link_directories),最后链接依赖(target_link_libraries。同时,被链接的目标(如库)必须在链接命令之前创建。

关键顺序规则:

  1. add_library 必须最先执行 :因为 target_* 系列命令(包括 target_include_directoriestarget_link_directoriestarget_link_libraries)的操作对象是"目标"(如库或可执行文件),必须先通过 add_library(或 add_executable 用于可执行文件)创建目标,否则 CMake 会报错"目标不存在"。
  2. target_include_directoriestarget_link_directories 需在目标创建后、链接前执行 :这两个命令是给目标设置"编译时头文件路径"和"链接时库路径",需要在目标被链接(target_link_libraries)前完成配置,否则可能导致编译或链接时找不到路径。
  3. target_link_libraries 需在被链接的目标创建后执行 :如果要链接的是通过 add_library 创建的自定义库,必须先通过 add_library 生成该库目标,再用 target_link_libraries 链接,否则会找不到依赖库。

示例说明

假设一个工程结构如下(多模块项目,包含一个自定义库 mylib 和一个依赖它的可执行文件 myapp):

复制代码
project/
├── CMakeLists.txt
├── include/          # 公共头文件目录
│   └── mylib.h
├── src/
│   ├── mylib.cpp     # 库的源文件
│   └── main.cpp      # 可执行文件的源文件

对应的 CMakeLists.txt 正确顺序如下:

cmake 复制代码
# 1. 最低版本要求(必须在 project 前)
cmake_minimum_required(VERSION 3.10)
# 2. 定义项目
project(MyProject LANGUAGES CXX)

# --------------------------
# 步骤1:创建库目标(add_library 必须先执行)
# --------------------------
add_library(mylib STATIC
    src/mylib.cpp       # 库的源文件
)

# --------------------------
# 步骤2:配置库的头文件路径(target_include_directories 在目标创建后)
# --------------------------
# 为 mylib 设置头文件目录,PUBLIC 表示依赖 mylib 的目标(如 myapp)会自动继承该路径
target_include_directories(mylib PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/include  # 公共头文件目录
)

# --------------------------
# 步骤3:创建可执行目标(依赖 mylib,需在链接前创建)
# --------------------------
add_executable(myapp
    src/main.cpp        # 可执行文件的源文件
)

# --------------------------
# 步骤4:(可选)配置可执行文件的链接路径(如果有额外库路径)
# --------------------------
# 假设 myapp 还需要链接第三方库,其路径在 ./third_party/lib
target_link_directories(myapp PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/third_party/lib
)

# --------------------------
# 步骤5:链接依赖库(target_link_libraries 在被链接目标创建后)
# --------------------------
# 让 myapp 链接自定义库 mylib(mylib 已通过 add_library 创建)
# 同时链接第三方库(如 pthread 或其他)
target_link_libraries(myapp PRIVATE
    mylib           # 自定义库(必须先通过 add_library 创建)
    pthread         # 系统库(无需提前创建)
)

顺序解释:

  1. add_library(mylib ...) 先执行 :创建库目标 mylib,后续的 target_include_directories(mylib ...) 才能操作这个目标。
  2. target_include_directories(mylib ...) 紧随其后 :为 mylib 设置头文件路径,由于用了 PUBLIC,后续依赖 mylibmyapp 会自动继承这个路径(无需再给 myapp 重复设置 include 目录)。
  3. add_executable(myapp ...) 创建可执行目标myapp 是最终要生成的程序,必须先创建才能对其配置链接路径和依赖。
  4. target_link_directories(myapp ...) 配置链接路径 :如果 myapp 需要链接额外的第三方库,需在链接前指定其路径(否则链接器可能找不到库文件)。
  5. target_link_libraries(myapp ...) 最后链接 :此时 mylib 已存在,myapp 的链接路径也已配置,链接操作才能正常执行。

错误顺序的后果:

  • 如果在 add_library(mylib) 之前调用 target_include_directories(mylib ...),CMake 会报错:Cannot specify include directories for target "mylib" which is not built by this project(目标不存在)。
  • 如果在 add_library(mylib) 之前调用 target_link_libraries(myapp mylib),CMake 会报错:Target "myapp" links to target "mylib" which is not built by this project(被链接的目标不存在)。

因此,严格遵循"先创建目标 → 再配置属性 → 最后链接依赖"的顺序是保证 CMake 脚本正确执行的基础。。

相关推荐
weixin_4617694015 小时前
15. 三数之和
c++·算法·leetcode·三数之和
小镇学者16 小时前
【c++】C++字符串删除末尾字符的三种实现方法
java·开发语言·c++
ue星空16 小时前
R3注入反截图
c++
塔尖尖儿16 小时前
For循环中++i与i++有什么不一样?
c++
Ralph_Y17 小时前
C++虚继承
开发语言·c++
ZzZz_ing17 小时前
2026 - 零碎知识随记录
c++
SweetCode17 小时前
【无标题】
开发语言·c++·算法
王老师青少年编程17 小时前
信奥赛C++提高组csp-s之拓扑排序详解
c++·算法·拓扑排序·csp·信奥赛·csp-s·提高组
xie_pin_an18 小时前
C++ 从入门到进阶:核心知识与实战指南
java·c++·算法