Wie kann ich beim Verknüpfen mit GCC nur einige bestimmte Bibliotheken statisch mit meiner Binärdatei verknüpfen?
gcc ... -static ...
versucht, alle verknüpften Bibliotheken statisch zu verknüpfen, aber ich habe nicht die statische Version einiger von ihnen (z. B. libX11).
gcc
linker
static-libraries
Peoro
quelle
quelle
Antworten:
gcc -lsome_dynamic_lib code.c some_static_lib.a
quelle
code.c
garantiert das Auflisten der statischen Bibliothek vor der Datei, dass die darin enthaltenen Symbole ignoriert werden, sofern dies nicht der Fall ist einemain()
Funktion in einer der Bibliotheksobjektdateien.Sie können auch die
ld
Option verwenden-Bdynamic
Alle Bibliotheken danach (einschließlich der von gcc automatisch verknüpften Systembibliotheken) werden dynamisch verknüpft.
quelle
Sie können auch verwenden:
-static-libgcc -static-libstdc++
Flags für gcc-BibliothekenDenken Sie daran, dass der Linker , wenn
libs1.so
undlibs1.a
beides vorhanden ist, auswählt,libs1.so
ob es vorher-Wl,-Bstatic
oder nachher ist-Wl,-Bdynamic
. Vergessen Sie nicht zu bestehen,-L/libs1-library-location/
bevor Sie anrufen-ls1
.quelle
-static
irgendwo im Befehl fehlschlägt (ich gehe davon aus, dass versucht wird, mehr Dinge statisch zu verknüpfen als nur die gewünschten Bibliotheken).-Wl,-Bstatic
und-Wl,-Bdynamic
ist wichtig.In der Manpage von
ld
(dies funktioniert nicht mit gcc) wird auf die--static
Option verwiesen:Eine Lösung besteht darin, Ihre dynamischen Abhängigkeiten vor die
--static
Option in der Befehlszeile zu stellen.Eine andere Möglichkeit besteht darin
--static
, den vollständigen Dateinamen / Pfad der statischen Objektdatei nicht zu verwenden , sondern stattdessen anzugeben (dh die Option -l nicht zu verwenden), um eine bestimmte Bibliothek statisch zu verknüpfen. Beispiel:Wie Sie im Beispiel sehen können,
libX11
befindet es sich nicht in der Liste der dynamisch verknüpften Bibliotheken, da es statisch verknüpft wurde.Achtung: Eine
.so
Datei wird immer dynamisch verknüpft, auch wenn sie mit einem vollständigen Dateinamen / Pfad angegeben ist.quelle
ldd a.out
?ldd
gibt die erforderlichen gemeinsam genutzten Bibliotheken aus und libX11 wird in dieser Liste nicht angezeigt.Das Problem, wie ich es verstehe, ist wie folgt. Sie haben mehrere Bibliotheken, einige statische, einige dynamische und einige sowohl statische als auch dynamische. Das Standardverhalten von gcc besteht darin, "meist dynamisch" zu verknüpfen. Das heißt, gcc verlinkt nach Möglichkeit auf dynamische Bibliotheken , greift aber ansonsten auf statische Bibliotheken zurück. Wenn Sie die Option -static für gcc verwenden, besteht das Verhalten darin, nur statische Bibliotheken zu verknüpfen und mit einem Fehler zu beenden , wenn keine statische Bibliothek gefunden werden kann, selbst wenn eine geeignete dynamische Bibliothek vorhanden ist.
Eine weitere Option, die ich bei verschiedenen Gelegenheiten haben wollte gcc hatte, nenne ich -meist statisch und ist im Wesentlichen das Gegenteil von -Dynamic (Standardeinstellung). -mostly-static würde, falls vorhanden, lieber eine Verknüpfung mit statischen Bibliotheken herstellen, würde jedoch auf dynamische Bibliotheken zurückgreifen.
Diese Option existiert nicht, kann jedoch mit dem folgenden Algorithmus emuliert werden:
Erstellen der Link-Befehlszeile ohne Einbeziehung von -static .
Durchlaufen Sie die dynamischen Verknüpfungsoptionen.
Akkumulieren Sie Bibliothekspfade, dh diese Optionen der Form -L <Lib_Dir> in einer Variablen <Lib_Pfad>
Führen Sie für jede Option für dynamische Verknüpfungen, dh für die Form -l <Lib -Name > , den Befehl gcc <Lib_Pfad> -print-Dateiname = lib <Lib_name> .a aus und erfassen Sie die Ausgabe.
Wenn der Befehl etwas anderes als das ausgibt, was Sie übergeben haben, ist dies der vollständige Pfad zur statischen Bibliothek. Ersetzen Sie die Option für die dynamische Bibliothek durch den vollständigen Pfad zur statischen Bibliothek.
Spülen und wiederholen, bis Sie die gesamte Link-Befehlszeile verarbeitet haben. Optional kann das Skript auch eine Liste von Bibliotheksnamen verwenden, um diese von der statischen Verknüpfung auszuschließen.
Das folgende Bash-Skript scheint den Trick zu tun:
Beispielsweise:
auf meinem System gibt zurück:
oder mit einem Ausschluss:
Ich bekomme dann:
quelle
Es gibt auch eine
-l:libstatic1.a
(minus l Doppelpunkt) Variante der Option -l in gcc, mit der die statische Bibliothek verknüpft werden kann (Dank an https://stackoverflow.com/a/20728782 ). Ist es dokumentiert? Nicht in der offiziellen Dokumentation von gcc (die auch für gemeinsam genutzte Bibliotheken nicht genau ist): https://gcc.gnu.org/onlinedocs/gcc/Link-Options.htmlDas binutils ld doc beschreibt es. Die
-lname
Option suchtlibname.so
dann nach demlibname.a
Hinzufügen des lib-Präfixes und.so
(falls derzeit aktiviert) oder nach dem.a
Suffix. Die-l:name
Option sucht jedoch nur genau nach dem angegebenen Namen: https://sourceware.org/binutils/docs/ld/Options.htmlDie Variante
-l:namespec
ist seit der Version 2.18 von binutils (2007) dokumentiert: https://sourceware.org/binutils/docs-2.18/ld/Options.htmlquelle
Einige Lader (Linker) bieten Schalter zum Ein- und Ausschalten des dynamischen Ladens. Wenn GCC auf einem solchen System (Solaris - und möglicherweise anderen) ausgeführt wird, können Sie die entsprechende Option verwenden.
Wenn Sie wissen, welche Bibliotheken Sie statisch verknüpfen möchten, können Sie einfach die statische Bibliotheksdatei in der Verknüpfungszeile angeben - über den vollständigen Pfad.
quelle
In den Link dynamische und statische Bibliothek innerhalb einer Zeile, müssen Sie statische Bibliotheken setzen nach dynamischen Bibliotheken und Objektdateien, wie folgt aus :
gcc -lssl main.o -lFooLib -o main
Andernfalls funktioniert es nicht. Ich brauche einige Zeit, um es herauszufinden.
quelle