62 Stimmen

Statische Verknüpfung unter OS X

Ich versuche, eine statische Bibliothek unter OS X zu verlinken. Ich habe die -static Flagge im gcc-Befehl, aber ich erhalte die folgende Fehlermeldung:

ld\_classic: can't locate file for: -lcrt0.o
collect2: ld returned 1 exit status

Ich habe in den Man Pages nachgeschaut und es steht dort etwas wie:

Diese Option funktioniert unter Mac OS X nur, wenn alle Bibliotheken (einschließlich libgcc.a) ebenfalls mit -static kompiliert wurden. Da weder eine statische Version von libSystem.dylib noch crt0.o zur Verfügung gestellt werden, ist diese Option für die meisten Leute nicht nützlich.

Gibt es eine andere Möglichkeit, eine Verbindung zu dieser statischen Bibliothek herzustellen?

3 Stimmen

Die blöden Apple-Dokumente empfehlen dynamisches Linken, aber sie zeigen keine ld Befehl, der dies tatsächlich tut.

55voto

Employed Russian Punkte 180738

Um auf eine Archivbibliothek (manchmal auch statische Bibliothek genannt) zu verlinken, fügen Sie sie einfach der Link-Zeile hinzu:

gcc main.o ... -lfoo ...

Der Linker sucht nach libfoo.dylib und dann nach libfoo.a, was alles ist, was Sie brauchen.

Wenn Sie eine beide Versionen der Bibliothek haben und mit einer Archivversion anstelle der dynamischen Version linken wollen, geben Sie einfach den vollständigen Pfad zum Archiv in der Linkzeile an:

gcc main.o ... /path/to/libfoo.a ...

22voto

Michael Chinen Punkte 16097

Ein häufiger Fall ist statische Verknüpfung mit einer dritten Benutzerbibliothek bei gleichzeitiger dynamischer Verknüpfung mit den System-Frameworks und Bibliotheken, so dass Ihre Benutzer keine Bibliotheken von Drittanbietern installieren müssen, bevor sie Ihr Programm verwenden. Wenn die Bibliothek dynamisch gegen Frameworks gelinkt ist (was oft der Fall ist), kann sie immer noch mit einer statischen .a ausgeliefert werden, aber es reicht nicht aus, nur die -l<libname> con /path/to/libname.a weil die .a-Datei die Abhängigkeiten nicht enthalten wird. Sie müssen auch dynamisch gegen die Frameworks linken, die Ihre Bibliothek verwendet hat.

Nehmen wir an, Sie wollen ein Programm schreiben, das die Open-Source-Libusb verwendet, ohne dass der Benutzer die Libusb herunterladen und installieren muss. Nehmen wir an, Sie haben eine dynamisch gelinkte Binärdatei, die Sie mit dieser erstellt haben:

clang -lusb-1.0 main.c -o myprogram

Um unter OS X statisch zu linken, sieht der Befehl wie folgt aus (beachten Sie das -framework Argumente):

clang -framework CoreFoundation -framework IOKit main.c /path/to/libusb-1.0.a -o myprogram

Um herauszufinden, welche System-Frameworks und -Bibliotheken Sie hinzufügen müssen, sehen Sie sich die Drittanbieter-Dylib mit otool an:

otool -L /usr/local/opt/libusb/lib/libusb-1.0.0.dylib

die zeigt:

/usr/local/opt/libusb/lib/libusb-1.0.0.dylib:
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1348.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)  

Sie können damit beginnen, die Frameworks hinzuzufügen, gefolgt von den Bibliotheken, eine nach der anderen, und Sie werden sehen, dass die Liste der undefinierten Referenzfehler kleiner wird. Beachten Sie, dass Sie wahrscheinlich nicht jede Bibliothek hinzufügen müssen, da einige als Abhängigkeiten für die von Ihnen explizit hinzugefügten Bibliotheken geladen werden können.

Wenn Sie nicht sicher sind, wo die Dylib existiert, erstellen Sie Ihr Programm auf die ursprüngliche dynamische Weise (mit -lusb-1.0) und führen Sie otool darauf aus:

clang -lusb-1.0 main.c -o myprogram
otool -L myprogram

das ergibt:

myprogram:
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)

Lesen Sie auch die Lizenz der Bibliothek, auf die Sie verlinken wollen.

20voto

alecco Punkte 2804

Bedauerlicherweise, es wird nicht unterstützt . Einige Leute berichteten, es sei möglich, crt0 manuell zu kompilieren, aber niemand bestätigt es .

9voto

atrens Punkte 99

-Bstatic scheint unter OS-X Lion ein No-op zu sein - verwendet gcc -v um dies zu bestätigen.

2voto

Zhi Q. Punkte 61

Ich bin auf das gleiche Problem gestoßen. Hier ist ein Beispiel, um zu arbeiten:

SCHRITT1: Dateien erstellen

myfunc1.c:

#include <stdio.h>

void myfunc1() {
    printf( "This is my func1!\n" );
}

myfunc2.c:

#include <stdio.h>

void myfunc2() {
    printf( "This is my func2!\n" );
}

und myfunc.c:

#include <stdio.h>

void myfunc1( void );
void myfunc2( void );

int main() {
    myfunc1();
    myfunc2();
    return 0;
}

SCHRITT 2: Erstellen der Lib

gcc -c myfunc1.c myfunc2.c

ar -r libmyfuncs.a myfunc1.o myfunc2.o

SCHRITT3: Link

gcc -o myfunc -L. myfunc.c -lmyfuncs 

Vergessen Sie nicht, "-L." einzugeben; der Punkt gibt den aktuellen Pfad an.

Ich hoffe, das hilft.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X