CMake 学习笔记(target_compile_features())

2023-11-04

CMake 学习笔记(target_compile_features())

这一篇博客讲一讲target_compile_features()。这条命令时 CMake 3.1 引入的。在这个之前。如果我们要设置C++ 编译开启 C++11 的支持。需要用如下的两行:

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

这两行对编译器的设置是全局的,也就是整个项目中每一个 C++ 文件编译时都会开启 C++11 的支持。在小项目中没有任何问题。但是如果项目比较大,包含了多个库。有可能编译某些库时就不能开启 C++11。因此我们需要更加细粒度的控制。找个就要用到 target_compile_features()。

下面是个简单的例子,只是一个代码片段:

target_compile_features(Tutorial INTERFACE cxx_std_11)

可以看到一行代码就可以开启C++编译器的支持。其实,大多数时候我们的编译器都是默认支持C++ 的比较高的标准的。上面这行代码主要是当编译器不支持某个特性时,能够报警提示我们。另外就是有时C++的不同版本的标准不兼容时,我们需要告诉编译器我们用的是哪个标准。这时通常是我们要告诉编译器我们的代码用到了某一个特别低的C++ 标准,不要开启对高标准的支持。

大多数的cmake 教程或者官方文档中,都不是我上面那种写法,而是像下面这样:

add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
target_link_libraries(Tutorial PUBLIC tutorial_compiler_flags)

这三行第一行引入了一个接口库 tutorial_compiler_flags,找个库其实是个虚拟的库,并没有任何的文件。然后给这个接口库设置了一个编译特性cxx_std_11。那么只要依赖找个虚拟库的对象,在编译时都会使用到cxx_std_11找个特征。

上面这样写的好处是 tutorial_compiler_flags 可以被许多个目标所使用。如果项目中只有一个目标需要用到这个 compile_features ,那就不如像我那样写一行。

对于 C++ 语言来说,CMake 支持的 compile_features 包括下面这些:

  • cxx_std_98

  • cxx_std_11

  • cxx_std_14

  • cxx_std_17

  • cxx_std_20

  • cxx_std_23

  • cxx_std_26

我们知道编译器对C++ 新标准的支持是滞后的。有时,编译器只是部分的支持了C++ 的某个标准。CMake 也有几个这样的 compile_features 用来保证编译器支持某个特定的特性:

  • cxx_alias_templates
  • cxx_alignas
  • cxx_alignof
  • cxx_attributes
  • cxx_auto_type
  • cxx_constexpr
  • cxx_decltype_incomplete_return_types
  • cxx_decltype
  • 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

以上这些是 C++ 的特性,具体每一项的含义可以查看 CMake 的帮助文档。https://cmake.org/cmake/help/latest/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES

除此之外还有 C 语言的 compile_features:

  • c_std_90
  • c_std_99
  • c_std_11
  • c_std_17
  • c_std_23
  • c_function_prototypes
  • c_restrict :restrict keyword ,C99 中引入的特性
  • c_static_assert : Static assert C11 中引入的特性
  • c_variadic_macros :Variadic macros, C99 中引入的特性

