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
    • Basic 08-third-party-library
    • Basic 09-compiling-with-clang
    • Basic 10-building-with-ninjia
    • Basic 11-cpp-standard
      • 设置编译器的C语言标准
      • common-method
        • 介绍
        • 概念解释
        • 检查编译标志(Compile Flag)
        • 添加编译标志
        • 构建本例
      • cxx-standard
        • 介绍
        • 概念解释
        • 构建本例
      • complie feature(推荐🌟🌟🌟🌟🌟)
        • 介绍
        • 概念
        • 使用target_compile_features
        • 构建本例
    • 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-20
目录

Basic 11-cpp-standard

# 设置编译器的 C 语言标准

CMake 提供了三种方法来设置编译器的 C 语言标准:

  • common-method: 在大部分版本的 CMake 上都能使用
  • cxx-standard: 使用变量 CMAKE_CXX_STANDARD , 在 CMake3.1 版本被引入。
  • complie-features: 使用函数 target_compile_features , 在 CMake3.1 版本被引入。

# common-method

# 介绍

这种方法在大部分的 CMake 版中上都能被使用,但是我不建议使用这种方法。因为新版本的 CMake 引入了 target_complie_features ,使得 C 标准的选择是面向 target 的。

本例的目录🌲:

A-hello-cmake$ tree
.
├── CMakeLists.txt
├── main.cpp
1
2
3
4

CMakeLists.txt:

# Set the minimum version of CMake that can be used
# To find the cmake version run
# $ cmake --version
cmake_minimum_required(VERSION 2.8)

# Set the project name
project (hello_cpp11)

# try conditional compilation
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)

# check results and add flag
if(COMPILER_SUPPORTS_CXX11)#
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)#
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

# Add an executable
add_executable(hello_cpp11 main.cpp)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 概念解释

# 检查编译标志 (Compile Flag)

CMake 支持向函数 CMAKE_CXX_COMPILER_FLAG 中传入参数,然后检查该参数在默认的编译器中是否可用,并将判断结果保存到一个变量中。

举例:

  • include 告诉 CMake 引入函数 CheckCXXCompilerFlag ,使得该函数可用
  • 通过函数 CHECK_CXX_COMPILER_FLAG 检查参数 "-std=c++11" 在编译器中是否是可用的,然后将判断结果保存到变量 COMPILER_SUPPORTS_CXX11 中。
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
1
2

# 添加编译标志

在检查完编译标志是否可用后,就可以决定是否需要向变量 CMAKE_CXX_FLAGS 中添加次编译标志标志。举例:

其中 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 的作用是在当前编译标志 ${CMAKE_CXX_FLAGS} 的末尾添加新的标志 "-std=c++11"

if(COMPILER_SUPPORTS_CXX11)#
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)#
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
1
2
3
4
5
6
7

# 构建本例

$ 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
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Performing Test COMPILER_SUPPORTS_CXX0X
-- Performing Test COMPILER_SUPPORTS_CXX0X - Success
-- Configuring done
-- Generating done
-- Build files have been written to: /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/i-common-method/build

$ make
Scanning dependencies of target hello_cpp11
[ 50%] Building CXX object CMakeFiles/hello_cpp11.dir/main.cpp.o
[100%] Linking CXX executable hello_cpp11
[100%] Built target hello_cpp11
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

# cxx-standard

# 介绍

本例展示了如何使用变量 CMAKE_CXX_STANDARD 来指定编译器编译的 C++ 版本。

本例的目录🌲:

A-hello-cmake$ tree
.
├── CMakeLists.txt
├── main.cpp
1
2
3
4

CMakeLists.txt

# Set the minimum version of CMake that can be used
# To find the cmake version run
# $ cmake --version
cmake_minimum_required(VERSION 3.1)

# Set the project name
project (hello_cpp11)

# set the C++ standard to C++ 11
set(CMAKE_CXX_STANDARD 11)

# Add an executable
add_executable(hello_cpp11 main.cpp)
1
2
3
4
5
6
7
8
9
10
11
12
13

# 概念解释

设置变量 CMAKE_CXX_STANDARD 会导致 CMakeLists.txt 中的所有目标都使用 CXX_STANDARD 来进行编译。

如果设置给 CMAKE_CXX_STANDARD 的值不存在,CMkae 会自动设置一个最近的 C++ 标志。比如你设置了 set(CMAKE_CXX_STANDARD 11) 并且该标志在当前编译器不可用,最终可能会得到 -std=gnu0x ,并且不会报错。

# 构建本例

$ 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/L-cpp-standard/ii-cxx-standard/build

