我有一个使用一些 SDL2 库编写的小型 C++17 程序。我使用 Cmake、ninja、MSYS2 和 MinGW 创建了该项目。当通过 MSYS/mingw 终端启动时,我生成的 exe 按预期执行。但是,在该终端之外启动程序会导致缺少 DLL 错误(例如 libwinpthread-1.dll)。正如我需要包含 SDL2 的 DLL 一样,如果我想将其分发到未安装 MinGW 或未添加到路径中的系统,是否还需要包含一些 MinGW DLL ?
我正在使用 MSYS2/MinGW 终端来“模仿”带有包管理器的 Linux 终端。我运行 CMake 来查找所需的包并创建构建脚本。然后我使用 Ninja 构建项目,该项目在某个时候调用 MinGW 的 g++ 端口来编译必要的文件。这是正确的吗?
首先,使用
ntldd
安装 pacman -S ...-ntldd
(例如,pacman -S mingw-w64-x86_64-ntldd
用于 MINGW64 环境)。
运行
ntldd -R my_program.exe
(相当于 Linux 上的 ldd my_program
)。
它将输出 DLL 列表。在这些 DLL 中:
bin
目录中的所有 DLL。C:\Windows
中的 DLL 以及 PATH 中的目录中的 DLL。检查第三个类别中忽略的每个 DLL 也是一个好主意,确保它不存在于不同的路径下(前两个类别之一)。如果存在重叠,您需要重新运行
ntldd
,并从 PATH 中删除有问题的目录。
如果您在 MSYS2 shell 中运行,这通常不是问题,因为它会清除 PATH,除非您以某种方式将自定义 DLL 安装到
C:\Windows\**
。
第一站始终是 dependency walker 来了解运行时需要哪些 dll,任何不在
C:\Windows
中的 dll 都需要与可执行文件一起放在同一文件夹中。
您可以使用 mingw 的
-static
选项来静态链接这些依赖项并生成不需要 mingw 的任何 dll 的二进制文件,您只需要链接额外的 dll,但生成的 dll/可执行文件将具有明显更大的大小.
如果你不静态链接 mingw 库,那么最基本的依赖项是 c++ 的
libgcc
和 libstdc++
,但是如果你使用线程,你将需要 libwinpthread
,如果你使用 openmp,你需要 libgomp
和列表继续,所以当你不确定时最好使用依赖遍历器。