2010-09-07 2 views
5

Die VerrücktheitGCC Reduzierung Binary aufblasen - Strange Side Effect

Ich habe Google Protocol Buffers zusammengestellt keine zusätzlichen Parameter für eine „aufblasen“ kompilieren verwenden und kompilieren mit dem folgenden Befehl ./configure CXXFLAGS="-ffunction-sections -fdata-sections". ein du-h zeigt:

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 

Die Frage

ich nicht die Build-Skripte verändert haben ein "--gc-sections" während der Verknüpfung daher shouldn‘ausführen t das unblotige Build gleich, wenn nicht größer sein? Was hat die Größenreduzierung verursacht?

Hintergrund

Ich bin eine Low-Level-Bibliothek mit gcc zur Zeit zusammenzustellen und die Bibliothek ist ein ginormous 2,5MB ungestreiften und gestrippt 970KB. Das ist inakzeptabel, und ich muss den toten Code entfernen - ich bin auf OpenSSL, Protokollpuffer und 3 Bibliotheken von Boost angewiesen, und ich werde die letzten 2 in meine Bibliothek statisch verknüpfen. Die beiden statisch verknüpften Bibliotheken müssen mit den "-function-sections -fdata-sections" kompiliert werden, um toten Code zu entfernen.

Verwandte Frage

Mein next question geht darum, wie die Wurzel zu spezifizieren verwendet toten Code zu beseitigen.

+1

musste alten Post löschen, da ich aus irgendeinem Grund eine Doppelpost hatte. Ja, 2,5 MB ist ginormous - Ich habe ähnliche Bibliotheken geschrieben und kann sie auf 80-300kb runterladen (mit MSVC). Die GCC-Toolchain sollte in der Lage sein, das Gleiche zu tun. –

+0

@Hassan Syed, ich denke, dass dein Hintergrundabschnitt mehr Probleme verursacht, als er löst. Es bezieht sich nicht auf die Frage, und es klingt wie Sie nach Möglichkeiten fragen, die Dateigröße einer Binärdatei zu reduzieren. Ich würde es entfernen oder es am Ende der Frage stellen. – strager

+0

Nun zählt die Größe ohne Stripping nicht. Denn das enthält all die Extras, die Sie zum Debuggen benötigen, und ist für die Produktion nicht wirklich relevant. –

Antwort

1

Ich fürchte, der Gewinn hat nichts mit -ffunction-sections -fdata-sections zu tun: Wenn Sie auf konfigurieren Befehlszeile angegeben, überschreiben Sie die Standard-Flags, die -O2 -g -DNDEBUG waren. Daher wurde Ihr Code ohne Optimierungen kompiliert.

Sie sollten Ihren Test mit CXXFLAGS="-ffunction-sections -fdata-sections -O2 -g -DNDEBUG" wiederholen und Sie erhalten die erwarteten (d. H. Identische) Ergebnisse.

+0

Er wird * sicherlich * keine identischen Ergebnisse erhalten, aber Ihre Theorie über fehlende -O2 ist etwas plausibel. Wenn er jedoch wirklich ohne '-g' kompiliert hätte, dann hätte sein 'Bloat' * viel * kleiner sein müssen, was den beobachteten Tatsachen widerspricht. –

+0

Ich habe meine "Theorie" vor dem Posten überprüft :) Natürlich wird das Ergebnis nicht genau identisch sein (weil Querschnitte statt PC-relative Aufrufe innerhalb desselben Objektmoduls stattfinden), aber der Größenunterschied wird sehr groß sein klein. In Bezug auf das "viel kleinere" Problem, vergiss nicht, dass Code, der mit "-O0" kompiliert wurde, oft größer ist als Code, der mit "-O2" kompiliert wurde, was ein bisschen die Abwesenheit von "-g" ausgleicht. –

+0

Das klingt wie die wahrscheinlichste Ursache, Danke für die Erklärung. –

1

mit -ffunction-sections Kompilieren verursacht jede Funktion in einem eigenen Abschnitt emittiert wird, und das bewirkt, dass jede Objektdatei größer werden (statt nur .text Abschnitt, Sie haben jetzt .text.foo, .text.bar, etc.). Gleiches für -fdata-sections. Das Ergebnis ist genau das, was erwartet wird.

Aber Sie sollten nicht Pflege, wie groß Ihre Build-Bereich ist. Was Sie sollte kümmern ist, wie groß Ihre endgültige ausführbare Datei (oder gemeinsam genutzte Bibliothek) ist.

Mit den Flags, die Sie angegeben haben, kann die "Bloat" ausführbare Datei immer noch größer sein (aber wahrscheinlich nicht viel). Fügen Sie nun -Wl,--gc-sections hinzu, und Ihre ausführbare Datei "bloat" wird deutlich kleiner.