$ make VERBOSE=1
/usr/bin/cmake -S/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard -B/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build/CMakeFiles /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build'
make -f CMakeFiles/hello_cpp11.dir/build.make CMakeFiles/hello_cpp11.dir/depend
make[2]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build'
cd /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build/CMakeFiles/hello_cpp11.dir/DependInfo.cmake --color=
Dependee "/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build/CMakeFiles/hello_cpp11.dir/depend.internal".
Scanning dependencies of target hello_cpp11
make[2]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build'
make -f CMakeFiles/hello_cpp11.dir/build.make CMakeFiles/hello_cpp11.dir/build
make[2]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build'
[ 50%] Building CXX object CMakeFiles/hello_cpp11.dir/main.cpp.o
/usr/lib/ccache/c++    -std=gnu++11 -o CMakeFiles/hello_cpp11.dir/main.cpp.o -c /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/main.cpp
[100%] Linking CXX executable hello_cpp11
/usr/bin/cmake -E cmake_link_script CMakeFiles/hello_cpp11.dir/link.txt --verbose=1
/usr/lib/ccache/c++    -rdynamic CMakeFiles/hello_cpp11.dir/main.cpp.o  -o hello_cpp11 
make[2]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build'
[100%] Built target hello_cpp11
make[1]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/build'
/usr/bin/cmake -E cmake_progress_start /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/ii-cxx-standard/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

# complie feature (推荐🌟🌟🌟🌟🌟)

# 介绍

本例介绍如何使用 Modern CMake 的 target_complie_feature 设置编译器使用的 C++ 版本。
在 Modern CMake 上,建议使用这种方法来设置编译器使用的 C++ 版本。

本例的目录🌲:

.
├── CMakeLists.txt
├── main.cpp
1
2
3

CMakeLists.txt:

# Set the minimum version of CMake that can be used
# To find the cmake version run
# $ cmake --version
cmake_minimum_required(VERSION 3.1)

# Set the project name
project (hello_cpp11)

# Add an executable
add_executable(hello_cpp11 main.cpp)

# set the C++ standard to the appropriate standard for using auto
target_compile_features(hello_cpp11 PUBLIC cxx_auto_type)

# Print the list of known compile features for this version of CMake
message("List of compile features: ${CMAKE_CXX_COMPILE_FEATURES}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 概念

# 使用 target_compile_features

使用 target_compile_features 的好处在于可以指定编译特征的可见性。关于 target_xxx 我在 Basic 03-static-library 有过具体讲解。

该函数可以使用的 feature 可以在CMAKE_CXX_COMPILE_FEATURES (opens new window) 中找到。

你可以使用 message("List of compile features: ${CMAKE_CXX_COMPILE_FEATURES}") 打印出所有可用的 complie feature。

# 构建本例

$ 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
List of compile features: cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20
-- Configuring done
-- Generating done
-- Build files have been written to: /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build

$ make VERBOSE=1
/usr/bin/cmake -S/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features -B/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build/CMakeFiles /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build'
make -f CMakeFiles/hello_cpp11.dir/build.make CMakeFiles/hello_cpp11.dir/depend
make[2]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build'
cd /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build/CMakeFiles/hello_cpp11.dir/DependInfo.cmake --color=
Dependee "/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build/CMakeFiles/hello_cpp11.dir/DependInfo.cmake" is newer than depender "/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build/CMakeFiles/hello_cpp11.dir/depend.internal".
Dependee "/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build/CMakeFiles/hello_cpp11.dir/depend.internal".
Scanning dependencies of target hello_cpp11
make[2]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build'
make -f CMakeFiles/hello_cpp11.dir/build.make CMakeFiles/hello_cpp11.dir/build
make[2]: Entering directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build'
[ 50%] Building CXX object CMakeFiles/hello_cpp11.dir/main.cpp.o
/usr/lib/ccache/c++     -o CMakeFiles/hello_cpp11.dir/main.cpp.o -c /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/main.cpp
[100%] Linking CXX executable hello_cpp11
/usr/bin/cmake -E cmake_link_script CMakeFiles/hello_cpp11.dir/link.txt --verbose=1
/usr/lib/ccache/c++    -rdynamic CMakeFiles/hello_cpp11.dir/main.cpp.o  -o hello_cpp11 
make[2]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build'
[100%] Built target hello_cpp11
make[1]: Leaving directory '/home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/build'
/usr/bin/cmake -E cmake_progress_start /home/tartarus/cmake/cmake-examples/01-basic/L-cpp-standard/iii-compile-features/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
上次更新: 12/27/2023, 8:55:47 AM
Basic 10-building-with-ninjia
Intermediate sub-projects

← Basic 10-building-with-ninjia Intermediate sub-projects→

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