簡體   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