GCC Reducing Binary Bloat -- Strange Side Effect
The Weirdness
I have compiled Google Protocol Buffers using no extra parameters for a "bloat" compile, and compile with the following command ./configure CXXFLAGS="-ffunction-sections -fdata-sections"
. a du-h reveals:
120K ./bloat/bin
124K ./bloat/include/google/protobuf/io
8.0K ./bloat/include/google/protobuf/compiler/java
12K ./bloat/include/google/protobuf/compiler/python
8.0K ./bloat/include/google/protobuf/compiler/cpp
128K ./bloat/include/google/protobuf/compiler
52K ./bloat/include/google/protobuf/stubs
848K ./bloat/include/google/protobuf
852K ./bloat/include/google
856K ./bloat/include
12K ./bloat/lib/pkgconfig
37M ./bloat/lib
38M ./bloat
20K ./unbloat/bin
124K ./unbloat/include/google/protobuf/io
8.0K ./unbloat/include/google/protobuf/compiler/java
12K ./unbloat/include/google/protobuf/compiler/python
8.0K ./unbloat/include/google/protobuf/compiler/cpp
128K ./unbloat/include/google/protobuf/compiler
52K ./unbloat/include/google/protobuf/stubs
848K ./unbloat/include/google/protobuf
852K ./unbloat/include/google
856K ./unbloat/include
12K ./unbloat/lib/pkgconfig
15M ./unbloat/lib
16M ./unbloat
53M .
Drill Down:
ls -gGh bloat/lib/
total 37M
-rw-r--r-- 1 13M 2010-09-07 13:57 libprotobuf.a
-rwxr-xr-x 1 986 2010-09-07 13:57 libprotobuf.la
-rw-r--r-- 1 1.6M 2010-09-07 13:57 libprotobuf-lite.a
-rwxr-xr-x 1 1021 2010-09-07 13:57 libprotobuf-lite.la
lrwxrwxrwx 1 25 2010-09-07 13:57 libprotobuf-lite.so -> libprotobuf-lite.so.6.0.0
lrwxrwxrwx 1 25 2010-09-07 13:57 libprotobuf-lite.so.6 -> libprotobuf-lite.so.6.0.0
-rwxr-xr-x 1 771K 2010-09-07 13:57 libprotobuf-lite.so.6.0.0
lrwxrwxrwx 1 20 2010-09-07 13:57 libprotobuf.so -> libprotobuf.so.6.0.0
lrwxrwxrwx 1 20 2010-09-07 13:57 libprotobuf.so.6 -> libprotobuf.so.6.0.0
-rwxr-xr-x 1 5.5M 2010-09-07 13:57 libprotobuf.so.6.0.0
-rw-r--r-- 1 12M 2010-09-07 13:57 libprotoc.a
-rwxr-xr-x 1 1.1K 2010-09-07 13:57 libprotoc.la
lrwxrwxrwx 1 18 2010-09-07 13:57 libprotoc.so -> libprotoc.so.6.0.0
lrwxrwxrwx 1 18 2010-09-07 13:57 libprotoc.so.6 -> libprotoc.so.6.0.0
-rwxr-xr-x 1 4.6M 2010-09-07 13:57 libprotoc.so.6.0.0
drwxr-xr-x 2 4.0K 2010-09-07 13:57 pkgconfig
ls -gGh unbloat/lib/
total 15M
-rw-r--r-- 1 5.8M 2010-09-07 14:03 libprotobuf.a
-rwxr-xr-x 1 988 2010-09-07 14:03 libprotobuf.la
-rw-r--r-- 1 764K 2010-09-07 14:03 libprotobuf-lite.a
-rwxr-xr-x 1 1023 2010-09-07 14:03 libprotobuf-lite.la
lrwxrwxrwx 1 25 2010-09-07 14:03 libprotobuf-lite.so -> libprotobuf-lite.so.6.0.0
lrwxrwxrwx 1 25 2010-09-07 14:03 libprotobuf-lite.so.6 -> libprotobuf-lite.so.6.0.0
-rwxr-xr-x 1 393K 2010-09-07 14:03 libprotobuf-lite.so.6.0.0
lrwxrwxrwx 1 20 2010-09-07 14:03 libprotobuf.so -> libprotobuf.so.6.0.0
lrwxrwxrwx 1 20 开发者_运维百科2010-09-07 14:03 libprotobuf.so.6 -> libprotobuf.so.6.0.0
-rwxr-xr-x 1 2.7M 2010-09-07 14:03 libprotobuf.so.6.0.0
-rw-r--r-- 1 3.7M 2010-09-07 14:04 libprotoc.a
-rwxr-xr-x 1 1.1K 2010-09-07 14:04 libprotoc.la
lrwxrwxrwx 1 18 2010-09-07 14:04 libprotoc.so -> libprotoc.so.6.0.0
lrwxrwxrwx 1 18 2010-09-07 14:04 libprotoc.so.6 -> libprotoc.so.6.0.0
-rwxr-xr-x 1 1.3M 2010-09-07 14:04 libprotoc.so.6.0.0
drwxr-xr-x 2 4.0K 2010-09-07 14:03 pkgconfig
The Question
I have not altered the build scripts to perform a "--gc-sections
" during linking, therefore shouldn't the unbloat build be the same if not bigger ? What caused the reduction in size ?
Background
I am compiling a low-level library with gcc at the moment and the library is a ginormous 2.5MB unstriped and 970KB stripped. This is unacceptable, and I need to remove dead-code -- I depend on OpenSSL, Protocol Buffers and 3 Libraries from Boost, and I will static link the last 2 into my library. The two statically linked libraries will have to be compiled them with the "-ffunction-sections -fdata-sections" for me to remove dead code.
Related Question
My next question is about how to specify the root used to eliminate dead code.
I am afraid the gain has nothing to do with -ffunction-sections -fdata-sections
: when you specified CXXFLAGS="-ffunction-sections -fdata-sections"
on configure command line, you overwrote the default flags which were -O2 -g -DNDEBUG
. As a consequence, your code was compiled with no optimizations.
You should redo your test with CXXFLAGS="-ffunction-sections -fdata-sections -O2 -g -DNDEBUG"
and you will get the expected (i.e., identical) results.
Compiling with -ffunction-sections
causes every function to be emitted into its own section, and that causes every object file to become larger (instead of just .text
section, you now have .text.foo
, .text.bar
, etc.). Same for -fdata-sections
. So the result you've got is exactly what's expected.
But you shouldn't care how big your build area is. What you should care about is how big your final executable (or shared library) is.
With the flags you've specified, the "bloat" executable may still be bigger (but probably not by much). Now add -Wl,--gc-sections
, and your "bloat" executable will become markedly smaller.
精彩评论