【Make编译控制 07】CMake常用命令

本文详细介绍了CMake中的变量定义、C++标准设置、输出路径配置、文件搜索命令(如file、aux_source_directory和include_directories)以及字符串操作(如输出、拼接和移除)等关键概念,帮助读者更好地理解和运用CMake进行项目构建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、变量相关命令

1. 定义变量

2. 设置C++标准

3. 设置输出路径

二、文件相关命令

 1. file 命令

2. aux_source_directory 命令

2. include_directories 命令

三、字符串相关命令

1. 字符串输出

2. 字符串拼接

3. 字符串移除


前情提示:【Make编译控制 06】CMake初步使用-优快云博客

一、变量相关命令

1. 定义变量

在CMake初步使用的例子中出现了3个源文件,假设这3个源文件需要被反复使用,那么每次都直接将这3个源文件名称都列出来会很麻烦,此时我们可以定义一个变量,将多个源文件的名称作为一个字符串变量存储起来,在CMake里面定义变量需要 set 关键字。

# SET 指令的语法是:
# [] 中的参数为可选项, 如不需要可以不写
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
# set(SRC_LIST add.cpp;sub.cpp;main.cpp)
set(SRC_LIST add.cpp sub.cpp main.cpp)
add_executable(math.exe ${SRC_LIST})

# 与 Makefile 不同是取变量的值只能用 ${}

2. 设置C++标准

# C++标准对应有一宏叫做DCMAKE_CXX_STANDARD。
# 在CMake中想要指定C++标准有两种方式:

# 1. 在 CMakeLists.txt 中通过 set 命令指定
# -std=c++11
set(CMAKE_CXX_STANDARD 11)

# 2. 在执行 cmake 命令的时候指定出这个宏的值
# cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=11

3. 设置输出路径

# 在CMake中指定可执行程序输出的路径,也对应一个宏,叫做EXECUTABLE_OUTPUT_PATH

set(HOME /root/gitee/Test/Make_Learn/10_test)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
# 第一行:定义一个变量用于存储一个绝对路径
# 第二行:将拼接好的路径值设置给EXECUTABLE_OUTPUT_PATH宏
# 如果这个路径中的子目录不存在,会自动生成

# 由于可执行程序是基于 cmake 命令生成的 makefile 文件然后再执行 make 命令得到的,
# 所以如果此处指定可执行程序生成路径的时候使用的是相对路径 ./xxx/xxx,
# 那么这个路径中的 ./ 对应的就是 makefile 文件所在的那个目录。
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# make
Scanning dependencies of target math.exe
[ 33%] Building CXX object CMakeFiles/math.exe.dir/add.cpp.o
[ 66%] Building CXX object CMakeFiles/math.exe.dir/sub.cpp.o
[100%] Building CXX object CMakeFiles/math.exe.dir/main.cpp.o
Linking CXX executable ../bin/math.exe
[100%] Built target math.exe
(base) [root@localhost build]# cd ..
(base) [root@localhost 10_test]# ls
add.cpp  add.h  bin  build  CMakeLists.txt  main.cpp  sub.cpp  sub.h
(base) [root@localhost 10_test]# ./bin/math.exe 
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost 10_test]# 

二、文件相关命令

 1. file 命令

如果一个项目里边的源文件很多,在编写CMakeLists.txt文件的时候不可能将项目目录的各个文件一一罗列出来,这样太麻烦也不现实。

所以我们可以通过 CMake 提供给我们的搜索文件命令,快速地获得某个路径下的所有源文件。

file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径及文件类型)
# GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。
# GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。
# CMakeLists.txt 文件

cmake_minimum_required(VERSION 2.8)
project(MATH)

file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

add_executable(math.exe ${SRC_LIST})

set(CMAKE_CXX_STANDARD 11)

set(HOME /root/gitee/Test/Make_Learn/10_test)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# make
Scanning dependencies of target math.exe
[ 33%] Building CXX object CMakeFiles/math.exe.dir/add.o
[ 66%] Building CXX object CMakeFiles/math.exe.dir/main.o
[100%] Building CXX object CMakeFiles/math.exe.dir/sub.o
Linking CXX executable ../bin/math.exe
[100%] Built target math.exe
(base) [root@localhost build]# ../bin/math.exe 
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost build]# 

2. aux_source_directory 命令

aux_source_directory(< dir > < variable >)
# dir:要搜索的目录
# variable:将从dir目录下搜索到的源文件列表存储到该变量中
# 相比于 file 命令,aux_source_directory 命令可以自动选择源文件
# CMakeLists.txt 文件

cmake_minimum_required(VERSION 2.8)
project(MATH)

aux_source_directory(${PROJECT_SOURCE_DIR} SRC_LIST)
# PROJECT_SOURCE_DIR 宏表示的路径是使用 cmake 命令时后面跟随的路径
# CMAKE_CURRENT_SOURCE_DIR 宏表示的路径是 CMakeLists.txt 文件的路径
# PROJECT_SOURCE_DIR 和 CMAKE_CURRENT_SOURCE_DIR 是同一个路径

