2010-09-12 8 views
18

Ich habe ein Makefile für Linux, das ich nach Darwin portiere. Das Makefile nimmt eine Reihe von .o-Dateien und verbindet sie zu einem .so-Objekt. Okay, also dachte ich (liege ich falsch?), Dass das beste Analog in Darwin das Dylib ist. Also habe ich das Flag -shared in -dynamiclib geändert.Was ist der Deal mit undefinierten Symbolen in einer gemeinsam genutzten Bibliothek oder Dylib?

Nun hängt der Code, den ich in der Dylib zusammen bin, von vielen externen Bibliotheken ab. Wenn ich versuche, die Dylib zu erstellen, bekomme ich Fehler, die sagen, dass es nicht definierte Referenzen gibt. Das Linux-Makefile gibt jedoch keine der Optionen -lwhatever oder -L/path/whatever im Build-Schritt an, der die .so-Datei erstellt. Hm? Liegt das daran, dass beim Erstellen einer ELF-.so-Datei standardmäßig externe Referenzen nicht aufgelöst werden und dann beim Laden der gemeinsam genutzten Bibliothek rekursiv gemeinsam genutzte Bibliotheken lädt, die von der gemeinsam genutzten Bibliothek abhängen, die Sie laden? Wäre es nicht so, dass wenn die shared library von einer .a oder .o Datei abhängt, Sie diese statisch in die shared library einbinden müssten, sonst könnten Sie zur Laufzeit nicht verlinken? Wie kommt man mit undefinierten Referenzen in einer Bibliothek, die zur Laufzeit geladen wird, außer die Verweise sind auch auf dynamisch ladbare Bibliotheken? Wie dem auch sei

so, wenn ich angeben

-undefined suppress -flat_namespace 

es mich nicht verlangen, um die -l und -L Optionen hinzuzufügen, wenn die gemeinsame Bibliothek zu schaffen. Aber ich verstehe immer noch nicht, wie das letztendlich funktionieren kann.

Antwort

1

Verwenden Sie libtool.

libtool -dynamic -multiply_defined suppress -install_name `basename ../../../../rlp/lib/universal-darwin9-gcc40/libbtutils.dylib` -o ../../../../rlp/lib/universal-darwin9-gcc40/libbtutils.dylib ../../../../rlp/lib/universal-darwin9-gcc40/libbtd.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttrie.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtkey.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtunit.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtutilities.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtopts.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtxcode.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtprops.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtxml.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttake3.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttake5.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtac.a -lstdc++.6 -lgcc_s.10.4 ../../../../build_system/lib/universal-darwin9-gcc40/libgcc.a -lSystem -lSystemStubs` 
+1

Danke, ich denke, das wird funktionieren, aber ich bin auch interessiert an dem Hintergrund hinter dem, was passiert. – eeeeaaii

+0

MacOS ist nicht ganz Linux. Es ist schließlich ursprünglich NextOS. Der Linker ist ein bisschen exzentrisch. Fügen Sie -v dem Libtool hinzu und es wird Ihnen sagen, was es macht. – bmargulies

13

This thread diskutiert auch dieses Problem. Ich denke, der entscheidende Punkt ist, dass Sie das Flag "-undefined dynamic_lookup" angeben müssen, um das Linux-ähnliche Verknüpfungsverhalten zu erhalten. Standardmäßig gibt der Darwin-Linker einen Fehler aus, wenn in einer dynamischen Bibliothek nicht definierte Verweise vorhanden sind. Sie können auch -U verwenden, um dieses Verhalten für jedes Symbol festzulegen. Siehe 'man ld' als Referenz.