Microsoft Visual C++ с /MDd создает испорченный исполняемый файл внутри контейнера Windows

Я строю код C++ в контейнере Windows, используя Microsoft Visual C++ Build Tools 2015

msbuild /p:Configuration=Debug по сути работает cl.exe с /MDd Опция и производит непригодный исполняемый файл - см. ниже

/p:Configuration=Release использования /MD и делает прекрасно исполняемый файл.

Образец кода hello-world.cxx:

#include <iostream>
int main()
{
  std::cout << "Hello World!";
}

Компилирование с /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

Компилирование с /MD:

> cl.exe /EHsc /MD hello-world.cxx
...
> hello-world.exe
Hello World!
> echo %ERRORLEVEL%
0

Вот соответствующая часть моего 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

Как видите, я устанавливаю Visual C++ Build Tools 2015 через пакет choco.

Я прочитал документацию: https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library

Так /MDd определяет _DEBUG а также места MSVCRTD.lib в файл.obj, а не MSVCRT.lib

На моем ноутбуке у меня установлена ​​полноценная Visual Studio, и она прекрасно работает.

Я сравнил MSVCRTD.lib под которым я установил C:\Program Files (x86)\Microsoft Visual Studio 14.0 и в обеих системах файлы одинаковы.

Смущенный...

1 ответ

Решение

РЕШИТЬ

Контейнер не имеет графического интерфейса, и скомпилированный.exe пытается показать диалог графического интерфейса с сообщением:

"Программа не может запуститься, потому что ucrt based.dll отсутствует на вашем компьютере. Попробуйте переустановить программу, чтобы решить эту проблему."

(обнаружил это при запуске встроенного.exe в аналогичной среде, но с графическим интерфейсом)

Интересно, что C++ Build Tools 2015 установил эти dll-ы под:

  • C: \ Program Files (x86) \ Windows Kits \ 10 \ bin \ x64 \ ucrt \
  • C: \ Program Files (x86) \ Windows Kits \ 10 \ bin \ x86 \ ucrt \

Однако при запуске.exe он не может их найти.

При полной установке VS я обнаружил, что эти файлы также скопированы в

  • C: \ Windows \ System32 \
  • C: \ Windows \ SysWOW64 \

Переустановка C++ Build Tools помогла, однако она медленная и странная. Поэтому я просто скопировал эти файлы вручную.

Добавлено в 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\
Другие вопросы по тегам