![](/img/trans.png)
[英]How to increase stack size when compiling a C++ program using MinGW compiler
[英]C++ executable size using MinGW
我通常用C编写大小编码演示竞赛(64kb),但考虑转向C ++。
在MinGW g ++下,我对.exe-size有些麻烦。 (在使用可执行程序包装程序之前,我必须将其降低到<100 kb。)。
我看过这个: 如何减少MinGW g ++编译器生成的可执行文件的大小? 但是我已经在使用MinGW / g ++ 4.8.1和-s -Os ...见下文(对于4.8.1也是如此: unrecognized option '-shared-libstdc++'
并且cannot find -lstdc++_s
)。
这个小小的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 ++ _ s?
可选2:当我尝试-nostdlib
并用WinMain
替换main
时:
#include "windows.h"
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
MessageBoxA(0, "test", "test", 0);
return 0;
}
我没有编译器警告,但运行时崩溃,它编译为C时工作正常。 (可选,因为我不希望你/我花时间调试crt-startup,编译器 - 链接器标志来修剪库会更有帮助)
这些额外的字节被标准库调用“拉入” - 高级别的字节往往会带来它们下面的所有内容,内存分配,它们使用的异常等等。 最简单的方法是尽量减少使用的内容。 在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”文件。 输出文件的第一部分列出了每个被拉入的部分以及需要它的部分。*
*地图文件还会显示函数部分对标准库没有任何作用,因为它已经在没有该标志的情况下编译,除此之外
你无法摆脱MinGW GCC编译的可执行文件需要运行的额外代码。 您可以尝试使用MinGW-w64工具链,它以不同的方式接近CRT,但就“Hello world”大小而言,它可能比普通MinGW更差。
如果二进制大小非常重要,我强烈建议使用MSVC,因为它依赖于自己内置于操作系统的CRT代码。 我可以用某种方式小心地称之为“作弊”:-)。
关于DLL libstdc ++,当然有可能,你只需要一个像样的工具链;-)。 看到这里 。 请注意,这也是“作弊”,因为我怀疑比赛会忽略运行时库的大小。 这就是代码化比赛是愚蠢的原因。 总是有一个你忽略的运行时层。 直到你击中裸机内核或组装,这不是所谓的比赛的重点。
我试图在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
它是黑暗中的一个镜头,但在链接时尝试-fwhole-program选项。 同时-flto编译和链接可能会有所帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.