0%
chapter04 - targets
创建 target
三种方式:
add_executable # 默认在 ALL 中
add_library # 默认在 ALL 中
add_custom_target # 默认不在 ALL 中
# add_custom_command 是创建文件的方式,但是不是创建 target
add_library
: https://cmake.org/cmake/help/latest/command/add_library.html#object-libraries
- Normal library: 如果不指定
STATIC
/SHARED
/MODULE
,add_library
会根据BUILD_SHARED_LIBS
变量去决定是否使用SHARED
还是STATIC
。 - Object library: 生成目标文件。
- Interface library:不生成文件。用来打包传播属性。
- Imported library:
IMPORTED
属性和STATIC
等是可以叠加的。IMPORTED
库是已经被编译好的库,不需要另外编译,但是需要用set_target_property
来设置其位置。 - Alias library
add_custom_target
可以有多条命令,而且不一定有产物。add_custom_target
创建的 target 是默认不 ALL 的!和 add_custom_command
的对比看后文。
chapter04.a - 梳理依赖是如何创建的
发表于:
分类于:
modern-cmake-for-cpp
我认为的依赖有两种:
- 文件依赖(sources)既有同级依赖(比如
add_custom_command
的DEPENDS
参数),又有 targets 到 sources 的依赖。 - target 依赖是一种 targets 之间的同级依赖关系。
Target 依赖
创建 target 可以用 add_executable
/add_library
/add_custom_target
。前面两个都默认包含在 all 中,而最后一个默认不包含在 all 中。此外,add_custom_target
如果给的是命令,而不是依赖文件,则创建的 targets 永远处于“需要被构建”的状态;如果给的是文件,则就只是文件依赖。
可以用 add_dependencies
来创建 targets 之间的依赖。
文件依赖
如果 target 或者 command(由 add_custom_command
创建)依赖一个源文件,这个文件找不到、但是又被标记了 GENERATED
属性,则会想办法去生成这个文件。
chapter05 - compiling c++ sources
Initial configuration
target_sources # 追加源码
target_include_directories
target_compile_definitions
target_compile_options # 不能跨平台
target_compile_features # 对编译器要求某种特性
target_precompile_headers
- 用
target_sources
中添加了头文件是会被过滤掉的,会形成依赖,但是不会真正被编译。 target_compile_features
的特性非常多。一般也就只用cxx_std_{98,11,14,17,20,23}
这种语言标准,而不是具体的标准。
Preprocessor configuration
target_compile_definitions
能够自动去除多加的 -D
,不过最好还是不要加,因为这个命令本来就是用于跨平台的,不加风格更统一。
通过 execute_process 和 宏定义,可以将当前的最新 commit 传入源码,这样源码就能自己计算最新版本,而不需要每次都手动更改!然后提交的代码通过 CD 就能够自动构建了。特别是在用户只有产品时,能够获得具体的 commit sha1 能够很方便定位出问题的版本。
chapter06 - linking
程序分段
.text section: Machine code, with all the instructions to be executed by the processor
.data section: All values of the initialized global and static objects (variables)
.bss section: All values of the uninitialized global and static objects (variables), which will be initialized to zero on program start
.rodata section: All values of the constants (read-only data)
.strtab section: 常量字符串的表
.shstrtab section: 每个 section 的名称字符串的表
可执行文件有一些差异,其中之一就是 program header,它描述了创建进程镜像的信息。
库的分类
CMake 支持的有 STATIC
, SHARED
, MODULE
:
MODULE
不应该将 MODULE
链接到其他文件。成为 MODULE
的库需要在运行时被显式链接。
chapter07 - managing dependencies
Best option: find_package
https://cmake.org/cmake/help/latest/command/find_package.html
有三种工作模式。
Module mode
Find<PackageName>.cmake
主要是包外提供,比如 CMake、操作系统、或者写当前工程的人提供的试探性地去搜索库的方式。先找 CMAKE_MODULE_PATH
,然后就是 cmake 的安装目录。
我们实验室项目不少路径都是硬编码的,感觉写 Find Module 会更合适。
chapter09 - program analysis tools
发表于:
分类于:
modern-cmake-for-cpp
说明
这一章节是作者将一些分析工具以函数或内置支持的形式自动化地加入到了 CMake 构建工程的过程中了。
格式化
clang-format
静态检查
- clang-tidy
- cpplint(按照 Google Coding Style 检查)
- cppcheck
- include-what-you-use
- link what you use(CMake 内置)
静态检查受到 CMake 的直接支持:
All we need to do is set an appropriate target property to a semicolon-separated list containing the path to the checker’s executable, followed by any command-line options that should be forwarded to the checker.
<LANG>_CLANG_TIDY
<LANG>_CPPCHECK
<LANG>_CPPLINT
<LANG>_INCLUDE_WHAT_YOU_USE
LINK_WHAT_YOU_USE
chapter10 - documents
发表于:
分类于:
modern-cmake-for-cpp
Adding Doxygen to your project
安装必要软件包:
apt-get install doxygen graphviz
然后就能在 CMake 中引入 Doxygen 包并使用 doxygen_add_docs
。
Since CMake 3.9, we can use the
doxygen_add_docs()
function fromFindDoxygen
find-module, which sets the documentation target up.注意 FindDoxygen module 推荐使用方式是 find_package,虽然可以 include 但是不推荐。
doxygen 用的是 Javadoc 的格式。
chapter11 - installing and packaging
Exporting without installation
使用 export
命令可以创建导出文件,然后其他工程只要 include 这个导出文件就能使用当前这个包中的 target,而不需要先将这个包用 install
安装在系统里。
export(TARGETS [target1 [target2 [...]]]
[NAMESPACE <namespace>] [APPEND] FILE <path>
[EXPORT_LINK_INTERFACE_LIBRARIES]
NAMESPACE
is recommended as a hint, stating that the target has been imported from other projects.
APPEND
tells CMake that it shouldn’t erase the contents of the file before writing. 也就是说本身会按照FILE
来覆写文件,但是APPEND
使得写入方式变成追加。
EXPORT_LINK_INTERFACE_LIBRARIES
will export target link dependencies (including imported and config-specific variants).
例子:
cmake_minimum_required(VERSION 3.20.0)
project(ExportCalcCXX)
add_subdirectory(src bin)
set(EXPORT_DIR "${CMAKE_CURRENT_BINARY_DIR}/cmake")
export(TARGETS calc
FILE "${EXPORT_DIR}/CalcTargets.cmake"
NAMESPACE Calc::
)
...