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:
However when .exe runs it can't find them.
On full VS installation I found these files also copied under
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\