Confusing flags passed to MSVC through NVCC with CMake - visual-c++

I have a CMake file which I'm using to build some CUDA on Windows (NVCC/MSVC). I'm trying to set the MSVC warning level to /W4, using:
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")
Building with CMake 3.9, I get this warning:
(CudaBuildCore target) ->
cl : Command line warning D9025: overriding '/W4' with '/W3'
In CMake 3.15, the policy was changed to not automatically set /W3 in the CUDA flags, but with that version I get:
(CudaBuildCore target) ->
cl : Command line warning D9025: overriding '/W4' with '/W1'
If I do the build step with --verbose I see the following with 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"
and with 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"
Spoiler: these are identical, except for the -Xcompiler "/EHsc /W3 /nologo /Od /Fdfish.dir\Debug\fish.pdb /FS /Zi /RTC1 /MDd /GR" portion.
Try as I might, I cannot find where this set of flags is being introduced (by CMake et al.), and hence can't start working out how to change the behaviour.
EDIT1: Adding color to the story...
I grep'd my CMake install for /nologo and found several .cmake files with lines like:
35: set(CMAKE_CL_NOLOGO "/nologo")
I changed them all to variations of
35: set(CMAKE_CL_NOLOGO "/nologo_EDD")
But none of them turn up in the confusing set of options. So either I've missed something or they're being introduced from something outside CMake?
EDIT2:
#squareskittles said:
you can remove the default flag from the CMAKE_CXX_FLAGS_INIT variable
Fair enough, I can see the logic to that: it's simple and it directly addresses my immediate issue. But it seems a bit blunt and doesn't address where the flags are coming from in the first place.
Anyway, objections aside, I added this ugly morsel to my script:
message( "--------------------------- ${CMAKE_CXX_FLAGS_INIT}")
string (REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT}")
message( "--------------------------- ${CMAKE_CXX_FLAGS_INIT}")
With CMake 3.9, I see:
--------------------------- /DWIN32 /D_WINDOWS /W3 /GR /EHsc
--------------------------- /DWIN32 /D_WINDOWS /GR /EHsc
as hoped. But with 3.15, I see:
--------------------------- /DWIN32 /D_WINDOWS /GR /EHsc
--------------------------- /DWIN32 /D_WINDOWS /GR /EHsc
ie, the /W3 flag isn't there in the first place (let alone a /W1 flag) due to the policy change. But even worse, the primary issue still persists in both cases:
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: Some progress!
With this simple change:
#add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/W4>")
there are no more complaints! The confusing flags persist, but now read:
-Xcompiler "/EHsc /W4 /nologo /Od /Ffish.dir\Debug\fish.pdb
/FS /Zi /RTC1 /MDd /GR"
ie. CMake has spotted the /W4 and overridden its default.
But despite scouring the CMake source, I've still yet to determine where all this is done.
EDIT4: MSVC has a hand in all this.
The 'mystery' options are generated somewhat automatically by MSVC from the .vcxproj file. If I use the -Xcompile=/W4 approach, the project XML contains:
<CudaCompile>
...
<AdditionalOptions>%(AdditionalOptions) -Xcompiler="/EHsc -Zi -Ob1"</AdditionalOptions>
...
<Warning>W4</Warning>
</CudaCompile>
But with the original, --compiler-options=/W4 I get:
<CudaCompile>
<AdditionalOptions>%(AdditionalOptions) --compiler-options=/W4 -Xcompiler="/EHsc -Zi -Ob1"</AdditionalOptions>
...
</CudaCompile>
And this all sort of makes sense; with no Warning level specified, MSVC must default to W1, hence the complaint.
Also, there was a clue-with-hindsight: the build step had:
-Xcompiler="/EHsc -Zi -Ob0"
-Xcompiler "/EHsc /W1 /nologo /Od ..."
Note one has an equals and one does not implying they come from different places.
I think my investigation has gone far enough for now.

A TL;DR summary of my own shaggy-dog-tale of a question:
I had:
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=/W4>")
but found:
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/W4>")
to be more appropriate.
Basically, the CMake/NVCC/MSVC pipeline understood that the -Xcompiler option overrode the default, but didn't realise that --compiler-options was an equivalent statement, resulting in a command line with ambiguous directives.

