为什么我的C++;输出可执行文件这么大? 我有一个相当简单的C++项目,它使用Booo::正则表达式库。我得到的输出是3.5Mb大小。据我所知,我正在静态链接所有boost.CPP文件,包括所有函数/方法。也许有可能指示我的链接器只使用boost中的必要元素,而不是所有元素?谢谢 $ c++ —version i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659)

为什么我的C++;输出可执行文件这么大? 我有一个相当简单的C++项目,它使用Booo::正则表达式库。我得到的输出是3.5Mb大小。据我所知,我正在静态链接所有boost.CPP文件,包括所有函数/方法。也许有可能指示我的链接器只使用boost中的必要元素,而不是所有元素?谢谢 $ c++ —version i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659),c++,boost,C++,Boost,这就是size所说的: $ size a.out __TEXT __DATA __OBJC others dec hex 1556480 69632 0 4296504912 4298131024 100304650 我试过脱衣舞: $ ls -al ... 3946688 May 21 13:20 a.out $ strip a.out $ ls -al ... 3847248 May 21 13:20 a.out 注:这就是我的代码的组织方式(可能这是问题的主要原

这就是
size
所说的:

$ size a.out
__TEXT  __DATA  __OBJC  others  dec hex
1556480 69632   0   4296504912  4298131024  100304650
我试过脱衣舞:

$ ls -al
...  3946688 May 21 13:20 a.out
$ strip a.out
$ ls -al
...  3847248 May 21 13:20 a.out
注:这就是我的代码的组织方式(可能这是问题的主要原因):


你怎么看?

如果你是静态链接,那么大多数链接器将只包含所需的对象


3.5Mb没有那么大-在PC系统上,因此大小可能取决于操作系统等

编译时是否启用了调试符号?这可能占了这个规模的很大一部分。另外,如何确定二进制文件的大小?假设您在类UNIX平台上,您使用的是直接的“”或“”命令。如果二进制文件包含调试符号,则这两种方法可能会给出截然不同的结果。例如,以下是我在构建“”示例时得到的结果

仅生成对象文件时会出现类似的结果:

$ g++ -c -g -O3 foo.cpp

$ ls -l foo.o 
-rw-r--r-- 1 void void 622476 2010-05-20 10:40 foo.o

$ size foo.o
   text    data     bss     dec     hex filename
  49119       4      40   49163    c00b foo.o

编辑:添加了一些静态链接结果

这是静态链接时的二进制大小。它更接近你所得到的:

$ g++ -static -g -O3 foo.cpp -lboost_regex-mt -lpthread

$ ls -l a.out 
-rwxr-xr-x 1 void void 2019905 2010-05-20 11:16 a.out

$ size a.out 
   text    data     bss     dec     hex filename
1204517    5184   41976 1251677  13195d a.out
也有可能大部分大型库来自Boost.Regex库所依赖的其他库。在我的Ubuntu盒上,Boost.Regex共享库的依赖项如下:

$ ldd /usr/lib/libboost_regex-mt.so.1.38.0 
        linux-gate.so.1 =>  (0x0053f000)
        libicudata.so.40 => /usr/lib/libicudata.so.40 (0xb6a38000)
        libicui18n.so.40 => /usr/lib/libicui18n.so.40 (0x009e0000)
        libicuuc.so.40 => /usr/lib/libicuuc.so.40 (0x00672000)
        librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x001e2000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x001eb000)
        libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00110000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x009be000)
        libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x00153000)
        libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x002dd000)
        /lib/ld-linux.so.2 (0x00e56000)
图书馆可以变得相当大。除了调试符号外,它们可能是二进制文件大小的主要因素。此外,在静态链接的情况下,Boost.Regex库本身似乎由大型对象文件组成:

$ size --totals /usr/lib/libboost_regex-mt.a | sort -n
      0       0       0       0       0 regex_debug.o (ex /usr/lib/libboost_regex-mt.a)
      0       0       0       0       0 usinstances.o (ex /usr/lib/libboost_regex-mt.a)
      0       0       0       0       0 w32_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
   text    data     bss     dec     hex filename
    435       0       0     435     1b3 regex_raw_buffer.o (ex /usr/lib/libboost_regex-mt.a)
    480       0       0     480     1e0 static_mutex.o (ex /usr/lib/libboost_regex-mt.a)
   1543       0      36    1579     62b cpp_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
   3171     632       0    3803     edb regex_traits_defaults.o (ex /usr/lib/libboost_regex-mt.a)
   5339       8      13    5360    14f0 c_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
   5650       8      16    5674    162a wc_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
   9075       4      32    9111    2397 regex.o (ex /usr/lib/libboost_regex-mt.a)
  17052       8       4   17064    42a8 fileiter.o (ex /usr/lib/libboost_regex-mt.a)
  61265       0       0   61265    ef51 wide_posix_api.o (ex /usr/lib/libboost_regex-mt.a)
  61787       0       0   61787    f15b posix_api.o (ex /usr/lib/libboost_regex-mt.a)
  80811       8       0   80819   13bb3 icu.o (ex /usr/lib/libboost_regex-mt.a)
 116489       8     112  116609   1c781 instances.o (ex /usr/lib/libboost_regex-mt.a)
 117874       8     112  117994   1ccea winstances.o (ex /usr/lib/libboost_regex-mt.a)
 131104       0       0  131104   20020 cregex.o (ex /usr/lib/libboost_regex-mt.a)
 612075     684     325  613084   95adc (TOTALS)

