如何在Visual Studio 2017中使用CMake设置编译器选项 [英] How to set compiler options with CMake in Visual Studio 2017

查看:1542
本文介绍了如何在Visual Studio 2017中使用CMake设置编译器选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Visual Studio 2017 comes with full CMake integration. To learn about this combination, I was starting with this basic sample:

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

// foo.cpp
int main() {}

这会正确生成生成脚本,并且编译和链接没有问题。

This properly generates build scripts, and compiles and links with no issues. That was easy.

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

Trying to set compiler options, on the other hand, turned out to be anything but trivial. In my case I was attempting to set the warning level to 4.

显而易见的解决方案

add_compile_options("/W4")

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

didn't pan out as expected. The command line passed to the compiler now contains both /W4 (as intended) as well as /W3 (picked up from somewhere else), producing the following warning:


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


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

To work around this, I would need to replace any incompatible compiler option(s) instead of just adding one. CMake does not provide any immediate support for this, and the standard solution (as this Q&A suggests) seems to be:

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()

但是,这有两个问题:


  • 它设置全局 CMAKE_CXX_FLAGS ,并应用于所有C ++目标。这可能不是故意的(现在对我来说不是问题)。

  • 它无法扩展。对于要添加的每个编译器选项,您都必须阅读不兼容的选项,并首先手动删除那些不兼容的选项。这将不可避免地失败 1

  • It sets the global CMAKE_CXX_FLAGS, applying to all C++ targets. This may not be intended (not an issue for me right now).
  • It doesn't scale. For every compiler option to add, you would have to read up on incompatible options, and manually strip those first. This will inevitably fail1.

我的问题有两个:


  1. CMake集成从哪里获取默认设置,并且可以对其进行控制?

  2. 如何在以下位置设置编译器选项一般? (如果这是一个太宽泛的话题,我很乐意仅在设置警告级别上提供帮助。)



1 偶然地,我复制的解决方案无法说明 / Wall 选项,该选项与<$不兼容c $ c> / W4 。


1 Incidentally, the solution I replicated fails to account for the /Wall option, that is incompatible with /W4 as well.

推荐答案

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

The default settings for the compiler are picked up from standard module files located in the Modules directory of the CMake installation. The actual module file used depends on both the platform and the compiler. E.g., for Visual Studio 2017, CMake will load the default settings from the file Windows-MSVC.cmake and language specific settings from Windows-MSVC-C.cmake or Windows-MSVC-CXX.cmake.

检查默认值设置,在项目目录中创建文件 CompilerOptions.cmake ,内容如下:

To inspect the default settings, create a file CompilerOptions.cmake in the project directory with the following contents:

# 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的输出窗口中:

When the project is configured upon opening the directory in Visual Studio 2017, the following information will be show in the IDE's output window:

 ...
 -- 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
 ...

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

So the warning setting /W3 is picked up from the CMake variable CMAKE_CXX_FLAGS_INIT which then applies to all CMake targets generated in the project.

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

To control the warning level on the CMake project or target level, one can alter the CMAKE_CXX_FLAGS_INIT variable in the CompilerOptions.cmake by adding the following lines to the file:

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 中设置目标编译选项来控制警告标志:

The warning flags can then be controlled by setting the target compile options in CMakeLists.txt:

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

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

For most CMake projects it makes sense to control the default compiler options in an override file instead of manually tweaking variables like CMAKE_CXX_FLAGS.

CompilerOptions.cmake 文件进行更改时,有必要重新创建构建文件夹。在打开文件夹模式下使用Visual Studio 2017时,选择命令 Cache ...->。从 CMake 菜单中删除缓存文件夹,然后从 Cache ...->删除。从 CMake 菜单生成,以重新创建构建文件夹。

When making changes to the CompilerOptions.cmake file, it is necessary to recreate the build folder. When using Visual Studio 2017 in Open Folder mode, choose the command Cache ... -> Delete Cache Folders from the CMake menu and then Cache ... -> Generate from the CMake menu to recreate the build folder.

这篇关于如何在Visual Studio 2017中使用CMake设置编译器选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