I had a similar issue (but with another flag) and used CMake's regular expressions to fix that. The code is like this.
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)

Related

how do I change debug to release using conan manager, msvc and cmake

Using conan manager with build_type=Release, the generator still uses Debug configuration see below. I don't want to use any additional .json file to setup the behavior. Any idea how to do that by using conan manager?
I found out that this:
cmake --build . --config Release -j
command changes debug configuration to release but I don't know how to do that in conan.
[settings]
os=Windows
os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=Visual Studio
compiler.version=16
build_type=Release
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\bin\HostX64\x64\CL.exe /c /IC:.conan\f23e85\1\include /IC:.conan\733d7c\1\include /Zi /nologo /W3 /WX- /diagnostics:column /Od /Ob0 /D WIN32 /D _WINDOWS /D "CMAKE_INTDIR="Debug"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /Fo"MyOpenCV.dir\Debug\" /Fd"MyOpenCV.dir\Debug\vc142.pdb" /Gd /TP /errorReport:queue C:\Users\Peter\source\repos\MyOpenCV\src\main.cpp
main.cpp
Solution to my question
missing setup in CMakeLists.txt file from generated conanbuildinfo.cmake file
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
and at the end
conan_target_link_libraries(MyOpenCV)

Why can't QuantLib compile on its last release?

After following the QuantLib 1.9 installation tutorial, I can't compile the library on my computer.
my setup
tutorial : https://www.quantlib.org/install/windows-python.shtml
python 3.6.3
Quantlib 1.9
Quantlib-SWIG 1.9
boost boost_1_66_0
visual studio 2017
windows 10
My error is the following :
"running build
running build_py
running build_ext
building 'QuantLib._QuantLib' extension
C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -D__WIN32__ -DWIN32 -DNDEBUG -D_WINDOWS -DNOMINMAX (.....) IC:\Users\AppData\Local\Continuum\anaconda3\Lib\site-packages\boost_1_66_0 /EHsc /TpQuantLib/quantlib_wrap.cpp /Fobuild\temp.win-amd64-3.6\Release\QuantLib/quantlib_wrap.obj /GR /FD /Zm250 /EHsc /bigobj /MD
quantlib_wrap.cpp
Info: Boost.Config is older than your compiler version - probably nothing bad will happen - but you may wish to look for an update Boost version. Define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE to suppress this message.
C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO (....)/OUT:build\lib.win-amd64-3.6\QuantLib_QuantLib.cp36-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.6\Release\QuantLib_QuantLib.cp36-win_amd64.lib /subsystem:windows /machine:x64
LINK : fatal error LNK1104: impossible d'ouvrir le fichier 'QuantLib-vc141-x64-mt.lib'
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\link.exe' failed with exit status 1104"
Wish someone could help with this one.

Compiling cuda in VS2012: fatal error C1083: Cannot open compiler generated file, no such file or directory

I've installed Visual Studio 2012 and the CUDA 6.0 toolkit. I can start a new project and select the CUDA 6.0 Runtime, but when I try to compile, it apparently can't find the object file.
This is the output for the sample code that comes when creating a CUDA project, although I get the same problem even if it's just a normal C program without any CUDA syntax.
Here is the full output I get when building kernel.cu:
1>------ Build started: Project: Temp, Configuration: Debug Win32 ------
1>Build started 08/06/2014 13:14:40.
1>PrepareForBuild:
1> Creating directory "d:\my documents\visual studio 2012\Projects\Temp\Debug\".
1>InitializeBuildStatus:
1> Creating "Debug\Temp.unsuccessfulbuild" because "AlwaysCreate" was specified.
1>CudaBuild:
1> Compiling CUDA source file kernel.cu...
1>
1> D:\Programming>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\bin\nvcc.exe" -gencode=arch=compute_10,code=\"sm_10,compute_10\" --use-local-env --cl-version 2012 -ccbin "D:\Programs\VC\bin" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\include" -G --keep-dir Debug -maxrregcount=0 --machine 32 --compile -cudart static -g -DWIN32 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd " -o Debug\kernel.cu.obj "d:\my documents\visual studio 2012\Projects\Temp\Temp\kernel.cu"
1>nvcc : warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
1> kernel.cu
1>C:\Users\Mort\AppData\Local\Temp\tmpxft_00001d3c_00000000-20_kernel.ii : fatal error C1083: Cannot open compiler generated file: 'Debug/kernel.cu.obj': No such file or directory
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\BuildCustomizations\CUDA 6.0.targets(597,9): error MSB3721: The command ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\bin\nvcc.exe" -gencode=arch=compute_10,code=\"sm_10,compute_10\" --use-local-env --cl-version 2012 -ccbin "D:\Programs\VC\bin" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\include" -G --keep-dir Debug -maxrregcount=0 --machine 32 --compile -cudart static -g -DWIN32 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd " -o Debug\kernel.cu.obj "d:\my documents\visual studio 2012\Projects\Temp\Temp\kernel.cu"" exited with code 1.
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:03.36
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I'm running Win7 64 bit and VS 2012 Ultimate.
Thanks!
I'm making this an answer since it solved your problem: there seems to be a mismatch between NVCC's path (D:\Programming) and your project's path.
You might end up compiling stuff in the wrong directory and then failing to find the temporaries created by the previous phase. Make sure to fix those paths and the compilation should proceed just fine since everything else matches (i.e. bitness/include paths)

