Sie benötigen die statische Version der Bibliothek, um sie zu verknüpfen.
Eine gemeinsam genutzte Bibliothek ist eine ausführbare Datei in einem speziellen Format mit angegebenen Einstiegspunkten (und einigen Problemen bei der Adressierung). Es verfügt nicht über alle Informationen, die für eine statische Verknüpfung erforderlich sind.
Sie können eine gemeinsam genutzte Bibliothek nicht statisch verknüpfen (oder eine statische Bibliothek dynamisch verknüpfen).
Das Flag -staticzwingt den Linker, statische Bibliotheken (.a) anstelle von gemeinsam genutzten (.so) zu verwenden. Da statische Bibliotheken jedoch nicht immer standardmäßig installiert sind, müssen Sie die statische Bibliothek möglicherweise selbst installieren.
Ein anderer möglicher Ansatz ist die Verwendung von Statifier oder Hermelin . Beide Tools verwenden als Eingabe eine dynamisch verknüpfte ausführbare Datei und erstellen als Ausgabe eine in sich geschlossene ausführbare Datei, in die alle gemeinsam genutzten Bibliotheken eingebettet sind.
Gibt es nicht eine Möglichkeit, gcc direkt mitzuteilen, was statisch verknüpft werden soll, und ihn nicht zu umgehen und mit dem Linker zu sprechen?
Elazar Leibovich
1
@ElazarLeibovich Sie können auf diese Weise keine Kombination aus statisch und dynamisch erhalten.
Haozhun
@ EugeneBujak: Die Einschränkung gilt nicht für mein System. Beispiel: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L.libB verwendet libA , ist verknüpft und lddzeigt keinen Verweis auf libA an . Die ausführbare Datei funktioniert einwandfrei. Getestet mit g ++ 4.7.3.
Radix
Eine indirekte (verschachtelte) statische Abhängigkeit einer direkten, dynamischen Abhängigkeit wird selbst nicht dynamisch verknüpft.
Vinny
Beachten Sie Folgendes: binA hängt von libB.so ab, was von libC.a abhängt. Wie andere bereits angegeben haben, sind .so selbst ausführbare Dateien. Wenn also ein freigegebenes Objekt verknüpft wird, werden alle statischen Bibliotheksabhängigen vom Linker ähnlich verarbeitet, als ob Eine ausführbare Datei wurde verknüpft: Die einzigen Symbole, die aus der statischen .a-Bibliothek abgerufen werden, sind diejenigen, auf die die .so verweist (und die nicht aufgelöst werden). Dies bedeutet, dass wenn binA auf ein Symbol in libC.a verweist, auf das in libB.so nirgendwo verwiesen wird, dieses Symbol auch dann nicht definiert ist, wenn binA auf libB.so verweist (es sei denn, -Wl, - wird beim Verknüpfen das gesamte Archiv verwendet libB.so).
Vinny
18
Wenn Sie die .a-Datei Ihrer gemeinsam genutzten Bibliothek (.so) haben, können Sie sie einfach in ihren vollständigen Pfad einfügen, als wäre es eine Objektdatei, wie folgt:
Dies erzeugt main.o durch einfaches Kompilieren:
gcc -c main.c
Dadurch wird diese Objektdatei mit der entsprechenden statischen Bibliothek verknüpft und die ausführbare Datei (mit dem Namen "main") erstellt:
gcc main.o mylibrary.a -o main
Oder in einem einzigen Befehl:
gcc main.c mylibrary.a -o main
Es könnte auch ein absoluter oder relativer Pfad sein:
Ja, ich weiß, dass dies eine 8 Jahre alte Frage ist, aber mir wurde gesagt, dass es möglich ist, eine statische Verknüpfung mit einer Bibliothek mit gemeinsam genutzten Objekten herzustellen, und dies war buchstäblich der Top-Hit, als ich nach weiteren Informationen darüber suchte.
Verwenden Sie den folgenden Befehl, um zu demonstrieren, dass das statische Verknüpfen einer Bibliothek mit gemeinsam genutzten Objekten mit ld( gcc's Linker) nicht möglich ist - im Gegensatz zu nur einer Gruppe von Personen, die darauf bestehen, dass dies nicht möglich ist gcc:
(Natürlich müssen Sie objectname.oaus kompilieren sourcename.c, und Sie sollten wahrscheinlich auch Ihre eigene Bibliothek für gemeinsam genutzte Objekte erstellen . Wenn Sie dies tun, verwenden Sie -Wl,--library-path,.diese Option , damit ld Ihre Bibliothek im lokalen Verzeichnis finden kann.)
Der tatsächliche Fehler, den Sie erhalten, ist:
/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status
Ein bisschen spät, aber ... Ich habe einen Link gefunden, den ich vor ein paar Jahren gespeichert habe, und ich dachte, er könnte für euch nützlich sein:
CDE: Erstellen Sie automatisch tragbare Linux-Anwendungen
Führen Sie die Binärdatei aus, indem Sie als Argument den Namen der Binärdatei übergeben, die portabel gemacht werden soll, z. B. nmap
./cde_2011-08-15_64bit nmap
Das Programm liest alle mit nmap und seinen Abhängigkeiten verknüpften Bibliotheken und speichert sie alle in einem Ordner namens cde-package / (in demselben Verzeichnis wie Sie).
Schließlich können Sie den Ordner komprimieren und die tragbare Binärdatei in einem beliebigen System bereitstellen.
Denken Sie daran, um das tragbare Programm zu starten, müssen Sie die Binärdatei in cde-package / nmap.cde ausführen
Antworten:
Beziehen auf:
http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/
http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html
Sie benötigen die statische Version der Bibliothek, um sie zu verknüpfen.
Eine gemeinsam genutzte Bibliothek ist eine ausführbare Datei in einem speziellen Format mit angegebenen Einstiegspunkten (und einigen Problemen bei der Adressierung). Es verfügt nicht über alle Informationen, die für eine statische Verknüpfung erforderlich sind.
Sie können eine gemeinsam genutzte Bibliothek nicht statisch verknüpfen (oder eine statische Bibliothek dynamisch verknüpfen).
Das Flag
-static
zwingt den Linker, statische Bibliotheken (.a) anstelle von gemeinsam genutzten (.so) zu verwenden. Da statische Bibliotheken jedoch nicht immer standardmäßig installiert sind, müssen Sie die statische Bibliothek möglicherweise selbst installieren.Ein anderer möglicher Ansatz ist die Verwendung von Statifier oder Hermelin . Beide Tools verwenden als Eingabe eine dynamisch verknüpfte ausführbare Datei und erstellen als Ausgabe eine in sich geschlossene ausführbare Datei, in die alle gemeinsam genutzten Bibliotheken eingebettet sind.
quelle
Wenn Sie beispielsweise libapplejuice statisch verknüpfen möchten , aber nicht liborangejuice , können Sie Folgendes verknüpfen:
Es gibt eine Einschränkung - wenn
liborangejuice
verwendetlibapplejuice
,libapplejuice
wird auch dynamisch verknüpft.Sie müssen
liborangejuice
statisch mit verknüpfenlibapplejuice
, umlibapplejuice
statisch zu werden.Und vergessen
-Wl,-Bdynamic
Sie nicht , alles zu behalten, sonst verknüpfen Sie am Ende alles Statische, einschließlichlibc
(was nicht gut ist).quelle
gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L.
libB verwendet libA , ist verknüpft undldd
zeigt keinen Verweis auf libA an . Die ausführbare Datei funktioniert einwandfrei. Getestet mit g ++ 4.7.3.Wenn Sie die .a-Datei Ihrer gemeinsam genutzten Bibliothek (.so) haben, können Sie sie einfach in ihren vollständigen Pfad einfügen, als wäre es eine Objektdatei, wie folgt:
Dies erzeugt main.o durch einfaches Kompilieren:
Dadurch wird diese Objektdatei mit der entsprechenden statischen Bibliothek verknüpft und die ausführbare Datei (mit dem Namen "main") erstellt:
Oder in einem einzigen Befehl:
Es könnte auch ein absoluter oder relativer Pfad sein:
quelle
Ja, ich weiß, dass dies eine 8 Jahre alte Frage ist, aber mir wurde gesagt, dass es möglich ist, eine statische Verknüpfung mit einer Bibliothek mit gemeinsam genutzten Objekten herzustellen, und dies war buchstäblich der Top-Hit, als ich nach weiteren Informationen darüber suchte.
Verwenden Sie den folgenden Befehl, um zu demonstrieren, dass das statische Verknüpfen einer Bibliothek mit gemeinsam genutzten Objekten mit
ld
(gcc
's Linker) nicht möglich ist - im Gegensatz zu nur einer Gruppe von Personen, die darauf bestehen, dass dies nicht möglich istgcc
:(Natürlich müssen Sie
objectname.o
aus kompilierensourcename.c
, und Sie sollten wahrscheinlich auch Ihre eigene Bibliothek für gemeinsam genutzte Objekte erstellen . Wenn Sie dies tun, verwenden Sie-Wl,--library-path,.
diese Option , damit ld Ihre Bibliothek im lokalen Verzeichnis finden kann.)Der tatsächliche Fehler, den Sie erhalten, ist:
Hoffentlich hilft das.
quelle
Ein bisschen spät, aber ... Ich habe einen Link gefunden, den ich vor ein paar Jahren gespeichert habe, und ich dachte, er könnte für euch nützlich sein:
CDE: Erstellen Sie automatisch tragbare Linux-Anwendungen
http://www.pgbovine.net/cde.html
Führen Sie die Binärdatei aus, indem Sie als Argument den Namen der Binärdatei übergeben, die portabel gemacht werden soll, z. B. nmap
./cde_2011-08-15_64bit nmap
Das Programm liest alle mit nmap und seinen Abhängigkeiten verknüpften Bibliotheken und speichert sie alle in einem Ordner namens cde-package / (in demselben Verzeichnis wie Sie).
Denken Sie daran, um das tragbare Programm zu starten, müssen Sie die Binärdatei in cde-package / nmap.cde ausführen
Freundliche Grüße
quelle
In gcc wird dies nicht unterstützt. Tatsächlich wird dies in keinem mir bekannten Compiler / Linker unterstützt.
quelle