繁体   English   中英

使用MinGW的C ++可执行文件大小

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM