Graphviz: 查看dependenices
预定于变量
变量名 |
描述 |
备注 |
PROJECT_SOURCE_DIR |
工程的根目录 |
|
PROJECT_BINARY_DIR |
运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build |
|
PROJECT_NAME |
返回通过 project 命令定义的项目名称 |
|
CMAKE_CURRENT_SOURCE_DIR |
当前处理的 CMakeLists.txt 所在的路径 |
|
CMAKE_CURRENT_BINARY_DIR |
target/out 编译目录,即build目录 |
|
CMAKE_CURRENT_LIST_DIR |
CMakeLists.txt 的完整路径 |
|
CMAKE_CURRENT_LIST_LINE |
当前所在的行 |
|
CMAKE_MODULE_PATH |
定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块 |
|
EXECUTABLE_OUTPUT_PATH |
重新定义目标二进制可执行文件的存放位置 |
|
LIBRARY_OUTPUT_PATH |
重新定义目标链接库文件的存放位置 |
|
指定cmake的最小版本
1
|
cmake_minimum_required(VERSION3.4.1)
|
- 这行命令是可选的,我们可以不写这句话,但在有些情况下,如果 CMakeLists.txt 文件中使用了一些高版本 cmake 特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行 cmake。
设置项目名称
- 这个命令不是强制性的,但最好都加上。它会引入两个变量
demo_BINARY_DIR
和 demo_SOURCE_DIR
- 同时,cmake 自动定义了两个等价的变量
PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
。
设置编译类型
1
2
3
|
add_executable(demo demo.cpp) # 生成可执行文件
add_library(common STATIC util.cpp) # 生成静态库
add_library(common SHARED util.cpp) # 生成动态库或共享库
|
- add_library 默认生成是静态库,通过以上命令生成文件名字,
- 在 Linux 下是:demo、libcommon.a、libcommon.so
- 在 Windows 下是:demo.exe、common.lib、common.dll
构建命令
1
|
cmake -B <build tree> -S <source tree>
|
1
|
cmake --build <build tree>
|
1
|
cmake -G <generator-name> <path-to-source>
|
1
|
cmake --system-information [file]
|
- 将信息信息输出到文件中(变量、命令、宏和其它设置)
避免重复include .h文件
target_compile_options(debug PRIVATE -H)
6、Linking with cmake
- static
- share
- share module
ODR-One Definition Rule
ELF
- 标识目标操作系统
- elf文件类型
- 目标指令集体系结构
- program headers table 和 section headers table 信息
.text
.data
.bss
- 未定义初始化值的全局/静态变量,程序加载的时候使用0值初始化
.rodata
.strtab
.shstrtab
- 包含了名称、类型、标志、内存中目标地址、文件中的偏移量以及其它信息。
- 通过该信息可了解文件的组成成分。–目录的角色
Dependencies Manager
- 从 CMAKE_MODULE_PATH 变量定义的路径开始检索dependencies。检索优先级find-modules > config-files > cmake已安装的内置模块
- CMAKE_MODULE_PATH 默认为空
find_package (具备PKGNAMEConfig.cmake/pkgname-config.cmake的模块可用)
- find_package( [version] [EXACT] [QUIET] [REQUIRED])
- 使用find_package 方法检索到目标依赖后,通常可以通过下列变量来使用检索到的依赖库
- <PACKAGE_NAME>_FOUND
- <PACKAGE_NAME>_INCLUDE_DIRS or <PACKAGE_NAME>_INCLUDES
- <PACKAGE_NAME>_LIBRARIES or <PACKAGE_NAME>_LIBS
- <PACKAGE_NAME>_DEFINATIONS
- IMPORTED
FindPkgConfig (具备PkgConfig的模块可用)
.pc文件示例
1
2
3
4
5
6
7
8
9
10
|
prefix=/usr/local
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Name: foobar
Description: A foobar library
Version: 1.0.0
Cflags: -I${includedir}/foobar
Libs: -L${libdir} -lfoobar
|
- 获取链接库标识:pkg-config –libs pkg name
- 获取库的include 目录:pkg-config –cflags pkg name
PKG_CONFIG_EXECUTABLE
1、使用PKG_CONFIG_FOUND确认库是否可用
2、使用pkg_check_modules 扫描包
custom find-module
find-module可提供如下变量
- <PKG_NAME>_FIND_REQUIRED:find_package(<PKG_NAME> REQUIRED) 被调用时,如果找到目标库,变量值设置为1,否则调用message(FATAL_ERROR)
- <PKG_NAME>_FIND_QUIETLY:find_package(<PKG_NAME> QUIET)被调用时,如果找到目标库,变量值设置为1,否则
- <PKG_NAME>_FIND_VERSION :
构建自定义find-module步骤
- 引入CMakeFindDependencyMacro宏,使用find_dependency()检索目标库
- 使用find_library查找目标库的library路径
- 使用find_path 查找目标库headers路径
- 引入FindPackageHandleStandardArgs宏。使用find_package_handle_standard_args()方法检测library和headers是否成功检索到
- 若成功找到则执行下列步骤
- 确定library、headers的路径
- 创建一个 IMPORTED target
- 设置必要的属性 IMPORTED_LOCATION、INTERFACE_INCLUDE_DIRECTORIES、IMPORTED
- 存储库的路径到缓存变量中以避免二次查找目标库
- 创建PQXX_FOUND缓存变量并给一个明确的值
- 把变量标记为advanced(mark_as_advanced),除非advanced 标识被开起,否在在CMAKE GUI程序中不可见
find_dependency
Git repo
ExternalProject\FetchContent
ExternalProject_Add()
功能
- 管理external project 的目录结构
- 从url中下载源码
- 支持常用的代码版本管理仓库
- 有需要时获取更新
- 使用cmake 或者指定的工具配置和构建project
- 执行安装和测试操作
- 日志文件
- 从终端请求用户输入
- 依赖其它的target
- 针对构建增加自定义命令和步骤
针对使用ExternalProject_Add方法处理的external project,cmake自动执行下列操作:
- mkdir- 针对external project创建一个目录
- download- 从仓库或者url获取工程文件
- update- 重新运行时刷新文件
- patch – 可选择执行补丁命令,根据项目的需要更改下载的文件
- configure- 针对cmake工程,执行configure操作,针对非cmake工程,需手动配置
- build- 针对cmake工程,执行build操作,针对其它依赖,执行cmake命令
- install- 安装cmake工程,针对其它依赖执行cmake install 命令
- test- 如果定义来测试选项,执行测试操作