对于相同的c ++源文件,其gcc可执行文件在Windows中比在Linux中大655倍。 为什么这么多差异?

我正在testing这个简单的c + +代码在我的Windows 8.1,英特尔i7-3517U 64位笔记本电脑与GCC 4.8.2。

#include<iostream> using namespace std; int main(int argc, char **argv){ cout << "This test code will simply display any arguments passed." << endl ; for(int i=0; i<argc; i++){ cout << argv[i] << endl ; } return 0 ; } 

令人惊讶的是,在编译之后,可执行文件竟然是5905KB 。 出于好奇,我试着在Linux Fedora 20 64位机器上用相同的GCC版本编译相同的文件。 而可执行文件只有9KB

使用g++ -Ox -o fileWithOx.exe file.cpp (x = 1,2,3,s)进行各种优化之后,Windows可执行文件的大小几乎相同。 做了一些研究,并遵循MinGW的build议,我试图编译它们没有debugging信息使用strip g++ -s -o fileWithStrip.exe file.cpp ,但可执行文件仍然是597KB大。

而另一方面,对于相同的选项,Linux可执行文件只有6-13KB

做了一些实验, 一些更多的研究和堆栈溢出 ,我几乎相信,巨大的规模是由于iostream链接到许多其他头文件和/或生成一些初始化代码。

但是我的疑问是iostream既可以在Windows中使用,也可以在Linux中使用。 那为什么这么大的差别呢? 我知道Windows和Linux可执行文件的工作方式不同。 但655倍大 ,这是不是有点极端?

不同之处可能不是编译而是编译阶段。

首先尝试仅编译,在Unix中使用-c例如g++ -c code.cpp来停止命令,并在你的Windows环境中找到相应的标志。 然后比较对象文件,它们应该几乎相同的大小。 这些目标文件( .o扩展名)只包含你的代码到机器代码的翻译。 大小可能不同,可能是2或3的因素,但这不相关。

发生了什么事是你的Windows的编译器可能在某个库上使用了静态链接,因此可执行文件包含了你在库中使用的代码。 在Unix上,编译器可能会动态地链接所有东西,这就是说,库将在运行时加载,而不包含在可执行文件中。

请参阅您的编译器文档以查找如何执行静态/动态链接。 你应该知道,有可能某些环境可能不提供这两种类型的图书馆…

刚刚在windows下建立你的程序,使用mingw g ++版本4.7.2 – 我只得到10kb。 不知道你是如何设法扩大到超过5MB的。 当我在Code :: Blocks 13.12中点击Ctrl-F11时,这里是cmd行和输出:

mingw32-g ++ .exe -Wall -fexceptions -O2 -I“C:\ Program Files(x86)\ CodeBlocks \ MinGW \ include”-c C:\ Users \ enhzflep \ Documents \ code \ 001-sizeTestDeleteMe \ main.cpp – o obj \ Release \ main.o mingw32-g ++。exe -o bin \ Release \ 001-sizeTestDeleteMe.exe obj \ Release \ main.o -s
输出文件是大小为10.50 KB的bin \ Release \ 001-sizeTestDeleteMe.exe

对不起,我现在没有任何Windows盒子,但是如果我相信这篇文章,

  • 如何减小MinGW g ++编译器生成的可执行文件的大小?

也许是因为你的Windows可执行文件被静态链接到libstdc++.a与Mingw编译器一起提供的libstdc++.a ,而Linux版本则被动态地链接到/usr/lib64/libstdc++.so.6 。 后者是大多数Linux发行版的标准组件之一,可以通过动态连接器进行搜索,所以Linux g++可以安全地依靠它。 但前者不是,所以也许Mingw g++决定采用静态链接。

下面的文章(在Mingw GCC 4.4上)说你可以告诉Mingw g++动态链接libstdc++.dll和cmd行选项-lstdc++_s Mingw g++

只是FYI,这是一个小的C + + EXE是如何动态链接到我的Debian框libstdc++.so.6

 $ ldd valueInit linux-vdso.so.1 (0x00007fff641fe000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f20618e2000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f20615e4000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f20613cd000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2061021000) /lib64/ld-linux-x86-64.so.2 (0x00007f2061c12000) $ LANG=C ls -lH /usr/lib/x86_64-linux-gnu/libstdc++.so.6 -rw-r--r-- 1 root root 953K Jan 6 12:24 /usr/lib/x86_64-linux-gnu/libstdc++.so.6 

libstdc++.so.6包含许多iostream函数的定义

 $ readelf -sW /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep stream | c++filt | head -3 135: 0000000000084360 51 FUNC WEAK DEFAULT 12 std::money_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, bool, std::ios_base&, std::_Ios_Iostate&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&) const@@GLIBCXX_3.4 137: 00000000002e8ff0 24 OBJECT WEAK DEFAULT 23 typeinfo for std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >@@GLIBCXX_3.4 138: 000000000009f1d0 15 FUNC WEAK DEFAULT 12 std::num_put<wchar_t, std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> > >::put(std::ostreambuf_iterator<wchar_t, std::char_traits<wchar_t> >, std::ios_base&, wchar_t, void const*) const@@GLIBCXX_3.4