With Visual C , typeid throw an exception but only in debug mode

The following code comes from an answer to question 398069. It works very well for me under Linux and also under Windows in optim mode. Unfortunately, my app crashes under Windows and I have to debug it...
template <class T>
T *set_the_global(T *candidate)
{
std::map<std::string,void*>::iterator r = MainFactoriesMap::mainFactoriesMap().find(std::string(typeid(*candidate).name()));
...
}
In debug mode (Windows, with qtcreator, cmake 2.8.2, Visual C++ 10, Qt and boost are available as debug and not debug), the call to typeid, which occurs before entering main, crashes, throwing an exception it seems. I forced the use of /GR option. It makes no difference...
I put below the calls to compiler and linker in debug and output modes. Note that I tried to compile everything under Visual Studio but it fails (but this will be another question).
Optim build: it works
c:\PROGRA~2\MICROS~2.0\VC\bin\amd64\cl.exe /Zc:wchar_t- /EHsc /GR /MD /O2 /Ob2 /D NDEBUG -IE:\Projets\Amose\Sources\lima_common\src -IC:\Qt\v4.8.2\include -IC:\Qt\v4.8.2\include\QtXml -IC:\Qt\v4.8.2\include\QtCore -IC:\PROGRA~1\boost\BOOST_~1\include -Ic:\amose\include -D DEBUG_CD -D WIN32 -D QT_NO_KEYWORDS -Dlima_common_factory_EXPORTS -DQT_DLL -DQT_XML_LIB -DQT_CORE_LIB -DBOOST_ALL_DYN_LINK -DLIMA_FACTORY_EXPORTING -DQT_NO_DEBUG /TP /FoCMakeFiles\lima-common-factory.dir\AmosePluginsManager.cpp.obj /FdC:\amose-vcbuild\lima-common\src\common\AbstractFactoryPattern\lima-common-factory.pdb -c E:\Projets\Amose\Sources\lima_common\src\common\AbstractFactoryPattern\AmosePluginsManager.cpp
...
"C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -E vs_link_dll c:\PROGRA~2\MICROS~2.0\VC\bin\amd64\link.exe #CMakeFiles\lima-common-factory.dir\objects1.rsp /out:lima-common-factory.dll /implib:lima-common-factory.lib /pdb:C:\amose-vcbuild\lima-common\src\common\AbstractFactoryPattern\lima-common-factory.pdb /dll /version:0.0 /STACK:10000000 /machine:x64 /INCREMENTAL:NO -LIBPATH:C:\PROGRA~1\boost\BOOST_~1\lib -LIBPATH:c:\amose\lib ..\QsLog\lima-common-qslog.lib ..\misc\lima-common-misc.lib ..\Data\lima-common-data.lib ..\QsLog\lima-common-qslog.lib C:\Qt\v4.8.2\lib\QtXml4.lib C:\Qt\v4.8.2\lib\QtCore4.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
Debug build: it fails
c:\PROGRA~2\MICROS~2.0\VC\bin\amd64\cl.exe /Zc:wchar_t- /EHsc /GR /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 -IE:\Projets\Amose\Sources\lima_common\src -IC:\Qt\v4.8.2\include -IC:\Qt\v4.8.2\include\QtXml -IC:\Qt\v4.8.2\include\QtCore -IC:\PROGRA~1\boost\BOOST_~1\include -Ic:\amose-debug\include -D DEBUG_CD -D WIN32 -D QT_NO_KEYWORDS -Dlima_common_factory_EXPORTS -DQT_DLL -DQT_XML_LIB -DQT_CORE_LIB -DBOOST_ALL_DYN_LINK -DLIMA_FACTORY_EXPORTING -DQT_DEBUG /TP /FoCMakeFiles\lima-common-factory.dir\AmosePluginsManager.cpp.obj /FdC:\amose-vcbuild\lima-common-debug\src\common\AbstractFactoryPattern\lima-common-factoryd.pdb -c E:\Projets\Amose\Sources\lima_common\src\common\AbstractFactoryPattern\AmosePluginsManager.cpp
...
"C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -E vs_link_dll c:\PROGRA~2\MICROS~2.0\VC\bin\amd64\link.exe #CMakeFiles\lima-common-factory.dir\objects1.rsp /out:lima-common-factoryd.dll /implib:lima-common-factoryd.lib /pdb:C:\amose-vcbuild\lima-common-debug\src\common\AbstractFactoryPattern\lima-common-factoryd.pdb /dll /version:0.0 /STACK:10000000 /machine:x64 /debug /INCREMENTAL -LIBPATH:C:\PROGRA~1\boost\BOOST_~1\lib -LIBPATH:c:\amose-debug\lib ..\QsLog\lima-common-qslogd.lib ..\misc\lima-common-miscd.lib ..\Data\lima-common-datad.lib ..\QsLog\lima-common-qslogd.lib C:\Qt\v4.8.2\lib\QtXmld4.lib C:\Qt\v4.8.2\lib\QtCored4.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
Showing the debuging session using qtcreator:

