如何在Visual Studio 2017中使用CMake设置编译器选项

IInspectable:

Visual Studio 2017带有完整的CMake集成。要了解这种组合,我从以下基本示例开始:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(foo)
add_executable(foo foo.cpp)

// foo.cpp
int main() {}

这样可以正确生成构建脚本,并且可以毫无问题地进行编译和链接。那很简单。

另一方面,尝试设置编译器选项却很简单。就我而言,我试图将警告级别设置为4。

显而易见的解决方案

add_compile_options("/W4")

没有按预期完成。现在,传递给编译器的命令行既包含/W4(按预期)又包含/W3从其他地方拾取),从而产生以下警告:

cl : Command line warning D9025: overriding '/W3' with '/W4'

要解决此问题,我需要替换所有不兼容的编译器选项,而不仅仅是添加一个。CMake对此不提供任何直接支持,并且标准解决方案(如该问答所建议的)似乎是:

if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
    string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()

但是,这有两个问题:

  • 它设置了global CMAKE_CXX_FLAGS,适用于所有C ++目标。这可能不是故意的(现在对我来说不是问题)。
  • 它无法缩放。对于要添加的每个编译器选项,您都必须阅读不兼容的选项,并首先手动删除那些不兼容的选项。这将不可避免地失败1

我的问题有两个:

  1. CMake集成从哪里获取默认设置,并且可以对其进行控制?
  2. 您一般如何设置编译器选项?(如果这个话题太笼统,我很乐意仅在设置警告级别时提供帮助。)


1 顺便说一句,我复制的解决方案无法说明该/Wall选项,因为该选项也不兼容/W4

该死的:

编译器的默认设置是从ModulesCMake安装目录中的标准模块文件中提取的使用的实际模块文件取决于平台和编译器。例如,对于Visual Studio 2017,CMake将从文件中加载默认设置,Windows-MSVC.cmake并从Windows-MSVC-C.cmake或中加载特定于语言的设置Windows-MSVC-CXX.cmake

要检查默认设置,请CompilerOptions.cmake在项目目录中创建一个包含以下内容的文件:

# log all *_INIT variables
get_cmake_property(_varNames VARIABLES)
list (REMOVE_DUPLICATES _varNames)
list (SORT _varNames)
foreach (_varName ${_varNames})
    if (_varName MATCHES "_INIT$")
        message(STATUS "${_varName}=${${_varName}}")
    endif()
endforeach()

然后CMAKE_USER_MAKE_RULES_OVERRIDE在您的中初始化变量CMakeLists.txt

# CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
set (CMAKE_USER_MAKE_RULES_OVERRIDE "${CMAKE_CURRENT_LIST_DIR}/CompilerOptions.cmake")
project(foo)
add_executable(foo foo.cpp)

在Visual Studio 2017中打开目录配置项目后,IDE的输出窗口中将显示以下信息:

 ...
 -- CMAKE_CXX_FLAGS_DEBUG_INIT= /MDd /Zi /Ob0 /Od /RTC1
 -- CMAKE_CXX_FLAGS_INIT= /DWIN32 /D_WINDOWS /W3 /GR /EHsc
 -- CMAKE_CXX_FLAGS_MINSIZEREL_INIT= /MD /O1 /Ob1 /DNDEBUG
 -- CMAKE_CXX_FLAGS_RELEASE_INIT= /MD /O2 /Ob2 /DNDEBUG
 -- CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT= /MD /Zi /O2 /Ob1 /DNDEBUG
 ...

因此,警告设置/W3是从CMake变量中选取的CMAKE_CXX_FLAGS_INIT,然后将其应用于项目中生成的所有CMake目标。

要在CMake项目或目标级别上控制警告级别,可以通过在文件中添加以下几行来更改中的CMAKE_CXX_FLAGS_INIT变量CompilerOptions.cmake

if (MSVC)
    # remove default warning level from CMAKE_CXX_FLAGS_INIT
    string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT}")
endif()

然后可以通过在以下位置设置目标编译选项来控制警告标志CMakeLists.txt

...
add_executable(foo foo.cpp)
target_compile_options(foo PRIVATE "/W4")

对于大多数CMake项目,有必要在覆盖文件中控制默认的编译器选项,而不是手动调整变量CMAKE_CXX_FLAGS

更改CompilerOptions.cmake文件时,必须重新创建构建文件夹。Open Folder模式下使用Visual Studio 2017时,请Cache ... -> Delete Cache FoldersCMake菜单中选择命令,然后Cache ... -> GenerateCMake菜单中选择以重新创建生成文件夹。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Visual Studio 2015中使用roslyn C#编译器?

使用Visual Studio 2017的编译器在C ++ 17中使用Lambda编译Kevlin Henney的Fizzbuzz

如何在Windows下使用cmake生成使用Intel编译器的Visual Studio项目

在Visual Studio 2013中使用Roslyn编译器

如何在Visual Studio中使用更少的自动编译器

如何在Visual Studio 2017中使用Qt库?

如何在Visual Studio 2017中使用Java

如何在Visual Studio 2017中使用Jupyter Notebook?

如何在Visual Studio 2017中使用自定义条件编译符号?

如何在 Visual Studio 2017 中使 != 变为 ==

在Visual Studio中配置编译器优化选项

如何在Visual Studio 2017中编译更少/无效的文件

在Visual Studio中使用64位编译器

如何在Visual Studio中使用PhoneGap

如何在Visual Studio中使用IntelliCode?

如何在Visual Studio中使用Startswith

如何在Visual Studio Code for TypeScript中完全导入而获得编译器错误消息?

如何在Visual Studio 2012 Release 2中获得.less编译器支持?

如何在Visual Studio中查看模板编译器错误详细信息

如何在Dymola 2019 FD01中为Visual Studio编译器利用编译器标志

如何在 Visual Studio 2017、C++、CMake 中使用数据断点?

如何在Visual Studio Code中设置Beautify扩展选项?

编译器指令如何在Visual Studio 2015中与project.json一起使用

如何在Visual Studio 2017中使用最新版本的Xamarin表单针对Android 4.4进行编译?

如何在TFS Visual Studio构建步骤中使用Visual Studio 2017

如何在 Visual Studio 2017 中添加和使用图像?

如何在Visual Studio中更改“许可给”?

如何在Visual Studio中升级ReSharper?

如何在Visual Studio中包括OpenSSL