warum mein C++ - Ausgabe-executable ist so groß,?
Ich habe ein ganz einfaches C++ - Projekt, die verwendet boost::regex-Bibliothek. Die Ausgabe, die ich bekommen hab, ist 3,5 Mb groß. So wie ich das verstehe, ich bin statisch gelinkt werden alle boost .CPP-Dateien, einschließlich aller Funktionen/Methoden. Vielleicht ist es möglich irgendwie anweisen, mein linker verwenden Sie nur notwendige Elemente, die von boost, nicht alle von Ihnen? Danke.
$ c++ —version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659)
Dies ist, was size
sagt:
$ size a.out
__TEXT __DATA __OBJC others dec hex
1556480 69632 0 4296504912 4298131024 100304650
Versuchte ich strip
:
$ ls -al
... 3946688 May 21 13:20 a.out
$ strip a.out
$ ls -al
... 3847248 May 21 13:20 a.out
ps. Dies ist, wie mein code organisiert ist (vielleicht ist das die Hauptursache des Problems):
//file MyClass.h
class MyClass {
void f();
};
#include "MyClassImpl.h"
//file MyClassImpl.h
void MyClass::f() {
//implementation...
}
//file main.cpp
#include "MyClass.h"
int main(int ac, char** av) {
MyClass c;
c.f();
}
Was denkst du?
- Vielleicht sind Sie Gebäude mit debugging-Informationen eingefügt, die in der ausführbaren Datei. Versuchen Sie, bauen Sie mit aktivierter Optimierung.
- Sind Sie kompilieren mit Optimierungen?
- Ich bin mit dem flag -O3
- Welchen compiler/linker benutzt du, und welches Betriebssystem?
- Da es ein relativ einfaches Projekt, vielleicht könnten Sie Kochen es nach unten, um einige Beispiel-code, der kompiliert viel größer als Sie möchten/erwarten? Würde den Menschen helfen hier herauszufinden, was Los ist.
- Ich habe gerade eine kurze Erklärung, meine code-Struktur. Vielleicht wird dies helfen. Dank
- Sorry, ich wollte sagen, einige code, der beispielhaft für den boost und stl template-Nutzung. Der code, den Sie geschrieben ist nicht hilfreich in dieser Hinsicht. Wenn die include-Struktur scheint ein wenig ungewöhnlich, aber dies könnte dazu führen, mehrere symbol definition Fehler, anstatt aufblasen...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hast du das kompilieren mit debug-Symbole aktiviert? Das könnte für einen großen Teil der Größe. Auch wie sind Sie mit der Bestimmung der Größe des binären? Angenommen, Sie sind auf einer UNIX-ähnlichen Plattform sind Sie mit einem geraden "
ls -l
" oder die "size
" - Befehl. Die beiden geben stark unterschiedliche Ergebnisse, wenn die Binärdatei enthält die debugging-Symbole. Zum Beispiel, hier sind die Ergebnisse bekomme ich beim erstellen der Boost.Regex "credit_card_example.cpp" Beispiel.Ähnliche Ergebnisse auftreten, wenn nur die Erzeugung der Objekt-Datei:
BEARBEITEN: Hinzugefügt einige statische Verlinkung Ergebnisse ...
Hier ist die binäre Größe, wenn Sie statisch gelinkt werden. Es ist näher an, was Sie bekommen:
Es ist auch möglich, dass viel von der großen Größe ist aus anderen Bibliotheken ist die Boost.Regex-Bibliothek abhängt. Auf meiner Ubuntu-box, die Abhängigkeiten für den Boost.Regex shared library sind die folgenden:
Den ICU Bibliotheken Recht groß. Neben den debugging-Symbole, vielleicht sind Sie der primäre Mitwirkende zu der Größe Ihres binären. Außerdem, in der statisch verlinkten Fall sieht es so aus das Steigern.Regex-Bibliothek selbst besteht aus großen Objekt-Dateien:
Konnte man bis zu ~600K kommen, die von Boost.Regex alleine, wenn einige oder alle diese object-Dateien verbunden, die in Ihrer binären.
-O2 -g
. 250LoC --> 20M, kein Witz. Die Symbole sind so lang, stürzt es valgrind. Template-debug-Symbole nicht Durcheinander herum.strip -g
auf die ausführbare Datei, um Streifen aus der debugging-Symbole.(Beachten Sie, dass debug-Informationen arn nicht geladen, beim ausführen der exe, es gibt keine Auswirkungen auf Ihre RAM, indem Sie die ausführbare Datei)strip -d
oderstrip --strip-debug
. Welche version von strip zu tun Sie haben (strip -V
)?Den
-O3
- flag wird nicht optimieren Sie Ihren code für die Größe, aber eher für die Ausführungsgeschwindigkeit. Also vielleicht z.B. einige loop-unroling wird Ursache eine größere Datei. Versuchen Sie es zu kompilieren mit einigen anderen Optimierungs-flag. Die-Os
Flagge optimieren wird, für eine kleine ausführbare Datei.credit_card_example.cpp
" Beispiel mit-Os
sank die Größe der Binärdatei über 20K sowohl die dynamisch und statisch gelinkten Fällen (siehe meine Antwort für-O3
Ergebnisse). Egal, ich würde mich Wundern, wenn es gelöscht @Vincenzo binäre Größe deutlich. Sicherlich ist es einen Versuch Wert.Wenn Sie statisch gelinkt werden dann die meisten linkers werden nur die Objekte, die benötigt werden.
3,5 Mb nicht groß ist - auf einem PC-system also für die Größe, könnte davon abhängen, OS etc
Wenn Sie Ihren link-Reihenfolge richtig eingestellt (die meisten abhängigen, gefolgt von mindestens abhängig) der linker sollte nur greifen Symbole, die Ihr Programm tatsächlich nutzt. Außerdem haben viele (aber nicht alle, und ich kann nicht sprechen für regex) - boost-Funktionalität-header-nur durch Vorlage verwenden.
Wahrscheinlicher ist, dass debugging-Informationen/symbol-Tabelle/etc nimmt Platz in Ihre binäre. Template-Namen (z.B. iostream und standard-Container) sind sehr lang und es entstehen große Einträge in der Symboltabelle.
Du nicht sagst, welches Betriebssystem du verwendest, aber wenn es eine unix-Variante als test kann man eigentlich
strip
eine Kopie Ihrer binary zu löschen, alle extra-info und sehen, was ' s Links:Auf eine binäre getestet habe ich es entfernt etwa 90% der Datei Größe. Beachten Sie, dass wenn Sie dies tun, alle Kerne werden ziemlich nutzlos, ohne eine Kopie der unstripped-binary debug-gegen - Sie müssen nicht jedes symbol, Namen oder so, einfach Montage und Adressen. 3.5 MB ist wirklich eine winzige Datei in den modernen Zeiten. Wahrscheinlich gibt es nur ist, dass viel debugging - /symbol-Informationen auch nur aus 10Ksloc der Quelle.
size
Befehl, wie beschrieben in meiner Antwort.Sie sagen, Sie haben 3 Dateien.
Für mich, MyClassImpl.h ist wahrscheinlich ein .cpp, da Sie die Umsetzung.
Sowieso, wenn Sie tatsächlich kompilieren zwei Dateien, einschließlich boost::regex, werden Sie am Ende mit zwei mal der Größe von boost::regex (gerade, wenn Sie verwenden die gleiche Funktionalität in beiden Dateien müssen Sie das doppelte der Kosten im Raum).
Diese aufgrund der Tatsache, dass die meisten boost-Funktionen sind inline-Vorlagen.
besten,
wenn du ldd verfügbar ist, können Sie es verwenden, um zu überprüfen, ob Sie wirklich die Verknüpfung mit dem alle boost-Bibliotheken.
Andere Möglichkeit ist, dass die Größe ist der Nebeneffekt der Verwendung von nur Kopfzeilen Bibliotheken, viele boost-Bibliotheken sind von der Art, und Sie können mehr inline-code, den Sie glauben konnte. Sie können auch generieren eine Art kombinatorische explosion aufgrund der Verwendung verschiedener template-Parameter.
Um eine bessere Diagnose sollten Sie versuchen, erstellen Sie ein wirklich kurzes Programm mit regex und sehen, die Größe, die Sie erhalten. Wenn Ihr Programm ist wirklich kurz, 3,5 Mo ist ziemlich groß. Mein Aktuelles projet ausführbare auch die Verwendung von BOOST (aber nicht regex) und etwa die gleiche Größe . Aber ich spreche von rund 20000 Zeilen C++. Daher sollte es einen Haken irgendwo.