Cmake学习笔记
- Cmake-Cookbook
- 1、cmake中相关路径
- 2、cmake常用变量、函数、语法
- 3、引入第三方库
- 4、静态库与动态库
- 5、Gcc、G++区别
- 6、CMAKE_TOOLCHAIN_FILE交叉编译
- 7、Cmake Option
- 8、cmake COMPILE_FLAGS
- 9、Norma Variables和Cache Variables
- 10、在目录中查找所有源文件
- 11、超级构建ExternalProject_Add添加/在线下载外部项目并编译
- 12、cmake -D -G -P -Wdey 及编译器相关
- 13、add_library、target_link_libraries、target_include_directories
- 14、CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
- 15、CMake: Public VS Private VS Interface
- 16、编译特性和语言标准
- 17、target_compile_definitions及预处理器
- 18、查询运行CMake的主机系统的系统信息及处理器指令集检测
- 19、`find_package`命令找到Python解释器
- 20、test测试enable_testing、add_test()
- 21 install安装
- 涉及的相关第三方库
Cmake-Cookbook
相关资料整理:
原仓库:https://github.com/dev-cafe/cmake-cookbook
陈晓伟对CMake-Cookbook的中文翻译:https://github.com/xiaoweiChen/CMake-Cookbook
CMake-Cookbook中文目录
官方文档: https://cmake.org/cmake/help/v3.12/manual/cmake-buildsystem.7.html#object-libraries
写在前面,常用的一些cmake命令
一、编译项目
mkdir build
cd build
cmake ..
二、构建项目生成可执行文件
cmake --build . --config Release
备注:等同于Cmakelists.txt中set(CMAKE_BUILD_TYPE Release CACHE STRING “Build type” FORCE)。在build时,利用config设置编译类型。
三、安装
设置安装路径并执行安装命令
cmake -DCMAKE_INSTALL_PREFIX=E:\cmakeoutput ..
cmake --build . --target install --config Release
1、cmake中相关路径
```bash
CMAKE_SOURCE_DIR: 顶级cmakelists.txt的文件夹目录。
CMAKE_BINRAY_DIR: 对应cmake的build的目录,主要是运行时生成的文件目录。
CMAKE_CURRENT_SOURCE_DIR: 一般来说,一个工程会有多个cmakelists.txt文件,对应当前文件目录。
CMAKE_CURRENT_BINARY_DIR: 对应build里的目录。
CMAKE_MODULE_PATH: api(include/find_package)包含别的cmake文件时的搜索目录。
CMAKE_PREFIX_PATH: api(find_libray/path)包含模块时的搜索目录。
CMAKE_INSTALL_PREFIX: 调用install相关函数,要生成/保存的根目录路径。
PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR是等价的。也就是当前源码的目录
CMAKE_SIZEOF_VOID_P 空指针的大小 EQUAL 8表示64位 EQUAL 4表示32位
CMAKE_HOST_SYSTEM_PROCESSOR 运行CMake的CPU的名称
2、cmake常用变量、函数、语法
变量
project(recipe-04 VERSION 2.0.1 LANGUAGES C)
PROJECT_VERSION_MAJOR #2
PROJECT_VERSION_MINOR #0
PROJECT_VERSION_PATCH #1
PROJECT_VERSION #cmake中的版本号变量
CMAKE_CXX_COMPILER_ID 编译器ID
CMAKE_SYSTEM_NAME 当前系统名字
BUILD_SHARED_LIB 是一个全局变量,主要是用于控制cmake是否可以生成动态so
语法
set 设置参数,包含一般/缓存/环境变量。
unset 取消设置参数
EXISTS #判断文件是否存在
list 针对列表操作,比如针对文件列表/参数列表/编译列表的增加删除这些。
list(APPEND _sources Message.hpp Message.cpp) 向_source变量添加源文件
string 针对字符串的操作,如大小写,查找,正则表达式匹配等。
message 打印消息,可以跟踪测试修改。
add_compile_options:不同平台一般来说有不同的编译设置。
add_definitions:添加预处理器定义。
include_directories: 如visual studio里的,头文件搜索目录,在当前项目以及当前项目用add_subdirectory添加的项目都会应用。
target_sources(helloworld xxx.cpp)#向依赖库中添加源文件
target_include_directories:针对指定目标的include_directories。
link_libraries: 添加库文件路径,注意是全路径,如果是本方案的项目,直接使用项目名就行。在当前项目以及当前项目用add_subdirectory添加的项目都会应用。
target_link_libraries:指定目标的link_directories。
add_library:添加库,根据参数生成静态或是动态库。
add_executable:添加执行文件。
set_target_properties:指定项目一些具体编辑器里的属性,如生成lib/dll的目录。
target_compile_definitions: 添加预处理器定义
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
message(STATUS "Configuring on/for Linux")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
message(STATUS "Configuring on/for Windows")
configure_file 可将cmake中的变量值传到.h.in文件变量中,然后生成转换成.h文件
configure_file(foo.h.in foo.h @ONLY) cmake-cookbook 2章4节
find_program # This command is used to find a program.
file:
file 针对文件操作,如收集文件列表,读写文件等。
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/helloworld.cpp helloworld) #读取当前目录下的helloworld.cpp文件为helloworld变量
file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path )
TO_NATIVE_PATH模式将cmake样式
语法:
# 字符串中添加变量
target_compile_definitions(hello-world PUBLIC "COMPILER_NAME=\"${CMAKE_CXX_COMPILER_ID}\"")
# 如果`MPI_FOUND`为真,那么` $<BOOL:${
MPI_FOUND}>`的值将为1
$<$<BOOL:${
MPI_FOUND}>:MPI::MPI_CXX>
foreach(<loop_var> <items>)
<commands>
endforeach()
其中< items >是用分号或空格分隔的项列表。foreach和匹配的endforeach之间的所有命令都被记录,而没有被调用。一旦endforeach被求值,记录的命令列表将为< items >中的每个项调用一次。在每次迭代开始时,变量< loop_var >将被设置为当前项的值。`
2.1 add_custom_command、add_custom_target
1. 使用`add_custom_command`编译目标,生成输出文件。
2. `add_custom_target`的执行没有输出。
3. 构建目标前后,`add_custom_command`的执行可以没有输出。
add_custom_target添加一个具有给定名称的目标,以执行给定命令。目标没有输出文件,即使命令试图创建具有目标名称的文件,也始终被视为过期。使用add_custom_command()命令生成具有依赖项的文件。默认情况下,任何内容都不依赖于自定义目标。使用add_dependencies()命令向其他目标或从其他目标添加依赖项。
add_custom_target(unpack-eigen
ALL
COMMAND
${
CMAKE_COMMAND} -E tar xzf ${
CMAKE_CURRENT_SOURCE_DIR}/eigen-eigen-5a0156e40feb.tar.gz
COMMAND
${
CMAKE_COMMAND} -E rename eigen-eigen-5a0156e40feb eigen-3.3.4
WORKING_DIRECTORY
${
CMAKE_CURRENT_BINARY_DIR}
COMMENT
"Unpacking Eigen3 in ${CMAKE_CURRENT_BINARY_DIR}/eigen-3.3.4"
)
add_dependencies(linear-algebra unpack-eigen)#指定可执行目标对自定义目标的依赖关系
add_custom_command(
OUTPUT
${
wrap_BLAS_LAPACK_sources}
COMMAND
${
CMAKE_COMMAND} -E tar xzf ${
CMAKE_CURRENT_SOURCE_DIR}/wrap_BLAS_LAPACK.tar.gz
COMMAND
${
CMAKE_COMMAND} -E touch ${
wrap_BLAS_LAPACK_sources}
WORKING_DIRECTORY
${
CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${
CMAKE_CURRENT_SOURCE_DIR}/wrap_BLAS_LAPACK.tar.gz
COMMENT
"Unpacking C++ wrappers for BLAS/LAPACK"
VERBATIM
)
2.2 CMakePrintHelpers模块
include(CMakePrintHelpers)
cmake_print_properties(
TARGETS MPI::MPI_CXX
PROPERTIES INTERFACE_LINK_LIBRARIES
)
2.3 include(GNUInstallDirs)模块
此模块帮助设置.lib .dll .pdb文件的输出路径
include(GNUInstallDirs)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${
CMAKE_BINARY_DIR}/${
CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${
CMAKE_BINARY_DIR}/${
CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${
CMAKE_BINARY_DIR}/${
CMAKE_INSTALL_BINDIR})
2.4 execute_process执行命令
类似于cmd命令之类,whoami是返回系统用户名
execute_process(COMMAND <cmd1> [<arguments>]
[COMMAND <cmd2> [<arguments>]]...
[WORKING_DIRECTORY <directory>]
[TIMEOUT <seconds>]
[RESULT_VARIABLE <variable>]
[RESULTS_VARIABLE <variable>]
[OUTPUT_VARIABLE <variable>]
[ERROR_VARIABLE <variable>]
[INPUT_FILE <file>]
[OUTPUT_FILE <file>]
[ERROR_FILE <file>]
[OUTPUT_QUIET]
[ERROR_QUIET]
[COMMAND_ECHO <where>]
[OUTPUT_STRIP_TRAILING_WHITESPACE]
[ERROR_STRIP_TRAILING_WHITESPACE]
[ENCODING <name>]
[ECHO_OUTPUT_VARIABLE]
[ECHO_ERROR_VARIABLE]
[COMMAND_ERROR_IS_FATAL <ANY|LAST>])
execute_process( # 执行一个子进程
COMMAND ${
GIT_EXECUTABLE} log -1 --pretty=format:%h # 命令
OUTPUT_VARIABLE ${
_git_hash} # 输出字符串存入变量
OUTPUT_STRIP_TRAILING_WHITESPACE # 删除字符串尾的换行符
ERROR_QUIET # 对执行错误静默
WORKING_DIRECTORY # 执行路径
${
CMAKE_CURRENT_SOURCE_DIR}
)
2.5 macro自定义宏、function函数
(1)${ARGC}保存给定宏的所有参数数量。
(2)${ARGV} 保存给定宏的所有参数列表。
(3)${ARGN}保存超过最后一个预期参数的参数列表,即额外参数列表。
macro(宏名称 参数1 参数2 ...)
...
endmacro()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake&