Kombinieren Sie zwei GCC-kompilierte .o-Objektdateien zu einer dritten .o-Datei

83

Wie kombiniert man zwei GCC-kompilierte .o-Objektdateien zu einer dritten .o-Datei?

$ gcc -c  a.c -o a.o
$ gcc -c  b.c -o b.o
$ ??? a.o b.o -o c.o
$ gcc c.o other.o -o executable

Wenn Sie Zugriff auf die Quelldateien haben, -combinewerden die Quelldateien vor dem Kompilieren mit dem GCC-Flag zusammengeführt:

$ gcc -c -combine a.c b.c -o c.o

Dies funktioniert jedoch nur für Quelldateien und GCC akzeptiert dies nicht .o Dateien als Eingabe für diesen Befehl.

Normalerweise .ofunktioniert das Verknüpfen von Dateien nicht ordnungsgemäß, da Sie die Ausgabe des Linkers nicht als Eingabe dafür verwenden können. Das Ergebnis ist eine gemeinsam genutzte Bibliothek und nicht statisch mit der resultierenden ausführbaren Datei verknüpft.

$ gcc -shared a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable
./executable: error while loading shared libraries: c.o: cannot open shared object file: No such file or directory
$ file c.o
c.o: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Lucian Adrian Grijincu
quelle
1
gcc hat derzeit keine -combineOption. Es existiert in gcc 4.1.2 und existiert nicht in gcc 6.3.0 (jemand anderes kann herausfinden, wann es entfernt wurde).
Keith Thompson

Antworten:

97

Durch Übergeben von -relocatableoder -ran ldwird ein Objekt erstellt, das als Eingabe von geeignet ist ld.

$ ld -relocatable a.o b.o -o c.o
$ gcc c.o other.o -o executable
$ ./executable

Die generierte Datei ist vom gleichen Typ wie die Originaldateien .o.

$ file a.o
a.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
$ file c.o
c.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
Lucian Adrian Grijincu
quelle
2
Ist es möglich, die inverse Operation durchzuführen? dh ao ​​und bo aus co produzieren?
Bert Regelink
7
@ BertRegelink nein, weil es keine eindeutige Umkehrung gibt. In mathematischen Begriffen bildet sich keine Gruppe: P
Alec Teal
7
Warnung: --relocatablescheint weniger tragbar zu sein. Das mit Android NDK gelieferte ld erkennt nur -relocatable. Wenn Sie Portabilität benötigen, bleiben Sie bei -r.
Martin Bonner unterstützt Monica
3
@matthijs Das Wort ist das gleiche; Der Unterschied ist eins minus oder zwei.
Martin Bonner unterstützt Monica
1
Ah, das habe ich nicht gesehen. Das Android NDK erkennt also nur -relocatable und -r , aber nicht --relocatable. Danke fürs klarstellen!
Matthijs Kooijman
9

Wenn Sie ein Archiv mit zwei oder mehr O-Dateien (dh einer statischen Bibliothek) erstellen möchten, verwenden Sie den folgenden arBefehl:

ar rvs mylib.a file1.o file2.o

quelle
@ Lucian Aber warum willst du das tun? Eine statische Bibliothek ist viel bequemer zu verknüpfen als eine .o-Datei.
4
Ich muss objcopydie resultierende Datei ausführen und einige Arten von Symbolen lokal für die Datei erstellen, damit sie extern nicht sichtbar sind. Einige der Symbole, die lokalisiert werden müssen, werden zwischen den Dateien a.ound referenziert b.o. Ich kann einzelne Dateien nicht lokalisieren, da die Symbole zum Zeitpunkt des Linkers nicht gefunden würden, und ich kann auch keine Symbole aus dem statischen Archiv lokalisieren.
Lucian Adrian Grijincu