我最近开始使用Msys2安装gcc编译器来为Windows制作一些exe。它工作得很好,但是将我的 exe 传递给我的兄弟时出现了问题。他的笔记本电脑没有安装 msys2,当他尝试运行我的 exe 时,会发生一些错误。似乎使用我的 exe 需要几个 dll 文件(如 msys-2.0.dll)。
我发现 msys2 使用这些文件来“伪造”机器上的操作系统,假装它是 POSIX 操作系统。有没有办法用 msys2 为 Windows 编译独立的 exe?我希望我的兄弟能够在不安装 msys 或其他程序的情况下使用我的 exe。
以下是所有详细信息,以便更好地了解我的情况:
g++ HelloWord.cpp -o Helloword
是我用来编译的行C:\msys64\mingw64\bin
这是g++存储的路径已修复: 我仅使用 g++ 参数
-static
解决了该问题。是不是太过分了?
我的MinGW版本有点旧...
C:\example>where g++
C:\misc\mingw810_64\bin\g++.exe
C:\example>g++ --version
g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
但同样的想法:
C:\example>cat > compile_me.cpp
#include <iostream>
int main () { std::cout << "hi" << std::endl; }
^Z
C:\example>g++ compile_me.cpp -o compiled.exe
C:\example>compiled.exe
hi
C:\example>dumpbin /dependents compiled.exe
...
Image has the following dependencies:
KERNEL32.dll
msvcrt.dll
libstdc++-6.dll
...
在这种情况下(动态链接的 stdlib),您可以使用可执行文件部署 libstdc++6.dll,将其安装到与 exe 相同的路径(另外两个通常存在于 Windows 系统路径中)。
如果您想删除该依赖项,请使用
-static
:
C:\example>g++ compile_me.cpp -o compiled.exe -static
C:\example>compiled.exe
hi
C:\example>dumpbin /dependents compiled.exe
...
Image has the following dependencies:
KERNEL32.dll
msvcrt.dll
...
单独部署 .exe 应该没问题。
文件大小会更大,但现在这不是什么大问题。另外,您的 MinGW / MSYS 安装可能会附带条带:
C:\example>dir compiled.exe
Volume in drive C is Windows
Volume Serial Number is D2BA-C6F0
Directory of C:\example
09/24/2022 06:49 PM 2,389,120 compiled.exe
1 File(s) 2,389,120 bytes
0 Dir(s) 135,945,314,304 bytes free
C:\example>strip compiled.exe
C:\example>dir compiled.exe
Volume in drive C is Windows
Volume Serial Number is D2BA-C6F0
Directory of C:\example
09/24/2022 07:03 PM 838,656 compiled.exe
1 File(s) 838,656 bytes
0 Dir(s) 135,944,765,440 bytes free
C:\example>compiled.exe
hi
如果您的特定可执行文件最终依赖于其他动态库,并且供应商选择不提供静态链接的替代方案,那么您必须使用 exe 来部署它们。通常很容易将所有内容放入 zip 文件中或使用您最喜欢的可编写脚本的安装程序。
(注意:dumpbin 随 Visual Studio 一起提供;并且可以在 vs 安装路径中 VC\Tools 中的某些适当的子目录中找到)。
OP 已经解决了他们的问题,但对于发现此问题的其他人来说:
mingw64.exe
或等效快捷方式启动 MSYS2。which g++
以确保您正在使用 /mingw64/bin/g++
。 如果显示其他 g++
,则运行 pacman -S mingw-w64-x86_64-toolchain
安装工具链。g++
编译代码并使用 -static
选项。ntldd yourprogram.exe
检查您的程序正在使用哪些 DLL,并确保它们是 Windows 的一部分,而不是 MSYS2 的一部分。编辑:如今,使用 MSYS2 的 UCRT64 环境而不是 MINGW64 可能更有意义。 不过我还没试过。 如果您想支持真正旧的 32 位 Windows 机器,请使用 MINGW32。
MSYS2 编译本机 PE32 可执行文件。它不依赖于任何神奇的 msys 环境或静态链接。
为自己准备一个依赖项遍历器,看看您的应用程序需要运行哪些 DLL。任何不在 Windows 子目录中的内容都应该是您重点关注的地方。另请确保您的应用程序不需要任何特殊的 Microsoft 可再发行依赖项。
最终,您应该为应用程序创建一个安装程序来处理依赖项。我个人喜欢 Inno 设置,但还有很多其他设置也很受欢迎。