Nur g ++ funktioniert, aber nicht "g ++ -c" und ld

9

Ich habe den folgenden Quellcode in main.cpp:

%Vor%

Dieser Befehl funktioniert und erstellt die ausführbare Datei:

%Vor%

Aber diese Befehle funktionieren nicht:

%Vor%

Der zweite Fehler mit:

%Vor%     
Valentin Lorentz 15.07.2011, 09:01
quelle

4 Antworten

13

Ich denke, wenn Sie ld direkt verwenden, enthält es standardmäßig keine C ++ - Bibliotheken. Sie können auch g++ verwenden, um die Verknüpfung zu erstellen, und ld mit den richtigen Einstellungen aufrufen.

%Vor%     
Sodved 15.07.2011, 09:04
quelle
12

GCC intern verlinkt gegen einige zusätzliche Bibliotheken und Objektdateien. Um zu sehen, was diese sind, führen Sie -### aus, was die Werkzeugbefehle ausgibt, die ausgeführt werden, einschließlich des Linkers. Der von meinem GCC verwendete Linker-Befehl ist: (Ich habe die tatsächliche .o -Datei erstellt, die ich aufgerufen habe, g++ auf fett , damit Sie sie leicht erkennen können).

  

/usr/lib/gcc/i686-pc-linux-gnu/4.6.0/collect2 --build-id --eh-frame-hdr -m elf_i386 "--hash-style = beide" -Dynamisch- Linker /lib/ld-linux.so.2 /usr/lib/gcc/i686-pc-linux-gnu/4.6.0/../../../crt1.o/usr/lib/gcc/i686 -pc-linux-gnu / 4.6.0 /../../../crti.o/usr/lib/gcc/i686-pc-linux-gnu/4.6.0/crtbegin.o -L / usr / lib / gcc / i686-pc-linux-gnu / 4.6.0 -L / usr / lib / gcc / i686-pc-linux-gnu / 4.6.0 /../../ .. main1.o "-lstdc ++" -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/i686-pc-linux-gnu/4.6.0/crtend.o/usr/lib/gcc/i686 -pc-linux-gnu / 4.6.0 /../../../ crtn.o

Sie können den Pfad collect2 durch ld ersetzen (wenn ich mich richtig erinnere, wird collect2 nur als Proxy für die realen ld von GCC-Backends benötigt, die keine modernen Binärformate unterstützen, bis < em> collect -Konstruktor- und Destruktorfunktionen entsprechend ihrem verkrüppelten Namen Das ELF-Format hat dafür native Sektionen.

Die Ausführung dieses Befehls, bei dem ld wörtlich ersetzt wurde, verknüpft die ausführbare Datei erfolgreich.

    
Johannes Schaub - litb 15.07.2011 09:12
quelle
7

Wenn Sie g++ verwenden, wird auch die Bibliothek libstd++ verknüpft, die der Linker verwendet, um die Namen aufzulösen. Wenn Sie jedoch g++ -c und dann ld verwenden, wird die Bibliothek nicht automatisch verknüpft. Sie müssen die Bibliothek jetzt manuell verknüpfen.

Versuch (ungetestet):

%Vor%

Oder Sie können in die richtige Syntax schauen, indem Sie dieses Handbuch lesen:

Nawaz 15.07.2011 09:05
quelle
1

Nun, Sie haben die Standardbibliothek nicht verknüpft. g++ erledigt dies automatisch für Sie; Deshalb verwenden wir es: es umschließt Aufrufe von ccplus1 und ld mit allen Extras, um die es geht.

BTW, genau genommen ist das Äquivalent von g++ main.cpp -o main :

%Vor%

( cc1plus ist vielleicht nicht auf deinem Pfad; ich habe meinen in /usr/libexec/gcc/i386-redhat-linux/4.1.1/ gefunden)

g++ -c main.cpp führt diesen ersten Schritt traditionell aus. g++ main.cpp -o main umschließt beide.

g++ ist ein -Wrapper für die einzelnen Kompilierungs- und Verknüpfungswerkzeuge, die auf C ++ abgestimmt sind. Als solches stellt es Argumente für cc1plus und ld bereit, wie es ihm passt, einschließlich des Arguments, das in der C ++ - Standardbibliothek verknüpft werden soll:

%Vor%

Es wird auch in der Laufzeit und möglicherweise einige andere Sachen verknüpfen.

Im Allgemeinen müssen Sie diese Dinge nicht selbst versuchen: Lassen Sie g++ darauf achten.

    
quelle

Tags und Links