如果将部分或全部对象文件链接到二进制文件中,仅Boost.Regex就可以获得高达600K的链接。如果链接顺序设置正确(最依赖,其次是最不依赖),则链接器应该只获取程序实际使用的符号。此外,很多(但不是全部,我不能代表regex)boost功能只是由于模板的使用

更可能的情况是调试信息/符号表/etc占用了二进制文件中的空间。模板名称(例如iostream和标准容器)非常长,会在符号表中创建较大的条目

您不会说您使用的是什么操作系统,但如果它是unix变体作为测试,您实际上可以
剥离
二进制文件的副本,以删除所有额外信息,并查看剩下的内容:

cp a.out a.out.test
strip a.out.test
ls -l a.out*

在一个二进制文件上,我测试它删除了大约90%的文件大小。请注意,如果您这样做,如果没有要调试的非压缩二进制文件副本,任何内核都将非常无用-您将没有任何符号名或任何东西,只有程序集和地址。在现代,3.5MB确实是一个很小的文件。最有可能的是,即使源代码只有10Ksloc,也有那么多调试/符号信息。

标记将不会优化代码的大小,而是优化代码的执行速度。因此,例如,某些循环展开可能会导致文件变大。尝试使用其他优化标志进行编译。
-Os
标志将针对一个小的可执行文件进行优化。

如果您有可用的ldd,您可以使用它来检查您是否真的链接了所有的boost库

另一种可能性是,大小是使用仅标头库的副作用,许多boost库都属于这种类型,包括它们可以内联更多您可以相信的代码。由于使用了几个不同的模板参数,您还可以生成某种组合爆炸

为了获得更好的诊断,您应该尝试使用regex创建一个非常短的程序,并查看您得到的大小。如果你的程序真的很短,3.5个月是相当大的。我当前的projet可执行文件也使用BOOST(但不是regex),大小大致相同。但我说的是20000行C++。因此,应该有一个陷阱。

你说你有3个文件。 对我来说,MyClassImpl.h可能是一个.cpp,因为它包含实现

无论如何,如果您实际编译两个文件,包括boost::regex,那么最终的大小将是boost::regex的两倍(确切地说,如果您在两个文件中使用相同的功能,那么空间开销将是boost::regex的两倍)

这是因为大多数boost功能都是内联模板


最好的情况是,

您可能正在使用插入到可执行文件中的调试信息进行构建。尝试在启用优化的情况下进行构建。您是否在使用优化进行编译?您使用的是什么编译器/链接器,以及哪个操作系统?因为这是一个相对简单的项目,也许您可以将其归结为一些编译比您希望/预期大得多的示例代码?将帮助这里的人们了解发生了什么。我刚刚添加了一个简短的代码结构说明。也许这会有帮助。谢天谢地,我的源代码只是10KSLOC,boost正则表达式是另一个6KSLOC。这段代码(16KSLOC)如何生成3.5Mb的可执行文件?@Vin模板、运行时、预处理器加起来。loc不是很有意义3.5MB不适合一级缓存。对于嵌入式设备(如索尼PSP),4兆是二进制文件在所有内存中的最大可分配大小,这也是一个真正的问题。我提醒演示制作者,只需4k的声音就可以制作3d程序,64k的声音就完全可以制作出世界级的演示。不需要调试符号和相关的粗制滥造,就不需要去除二进制文件来确定大小。只需使用
size
命令,如我的回答所述。这也是一个很好的观点。使用
-Os
编译Boost.Regex“
credit\u card\u example.cpp
”示例时,在动态和静态链接的情况下,二进制文件的大小都减少了约20K(请参见我的答案了解
-O3
结果)。不管怎样,我会的
$ size --totals /usr/lib/libboost_regex-mt.a | sort -n
      0       0       0       0       0 regex_debug.o (ex /usr/lib/libboost_regex-mt.a)
      0       0       0       0       0 usinstances.o (ex /usr/lib/libboost_regex-mt.a)
      0       0       0       0       0 w32_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
   text    data     bss     dec     hex filename
    435       0       0     435     1b3 regex_raw_buffer.o (ex /usr/lib/libboost_regex-mt.a)
    480       0       0     480     1e0 static_mutex.o (ex /usr/lib/libboost_regex-mt.a)
   1543       0      36    1579     62b cpp_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
   3171     632       0    3803     edb regex_traits_defaults.o (ex /usr/lib/libboost_regex-mt.a)
   5339       8      13    5360    14f0 c_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
   5650       8      16    5674    162a wc_regex_traits.o (ex /usr/lib/libboost_regex-mt.a)
   9075       4      32    9111    2397 regex.o (ex /usr/lib/libboost_regex-mt.a)
  17052       8       4   17064    42a8 fileiter.o (ex /usr/lib/libboost_regex-mt.a)
  61265       0       0   61265    ef51 wide_posix_api.o (ex /usr/lib/libboost_regex-mt.a)
  61787       0       0   61787    f15b posix_api.o (ex /usr/lib/libboost_regex-mt.a)
  80811       8       0   80819   13bb3 icu.o (ex /usr/lib/libboost_regex-mt.a)
 116489       8     112  116609   1c781 instances.o (ex /usr/lib/libboost_regex-mt.a)
 117874       8     112  117994   1ccea winstances.o (ex /usr/lib/libboost_regex-mt.a)
 131104       0       0  131104   20020 cregex.o (ex /usr/lib/libboost_regex-mt.a)
 612075     684     325  613084   95adc (TOTALS)
cp a.out a.out.test
strip a.out.test
ls -l a.out*