我有一个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;就是出于这种情况。
答案 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 bb
说CXX_STANDARD
是否是一个要求(bb
是YES
还是其他一些布尔等价物)或是否只是需要{bb
是{ {1}}或同等的。)
NO
启用(CXX_EXTENSIONS bb
)或禁用(bb = YES
)编译器扩展。这不仅会影响代码编译的内容,也不会影响代码编写的内容,它也会影响链接的标准库。
您不需要指定单独的编译器功能来实现您最终尝试执行的操作(为您的目标启用C ++ 14)。您可以找到有关整个区域的完整讨论here。