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 能够很方便定位出问题的版本。

configure_file(<input> <output>) 能够从模板(比如 configure.h.in)中生成各种诸多宏定义的头文件。

Configuring the optimizer

-O0
-O1
-O2
-O3

gcc 的描述:

Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions and -frename-registers options.

-Os 为速度优化
-Ofast 比 -O3 更激进,浮点数可以不遵循 IEEE754 标准,还有一些别的优化。

虽然说 -finline-functions-O3 开启的,-O1 也是能够将简单函数内联的: https://godbolt.org/z/3GxxKGEWT

默认 flag:

CMAKE_CXX_FLAGS_DEBUG equals -g
CMAKE_CXX_FLAGS_RELEASE equals -03 -DNDEBUG

可以手动添加 flag: https://stackoverflow.com/a/48114415/

Managing the process of compilation

个人感觉这里最有意思的点是预编译头文件。module 支持本书写时还没有出现。

…since version 3.16, CMake offers a command to enable header precompilation.

The list of added headers is stored in the PRECOMPILE_HEADERS target property.

一般的 header 都是用 PUBLIC 或者 INTERFACE 比较好,但是对于预编译的头文件,最好是 PRIVATE

第二种用 [[]] 是想要生成字面量,也就是包含双引号:

也可以从别的 target 借用预编译头文件。

Debugging the build

gcc 和 clang 的 -save-temps 选项能够在编译时保存中间产物,比如预处理结果和汇编。

-H 选项能够打印每个被包含头文件的位置。