是否可以使用MINGW g ++生成小型可执行文件?

时间:2011-04-12 10:35:24

标签: linker g++ compilation

我知道MINGW-g ++编译更大的可执行文件,因为它静态地链接了很多东西。另一方面,MSVC ++动态链接来自VCRedist包的DLL,这就是它产生较小可执行文件的原因。

但是,是否可以在Windows上以类似的方式使用g ++进行编译?不一定是MINGW-g ++,但我可以使用Qt Creator(我没有将Qt添加为标签,因为它与问题无关)。

3 个答案:

答案 0 :(得分:6)

MinGW完全能够动态链接到msvcrt运行时。你没有摆脱这种方式的唯一混乱是GCC / MinGW启动代码,这不是很大。

一个小的C ++测试程序(简单的iostream hello world程序,注意:我得到了与普通C printf版本相同的结果)。

#include <iostream>

using namespace std;

int main()
{
cout << "Hello World!" << endl;
return 0;
}

COMMANDLINES:

g++ main.cpp -MD -Os -s -o test.exe
cl /MD /Os main.cpp /link /out:test2.exe

可执行文件大小:

海湾合作委员会:13kB

MSVC:6kB

虽然这是双倍的,但所有必要的启动代码都会造成很大的差异;对于较大的程序,差异可以忽略不计。

答案 1 :(得分:3)

为了使用静态链接在VC ++和MinGW之间进行公平的比较,我建议在上面的命令行语法中删除编译器开关/ MD。这将导致Visual C ++编译器静态链接静态库,但仍然,Visual C ++编译器将生成比使用MinGW静态编译的可执行文件小得多的可执行文件。

因为Visual C ++编译器使用的链接器具有一个称为函数级链接的功能,所以链接器只根据代码中使用的函数链接必要的库。任何未引用或未使用的函数都不会链接到生成的最终可执行文件,从而导致更小的静态链接二进制文件。

回到上面的示例使用Visual C ++编译器,这一次,使用静态链接,命令行语法将是:

cl / Os main.cpp / link /out:test2.exe

你可以在这里注意到我已经删除了/ MD开关,因此编译器将使用静态链接而不是动态链接。

现在,为了制作一个小得多的静态链接可执行文件,我建议使用命令行语法:

cl / Ox main.cpp / link / FILEALIGN:512 / OPT:REF / OPT:ICF / INCREMENTAL:NO /out:test2.exe

如果检查生成的二进制文件,您会发现它小得多,这又是一个静态链接的可执行文件。

我实际上从本网站http://www.catch22.net/tuts/minexe

的讨论中得到了这个想法

包括Delphi在内的大多数Pascal编译器也具有相同的链接功能,它被称为智能链接,但由此产生的静态链接可执行文件比Visual C ++编译器生成的可执行文件要小得多。

MinGW使用的链接器是非常愚蠢的,它是不知道的,因此,它链接许多静态库,包括那些包含源代码中未使用的函数或例程的静态库,导致非常臃肿的静态链接二进制文件。

我建议转储MinGW并使用Visual C ++编译器。甚至MinGW的开发人员似乎并不关心使用静态链接减少代码膨胀。

答案 2 :(得分:1)

您可以使用cygwin(www.cygwin.com)。它们使用与MSVCRT非常相似的运行时DLL。那么你的程序依赖于cygwin运行时,当然(有点同义,抱歉)。