我如何知道需要包含哪些 DLL 才能使用 cmake 和 mingw 在 Windows 上正确构建项目?

问题描述 投票:0回答:2

我有一个使用一些 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++ 端口来编译必要的文件。这是正确的吗?

c++ windows mingw sdl-2 msys2
2个回答
1
投票

首先,使用

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。
  • 复制您有意手动链接的任何库的 DLL。
  • 忽略其余部分,例如
    C:\Windows
    中的 DLL 以及 PATH 中的目录中的 DLL。

检查第三个类别中忽略的每个 DLL 也是一个好主意,确保它不存在于不同的路径下(前两个类别之一)。如果存在重叠,您需要重新运行

ntldd
,并从 PATH 中删除有问题的目录。

如果您在 MSYS2 shell 中运行,这通常不是问题,因为它会清除 PATH,除非您以某种方式将自定义 DLL 安装到

C:\Windows\**


1
投票

第一站始终是 dependency walker 来了解运行时需要哪些 dll,任何不在

C:\Windows
中的 dll 都需要与可执行文件一起放在同一文件夹中。

您可以使用 mingw 的

-static
选项来静态链接这些依赖项并生成不需要 mingw 的任何 dll 的二进制文件,您只需要链接额外的 dll,但生成的 dll/可执行文件将具有明显更大的大小.

如果你不静态链接 mingw 库,那么最基本的依赖项是 c++ 的

libgcc
libstdc++
,但是如果你使用线程,你将需要
libwinpthread
,如果你使用 openmp,你需要
libgomp
和列表继续,所以当你不确定时最好使用依赖遍历器。

© www.soinside.com 2019 - 2024. All rights reserved.