分发用MinGW g++编译的程序

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

假设我使用 MinGW 64(g++ 编译器)创建并编译了一个简单的程序。在我的计算机上运行此程序并在 Process Explorer 中查找该程序正在使用的 DLL 文件(以及许多其他文件):

libgcc_s_seh-1.dll
libstdc++6.dll
libwinpthread-1.dll

这些是唯一驻留在我的 MinGW 安装文件夹下的文件。使用的其余 DLL 文件位于

C:\Windows
下。

问题1:

MinGW DLL 文件是 MinGW C++ 运行时库(可以这么说)吗?它们的用途是否与 msvcrXXX.dll(XXX = Microsoft 运行时库的版本)相同。

问题2:

如果我想在另一台未安装 MinGW 的计算机上运行该应用程序,是否足以包含上面列出的那些 DLL 文件(即将它们放在与我的可执行文件相同的文件夹中)以使其在另一台计算机上运行(我们假设另一台计算机也是 64 位 Windows 计算机)。如果是,这是否意味着我们基本上随可执行文件一起提供 MinGW C++ 运行时。如果不是,为什么?

c++ dll g++ mingw-w64
5个回答
9
投票

libstdc++6.dll是C++标准库,就像你说的。

libwinpthread-1.dll 用于 C++11 线程支持。 MinGW-W64 有两种可能的线程变体:要么使用像 CreateThread 这样的原生 Windows 函数,但是像 std::thread 这样的 C++11 东西将不可用;或者包含此库并使用 C++11 类(也)。
请注意,要切换线程模型,您需要重新安装 MinGW。仅删除 DLL 而不使用 C++11 内容是行不通的,尽管如此,您当前的安装仍然需要 DLL。

libgcc_s_seh-1.dll是关于C++异常处理的东西。

是的,交付 DLL 也应该足够了
(或使用静态链接并仅提供您的程序文件)。


5
投票

对于复杂的项目,您不确定需要包含哪些 DLL 文件来分发应用程序,我制作了一个方便的 dandy Bash 脚本(适用于 MSYS2 shell),它可以准确地告诉您需要包含哪些 DLL 文件。它依赖于 Dependency Walker 二进制文件。

#!/usr/bin/sh

depends_bin="depends.exe"
target="./build/main.exe" # Or wherever your binary is
temp_file=$(mktemp)
output="dll_list.txt"

MSYS2_ARG_CONV_EXCL="*" `cygpath -w $depends_bin` /c /oc:`cygpath -w $temp_file` `cygpath -w $target`
cat $temp_file | cut -d , -f 2 | grep mingw32 > $output

rm $temp_file

请注意,需要稍微修改此脚本才能在常规 MSYS 中使用(特别是 MSYS2_ARG_CONV_EXCL 和 cygpath 指令)。该脚本还假设您的 MinGW DLL 文件位于包含 MinGW 的路径中。

您甚至可以使用此脚本将相关 DLL 文件自动复制到您的构建目录中,作为自动部署系统的一部分。


4
投票

您可能希望添加选项

-static-libgcc
-static-libstdc++
来静态链接 C 和 C++ 标准库,从而无需携带这些库的任何单独副本。


2
投票

我使用 ntldd 来获取依赖项列表。 https://github.com/LRN/ntldd 我使用的是 msys2,所以我只是用 pacman 安装它。使用它,然后复制所有需要的依赖项


1
投票

分发编译软件有几个主要挑战:

  1. 编译所有目标处理器的代码(请记住,当涉及编译代码时,您需要为每种类型的指令集架构生成单独的下载/分发)。

  2. 确保构建是可重复的、一致的,并且可以轻松地与特定版本的代码(以及依赖项的版本)相关联。

  3. 确保构建输出是独立的,并包含其所有依赖项(以便它不依赖于您系统上恰好存在的任何其他安装)。

  4. 确保定期构建和分发您的代码,并自动分发更新,以便在出现安全问题时,您可以推出新的修补版本。

为了方便和扩大覆盖范围,对于不懂的用户来说,拥有可以安装的预构建版本是件好事。但是,我建议首先共享源代码。

这些要求中的大多数都相当重要,并且通常不仅需要自动化构建过程,还需要自动化应在其中进行构建的虚拟机的实例化/配置。但是,有一些开源项目可以提供帮助......例如,查看 Gitian

就要点#3而言,这里的关键是使用静态链接...虽然这确实会使您分发的二进制文件变得更大(因为它的依赖项现在已烘焙到输出中),但它也使您的二进制文件与系统上库的版本(避免“依赖地狱”)。

第 4 点非常棘手,但值得庆幸的是,这里还有开源工具可以提供帮助,例如 cloudup,它提供了一种向应用程序分发添加自动更新功能的方法。

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