1. CMakeLists.txt导览
1.1 cmake介绍
- cmake是GNU工具链中构建项目的重要一环,Linux常用,Windows下有cmake软件
- cmake根据CMakeLists.txt生成一个编译规则(Makefile文件)
- 编译器逐个文件进行编译,生成中间件,Makefile是将中间件统一编译的规则
- 查看cmake版本:cmake --version
1.2 CMakeLists.txt介绍
- 项目构建,每个需要管理的目录下均存在一个CMakeLists.txt
- CMakeLists.txt大小写敏感
- 在需要进行编译的文件夹内编写CMakeList.txt,.cpp/.c的文件夹内
- 通常将下层目录编译成一个静态库文件,让上层目录直接读取和调用,而上层目录就直接生成一个可执行文件
- 在最顶层创建build或cmake目录,然后编译
1.3 cmake构建方式
mkdir cmake && cd cmake
cmake .. # 指定CMakeLists.txt所在目录,cmake实际是做了一个转换,将CMakeLists.txt转换成Makefile文件
make project_name # 然后由make进行编译,输出project文件
./project_name # 运行可执行文件
2. CMakeLists.txt基本结构
# 简单举例:
cmake_minimum_required(VERSION 3.9) # cmake版本【可省略】
project(my_project) # 项目名称
add_executable # 添加源文件
target_include_directories # 添加头文件
target_link_directories # 库文件目录
target_link_libraries # 链接库文件
3. 命令介绍
1. set
功能:给文件名/路径名/源文件/库文件等起别名
set(变量 文件名/路径名/库文件/源文件)
set(THIRD_PARTY /data/libcommon.so) // 显示定义变量, 用变量代替值
2. target_link_libraries
功能:
将目标文件与库文件进行链接,不然会出现光声明没定义的错误
# 对add_executable生成的文件进行链接操作
# 库文件名称通常为libxxx.so,链接时只需要写xxx即可 */
target_link_libraries(main THIRD_PARTY) # THIRD_PARTY是多个库文件的别名
target_link_libraries(main xxx.so)
target_link_libraries(main xxx.a)
3. if else
功能:条件控制语句
### 方式1: ###
if()
# do something
endif()
### 方式2: ###
if(condition1)
# do something
elseif(condition2)
# do something
else()
# do something
endif()
if (DEFINED cpu AND "${cpu}" STREQUAL "x86")
set(THIRD_PARTY /x86/.../xx.so)
else()
set(THIRD_PARTY /arm/.../xx.so)
endif()
# DEFINED: 是否定义过
# AND/OR/NOT:与或非
4. -D和-G选项
功能:
-D: 使用cmake -D 创建一个要用的编译类型的cmake缓存
-G:设置指定的生成器,generator,可以设置IDE
# CMakeLists.txt中使用:
if (TARGET_CPU STREQUAL "x86")
# do something
else()
# do something
endif()
5. file
功能:
查找头文件/源文件
file参数较多,还有WRITE/READ/RENAME/REMOVE等参数
file(GLOB HEADER_FILES ${DIR}/*.h) # 查找DIR目录下所有头文件并保存到HEADER_FILES变量里
file(GLOB_RECURSE SRC_FILES ${DIR}/*.cpp) # 查找DIR目录下所有源文件并保存到SRC_FILES变量里
# GLOB和GLOB_RECURSE推荐使用RECURSE递归版本,避免源文件添加或删除引起识别错误
6. add_executable
功能:
添加不同项目要编译的可执行文件
将.cpp/.c/.cc等文件生成可执行文件
# add_executable(${PROJECT_NAME} xxx.cpp)
project(test)
add_executable(test ${SRC_FILES1} ${SRC_FILES2})
7. option
功能:
提供一个用户可以选择的选项:ON 或 OFF, 如果不提供初始值,默认为OFF
8. add_definitions
功能:
相当于添加编译宏,方便通过命令行而不是改代码进行参数控制
或用于添加编译选项
option(TORCH_DEBUG "option for torch debug" OFF)
if(TORCH_DEBUG)
add_definitions(-DTORCH_DEBUG)
endif(TORCH_DEBUG)
/* 源文件中 */
#ifdef TORCH_DEBUG
...
#else
...
#endif
- 构建项目的时候就可以添加参数控制宏的开启和关闭
cmake -DTORCH_DEBUG=ON .. # 打开
cmake -DTORCH_DEBUG=OFF .. # 关闭
# 添加编译选项
add_definitions("-Wall -g") # 显示所有类型log,用于gdb调试
9. target_include_directories
功能:
指定编译target所需要的头文件路径
# PUBLIC和INTERFACE具有依赖传递性,而PRIVATE没有
PRIVATE: 指这里引用的头文件路径仅仅被这个目标使用,目标不会对外暴露引用的头文件路径
PUBLIC:不仅被这个目标使用,目标还会对外暴露引用的头文件路径
INTERFACE:引用头文件不被这个目标使用,但目标会对外暴露引用的头文件路径
10. target_link_directories
功能:
目标添加链接库的查找目录,只是提供目录,具体链接库文件通过 target_link_libraries 添加
用法和 target_include_directories 基本类似
# target_link_libraries # 链接单个库文件或库文件目录下的所有库文件
# target_include_directories # 包含头文件
# 举例
target_link_directories(test PRIVATE ${OFFLINE_LIB})
11. target_compile_definitions
功能:目标添加编译器编译选项
12. message
功能:打印消息
message([mode] "message to display" ...)
mode: 模式,可不写;有STATUS/ERROR/DEBUG/TRACE等选项, STATUS表示一般的打印信息
"..." 为要显示的内容
... 表示可以连接多个输出
message(${STRING}) # 打印STRING变量值
13. add_subdirectory
功能:
添加编译的子文件夹
当执行到 add_subdirectory 这一句时会先将子文件夹进行编译生成库文件等
在 add_subdirectory 之前set的各个变量,包括子文件中生成的库文件,在子文件夹中可以调用
子文件夹里添加CMakeList.txt就可进行编译
# 代码结构
|--- example.cpp
|--- CMakeLists.txt # add_subdirectory(SubDir)
|--- SubDir
|-- subExample.xpp
|-- subHeader.h
|-- CMakeLists.yxy
|--- ThirdParty
|--- bin # 可执行文件
|--- include # 头文件
|--- lib # 库文件
14. aux_source_directory
功能:获取路径下所有的源文件.cpp/.c/.cc文件,并赋值给变量中
# aux_source_directory(路径 变量)
aux_source_directory(${PROJECT_SRC_DIR} SRC_FILES)
参考文章:
cmake: 推荐阅读
编译选项介绍
cmake基本用法
cmake备忘录
created by shuaixio, 2021.07.30