目录
一、变量相关命令
1. 定义变量
2. 设置C++标准
3. 设置输出路径
二、文件相关命令
1. file 命令
2. aux_source_directory 命令
2. include_directories 命令
三、字符串相关命令
1. 字符串输出
2. 字符串拼接
3. 字符串移除
前情提示:【Make编译控制 06】CMake初步使用-CSDN博客
在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 不同是取变量的值只能用 ${}
# 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
# 在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]#
如果一个项目里边的源文件很多,在编写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]#
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]#
在编译项目源文件的时候,如果源文件和其对应的头文件不在同一个目录下,那么就需要将源文件对应的头文件路径指定出来,这样才能保证在编译过程中编译器能够找到这些头文件,并顺利通过编译。
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]#
# 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]#
有时候项目中的源文件并不一定都在同一个目录中,但是这些源文件最终却需要一起进行编译来生成最终的可执行文件或者库文件。如果我们通过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命令的功能比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]#
我们在通过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 [ ...])
命令原型可以看到删除和追加数据类似,只不过是第一个参数变成了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]#