减少 Windows 可执行文件的大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/437685/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reduce windows executable size
提问by Martin Beckett
I have a C++/MFC app on windows - dynamically linked it's only 60kb static it's > 3Mb.
It is a being distributed to customers by email and so needs to be as small as possible.
我在 Windows 上有一个 C++/MFC 应用程序 - 动态链接它只有 60kb 静态它 > 3Mb。
它是通过电子邮件分发给客户的,因此需要尽可能小。
It statically links the MFC and MSCVRT libraries - because it is a fix to some problems and I don't want more support calls about missing libs - especially the very helpful 'application configuration is incorrect' one!
它静态链接 MFC 和 MSCVRT 库 - 因为它是对一些问题的修复,而且我不希望更多关于缺少库的支持调用 - 特别是非常有用的“应用程序配置不正确”!
Is there anyway to strip a Windows exe of all the extra MFC stuff that is the dll but that I'm not using?
Or tell it to dynamically link MSVCRT (which must be present) but statically link the MFC dll which might not be?
无论如何,是否可以从 Windows exe 中删除所有额外的 MFC 内容,即 dll 但我没有使用?
或者告诉它动态链接 MSVCRT(必须存在)但静态链接可能不是的 MFC dll?
Edit - thanks that got it down to 1.6Mb that will have to do!
编辑 - 感谢将其降低到 1.6Mb,这将不得不做!
回答by Stobor
回答by Joe
You can't mix the CRT/MFC dlls. Going from memory...
您不能混合使用 CRT/MFC dll。从记忆中走...
As the other answer suggested, you can #define WIN32_LEAN_AND_MEAN and VC_EXTRALEAN. These probably won't help though. They tend to be about minimizing build time - not the final exe size.
正如另一个答案所建议的那样,您可以#define WIN32_LEAN_AND_MEAN 和 VC_EXTRALEAN。不过,这些可能无济于事。它们往往是关于最小化构建时间 - 而不是最终的 exe 大小。
Short of rebuilding MFC (Which is an option - you could rebuild it /Os, or if you are feeling really cheeky, /GL - but this will probably lead to more downstream fun - hopefully it's already built /Gy).
缺少重建 MFC(这是一个选项 - 你可以重建它 /Os,或者如果你觉得很厚脸皮,/GL - 但这可能会带来更多下游乐趣 - 希望它已经构建 /Gy)。
OK. Simple things to try. Build your app with /GL /Os /GF /Gy /GA. In the linker you more or less want /OPT:REF and /OPT:ICF and /LTCG.
好的。简单的事情可以尝试。使用 /GL /Os /GF /Gy /GA 构建您的应用程序。在链接器中,您或多或少需要 /OPT:REF 和 /OPT:ICF 和 /LTCG。
I have to say - a release build from 30k to megabytes is a bit much. You could also pass /map: to the linker and see what's taking all that space - but that's very very tedius.
我不得不说 - 从 30k 到兆字节的发布版本有点多。您还可以将 /map: 传递给链接器,看看是什么占用了所有空间 - 但这非常非常乏味。
It almost sounds like MFC wasn't built with /Gy - but that would be surprising.
听起来 MFC 几乎不是用 /Gy 构建的 - 但这会令人惊讶。
回答by pmttavara
For programs using the CRT, you can use the technique in this video by Per Vognsenon achieving 3.5KB executables. Windows\System32\msvcrt.dll
ships with every Windows since 95, so by linking to that, you needn't package the Visual C++ Redistributable with your app.
对于使用 CRT 的程序,您可以使用Per Vognsen 视频中的技术实现 3.5KB 可执行文件。Windows\System32\msvcrt.dll
自 95 年以来的每个 Windows 都附带,因此通过链接到它,您无需将 Visual C++ Redistributable 与您的应用程序打包在一起。
The basic process is:
基本流程是:
- Run Visual Studio's
dumpbin
onSystem32\msvcrt.dll
and pipe it to a file - Run a simple filter (
awk '{print $4}'
) to create amsvcrt.def
file - Run VS's
lib
onmsvcrt.def
to generatemsvcrt.lib
- Disable default libraries in your project (
/NODEFAULTLIB
on thelink
command line) - Disable some Visual C++ checks (
/GS-
and remove any/RTC<x>
flags)
- 运行Visual Studio的
dumpbin
上System32\msvcrt.dll
和管道到一个文件 - 运行一个简单的过滤器 (
awk '{print $4}'
) 来创建一个msvcrt.def
文件 - 运行VS是
lib
在msvcrt.def
生成msvcrt.lib
- 禁用项目中的默认库(
/NODEFAULTLIB
在link
命令行上) - 禁用一些 Visual C++ 检查(
/GS-
并删除任何/RTC<x>
标志)
Link against kernel32.lib
and msvcrt.lib
and voilà, your tiny executable has zero dependencies besides the OS.
链接kernel32.lib
和msvcrt.lib
和瞧,您的小可执行文件除了操作系统之外还具有零依赖项。
(n.b.: To optimize for size (/O1
), specify memset
as an intrinsic as detailed here.)
(注意:要针对大小 ( /O1
)进行优化,请memset
按照此处的详细说明指定为内在函数。)
回答by Lawand
You can try Dependency Walkerto check which DLLs that your static EXE file depends on, then if it depends on a library you are certain it exists at your client's machine, you can compile without it and reduce the size.
您可以尝试使用Dependency Walker来检查您的静态 EXE 文件依赖于哪些 DLL,然后如果它依赖于一个库,您确定它存在于您的客户端机器上,您可以在没有它的情况下进行编译并减小大小。