我已经通过MSYS和MinGW在Windows上安装了GTK+(特别是GTK3)。现在我想将GTK+的dll文件复制到我的应用程序目录,以便在没有全局GTK+安装的计算机上运行它。哪些dll文件是GTK+操作所必需的?
编辑: GTK+文档现在包含在Windows上分发所需的图标和主题的说明。(虽然它没有为分发相关的DLL文件提供说明——请参见下面的答案。)
原来运行ldd mygtkapp.exe
(使用MinGW提供的ldd
)可以列出所有需要运行它的dll。为了仅获取GTK依赖项(而不是例如Win32 dll),我使用了以下命令:ldd mygtkapp.exe | sed -n 's/\([^ ]*\) => \/mingw.*/\1/p' | sort
。我的程序使用了Haskell绑定,所以依赖关系可能会有所不同,但这就是我得到的:
libatk-1.0-0.dll
libbz2-1.dll
libcairo-2.dll
libcairo-gobject-2.dll
libepoxy-0.dll
libexpat-1.dll
libffi-6.dll
libfontconfig-1.dll
libfreetype-6.dll
libgcc_s_seh-1.dll
libgdk_pixbuf-2.0-0.dll
libgdk-3-0.dll
libgio-2.0-0.dll
libglib-2.0-0.dll
libgmodule-2.0-0.dll
libgobject-2.0-0.dll
libgraphite2.dll
libgthread-2.0-0.dll
libgtk-3-0.dll
libharfbuzz-0.dll
libiconv-2.dll
libintl-8.dll
libpango-1.0-0.dll
libpangocairo-1.0-0.dll
libpangoft2-1.0-0.dll
libpangowin32-1.0-0.dll
libpcre-1.dll
libpixman-1-0.dll
libpixman-1-0.dll
libpng16-16.dll
libstdc++-6.dll
libwinpthread-1.dll
zlib1.dll
需要注意的是,如果您使用默认图标,还有其他几件事情需要做才能创建完全独立的应用程序;更多详细信息,请参见https://dev59.com/918d5IYBdhLWcg3wgya4#34673860。不过要注意,我需要复制16x16目录而不是可缩放目录。
编辑:我发现以下命令也非常有用:ldd mygtkapp.exe | grep '\/mingw.*\.dll' -o | xargs -I{} cp "{}" .
。这个命令会将dll文件复制到当前目录,避免了手工操作的繁琐过程。
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffb1c5f0000) ntdll.dll => /c/Windows/SysWOW64/ntdll.dll (0x77b50000) wow64.dll => /c/WINDOWS/System32/wow64.dll (0x7ffb1a820000) wow64win.dll => /c/WINDOWS/System32/wow64win.dll (0x7ffb1c270000)
- JackLoadLibrary()
函数,所以ldd
工具没有将它们列出来,于是我进入该包装器的源代码,并成功地找到了该包装器正在使用LoadLibrary()
加载的dll字符串列表,将它们放在与目标可执行文件相同的文件夹中,它就能够完美地工作了。 - Jack您可以在GTK网站的Windows页面上找到一些提示,这是名为“构建和分发您的应用程序”的部分。其中包含有关在Windows上分发GTK应用程序的博客文章。
那里提出的解决方案是为您的应用程序创建一个MSYS2软件包,然后将其及其所有依赖项(其中包括GTK)安装在特定的目录中,以便您可以重新分发整个软件包。
2020-12-09编辑:
阅读其他答案后,我想补充说明,此方法不仅可以获取共享对象和二进制文件的依赖项,还可以处理其他类型的资源(图像、帮助文件等),这些资源在所需软件包中,以及在运行时使用基于dlopen
的函数加载的共享对象。这是您无法通过只调用ldd
查找依赖项来实现的。
ldd kangaroo.exe | grep '\/mingw64\/bin\/.*dll' -o | xargs -I{} cp "{}" .
grep -o
,而我使用了 sed
。 - bradrn
ntldd
和试错的结合方式。你可以通过将路径设置为空,然后运行你的应用程序来测试它。但是现在我在自己的构建系统中使用静态编译,因此不需要DLL文件。 - David Grayson