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\