Compiling Visual c++ programs from the command line and msvcr90.dll

When I compile my Visual c++ 2008 express program from inside the IDE and redistribute it on another computer, It starts up fine without any dll dependencies that I haven't accounted for. When I compile the same program from the visual c++ 2008 command line under the start menu and redistribute it to the other computer, it looks for msvcr90.dll at start-up.
Here is how it is compiled from the command line
cl /Fomain.obj /c main.cpp /nologo -O2 -DNDEBUG /MD /ID:(list of include directories)
link /nologo /SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup /OUT:Build\myprogram.ex
e /LIBPATH:D:\libs (list of libraries)
and here is how the IDE builds it based on the relevant parts of the build log.
/O2 /Oi /GL /I clude" /I (list of includes) /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FD /EHsc /MD /Gy /Yu"stdafx.h" /Fp"Release\myprogram" /Fo"Release\\" /Fd"Release\vc90.pdb" /W3 /c /Zi /TP /wd4250 /vd2
Creating command line "cl.exe #d:\myprogram\Release\RSP00000118003188.rsp /nologo /errorReport:prompt"
/OUT:"D:\myprgram\Release\myprgram.exe" /INCREMENTAL:NO /LIBPATH:"d:\gtkmm\lib" /MANIFEST /MANIFESTFILE:"Release\myprogam.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"d:\myprogram\Release\myprogram.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /LTCG /ENTRY:"mainCRTStartup" /DYNAMICBASE /NXCOMPAT /MACHINE:X86 (list of libraries)
Creating command line "link.exe #d:\myprogram\Release\RSP00000218003188.rsp /NOLOGO /ERRORREPORT:PROMPT"
/outputresource:"..\Release\myprogram.exe;#1" /manifest
.\Release\myprogram.exe.intermediate.manifest
Creating command line "mt.exe #d:\myprogram\Release\RSP00000318003188.rsp /nologo"
I would like to be able to compile it from the command line and not have it look for such a late version of the runtime dll, like the version compiled from the IDE seems not to do. Both versions pass /MD to the compiler, so i am not sure what to do.
I know it is not exactly what you are looking for but you can invoke the ide build form the command line and it should give you the same output:
devenv solution.sln /build Release
This will build the Release configuration for solution.sln. (devenv /? on the command line for more info).

Resources