无法生成完整的静态链接应用程序

Posted

技术标签:

【中文标题】无法生成完整的静态链接应用程序【英文标题】:Can't generate a full statically linked application 【发布时间】:2017-07-26 05:49:57 【问题描述】:

我已经连续 15 个多小时尝试找到一种方法来静态编译我的 Native C++ 游戏,使其不需要某些 DLL(我认为这与 CRT 相关)。

下载我的游戏的用户抱怨缺少几个 DLL,例如:

VCRUNTIME140.dll
api-ms-win-core-timezone-l1-1-0.dll
api-ms-win-core-timezone-l2-1-0.dll
api-ms-win-core-processthreads-l1-1-1.dll
(and the list goes on)

我当前的构建命令行是:

/MP /GS /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl
/Fd"Release\vc140.pdb" /Zc:inline /fp:precise /D "WIN32"
/D "_CRT_SECURE_NO_WARNINGS" /D "_WIN32_WINNT=0x0501" /D "BOT_PROTECTION"
/D "CLIENT" /D "FW_GRAPHICS" /D "FW_NET" /D "FW_XML"
/D "NDEBUG" /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MT
/Fa"Release\" /EHsc /nologo
/Fo"Release\\Win32\src\%(RelativeDir)\" /Fp"Release\otclient.pch" 

有什么想法吗?

【问题讨论】:

除了偏好之外,还有什么理由避免使用 DLL? 这是偏好。但是,如果我可以将它减少到大约 2 或 3 个 DLL 文件,我不会介意。我真的不希望用户(对调查不感兴趣,只想点击播放)解压缩一个充满DLL文件的文件夹,而不得不四处寻找EXE。 这并不总是可能的,至少不使用您的链接器。动态库并不打算硬链接到您的程序中。这是some explanation。您可以做的是将它们烘焙到您的.exe 文件中,然后在运行时进行一些黑客操作以从中提取它们。如今,将其作为单数 .exe 提供也非常粗略。为人们提供一个安装程序,将内容放在正确的位置,创建开始菜单项,并注册它以进行卸载。 我只能同意@tadman。安装程序是干净的方式。 【参考方案1】:

/MT 确实告诉编译器将 CRT 链接到您的可执行文件中。但是,如果 另一个 DLL 仍然依赖于 VCRUNTIME140.DLL,这还不够。 DLL 可以依赖于其他 DLL,甚至是循环的。 Windows 只是按照遇到的顺序加载它们,除非已经加载。因此,如果 TEST.EXE 依赖于 A.DLL,Windows 会加载 A.DLL。如果 A.DLL 依赖于 B.DLL,Windows 会加载 B.DLL。如果 B.DLL 依赖于 A.DLL,那么它已经被加载了。

接下来,api-ms-... 是新的 Windows DLL。他们实现了旧的Kernel32.DLL 和类似的 DLL。它们不会导致对 VCRUNTIME140.DLL 的依赖。目前还不清楚你最终会如何依赖这些。

还有你没有列出的其他 DLL。其中之一一定是导致您看到的问题。

【讨论】:

我真的不喜欢向我的用户解释为什么他们必须保留一组巨大的“api-ms”DLL,以便他们可以运行一个简单的图形应用程序。我“解决了”我用 GCC Mingw 编译代码的问题。到目前为止没有“缺少 DLL”的投诉。

以上是关于无法生成完整的静态链接应用程序的主要内容,如果未能解决你的问题,请参考以下文章

cmake设置默认静态链接库

C++中lib 和 dll 的区别,生成以及使用详解

鸿蒙内核源码分析(静态链接篇) | 完整小项目看透静态链接过程 | 百篇博客分析HarmonyOS源码 | v54.01

Linux动态链接和静态链接简析

gcc编译工具生成动态库和静态库之一----介绍

如何使用cmake生成基于静态库的动态链接库