add_executable(math.exe ${SRC_LIST})

set(CMAKE_CXX_STANDARD 11)

set(HOME /root/gitee/Test/Make_Learn/10_test)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# make
Scanning dependencies of target math.exe
[ 33%] Building CXX object CMakeFiles/math.exe.dir/add.o
[ 66%] Building CXX object CMakeFiles/math.exe.dir/main.o
[100%] Building CXX object CMakeFiles/math.exe.dir/sub.o
Linking CXX executable ../bin/math.exe
[100%] Built target math.exe
(base) [root@localhost build]# ../bin/math.exe 
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost build]# 

2. include_directories 命令

在编译项目源文件的时候,如果源文件和其对应的头文件不在同一个目录下,那么就需要将源文件对应的头文件路径指定出来,这样才能保证在编译过程中编译器能够找到这些头文件,并顺利通过编译。

include_directories(headpath)
# 将项目代码存储在如下路径:

(base) [root@localhost 10_test]# tree .
.
├── build
├── CMakeLists.txt
├── include
│   ├── add.h
│   └── sub.h
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

3 directories, 6 files
(base) [root@localhost 10_test]#
# CMakeLists.txt 文件

cmake_minimum_required(VERSION 2.8)
project(MATH)

aux_source_directory(${CMAKE_SOURCE_DIR}/src SRC_LIST)
include_directories(${PROJECT_SOURCE_DIR}/include)
add_executable(math.exe ${SRC_LIST})

set(CMAKE_CXX_STANDARD 11)

set(HOME /root/gitee/Test/Make_Learn/10_test)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
(base) [root@localhost 10_test]# tree .
.
├── build
├── CMakeLists.txt
├── include
│   ├── add.h
│   └── sub.h
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

3 directories, 6 files
(base) [root@localhost 10_test]# cd build/
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# make
Scanning dependencies of target math.exe
[ 33%] Building CXX object CMakeFiles/math.exe.dir/src/add.o
[ 66%] Building CXX object CMakeFiles/math.exe.dir/src/main.o
[100%] Building CXX object CMakeFiles/math.exe.dir/src/sub.o
Linking CXX executable ../bin/math.exe
[100%] Built target math.exe
(base) [root@localhost build]# ../bin/math.exe 
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost build]# 

三、字符串相关命令

1. 字符串输出

# message 命令可输出字符串,常用于调试

message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
# (无) :重要消息
# STATUS :非重要消息
# WARNING:CMake 警告, 会继续执行
# AUTHOR_WARNING:CMake 警告 (dev), 会继续执行
# SEND_ERROR:CMake 错误, 继续执行,但是会跳过生成的步骤
# FATAL_ERROR:CMake 错误, 终止所有处理过程
# CMakeLists.txt 文件

cmake_minimum_required(VERSION 2.8)

message("hello cmake")
message(STATUS "hello cmake status")
message(WARNING "hello cmake warning")
message(FATAL_ERROR "hello cmake faltal_error")
message(STATUS "hello cmake status")
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
hello cmake
-- hello cmake status
CMake Warning at CMakeLists.txt:3 (message):
  hello cmake warning


CMake Error at CMakeLists.txt:4 (message):
  hello cmake faltal_error


-- Configuring incomplete, errors occurred!
See also "/root/gitee/Test/Make_Learn/10_test/build/CMakeFiles/CMakeOutput.log".
(base) [root@localhost build]# 

2. 字符串拼接

有时候项目中的源文件并不一定都在同一个目录中,但是这些源文件最终却需要一起进行编译来生成最终的可执行文件或者库文件。如果我们通过file命令对各个目录下的源文件进行搜索,最后还需要做一个字符串拼接的操作,关于字符串拼接可以使用 set 命令也或 list 命令。

# 方式1:通过 set 进行字符串拼接
# set(变量名1 ${变量名1} ${变量名2} ...)
# 关于上面的命令其实就是将从第二个参数开始往后所有的字符串进行拼接,
# 最后将结果存储到第一个参数中,如果第一个参数中原来有数据会对原数据就行覆盖。

cmake_minimum_required(VERSION 2.8)

