views:

195

answers:

2

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.

A: 

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.

Employed Russian
+1  A: 

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.

Samuel Tardieu
He will *most certainly* not get identical results, but your theory about missing -O2 is somewhat plausible. However, if he really did compile without '-g', then his "bloat" should have been *much* smaller, which contradicts observed facts.
Employed Russian
I checked my "theory" before posting :) Of course, the result won't be strictly identical (because cross-section calls will take place instead of PC-relative calls within the same object module) but the size difference will be very small. Concerning the "much smaller" issue, do not forget that code compiled with `-O0` is often larger than code compiled with `-O2`, which counterbalances a bit the absence of `-g`.
Samuel Tardieu
This does sound like the most likely cause, Thank you for the explanation.
Hassan Syed