带有 /MDd 的 Microsoft Visual C++ 在 Windows 容器内生成损坏的可执行文件
Microsoft Visual C++ with /MDd produces broken executable inside Windows container
我使用 Microsoft Visual C++ Build Tools 2015
在 Windows 容器 中构建 C++ 代码
msbuild /p:Configuration=Debug
本质上是使用 /MDd
选项运行 cl.exe
并生成无法使用的可执行文件 - 见下文。
/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.0\bin"
# Test msbuild can be accessed without path
RUN msbuild -version
如您所见,我通过 choco 包安装了 Visual C++ Build Tools 2015。
我已阅读文档: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,并且构建良好。
我比较了我在 C:\Program Files (x86)\Microsoft Visual Studio 14.0
下安装的 MSVCRTD.lib
,两个系统上的文件是相同的。
困惑...
已解决
容器没有 GUI,编译后的 .exe 试图显示带有消息的 GUI 对话框:
"The program can't start because ucrtbased.dll is missing from your
computer. Try reinstalling the program to fix this problem."
(当 运行 在类似的环境中使用 GUI 构建 .exe 时发现了这个)
有趣的是,C++ Build Tools 2015 在以下位置安装了这些 dll-s:
- C:\Program Files (x86)\Windows Kits\bin\x64\ucrt\
- C:\Program Files (x86)\Windows Kits\bin\x86\ucrt\
但是当 .exe 运行时找不到它们。
在完整的 VS 安装中,我发现这些文件也被复制到
- C:\Windows\System32\
- C:\Windows\SysWOW64\
重新安装 C++ Build Tools 有所帮助,但它很慢而且感觉很奇怪。
所以我最终只是手动复制了这些文件。
已添加到 Dockerfile:
RUN copy "C:\Program Files (x86)\Windows Kits\bin\x64\ucrt\ucrtbased.dll" C:\Windows\System32\
RUN copy "C:\Program Files (x86)\Windows Kits\bin\x86\ucrt\ucrtbased.dll" C:\Windows\SysWOW64\
我使用 Microsoft Visual C++ Build Tools 2015
在 Windows 容器 中构建 C++ 代码msbuild /p:Configuration=Debug
本质上是使用 /MDd
选项运行 cl.exe
并生成无法使用的可执行文件 - 见下文。
/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.0\bin"
# Test msbuild can be accessed without path
RUN msbuild -version
如您所见,我通过 choco 包安装了 Visual C++ Build Tools 2015。
我已阅读文档: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,并且构建良好。
我比较了我在 C:\Program Files (x86)\Microsoft Visual Studio 14.0
下安装的 MSVCRTD.lib
,两个系统上的文件是相同的。
困惑...
已解决
容器没有 GUI,编译后的 .exe 试图显示带有消息的 GUI 对话框:
"The program can't start because ucrtbased.dll is missing from your computer. Try reinstalling the program to fix this problem."
(当 运行 在类似的环境中使用 GUI 构建 .exe 时发现了这个)
有趣的是,C++ Build Tools 2015 在以下位置安装了这些 dll-s:
- C:\Program Files (x86)\Windows Kits\bin\x64\ucrt\
- C:\Program Files (x86)\Windows Kits\bin\x86\ucrt\
但是当 .exe 运行时找不到它们。
在完整的 VS 安装中,我发现这些文件也被复制到
- C:\Windows\System32\
- C:\Windows\SysWOW64\
重新安装 C++ Build Tools 有所帮助,但它很慢而且感觉很奇怪。 所以我最终只是手动复制了这些文件。
已添加到 Dockerfile:
RUN copy "C:\Program Files (x86)\Windows Kits\bin\x64\ucrt\ucrtbased.dll" C:\Windows\System32\
RUN copy "C:\Program Files (x86)\Windows Kits\bin\x86\ucrt\ucrtbased.dll" C:\Windows\SysWOW64\