This question already has answers here:
Correctly set Visual Studio linker flag /SUBSYSTEM in CMAKE
(2 answers)
Closed 29 days ago.
I want to set /SUBSYSTEM:WINDOWS option to a executable,but there is a default option /subsystem:console in there,I try to override it, but it didn't work.
Here is the log
cmd.exe /C "cd .&& F:\environment_application\CLion-2021.3.4.win\bin\cmake\win\bin\cmake.exe -E vs_link_exe --intdir=chapter5\CMakeFiles\meminfo.dir --rc="F:\Windows Kits\10\bin\10.0.22000.0\x64\rc.exe" --mt="F:\Windows Kits\10\bin\10.0.22000.0\x64\mt.exe" --manifests -- F:\environment_application\visual_studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx64\x64\link.exe /nologo chapter5\CMakeFiles\meminfo.dir\memInfo.cpp.obj /out:chapter5\meminfo.exe /implib:chapter5\meminfo.lib /pdb:chapter5\meminfo.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console /subsystem:WINDOWS kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
LINK Pass 1: command "F:\environment_application\visual_studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx64\x64\link.exe /nologo chapter5\CMakeFiles\meminfo.dir\memInfo.cpp.obj /out:chapter5\meminfo.exe /implib:chapter5\meminfo.lib /pdb:chapter5\meminfo.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console /subsystem:WINDOWS /SUBSYSTEM:WINDOWS kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:chapter5\CMakeFiles\meminfo.dir/intermediate.manifest chapter5\CMakeFiles\meminfo.dir/manifest.res" failed (exit code 1120) with the following output:
libcmtd.lib(exe_winmain.obj): error LNK2019: unresolved external symbol WinMain referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
notice the link options is
/version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console /subsystem:WINDOWS
The cmake code i used is here:
add_executable(meminfo memInfo.cpp memInfo.h)
target_compile_options(meminfo PUBLIC /MTd)
target_link_options(meminfo PUBLIC /SUBSYSTEM:WINDOWS)
set_target_properties(meminfo PROPERTIES
LINK_FLAGS
/subsystem:WINDOWS
)
Set the WIN32_EXECUTABLE to True.
set_target_properties(meminfo PROPERTIES WIN32_EXECUTABLE True)
You could also use the add_executable command to do this:
add_executable(meminfo WIN32 memInfo.cpp memInfo.h)
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)
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)
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.
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).