Visual Studio 2019 project generated with CMake ignores CMAKE_CXX_COMPILER - visual-studio

I'm trying to configure CMake 3.24.2 to generate a Visual Studio 2019 project that uses ccache to cache the output of previous builds. For that, I'm following alternative #1 from ccache's docs, where I'm trying to configure CMake to point the compiler to a copy of ccache which I've dumped in C:/tools/ccache/cl.exe. For that purpose I'm setting CMAKE_CXX_COMPILER to point to my ccache.exe, and I'm generating the project with the following command.
cmake.exe -DCMAKE_CXX_COMPILER=C:/tools/ccache/cl.exe -G "Visual Studio 16 2019" -A Win32 -DCMAKE_INSTALL_LIBDIR=lib/win/Release/x86 -S D:\proj\testproject -B D:\proj\testproject\cmake-build-release
However, this does not work and the vs2019 project keeps on pointing to the original cl.exe command. Here's an except I've taken from D:\proj\testproject\cmake-build-release\CMakeFiles\CMakeOutput.log:
The system is: Windows - 10.0.19041.0 - AMD64
Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
Compiler: C:/tools/ccache/cl.exe
Build flags:
Id flags:
The output was:
0
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 2/11/2023 4:51:26 PM.
Project "D:\proj\testproject\cmake-build-release\CMakeFiles\3.24.2\CompilerIdCXX\CompilerIdCXX.vcxproj" on node 1 (default targets).
PrepareForBuild:
Creating directory "Debug\".
Creating directory "Debug\CompilerIdCXX.tlog\".
InitializeBuildStatus:
Creating "Debug\CompilerIdCXX.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\HostX64\x86\CL.exe /c /nologo /W0 /WX- /diagnostics:column /Od /Oy- /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"Debug\\" /Fd"Debug\vc142.pdb" /external:W0 /Gd /TP /analyze- /FC /errorReport:queue CMakeCXXCompilerId.cpp
CMakeCXXCompilerId.cpp
(...)
Apparently the Visual Studio 2019 project does get the hint that it should use C:/tools/ccache/cl.exe, but for some unknown reason its ClCompile entry points to the original cl.exe.
Does anyone know what's going on for the Visual Studio 2019 insisting on not using the C++ compiler passed with CMAKE_CXX_COMPILER?

This happens because the original cl.exe is inferred from the chosen generator "Visual Studio 16 2019".
In order to switch to another compiler you should use other generator e.g. Ninja or Unix Makefiles.

Related

cmake on Jenkins windows slave fails unless an interactive logon has been opened for the build user

