【问题标题】:Confusing flags passed to MSVC through NVCC with CMake使用 CMake 通过 NVCC 传递给 MSVC 的混淆标志
【发布时间】:2020-01-02 14:19:14
【问题描述】:

我有一个 CMake 文件,用于在 Windows (NVCC/MSVC) 上构建一些 CUDA。我正在尝试将 MSVC 警告级别设置为 /W4,使用:

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")

使用 CMake 3.9 构建时,我收到以下警告:

(CudaBuildCore target) ->
  cl : Command line warning D9025: overriding '/W4' with '/W3'

在 CMake 3.15 中,该策略已更改为不自动在 CUDA 标志中设置 /W3,但使用该版本我得到了:

(CudaBuildCore target) ->
  cl : Command line warning D9025: overriding '/W4' with '/W1'

如果我使用 --verbose 执行构建步骤,我会在 3.9 中看到以下内容:

  "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin\nvcc.exe" -gencode=arch=compute_30,code=\"compute_30,compute_30\" --use-local-env -ccbin "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64" -x cu  -IC:\Users\eddi\Documents\temp\thur\sw\include -IC:\Users\eddi\Documents\temp\thur\sw\shared\common\include -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\include"     --keep-dir x64\Debug -maxrregcount=0  --machine 64 --compile -cudart static --compiler-options=/W4 --compiler-options= -Xcompiler="/EHsc -Zi -Ob0" -g   -D_WINDOWS -D"FISH_BUILD_TYPE=\"DEBUG\"" -D"CMAKE_INTDIR=\"Debug\"" -D"CMAKE_INTDIR=\"Debug\"" -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /Fdfish.dir\Debug\fish.pdb /FS /Zi /RTC1 /MDd /GR" -o fish.dir\Debug\fish_cuda.obj "C:\Users\eddi\Documents\temp\thur\sw\fish_cuda.cpp"

3.15:

  "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin\nvcc.exe" -gencode=arch=compute_30,code=\"compute_30,compute_30\" --use-local-env -ccbin "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64" -x cu  -IC:\Users\eddi\Documents\temp\thur\sw\include -IC:\Users\eddi\Documents\temp\thur\sw\shared\common\include -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\include"     --keep-dir x64\Debug -maxrregcount=0  --machine 64 --compile -cudart static --compiler-options=/W4 --compiler-options= -Xcompiler="/EHsc -Zi -Ob0" -g   -D_WINDOWS -D"FISH_BUILD_TYPE=\"DEBUG\"" -D"CMAKE_INTDIR=\"Debug\"" -D"CMAKE_INTDIR=\"Debug\"" -D_MBCS -Xcompiler "/EHsc /W1 /nologo /Od /Fdfish.dir\Debug\fish.pdb /FS /Zi /RTC1 /MDd /GR" -o fish.dir\Debug\fish_cuda.obj "C:\Users\eddi\Documents\temp\thur\sw\fish_cuda.cpp"

剧透:除了-Xcompiler "/EHsc /W3 /nologo /Od /Fdfish.dir\Debug\fish.pdb /FS /Zi /RTC1 /MDd /GR" 部分之外,这些都是相同的。

尽我所能,我找不到这组标志被引入的位置(由 CMake 等人),因此无法开始研究如何改变行为。


EDIT1:为故事添加色彩... 我为/nologo 安装了我的CMake,并找到了几个.cmake 文件,其中包含以下行:

   35:   set(CMAKE_CL_NOLOGO "/nologo")

我把它们都改成了

   35:   set(CMAKE_CL_NOLOGO "/nologo_EDD")

但它们都没有出现在令人困惑的选项集中。所以要么我错过了一些东西,要么它们是从 CMake 之外的东西引入的?


编辑2: @squareskittles 说:

您可以从 CMAKE_CXX_FLAGS_INIT 变量中删除默认标志

很公平,我可以看到其中的逻辑:它很简单,并且直接解决了我的紧迫问题。但这似乎有点生硬,并没有首先说明标志的来源。

不管怎样,抛开异议,我在我的脚本中添加了这个丑陋的东西:

message( "--------------------------- ${CMAKE_CXX_FLAGS_INIT}")
string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT}")
message( "--------------------------- ${CMAKE_CXX_FLAGS_INIT}")

使用 CMake 3.9,我明白了:

