tartarus's bolg tartarus's bolg
  • Linux and Unix Guide
  • CMake
  • gcc
  • gdb
  • bash
  • GNU Make
  • DDCA-ETH
  • CS106L
  • CS144
  • NJU PA
  • NJU OS(jyy)
  • C
  • C++
  • Python
  • reveal-md
  • LaTex
  • Paper Reading
  • TBD
  • Linux and Unix Guide
  • CMake
  • gcc
  • gdb
  • bash
  • GNU Make
  • DDCA-ETH
  • CS106L
  • CS144
  • NJU PA
  • NJU OS(jyy)
  • C
  • C++
  • Python
  • reveal-md
  • LaTex
  • Paper Reading
  • TBD
  • pdb

  • make

  • cmake

    • Introduction
    • Basic Intro
    • Basic 01-hello-cmake
    • Basic 02-hello-headers
    • Basic 03-static-library
    • Basic 04-shared-library
    • Basic 05-installing
    • Basic 06-build-type
    • Basic 07-complie-flags
      • 介绍
      • 概念解释
        • 方法一:设置Per-Target C++ Flags
        • 方法二: 直接给C++ Flags变量赋值
        • 在命令行中进行设置
      • 构建本例
    • Basic 08-third-party-library
    • Basic 09-compiling-with-clang
    • Basic 10-building-with-ninjia
    • Basic 11-cpp-standard
    • Intermediate sub-projects
    • Intermediate static-analysis
    • packge-management 04-conan
    • packge-management 05-vcpkg
    • Offical Tutorial(未完成)
  • Linux and Unix

  • Basic_Software
  • cmake
tartarus
2023-04-18
目录

Basic 07-complie-flags

# 介绍

上一节中我们介绍了 CMake 为我们提供的包装好的编译类型,本节我们将介绍两种方式设置 Complie Flags:

  1. 在 CMakeLists.txt 中使用 CMake 提供的函数 target_complie_definitions()
  2. 在 CMakeLists.txt 中使用内置变量 CMAKE_C_FLAGS 和 CMAKE_CXX_FLAGS
  3. 直接在命令行中进行设置

本例的目录🌲:

$ tree
.
├── CMakeLists.txt
├── main.cpp
1
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
)
1
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)
1

将会使得编译器使用编译选项: -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"
1
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

1
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
上次更新: 12/27/2023, 8:55:47 AM
Basic 06-build-type
Basic 08-third-party-library

← Basic 06-build-type Basic 08-third-party-library→

Theme by Vdoing | Copyright © 2023-2023 tartarus | CC BY-NC-SA 4.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式