让我们说我使用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 ++运行时。如果不是,为什么?
答案 0 :(得分:5)
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也应该足够了 (或使用静态链接并仅提供程序文件)。
答案 1 :(得分:2)
对于您不确定需要包含哪些DLL文件来分发应用程序的复杂项目,我制作了一个方便的花花公子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文件作为自动部署系统的一部分复制到构建目录中。
答案 2 :(得分:1)
分发编译软件有几个主要挑战:
编译所有目标处理器的代码(请记住,当涉及到编译代码时,您需要为每种类型的指令集架构生成单独的下载/分发。)
确保构建具有可重现性,一致性,并且可以轻松地与特定版本的代码(以及依赖项版本)相关联。
确保构建输出是自包含的,并包含其中的所有依赖项(以便它不依赖于恰好存在于您的系统上的任何其他安装)。
确保您的代码定期构建和分发,并自动分发更新,以便在出现安全问题时,您可以推出新的修补版本。
为了方便和扩大覆盖面,非精明用户可以拥有可以安装的预建版本。但是,我建议首先共享源代码。
这些要求中的大多数都是非常重要的,并且通常不仅需要自动化构建过程,还需要自动执行构建应该进行的VM的实例化/配置。但是,有一些开源项目可以帮助...例如,查看Gitian。
就要点#3而言,这里的关键是使用静态链接...虽然这确实使你分发的二进制文件大得多(因为它的依赖关系现在被烘焙到输出中),它也会使你的二进制文件与系统上的库版本隔离(避免“依赖地狱”)。
第4点非常棘手,但幸运的是还有开源工具可以提供帮助,例如cloudup,它提供了一种向应用程序分发添加自动更新功能的方法。
答案 3 :(得分:1)
我使用ntldd获取依赖项列表。 https://github.com/LRN/ntldd 我正在使用msys2,所以我只在pacman中安装了它。使用它,然后复制所有需要的依赖项
答案 4 :(得分:0)
您可能希望添加选项-static-libgcc
和-static-libstdc++
以静态链接C和C ++标准库,从而无需随身携带这些库的任何单独副本。