除此之外,CMake 还支持 CUDA 的一些 features.

  • cuda_std_03
  • cuda_std_11
  • cuda_std_14
  • cuda_std_17
  • cuda_std_20
  • cuda_std_23
  • cuda_std_26
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake 学习笔记(target_compile_features()) 的相关文章

  • ubuntu:升级软件(cmake)-版本消歧(本地编译)[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我的机器上安装了 cmake 2 8 0 来自 ubuntu 软件包 二进制文件放置在 usr bin cmake 中 我需要将 cmake 版本至少
  • Haskell 项目可以使用 cmake 吗?

    我正在计划一个用 Haskell 编写的项目 也许也有一些部分是用 C 编写的 对于构建系统 我决定不选择 Haskell 程序 cabal 的常见选择 主要是因为我想了解其他语言的构建程序是如何工作的 我听说过 CMake 我认为这是一个
  • 在cmake中,什么是“项目”?

    这个问题是关于project命令 推而广之 是什么concept of a project意思是cmake中的 我真的不明白什么是project是 以及它与target 我想我确实理解 我看了一下cmake 文档project http w
  • CMake:连续编译程序两次

    为了能够进行许多自动优化 我希望能够使用标志编译我的程序 fprofile generate首先 然后运行它生成配置文件 然后使用以下命令重新编译程序 fprofile use反而 这意味着我想连续编译我的程序两次 使用两个不同的CMAKE
  • 通过ExternalProject_Add 使用 pybind11 进行 CMake 项目的智能方法

    我正在使用编写一个 python 模块pybind11 with CMake3 9 4 因为方便所以想下载pybind11源文件使用ExternalProject Add in my CMakeLists txt 当我跑步时cmake 它不
  • 在生成器表达式中使用 cmake 选项

    我想在生成器表达式中使用 cmake 选项 为了打开某个编译标志 来自文档 https cmake org cmake help v3 10 manual cmake generator expressions 7 html我不清楚如何实现
  • Cmake:将子项目目标导出到主项目

    我目前有一个项目叫做LIBS具有这样的结构 Lib1 CMakeLists txt lib1 class cpp lib1 class h lib2 CMakeLists txt lib2 class cpp lib2 class h cm
  • 如何将 gnatmake/gnatbind/gnatlink 集成到 C/Ada 代码的 CMake 文件中?

    我用几种语言 C C Fortran77 Fortran90 编写了代码 并且可以使用 CMake 编译它 没有任何问题 效果很完美 现在 我想在用 C 编写的 main 中添加一些 Ada 函数 并且我想通过 CMake 编译它 鉴于我无
  • 使用 CMake 对 SDL 的未定义引用

    我正在使用 SDL v1 2 15 7 和 CMake 3 2 1 开发一个项目 在 h 文件中我添加了 include
  • 如何在使用 Cmake 构建期间编译 HLSL 着色器?

    我正在开发 d3d 应用程序 我想在使用 cmake 构建期间编译我的 hlsl 着色器 我不知道从哪里开始 这是我当前的 CMakeLists txt cmake minimum required VERSION 3 20 project
  • 将 Doctest 与代码一起使用时将实现放在哪里

    我在用着doctest https github com onqtam doctest用于我的 C 项目中的测试 我想将测试代码与我的实现放在一起 正如库所说是可能的 但我似乎不知道如何处理 doctest 实现代码 我有一个doctest
  • 使用星号更改多个源文件的 CMake 编译器标志

    我正在尝试调试与编译器优化相关的问题 O2 或以下版本没有问题 O3 出现段错误 并且我希望能够切换我的源代码块的编译器标志 以便我可以尝试缩小段错误的来源范围 我可以将全局优化级别设置为 O2 并更改单个文件的属性 如下所示 SET SO
  • 动态加载库和共享全局符号

    由于我在动态加载的库中观察到全局变量的一些奇怪行为 因此我编写了以下测试 首先我们需要一个静态链接库 头文件test hpp ifndef BASE HPP define BASE HPP include
  • CMake:使用其他平台的生成器。如何?

    如何使用 CMake 在 Linux 上生成 Visual Studio 项目文件 你不能 您必须在 Windows 上运行 CMake 才能为 Visual Studio 生成
  • 如何在Linux上构建GLFW3项目?

    我已经使用 cmake 和 make 编译了 glfw3 和包含的示例 没有出现任何问题 开始编写我的第一个项目 作为 opengl 和 glfw 的新手 并且对 C 和 CMake 没有经验 我正在努力理解示例构建文件 甚至要链接哪些库和
  • 如何在 CMake Makefile 中包含 OpenCV 库

    我希望你可以帮助我 我有一个简单的 CMakeLists txt 以便在 Leopard 10 5 8 上构建我的项目 我正在使用 CMake 2 8 1 目前这是代码 cmake minimum required VERSION 2 8
  • Clion如何将文件添加到项目中

    这看起来真的很基本 如何将文件添加到项目中而无需手动编辑CMakeLists txt 例如另一个目录中的源文件 CLion 解析CMakeLists txt并使用它生成项目视图 但我相信将文件添加到项目的唯一方法是编辑CMakeLists
  • Opencv - 找不到头文件

    我正在尝试使用 opencv 开始开发 问题是 到目前为止我几乎无法设置 opencv 因为我找不到它的头文件 我对此主题进行了一些研究 但没有一个真正有帮助 下面是一些链接 opencv2 包含文件在哪里 https stackoverf
  • 是否可以让 cmake 构建文件(CMakeLists.txt)不在 CLion 的根目录中

    是否可以让 cmake 构建文件 CMakeLists txt 不在 CLion 的根目录中 我目前正在开发的项目中 cmake 构建文件不在 CLion 项目的根目录中 在 out Debug 目录中 我希望 CLion 打开该项目的根目
  • CMake:Fortran 模块和编译顺序

    我有一个大型 Fortran 程序 其中包含许多目录 每个目录都在伪库中单独编译 但仍然存在相互依赖的混乱 因此最终所有伪库都组合在一个可用的库中 我想使用 Fortran 模块 但它非常脆弱 因为我不能依赖自动依赖项检查 并且根据顺序编译

随机推荐