我通常用C语言编写大小编码演示竞赛(64kb),但考虑转向C ++。
在 MinGW g ++下,我对.exe-size有些麻烦。 (在使用可执行程序包装程序之前,我必须将其降低到<100 kb。)。
我看过这个:
How to reduce the size of executable produced by MinGW g++ compiler?
但是我已经使用MinGW / g ++ 4.8.1和-s -Os ...见下文(也适用于4.8.1:unrecognized option '-shared-libstdc++'
和cannot find -lstdc++_s
)。< / p>
这个小小的helloworld只有 10 kb(没关系):
#include "windows.h"
int main() {
MessageBoxA(0, "test", "test", 0);
return 0;
}
然而,当我添加:
#include <string>
...
std::string asdf;
它变为 193 kb
当我添加:
#include <iostream>
然后它变为 756 kb。
我正在使用这些标志:
-std=c++11
-Wall
-s (or -Wl,-s)
-Os
-DNDEBUG
-fno-exceptions
-fno-rtti
(note: removed those with no effect)
必须有某种方式来链接我使用的东西。我错过了什么?
可选1:是否可以在MinGW / g ++ 4.8.1中使用-shared-libstdc ++或-lstdc ++ _?
可选2:当我尝试-nostdlib
并将main
替换为WinMain
时:
#include "windows.h"
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
MessageBoxA(0, "test", "test", 0);
return 0;
}
我没有编译器警告但是运行时崩溃,它在编译为C时工作正常。 (可选,因为我不希望你/我花时间调试crt-startup,编译器 - 链接器标志来修剪库会更有帮助)
答案 0 :(得分:4)
这些额外的字节被标准库调用“拉入” - 高级别的字节往往会带来它们下面的所有内容,内存分配,它们使用的异常等等。最简单的方法是尽量减少使用的内容。在putchar()上建立一个hello世界可能会给你一个很好的比较点。我将专注于静态链接的程序,因为我知道,rubenvb的答案似乎也很好地涵盖了共享库。
新功能,删除功能,纯虚函数功能等功能也可以提取库中的位以及下面的许多依赖项。这里有一个关于如何替换它们的快速概述:http://ptspts.blogspot.com.au/2010/12/how-to-write-c-program-without-libstdc.html - 如果你真的很极端,你可以找到一个以相同方式处理的malloc版本。
最近使用C ++ 11,如果你这样做,你会遇到__cxa_guard_acquire和__cxa_guard_release:
int foo() {
static int bar = 1; //thread safe in C++11, requires inbuilt functions
}
为此,如果编译器支持,请使用-fno-threadsafe-statics标志。
如果这对你的影响不够大,你可以在linux版本的ld上链接标志-Map = filename.map来生成“map”文件。输出文件的第一部分列出了所引入的每个部分以及需要它的部分。*
*地图文件还会显示函数部分对标准库没有任何作用,因为它已经在没有该标志的情况下编译,除此之外
答案 1 :(得分:2)
你无法摆脱MinGW GCC编译的可执行文件需要运行的额外代码。您可以尝试使用MinGW-w64工具链,它以不同的方式接近CRT,但就“Hello world”大小而言,它可能比普通MinGW更差。
如果二进制大小非常重要,我强烈建议使用MSVC,因为它依赖于自己内置于操作系统的CRT代码。我可以用某种方式小心地称之为“作弊”: - )。
关于DLL libstdc ++,当然有可能,你只需要一个像样的工具链;-)。见here。请注意,这也是“作弊”,因为我怀疑比赛会忽略运行时库的大小。这就是代码化比赛是愚蠢的原因。总是有一个你忽略的运行时层。直到你击中裸机内核或组装,这不是所述比赛的重点。
答案 2 :(得分:1)
我尝试在QT 5.1.0 MinGW 4.8 32位
下运行您的代码#include "windows.h"
#include <string>
#include <iostream>
int main() {
MessageBoxA(0, "test", "test", 0);
std::string asdf;
return 0;
}
在发布模式下,exe大小 34 kb, 在调试模式下,exe大小为 92 kb
答案 3 :(得分:0)
这是黑暗中的一个镜头,但在链接时尝试-fwhole-program选项。同时-flto编译和链接时可能会有所帮助