We've recently set up Jenkins to start automation of builds for a Windows application and this uses Cmake for builds.
Jenkins slaves are created on demand and connected to the Jenkins master using WinRM launching the java remoting.jar and this seems to work fine.
However, when running the build it will fail the ABI detection and then be unable to compile its test app because of certificate or network password issues as below:
[build] $ c:\jenkins\tools\hudson.plugins.cmake.CmakeTool\3.19.2\bin\cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE=Release -A x64 -D CMAKE_SYSTEM_NAME=WindowsStore -D CMAKE_SYSTEM_VERSION=10.0 c:\jenkins\workspace\tpc-win10
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.
-- The C compiler identification is MSVC 19.28.29335.0
-- The CXX compiler identification is MSVC 19.28.29335.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe - broken
CMake Error at C:/Jenkins/tools/hudson.plugins.cmake.CmakeTool/3.19.2/share/cmake-3.19/Modules/CMakeTestCCompiler.cmake:66 (message):
The C compiler
"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: C:/Jenkins/workspace/tpc-win10/build/CMakeFiles/CMakeTmp
Run Build Command(s):C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/MSBuild.exe cmTC_8452c.vcxproj /p:Configuration=Debug /p:Platform=x64 /p:VisualStudioVersion=16.0 /v:m && Microsoft (R) Build Engine version 16.8.2+25e4d540b for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29335 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
cl /c /I"C:\Jenkins\workspace\tpc-win10\build\CMakeFiles\CMakeTmp\\" /I"Generated Files\\" /IcmTC_8452c.dir\Debug\ /Zi /W3 /WX- /diagnostics:column /sdl /MP /Od /Ob0 /Oi /Oy- /D WIN32 /D _WINDOWS /D UNICODE /D _UNICODE /D "CMAKE_INTDIR=\"Debug\"" /D _UNICODE /D UNICODE /D WINAPI_FAMILY=WINAPI_FAMILY_APP /D __WRL_NO_DEFAULT_LIB__ /Gm- /MDd /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"cmTC_8452c.dir\Debug\\" /Fd"cmTC_8452c.dir\Debug\vc142.pdb" /Gd /TC /FU"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\lib\x86\store\references\platform.winmd" /analyze- /errorReport:queue "C:\Jenkins\workspace\tpc-win10\build\CMakeFiles\CMakeTmp\testCCompiler.c"
testCCompiler.c
LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification [C:\Jenkins\workspace\tpc-win10\build\CMakeFiles\CMakeTmp\cmTC_8452c.vcxproj]
cmTC_8452c.vcxproj -> C:\Jenkins\workspace\tpc-win10\build\CMakeFiles\CMakeTmp\Debug\cmTC_8452c.exe
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0\AppxPackage\Microsoft.AppXPackage.Targets(826,5): error : Certificate could not be opened: C:\Jenkins\workspace\tpc-win10\build\CMakeFiles\CMakeTmp\cmTC_8452c.dir\Windows_TemporaryKey.pfx. [C:\Jenkins\workspace\tpc-win10\build\CMakeFiles\CMakeTmp\cmTC_8452c.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0\AppxPackage\Microsoft.AppXPackage.Targets(826,5): error : The specified network password is not correct. [C:\Jenkins\workspace\tpc-win10\build\CMakeFiles\CMakeTmp\cmTC_8452c.vcxproj]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0\AppxPackage\Microsoft.AppXPackage.Targets(826,5): error : [C:\Jenkins\workspace\tpc-win10\build\CMakeFiles\CMakeTmp\cmTC_8452c.vcxproj]
The same build will succeed if a user creates a separate RDP session to the windows host prior to executing the build:
[build] $ c:\jenkins\tools\hudson.plugins.cmake.CmakeTool\3.19.2\bin\cmake -G "Visual Studio 16 2019" -D CMAKE_BUILD_TYPE=Release -A x64 -D CMAKE_SYSTEM_NAME=WindowsStore -D CMAKE_SYSTEM_VERSION=10.0 c:\jenkins\workspace\tpc-win10
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.
-- The C compiler identification is MSVC 19.28.29335.0
-- The CXX compiler identification is MSVC 19.28.29335.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29333/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Jenkins/workspace/tpc-win10/build
Initially I thought it may relate to Windows Defender but it seems to be as simple as needing the build user to have an interactive logon session open. Is there any way to emulate this for the process executing under WinRM without having to use RDP ?
What version of Jenkins are you using, and is the Windows PC always logged in as a user, and then WinRM just launches the JAR? Or are you logging in as a user when you do the RDP?
I suspect Windows is running the slave agent as something different and you're running into permissions issues somewhere.
I can get Windows to work by using the Jenkins Agent Service on Startup.
Initiate first slave on the target PC
Install Jenkins Agent as a service on the admin account
Set service to start on reboot or when the service is not detected
Using this method, no RDP is necessary after I reboot.

Microsoft Visual C++ with /MDd produces broken executable inside Windows container

I build C++ code inside Windows container using Microsoft Visual C++ Build Tools 2015
msbuild /p:Configuration=Debug essentially runs cl.exe with /MDd option and produces unusable executable - see below.
/p:Configuration=Release uses /MD and makes perfectly fine executable.
Sample code hello-world.cxx:
#include <iostream>
int main()
{
std::cout << "Hello World!";
}
Compiling with /MDd:
> cl.exe /EHsc /MDd hello-world.cxx
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24210 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
hello-world.cxx
Microsoft (R) Incremental Linker Version 14.00.24210.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:hello-world.exe
hello-world.obj
> echo %ERRORLEVEL%
0
> hello-world.exe
...nothing is printed here...
> echo %ERRORLEVEL%
-1073741515
Compiling with /MD:
> cl.exe /EHsc /MD hello-world.cxx
...
> hello-world.exe
Hello World!
> echo %ERRORLEVEL%
0
Here is the relevant part of my Dockerfile:
FROM microsoft/windowsservercore
...
# Install chocolatey ...
...
# Install Visual C++ Build Tools, as per: https://chocolatey.org/packages/vcbuildtools
RUN choco install -y vcbuildtools -ia "/InstallSelectableItems VisualCppBuildTools_ATLMFC_SDK"
# Add msbuild to PATH
RUN setx /M PATH "%PATH%;C:\Program Files (x86)\MSBuild\14.0\bin"
# Test msbuild can be accessed without path
RUN msbuild -version
As you can see I install Visual C++ Build Tools 2015 via choco package.
I've read documentation: https://learn.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library
So /MDd defines _DEBUG and also places MSVCRTD.lib into the .obj file, not MSVCRT.lib
On my laptop I have full Visual Studio installed and it builds fine.
I've compared MSVCRTD.lib that I have installed under C:\Program Files (x86)\Microsoft Visual Studio 14.0 and on both systems files are the same.
Confused...
SOLVED
Container has no GUI, and compiled .exe tries to show GUI dialog with the message:
"The program can't start because ucrtbased.dll is missing from your
computer. Try reinstalling the program to fix this problem."
(found this when running built .exe in a similar environment but with GUI)
Interestingly C++ Build Tools 2015 installed these dll-s under:
C:\Program Files (x86)\Windows Kits\10\bin\x64\ucrt\
C:\Program Files (x86)\Windows Kits\10\bin\x86\ucrt\
However when .exe runs it can't find them.
On full VS installation I found these files also copied under
C:\Windows\System32\
C:\Windows\SysWOW64\
Reinstallation of C++ Build Tools helped, however it's slow and feels weird.
So I've ended up just copy-ing those files manually instead.
Added to Dockerfile:
RUN copy "C:\Program Files (x86)\Windows Kits\10\bin\x64\ucrt\ucrtbased.dll" C:\Windows\System32\
RUN copy "C:\Program Files (x86)\Windows Kits\10\bin\x86\ucrt\ucrtbased.dll" C:\Windows\SysWOW64\

Visual Studio seemingly ignoring runtime library set in cmake

There are many posts about how to set the Runtime library in Visual Studio from CMake, but in my case it seems that Visual Studio is ignoring my setting.
I would like to build google-mock with /MD. This is the default setting in the project.
In a fresh build directory, built with:
cmake -G "Visual Studio 12 2013" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=C:\Users\mrussell\workspace\opal2\o2win32\Libs\gtest\"1.7.0" -DCMAKE_CXX_FLAGS_RELEASE="/MD /O2 /Ob2 /D NDEBUG" ../googlemock
All my cmake variables seem correct
However, when I go to build, either via the command line (I'm used to linux..) or from Visual Studio, it uses the /MT flag.
My build command (targeting 32 bit):
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\vcvars32.bat"
msbuild /m:4 /property:Configuration=%build_type% ALL_BUILD.vcxproj
Output:
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe /c /IC:\Users\mrussell\workspace\opal2\o2win32\Libs\gtest\g
test\include /IC:\Users\mrussell\workspace\opal2\o2win32\Libs\gtest\gtest /Zi /nologo /W4 /WX /O2 /Ob2 /Oy- /D WIN32 /D _WIND
OWS /D NDEBUG /D WIN32 /D _WINDOWS /D _UNICODE /D UNICODE /D WIN32 /D _WIN32 /D STRICT /D WIN32_LEAN_AND_MEAN /D GTEST_HAS_PT
HREAD=0 /D _HAS_EXCEPTIONS=1 /D "CMAKE_INTDIR=\"Release\"" /D _UNICODE /D UNICODE /Gm- /EHsc /MT /GS /fp:precise /Zc:wchar_t
/Zc:forScope /GR /Fo"gtest.dir\Release\\" /Fd"gtest.dir\Release\vc120.pdb" /Gd /TP /wd4127 /wd4251 /wd4275 /analyze- /errorRe
port:queue -J "C:\Users\mrussell\workspace\opal2\o2win32\Libs\gtest\gtest\src\gtest-all.cc"
(note the /MT hiding in there.)
In Visual Studio, I open the solution, choose release type Release, and in any of the targets, say gtest, Properties -> Configuration Properties -> C/C++ -> Code Generation, the Runtime Library is set to /MT, not /MD as set in the Cmake file.
Same thing happens if I try to build google-test (1.7.0)
Do I just not understand how to set these? Or is there a way to force Visual Studio to use the right flag without manually opening Visual Studio and setting it?
The CMake build systems of both google-test and google-mock aren't well behaved. They do not obey the compile options and runtime option set up by the user for good reason and override those with options that they consider reasonable for testing purposes.
To prevent the replacement of MD with MT you can set the option gtest_force_shared_crt to ON in the CMake cache. The modification of other compile options (e.g., warnings) however is done unconditionally.

'X86' conflicts with target machine type 'x64'

I'm getting the following error:
LNK1112: module machine type 'X86' conflicts with target machine type 'x64'
I'm working on a 64 bit machine (VS2008) and I have the x64 compiler. I checked that the build is on x64.
Why isn't it compiling? Here's the build log:
echo "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\bin\nvcc.exe" -gencode=arch=compute_10,code=\"sm_10,compute_10\" -gencode=arch=compute_20,code=\"sm_20,compute_20\" --machine 32 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin" -Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT " -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.1\include" -maxrregcount=0 --compile -o "x64\Debug/lowWrappers.cu.obj" lowWrappers.cu
In the top of the properties dialogue, there's a Platform dropdown. That should say "Active(x64)". If it says "Active(Win32)", that's your problem. Click "Configuration Manager..." in the top right, select the platform for your project, select "" and find x64. You can then delete the Win32 platform if you like.
(this might be a bit out of date...but I found a fix, since I just ran into this problem).
The short answer, in your Project Properties->Configuration Properties->CUDA RuntimeAPI->Host
set the "Target Machine Platform" to x64. (mine was at x86 despite having the platform at x64).
Make sure that any libraries you are using have also been compiled on 64 bit.

Why is DumpBin telling me there are no COMDATs in my binaries?

This is the output I get from dumpbin AchievementsTable.obj /HEADERS
Microsoft (R) COFF/PE Dumper Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file AchievementsTable.obj
File Type: ANONYMOUS OBJECT
ANON OBJECT HEADER VALUES
1 version
14C machine (x86)
4C51334D time date stamp Thu Jul 29 08:52:45 2010
ClassID: {0CB3FE38-D9A5-4DAB-AC9B-D6B6222653C2}
945F size
0 flags
ALL my source does this. I am using VisualStudio 2005. I know for a fact that there are lots of COMDATs being exported, as the .exe subsequently links and executes correctly: are there compiler switches I should be avoiding? Here are the ones I am using:
/O1
/Ob2
/Oi
/GT
/GL
/I "..\dxsdk\include" <lots of include paths>
/D "WIN32" <lots of #defines>
/GF
/FD
/MT
/GS-
/Gy
/arch:SSE2
/fp:fast
/GR-
/Fo <directory specified>
/Fd <pdb filename specified>
/FR <directory specified>
/W4
/c
/Zi
/TP .\Source\databases\AchievementsTable.cpp
I'm open to commentary on my selection in general, but DumpBin use is the focus of this question: take it away, boys and girls...
After a day of elimination, I discovered that the DUMPBIN documentation is a little ambiguous.
Switching on function level linking (/Gy) is needed to get the COMDAT output. Switching on cross module optimisations (/GL) delays code generation to link time. Therefore, although it is true that header information is available to code compiled with /GL, it is very limited. That's why it's the only option available to DUMPBIN - all the other options require more information, the generation of which is delayed by /GL.

Resources