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 脚本正确执行的基础。。

相关推荐
myloveasuka5 小时前
Java与C++多态访问成员变量/方法 对比
java·开发语言·c++
2301_821700535 小时前
C++编译期多态实现
开发语言·c++·算法
奥地利落榜美术生灬5 小时前
c++ 锁相关(mutex 等)
开发语言·c++
xixihaha13245 小时前
C++与FPGA协同设计
开发语言·c++·算法
小小怪7506 小时前
C++中的函数式编程
开发语言·c++·算法
Yupureki6 小时前
《MySQL数据库基础》1. 数据库基础
c语言·开发语言·数据库·c++·mysql·oracle·github
汉克老师8 小时前
GESP2026年3月认证C++二级( 第二部分判断题(1-10))
c++·gesp三级·gesp3级
样例过了就是过了8 小时前
LeetCode热题100 N 皇后
数据结构·c++·算法·leetcode·dfs·深度优先遍历
C++ 老炮儿的技术栈10 小时前
Linux 文件系统目录架构全解析
linux·服务器·c语言·开发语言·c++
样例过了就是过了11 小时前
LeetCode热题100 分割回文串
数据结构·c++·算法·leetcode·深度优先·dfs