一、CMake常见的预置的宏
PROJECT_NAME: 通过PROJECT指定的项目名称
project(Demo)
PROJECT_SOURCE_DIR: 工程的根目录,上图中的Demo目录
PROJECT_BINARY_DIR: 执行cmake命令的目录,一般是在build目录,在此目录执行cmake ..
CMAKE_CURRENT_SOURCE_DIR: 当前CMakeLists.txt文件所在目录
CMAKE_CURRENT_BINARY_DIR: 编译目录,可使用ADD_SUBDIRECTORY来修改此变量
CMAKE_INCLUDE_PATH: 环境变量,非cmake变量
CMAKE_LIBRARY_PATH: 环境变量
CMAKE_CURRENT_LIST_FILE: 输出调用这个变量的CMakeLists.txt的完整路径
CMAKE_CURRENT_LIST_LINE: 输出这个变量所在的行
CMAKE_MODULE_PATH: 定义自己的cmake模块所在的路径
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
设置输出
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) //设置编译后可执行文件输出路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) //LIBRARY_OUTPUT_PATH: 库文件输出位置
常用系统信息变量
CMAKE_MAJOR_VERSION: cmake的主版本号cmake version 3.11.2中的3
CMAKE_MINOR_VERSION: cmake的次版本号cmake version 3.11.2中的11
CMAKE_PATCH_VERSION: cmake的补丁等级cmake version 3.11.2中的2
在这里插入图片描述
CMAKE_SYSTEM: 系统名称,带版本号
CMAKE_SYSTEM_NAME: 系统名称,不带版本号
CMAKE_SYSTEM_VERSION: 系统版本号
CMAKE_SYSTEM_PROCESSOR: 处理器名称
编译选项
BUILD_SHARED_LIBS: 默认的库编译方式(shared or static),默认为static,一般在ADD_LIBRARY时直接指定编译库的类型
CMAKE_C_FLAGS: 设置C编译选项
CMAKE_CXX_FLAGS: 设置C++编译选项
CMAKE_CXX_FLAGS_DEBUG: 设置编译类型为Debug时的编译选项
CMAKE_CXX_FLAGS_RELEASE: 设置编译类型为Release时的编译选项
CMAKE_CXX_COMPILER: 设置C++编译器
# 设置C++编译器为g++
set(CMAKE_CXX_COMPILER "g++")
# 设置标准库版本为c++17 并开启警告
set(CMAKE_CXX_FLAGS "-std=c++17 -Wall")
# 设置Debug模式下,不开启优化,开启调试,生成更详细的gdb调试信息
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -ggdb")
# 设置Release模式下,开启最高级优化
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
二、include_directories 和 target_include_directories的区别
参考:https://stackoverflow.com/questions/31969547/what-is-the-difference-between-include-directories-and-target-include-directorie
include_directories(x/y):添加头文件搜索目录, 对应的是CMakeLists文件里所有的target,报错include_subdirectory里添加的目标,都会去x/y目录下寻找头文件
target_include_directories(t x/y):添加头文件搜索目录,对应的是CMakeLists文件里某个特指的target t, target_include_directories() 支持使用 PRIVATE, PUBLIC,和INTERFACE qualifiers来修饰
三、区分是否是Android平台编译
add_definitions(-D ANDROID)
四、BUILD_INTERFACE
使用示例:
CMake构建一个静态链接库的实例
五、递归添加头文件搜索目录
# 定义函数,用于递归添加头文件搜索目录
function(include_sub_directories_recursively root_dir)
if (IS_DIRECTORY ${root_dir}) # 当前路径是一个目录吗,是的话就加入到包含目录
message("include dir: " ${root_dir})
include_directories(${root_dir})
endif()
file(GLOB ALL_SUB RELATIVE ${root_dir} ${root_dir}/*) # 获得当前目录下的所有文件,让如ALL_SUB列表中
foreach(sub ${ALL_SUB})
if (IS_DIRECTORY ${root_dir}/${sub})
include_sub_directories_recursively(${root_dir}/${sub}) # 对子目录递归调用,包含
endif()
endforeach()
endfunction()
六 GLOB 和 GLOB_RECURSE
#添加所有源文件,可定义文件格式。
#说明一下:GLOB_RECURSE
#file(GLOB_RECURSE variable [RELATIVE path]
# [FOLLOW_SYMLINKS] [globbingexpressions]...)
#GLOB_RECURSE 与GLOB类似,区别在于它会遍历匹配目录的所有文件以及子目录下面的文件。
#对于属于符号链接的子目录,只有FOLLOW_SYMLINKS指定一或者cmake策略CMP0009没有设置为NEW时,才会遍历这些目录。
#
#GLOB的使用方法:
# file(GLOB variable [RELATIVE path] [globbingexpressions]...)
#
#GLOB 会产生一个由所有匹配globbing表达式的文件组成的列表,并将其保存到变量中。
#Globbing 表达式与正则表达式类似,但更简单。如果指定了RELATIVE 标记,
#返回的结果将是与指定的路径相对的路径构成的列表。 (通常不推荐使用GLOB命令来从源码树中收集源文件列表。
#原因是:如果CMakeLists.txt文件没有改变,
#即便在该源码树中添加或删除文件,产生的构建系统也不会知道何时该要求CMake重新产生构建文件。
macro(rw_module_source_all)
file(GLOB_RECURSE rw_module_source_list . "*.cpp" "*.c" "*.h" "*.hpp" "*.inl")
aux_source_directory(. rw_module_source_list)
endmacro(rw_module_source_all)