CMake:替换接口目标的编译标志

CMake: Replace compile flags of an INTERFACE target

本文关键字:编译 标志 目标 接口 替换 CMake      更新时间:2023-10-16

我需要将INTERFACE目标(仅标头库(的/std:c++14标志替换为/std:c++17.CMake 尚不支持直接在 VS 中设置 C++17 标志(请参阅如何使用 CMake 在 VS2017 中启用/std:c++17(,因此我需要手动替换它。

但是,检索当前设置的标志列表,然后随后将/std:c++14 替换为/std:c++17get_target_property(my_compile_flags mylib COMPILE_OPTIONS)不起作用:

INTERFACE_LIBRARY目标可能只有列入白名单的属性。 不允许使用属性"COMPILE_OPTIONS"。

但是,您可以通过target_compile_features(...)和手动设置它们,例如target_compile_options(mylib INTERFACE /std:c++17).但是后一个命令添加了标志,而不会删除/std:c++14

怎么办呢?

对于接口库,您需要更改INTERFACE_COMPILE_DEFINITIONS而不是COMPILE_DEFINITIONS(请参阅add_library(INTERFACE)(。

这是我用VS2017测试的完整示例(使用/std:c++latest,因为尚不支持/std:c++17CMake可能会忽略/删除(:

cmake_minimum_required(VERSION 3.8)
project(InterfaceLibCppStd)
include(CheckCXXCompilerFlag)
file(WRITE "mylib/Definitions.h" [=[ 
#define HELLO_TEXT "Hello Interface Lib"
]=])
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE "mylib")
target_compile_options(mylib INTERFACE "/std:c++14")
file(WRITE "main.cpp" [=[
#include "Definitions.h"
#include <iostream>
int main()
{
std::cout << HELLO_TEXT << std::endl;
}
]=])
add_executable(myexe "main.cpp")
if (MSVC_VERSION GREATER_EQUAL "1900")
CHECK_CXX_COMPILER_FLAG("/std:c++latest" _cpp_latest_flag_supported)
if (_cpp_latest_flag_supported)
get_target_property(_opt_old mylib INTERFACE_COMPILE_OPTIONS)
string(REPLACE "14" "latest" _opt_new "${_opt_old}")
set_target_properties(mylib PROPERTIES INTERFACE_COMPILE_OPTIONS "${_opt_new}")
endif()
endif()
target_link_libraries(myexe PUBLIC mylib)