file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*cpp)
file(GLOB INC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
set(ALL_FILES ${SRC_LIST} ${INC_LIST})

message(STATUS "SRC_LIST: ${SRC_LIST}")
message(STATUS "INC_LIST: ${INC_LIST}")
message(STATUS "ALL_FILES: ${ALL_FILES}")
(base) [root@localhost build]# cmake ..
-- SRC_LIST: /root/gitee/Test/Make_Learn/10_test/src/add.cpp;/root/gitee/Test/Make_Learn/10_test/src/main.cpp;/root/gitee/Test/Make_Learn/10_test/src/sub.cpp
-- INC_LIST: /root/gitee/Test/Make_Learn/10_test/include/add.h;/root/gitee/Test/Make_Learn/10_test/include/sub.h
-- ALL_FILES: /root/gitee/Test/Make_Learn/10_test/src/add.cpp;/root/gitee/Test/Make_Learn/10_test/src/main.cpp;/root/gitee/Test/Make_Learn/10_test/src/sub.cpp;/root/gitee/Test/Make_Learn/10_test/include/add.h;/root/gitee/Test/Make_Learn/10_test/include/sub.h
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# 
# 方式2:通过 list 进行字符串拼接
# list(APPEND <list> [<element> ...])
# list命令的功能比set要强大,字符串拼接只是它的其中一个功能,
# 所以需要在它第一个参数的位置指定出我们要做的操作,
# APPEND表示进行数据追加,后边的参数和set就一样了。

cmake_minimum_required(VERSION 2.8)

file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*cpp)
file(GLOB INC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
# set(ALL_FILES ${SRC_LIST} ${INC_LIST})
list(APPEND ALL_FILES ${INC_LIST} ${SRC_LIST})

message(STATUS "SRC_LIST: ${SRC_LIST}")
message(STATUS "INC_LIST: ${INC_LIST}")
message(STATUS "ALL_FILES: ${ALL_FILES}")
(base) [root@localhost build]# cmake ..
-- SRC_LIST: /root/gitee/Test/Make_Learn/10_test/src/add.cpp;/root/gitee/Test/Make_Learn/10_test/src/main.cpp;/root/gitee/Test/Make_Learn/10_test/src/sub.cpp
-- INC_LIST: /root/gitee/Test/Make_Learn/10_test/include/add.h;/root/gitee/Test/Make_Learn/10_test/include/sub.h
-- ALL_FILES: /root/gitee/Test/Make_Learn/10_test/include/add.h;/root/gitee/Test/Make_Learn/10_test/include/sub.h;/root/gitee/Test/Make_Learn/10_test/src/add.cpp;/root/gitee/Test/Make_Learn/10_test/src/main.cpp;/root/gitee/Test/Make_Learn/10_test/src/sub.cpp
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# 

3. 字符串移除

我们在通过file搜索某个目录就得到了该目录下所有的源文件,但是其中有些源文件并不是我们所需要的,比如在打包生成库的时候,我们就不需要包含有主函数的源文件。

(base) [root@localhost 10_test]# tree .
.
├── build
├── CMakeLists.txt
├── include
│   ├── add.h
│   └── sub.h
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

3 directories, 6 files
(base) [root@localhost 10_test]#

想要实现字符串的移除,也是同构 list 命令。

list(REMOVE_ITEM <list> <value> [<value> ...])

命令原型可以看到删除和追加数据类似,只不过是第一个参数变成了REMOVE_ITEM。

cmake_minimum_required(VERSION 2.8)

file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*cpp)

list(REMOVE_ITEM SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)

message(STATUS "SRC_LIST: ${SRC_LIST}")
(base) [root@localhost build]# cmake ..
-- SRC_LIST: /root/gitee/Test/Make_Learn/10_test/src/add.cpp;/root/gitee/Test/Make_Learn/10_test/src/sub.cpp
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# 

### 关于CMake编译命令详解 #### 初始化项目结构 为了使用CMake进行编译,首先需要创建一个`CMakeLists.txt`文件来定义项目的配置。此文件包含了指定源文件位置、设置可执行目标以及链接库所需的信息。 ```cmake project(MyProject) add_executable(myapp main.cpp) ``` 上述代码片段展示了最简单的CMake脚本例子[^1]。它声明了一个名为MyProject的工程,并指定了main.cpp作为构建myapp这个可执行程序的一部分。 #### 配置环境变量与选项 可以通过传递特定标志给CMake来自定义行为: - `-DCMAKE_BUILD_TYPE=Release`: 设置构建模式为发布版本,默认情况下会优化性能并移除调试信息。 - `-G "Unix Makefiles"` 或者其他生成器名称:告诉CMake要使用的构建工具链(例如Ninja, Xcode等) 运行如下命令来进行初步配置: ```bash mkdir build && cd build cmake .. ``` 这将在当前目录下创建一个新的子文件夹build用于存放所有的中间产物和最终二进制文件[^2]。 #### 构建过程中的常用操作 一旦完成了初始设定之后就可以调用下面这些常用的命令完成进一步的任务了: - `make` (或对应平台上的相应命令): 开始实际编译流程; - `ctest`: 执行测试套件; - `cpack`: 准备分发包; 如果想要清理之前产生的所有临时数据,则可以利用`make clean`清除掉不必要的缓存项以便重新开始新的迭代周期。 #### 添加外部依赖关系管理 当涉及到第三方库的时候,在`find_package()`函数的帮助下很容易集成进来。比如OpenCV这样的视觉处理框架只需要简单几行就能搞定其导入工作: ```cmake find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) target_link_libraries(myapp ${OpenCV_LIBS}) ``` 这段话意味着寻找安装好的OpenCV组件并且将其包含路径加入到我们的预处理器搜索列表里去同时还要把对应的静态/动态链接库关联起来形成完整的应用程序[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllinTome

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值