visual-studiomsvcrtwindows-containerwindows-server-container

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...


Solution

  • 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\