Basic 07-complie-flags
# 介绍
上一节中我们介绍了 CMake 为我们提供的包装好的编译类型,本节我们将介绍两种方式设置 Complie Flags:
- 在 CMakeLists.txt 中使用 CMake 提供的函数
target_complie_definitions() - 在 CMakeLists.txt 中使用内置变量
CMAKE_C_FLAGS和CMAKE_CXX_FLAGS - 直接在命令行中进行设置
本例的目录🌲:
$ tree
.
├── CMakeLists.txt
├── main.cpp
2
3
4
# 概念解释
# 方法一:设置 Per-Target C++ Flags
提示
在 Modern CMake 中建议使用 target_compile_definitions() 为 Target 设置编译定义
在 Modern CMake 中建议使用 target_compile_options() 为 Target 设置编译选项
在 Modern CMake 中建议使用 target_compile_definitions() 为 Target 设置编译定义,因为这可以产生我们之前在 Basic 03-static-library 提到过的继承关系 (可见性)。
target_compile_definitions() 中继承关系有三种:
- PRIVATE: C++Flags 只能被该目标使用。(C++Flags 被放到该目标的
COMPILE_DEFINITIONS属性中) - INTERFACE: C++Flags 只能被链接了该目标的目标使用。(C++Flags 被放到该目标的
INTERFACE_COMPILE_DEFINITIONS属性中) - PUBLIC: C++Flags 既可以被该目标使用,也可以被链接了该目标的目标使用。(C++Flags 被放到该目标的
COMPILE_DEFINITIONS和INTERFACE_COMPILE_DEFINITIONS属性中)
注意
注意上面提到的目标是可执行文件对应的目标 add_executable(executable_target source_files...) ,或者库对应的目标 add_library(library_target source_files...) 。
比如如果一个目标为 library target 并且可见性为 PUBLIC 或者 INTERFACE,那么该目标的编译选项在任何链接了该库的目标 (即调用了 target_link_libraries 的目标) 的构建中都会被使用。
关于继承关系的具体介绍看指定 Including Directories。
本例中可执行目标名为 cmake_examples_compile_flags ,使用可见性为 PRIVATE 使得编译选项只能被当前目标可见,即只能在编译当钱目标对应的源文件是使用。
target_compile_definitions(cmake_examples_compile_flags
PRIVATE EX3
)
2
3
对于指定编译前的预处理 flags 建议使用: target_compile_definitions
对于指定编译的 flags 建议使用 target_compile_options ,其语法和 target_compile_definitions 一样。
注意
目前我的理解是,预处理阶段的编译器 Flags 属于编译器的定义 (definition);编译阶段的 Flags 项属于是编译器的选项 (option)。
# 方法二:直接给 C++ Flags 变量赋值
CMake 的变量 CMAKE_CXX_FLAGS 要么为空,要么是我们在 Basic 06-build-type 使用的某种构建类型对应的编译选项。
为了设置默认的编译我么能够在 CMakeList.txt 的顶部添加:
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
将会使得编译器使用编译选项: -DEX2 。
和 CMAKE_CXX_FLAGS 的设置方法类似,我们也可以设置:
- C 的编译选项
CMAKE_C_FLAGS - 链接选项
CMAKE_LINKER_FLAGS
注意
一旦使用 CMAKE_C_FLAGS 和 CMAKE_CXX_FLAGS 设置了编译器选项 / 定义,所有的目标都会使用这些选项。所以 Modern CMake 不推荐使用这种方式进行设置。建议使用方法一进行设置。
# 在命令行中进行设置
还有一种方法和设置构建类型类似,可以直接在命令行中进行设置:
# 为编译器设置定义-DEX3
cmake .. -DCMAKE_CXX_FLAGS="-DEX3"
2
# 构建本例
$ mkdir build
$ cd build
$ cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/lib/ccache/cc
-- Check for working C compiler: /usr/lib/ccache/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/lib/ccache/c++
-- Check for working CXX compiler: /usr/lib/ccache/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build
$ make VERBOSE=1 #或者使用cmake --build .
/usr/bin/cmake -S/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags -B/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build'
make -f CMakeFiles/cmake_examples_compile_flags.dir/build.make CMakeFiles/cmake_examples_compile_flags.dir/depend
make[2]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build'
cd /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/DependInfo.cmake --color=
Dependee "/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/DependInfo.cmake" is newer than depender "/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/depend.internal".
Dependee "/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles/cmake_examples_compile_flags.dir/depend.internal".
Scanning dependencies of target cmake_examples_compile_flags
make[2]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build'
make -f CMakeFiles/cmake_examples_compile_flags.dir/build.make CMakeFiles/cmake_examples_compile_flags.dir/build
make[2]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build'
[ 50%] Building CXX object CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o
/usr/lib/ccache/c++ -DEX3 -DEX2 -o CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o -c /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/main.cpp
[100%] Linking CXX executable cmake_examples_compile_flags
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmake_examples_compile_flags.dir/link.txt --verbose=1
/usr/lib/ccache/c++ -DEX2 CMakeFiles/cmake_examples_compile_flags.dir/main.cpp.o -o cmake_examples_compile_flags
make[2]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build'
[100%] Built target cmake_examples_compile_flags
make[1]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build'
/usr/bin/cmake -E cmake_progress_start /home/tartarus/cmake/cmake-examples/01-basic/G-compile-flags/build/CMakeFiles 0
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47