Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual c++ 通过NVCC和CMake传递给MSVC的混淆标志_Visual C++_Cmake_Cuda - Fatal编程技术网

Visual c++ 通过NVCC和CMake传递给MSVC的混淆标志

Visual c++ 通过NVCC和CMake传递给MSVC的混淆标志,visual-c++,cmake,cuda,Visual C++,Cmake,Cuda,我有一个CMake文件,我正在使用它在Windows上构建一些CUDA(NVCC/MSVC)。我正在尝试使用以下方法将MSVC警告级别设置为/W4: add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>") 在CMake 3.15中,策略更改为不在CUDA标志中自动设置/W3,但在该版本中,我得到: (CudaBuildCore target) -> cl : Comma

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

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")
在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等人提出),因此无法开始研究如何改变行为


编辑1:为故事增添色彩。。。 我为
/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>")
例如,CMake发现了
/W4
,并覆盖了其默认值

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


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

<CudaCompile>
  ...
  <AdditionalOptions>%(AdditionalOptions) -Xcompiler="/EHsc -Zi -Ob1"</AdditionalOptions>
  ...
  <Warning>W4</Warning>
 </CudaCompile>
这一切都是有道理的;在未指定警告级别的情况下,MSVC必须默认为W1,因此投诉

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

-Xcompiler="/EHsc -Zi -Ob0"
-Xcompiler "/EHsc /W1 /nologo /Od ..."
注意,一个人有一个等于,一个人并不意味着他们来自不同的地方

我认为我的调查到目前为止已经足够深入了;博士总结了我自己关于毛茸茸的狗的一个问题:

我有:

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")
添加编译选项($)
但发现:

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/W4>")
添加编译选项($)
更合适

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

我也有类似的问题(但有另一个标志)并使用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)

这回答了你的问题吗?谢谢@squareskittles。我不确定这个链接是否涵盖了我的情况(至少不是在第一次阅读时)。我遇到的问题似乎与通过NVCC将两组冲突的编译器标志传递给MSVC有关。但是我会再读一遍,看看它是否提供了同样的线索。如果目标是将警告标志设置为
/W4
,并删除
/W3
/W1
,您可以按照链接答案中的建议从
CMAKE_CXX_FLAGS_INIT
变量中删除默认标志。谢谢@squareskittles,我更新了我的问题,告诉大家这似乎还不够。旁白:我在谷歌上搜索了
“EHsc/W3/nologo/Od”
,它给出了很多点击率(到目前为止似乎没有有用的),但这意味着它是来自某个地方的默认标志集。但是在哪里?!FWIW,我已经向CMake提出了一个问题:
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/W4>")
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)