2010-09-07 9 views
5

la stranezzaGCC Ridurre Binary Bloat - Strange Side Effect

ho compilato Google Protocol Buffer utilizzando parametri extra per un "gonfiare" la compilazione, e compilare con il seguente comando ./configure CXXFLAGS="-ffunction-sections -fdata-sections". un du-h rivela:

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 

La questione

non ho modificato gli script di build per eseguire un "--gc-sections" durante il collegamento, quindi shouldn' la build in unbloat è la stessa se non più grande? Cosa ha causato la riduzione delle dimensioni?

Sfondo

sto compilazione di una libreria di basso livello con gcc in questo momento e la biblioteca è un 2.5MB ginormous non sia in strip e 970KB spogliato. Questo è inaccettabile, e ho bisogno di rimuovere il dead-code - Dipendo da OpenSSL, Protocol Buffers e 3 Libraries da Boost, e collegherò staticamente gli ultimi 2 nella mia libreria. Le due librerie collegate staticamente dovranno essere compilate con "-ffunction-sections -fdata-sections" per me per rimuovere il codice morto.

questione connessa

mio next question è su come specificare la radice usata per eliminare codice morto.

+1

ha dovuto eliminare vecchi post poiché ho avuto un doppio post per qualche motivo. Sì 2.5 MB è ginormous - Ho scritto librerie simili e posso portarle a 80-300kb (usando MSVC). La toolchain GCC dovrebbe essere in grado di fare lo stesso. –

+0

@Hassan Syed, penso che la tua sezione di sfondo causi più problemi di quanti ne risolva. Non si riferisce alla domanda, e sembra che tu stia chiedendo modi per ridurre la dimensione del file di un file binario. Vorrei rimuoverlo o metterlo alla fine della domanda. – strager

+0

Beh, la dimensione non tagliata non conta. Dato che contiene tutte le cose extra che vuoi per il de-bugging e non è veramente rilevante per la produzione. –

risposta

1

Ho paura che il guadagno non abbia nulla a che fare con -ffunction-sections -fdata-sections: quando hai specificato CXXFLAGS="-ffunction-sections -fdata-sections" sulla riga di comando di configurazione, hai sovrascritto i flag predefiniti che erano -O2 -g -DNDEBUG. Di conseguenza, il tuo codice è stato compilato senza ottimizzazioni.

Si dovrebbe ripetere il test con CXXFLAGS="-ffunction-sections -fdata-sections -O2 -g -DNDEBUG" e si otterranno i risultati previsti (vale a dire identici).

+0

Egli * certamente * non otterrà risultati identici, ma la tua teoria sulla mancanza di O2 è in qualche modo plausibile. Tuttavia, se si fosse davvero compilato senza '-g', allora il suo "bloat" avrebbe dovuto essere * molto * più piccolo, il che contraddice i fatti osservati. –

+0

Ho controllato la mia "teoria" prima di postare :) Ovviamente, il risultato non sarà strettamente identico (perché le chiamate cross-section avverranno invece delle chiamate relative al PC all'interno dello stesso modulo oggetto) ma la differenza di dimensione sarà molto piccolo. Riguardo al problema "molto più piccolo", non dimenticare che il codice compilato con '-O0' è spesso più grande del codice compilato con' -O2', che controbilancia un po 'l'assenza di '-g'. –

+0

Sembra la causa più probabile, grazie per la spiegazione. –

1

compilazione con -ffunction-sections provoca ogni funzione da emessa nella propria sezione, e che fa sì che tutti i file oggetto per diventare più grande (e non solo .text sezione, ora avete .text.foo, .text.bar, etc.). Lo stesso per -fdata-sections. Quindi il risultato che hai ottenuto è esattamente ciò che è previsto.

Ma si non dovrebbe preoccuparsi di quanto è grande l'area di costruzione. Quello che si dovrebbe essere l'importanza del file eseguibile finale (o della libreria condivisa).

Con le bandiere che hai specificato, l'eseguibile "bloat" potrebbe essere ancora più grande (ma probabilmente non di molto). Ora aggiungi -Wl,--gc-sections e il tuo eseguibile "ingombrante" diventerà notevolmente più piccolo.