Visual Studio 2017提供完整的CMake集成.要了解这个组合,我从这个基本样本开始:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(foo)
add_executable(foo foo.cpp)
Run Code Online (Sandbox Code Playgroud)
和
// foo.cpp
int main() {}
Run Code Online (Sandbox Code Playgroud)
这正确地生成了构建脚本,并且编译和链接没有任何问题.那很简单.
另一方面,试图设置编译器选项,结果却是微不足道的.在我的情况下,我试图将警告级别设置为4.
明显的解决方案
add_compile_options("/W4")
Run Code Online (Sandbox Code Playgroud)
没有像预期的那样平息.传递给编译器的命令行现在既包含/W4
(按预期),也包含/W3
(从其他地方获取),产生以下警告:
Run Code Online (Sandbox Code Playgroud)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()
Run Code Online (Sandbox Code Playgroud)
然而,这有两个问题:
CMAKE_CXX_FLAGS
,适用于所有C++目标.这可能不是有意的(现在对我来说不是问题).我的问题是双重的:
/Wall
选项,这也是不兼容的/W4
. 我正在尝试编译一些 CUDA,并且希望显示编译器警告。相当于:
g++ fish.cpp -Wall -Wextra
Run Code Online (Sandbox Code Playgroud)
除了 NVCC 不理解这些,你必须通过它们:
nvcc fish.cu --compiler-options -Wall --compiler-options -Wextra
nvcc fish.cu --compiler-options "-Wall -Wextra"
Run Code Online (Sandbox Code Playgroud)
(我喜欢后一种形式,但最终,这并不重要。)
鉴于此 CMakeLists.txt (一个非常精简的示例):
cmake_minimum_required(VERSION 3.9)
project(test_project LANGUAGES CUDA CXX)
list(APPEND cxx_warning_flags "-Wall" "-Wextra") # ... maybe others
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options ${cxx_warning_flags}>")
add_executable(test_cuda fish.cu)
Run Code Online (Sandbox Code Playgroud)
但这扩展到:
nvcc "--compiler-options -Wall" -Wextra ...
Run Code Online (Sandbox Code Playgroud)
这显然是错误的。(省略生成器表达式周围的引号只会让我们陷入破碎的扩展地狱。)
...跳过蒙特卡洛编程的数千次迭代...
我已经到达了这个宝石:
set( temp ${cxx_warning_flags} )
string (REPLACE ";" " " temp "${temp}")
set( temp2 "--compiler-options \"${temp}\"" )
message( "${temp2}" )
Run Code Online (Sandbox Code Playgroud)
打印出看起来令人鼓舞的
--compiler-options "-Wall -Wextra"
Run Code Online (Sandbox Code Playgroud)
但是之后
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp2}>")
Run Code Online (Sandbox Code Playgroud)
扩展到:
nvcc "--compiler-options \"-Wall …
Run Code Online (Sandbox Code Playgroud)