---------------------------   /DWIN32 /D_WINDOWS /W3 /GR /EHsc
---------------------------   /DWIN32 /D_WINDOWS  /GR /EHsc

如所愿。但是在 3.15 中,我看到了:

---------------------------   /DWIN32 /D_WINDOWS /GR /EHsc
---------------------------   /DWIN32 /D_WINDOWS /GR /EHsc

即,由于政策变化,/W3 标志首先不存在(更不用说/W1 标志)。但更糟糕的是,在这两种情况下,主要问题仍然存在:

nvcc.exe ... --compiler-options=/W4 -Xcompiler="/EHsc -Zi -Ob0" ... -Xcompiler "/EHsc /W3 /nologo /Od /Fdfish.dir\Debug\fish.pdb /FS /Zi /RTC1 /MDd /GR" ...

EDIT3:取得了一些进展! 有了这个简单的改变:

#add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/W4>")

没有更多的抱怨!令人困惑的标志仍然存在,但现在阅读:

-Xcompiler "/EHsc /W4 /nologo /Od /Ffish.dir\Debug\fish.pdb
  /FS /Zi /RTC1 /MDd /GR"

即。 CMake 发现了 /W4 并覆盖了它的默认值。

但是尽管搜索了 CMake 源代码,我还没有确定所有这些是在哪里完成的。


EDIT4:MSVC 参与了这一切。 MSVC 从.vcxproj 文件中自动生成“神秘”选项。如果我使用 -Xcompile=/W4 方法,项目 XML 包含:

<CudaCompile>
  ...
  <AdditionalOptions>%(AdditionalOptions) -Xcompiler="/EHsc -Zi -Ob1"</AdditionalOptions>
  ...
  <Warning>W4</Warning>
 </CudaCompile>

但是对于原版,--compiler-options=/W4 我明白了:

<CudaCompile>
   <AdditionalOptions>%(AdditionalOptions) --compiler-options=/W4 -Xcompiler="/EHsc -Zi -Ob1"</AdditionalOptions>
   ...
</CudaCompile>

这一切都是有道理的;如果没有指定警告级别,MSVC 必须默认为 W1,因此会出现投诉。

此外,事后有一个线索:构建步骤:

-Xcompiler="/EHsc -Zi -Ob0"
-Xcompiler "/EHsc /W1 /nologo /Od ..."

注意一个有一个等号,一个不暗示他们来自不同的地方。

我认为我的调查目前已经足够深入了。

【问题讨论】:

  • 谢谢@squareskittles。我不确定该链接是否涵盖了我的情况(至少在初读时不是)。我遇到的问题似乎与通过 NVCC 将 两个 组冲突的编译器标志传递给 MSVC 有关。但我会再读一遍,看看它是否提供了同样的线索。
  • 如果目标是将警告标志设置为/W4,并删除/W3/W1,您可以按照链接中的建议从CMAKE_CXX_FLAGS_INIT 变量中删除默认标志回答。
  • 感谢@squareskittles,我更新了我的问题,但不幸的是这似乎还不够。
  • 旁白:我用谷歌搜索了"EHsc /W3 /nologo /Od",它提供了很多点击(目前还没有一个似乎有用的),但这意味着它是来自某个地方的一组默认标志。但是在哪里?!

标签: visual-c++ cmake cuda


【解决方案1】:

一个 TL;DR 对我自己的毛茸茸的狗故事的总结:

我有:

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")

但找到了:

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/W4>")

更合适。

基本上,CMake/NVCC/MSVC 管道理解 -Xcompiler 选项覆盖了默认值,但没有意识到 --compiler-options 是一个等效语句,导致命令行具有模棱两可的指令。

【讨论】:

【解决方案2】:

我有一个类似的问题(但有另一个标志)并使用 CMake 的正则表达式来解决这个问题。代码是这样的。

foreach(flag_var
        CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
    STRING (REGEX REPLACE "/W3" "/W4" ${flag_var} "${${flag_var}}")
endforeach(flag_var)

【讨论】:

    猜你喜欢
    • 2020-04-12
    • 1970-01-01
    • 2019-04-14
    • 2020-10-11
    • 2012-07-06
    • 1970-01-01
    • 2021-04-21
    • 2019-05-05
    • 1970-01-01
    相关资源
    最近更新 更多