CMake:子目录可以继承编译功能吗?

时间:2017-05-13 16:30:18

标签: c++ cmake c++14

我有一个C ++项目,它包含一个主程序(main.cpp),一个定义抽象类(algorithm.hpp)的头和一个充满类的子目录(algorithms/)实现抽象类。我已将CMake配置为将子目录构建为对象库:

# algorithms/CMakeLists.txt
add_library(algorithms_lib OBJECT
  algo1.cpp
  algo2.cpp
  # etc.
)

在我项目的根目录中,我使用此对象库作为应用程序的来源之一:

# Top-level CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(MyApp CXX)

add_subdirectory(algorithms)

add_executable(my-app
  main.cpp
  $<TARGET_OBJECTS:algorithms_lib>
)

我的应用程序是用C ++ 14编写的,所以我需要告诉CMake使用正确的编译选项。我不想要CMake版本3.8(因为它没有包装在我想支持的最新Linux发行版中),所以我不能使用cxx_std_14编译功能;相反,我列出了一些我使用的单个语言功能:

# Top-level CMakeLists.txt (cont.)
target_compile_features(my-app PUBLIC
  cxx_auto_type
  cxx_constexpr
  cxx_defaulted_functions
  # ...14 more lines...
)

问题是,这些功能仅适用于顶级my-app目标,而不适用于algorithms_lib目标,因此子目录中的源代码不会编译为C ++ 14

我知道我可以将整个大target_compile_features块复制到algorithms/CMakeLists.txt,但我宁愿不这样做 - 特别是因为这个例子已经简化了,我实际上已经 9 < / em>这样的子目录,每个构建自己的对象库。那就是很多重复的样板代码。

有没有办法为项目中的所有C ++目标(包括子目录)全局设置编译功能?或者最好摆脱add_subdirectory和对象库,只列出顶级add_executable命令中的所有单个子目录文件?我是CMake的新手,所以我不知道&#34;最佳实践&#34;就是出于这种情况。

1 个答案:

答案 0 :(得分:4)

听起来您希望将以下内容放在CMakeLists.txt文件的顶部:

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

这些设置默认值为同名的目标属性,不带前导CMAKE_。等效的目标属性执行以下操作:

CXX_STANDARD yy设置您的代码想要使用的最低C ++标准。

CXX_STANDARD_REQUIRED bbCXX_STANDARD是否是一个要求(bbYES还是其他一些布尔等价物)或是否只是需要{bb是{ {1}}或同等的。)

NO启用(CXX_EXTENSIONS bb)或禁用(bb = YES)编译器扩展。这不仅会影响代码编译的内容,也不会影响代码编写的内容,它也会影响链接的标准库。

您不需要指定单独的编译器功能来实现您最终尝试执行的操作(为您的目标启用C ++ 14)。您可以找到有关整个区域的完整讨论here