如何使用“现代CMake”设置编译器标志?

4

我正在尝试通过一个简单的项目学习CMake。这是我的示例CMakeLists.txt文件。

cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
set(PROJECT_NAME "MyLib" CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
project(${PROJECT_NAME})

include(${CMAKE_SOURCE_DIR}/Sources.cmake) 
set(SOURCE_FILES ${COMMON_CPP_FILES} ${COMMON_H_FILES})

include_directories(include)

add_compile_options("$<$<CONFIG:Debug>:/EHa /MTd /W3 /w14640>")

add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES})

我尝试基于这个文件创建一个Visual Studio项目,但是我无法弄清楚如何正确设置编译标志。当我打开Visual Studio时,我可以看到标志(/EHa)作为“附加选项”的一部分,但我仍然可以看到默认的(/EHsc)标志。

enter image description here

为什么默认标志仍然存在,我如何确保编译器确实使用了我指定的标志?

1
你走在正确的道路上。只有一个事实需要注意,就是每个生成器表达式应该使用一个标志,或者你必须使用分号;代替空格来使其成为选项列表(否则它会被引用并解释为单个命令行选项)。所以在你的情况下,应该使用 $<$<CONFIG:Debug>:/EHa;/MTd;/W3;/w14640> - Florian
@Florian 根据这个答案,最好使用target_compile_options。但是当我使用target_compile_options时,我注意到标志没有被替换,而只是被添加了,我在使用ninja时会收到警告,如这里所述。然而,当我使用add_compile_options时,我没有收到任何警告,因为这个命令似乎更加智能,实际上是替换而不是添加。你建议使用哪一个? - Ali
1个回答

2
你可以通过打印CMAKE_CXX_FLAGS和CMAKE_CXX_FLAGS_{RELEASE|DEBUG}来检查CMake使用的默认标志。 可以通过以下方式设置这些变量:
set(CMAKE_CXX_FLAGS "") 

但是,这样做不会清除它们。

我发现实现你所说的(清除特定默认标志)的唯一方法是针对每个默认标志执行以下操作:

string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")

我不知道为什么你不能轻松地清除所有默认标志而不使用这种语法。

4
我之前一直在做类似的事情,但现在到处都有“现代 CMake”的大肆宣传,人们认为手动操作CMAKE_CXX_FLAGS不是好习惯,因此我希望能够简单地设置这些标志而不用再去操心。 - Ali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接