2010-10-17 8 views
6

Sto scrivendo un eseguibile che utilizza dlopen() (LoadLibrary() su Windows) per caricare dinamicamente una libreria condivisa. La libreria condivisa utilizza i simboli dell'eseguibile.Mac: come esportare i simboli da un file eseguibile?

In Windows questo è possibile. I file eseguibili possono esportare simboli: i file declspec (dllexport) e .def funzionano entrambi. Il linker, quando crea l'exe, crea anche il file .lib (la "libreria di importazione"), quindi la DLL deve solo collegarsi a quel .lib.

In Linux, questo è anche possibile. Passo -Wl, -export_dynamic quando costruisci l'eseguibile in modo che esporti i suoi simboli.

In Mac OS X, invece ... -Wl, -export_dynamic non funziona, ma c'è -Wl, -exported_symbols_list, <filename> dove <filename> è un elenco di simboli per esportare (una sorta di una versione più semplice di un .def file). Ma poi, costruire la libreria condivisa non è così facile: il linker si lamenta dei simboli irrisolti.

Ho provato un hack: rinominato l'eseguibile in lib <executable> .dylib e, quando collegavo la libreria condivisa, ho passato -l <executable>. Ma dà l'errore "non può collegarsi con un eseguibile principale".

Il problema generale è che le librerie condivise Linux possono avere simboli non risolti, mentre Windows e Mac OS X non lo consentono. Ma Windows ha "librerie di importazione" per risolvere i simboli contro le dipendenze, e Mac OS X apparentemente non ...

Come può essere risolto su Mac OS X? Esiste un equivalente di una "libreria di importazione" (la libreria stub creata dal linker di Windows durante la creazione di un file .dll, quindi, se qualsiasi modulo deve collegarsi dinamicamente al file .dll, è collegato alla "libreria di importazione")? O qualche altra soluzione?

risposta

5

L'interprete standalone Lua supporta il caricamento dinamico (tramite dlopen) di librerie condivise che utilizzano simboli dell'eseguibile (l'API Lua). Nessun flag di collegamento speciale viene utilizzato durante la costruzione. Le librerie condivise sono costruiti utilizzando questa formula magica:

env MACOSX_DEPLOYMENT_TARGET=10.3 gcc -bundle -undefined dynamic_lookup -o random.so lrandom.o 
+1

BTW, "env MACOSX_DEPLOYMENT_TARGET = 10.3" non è necessario per 10.5 e versioni successive. – lhf

4

Grazie, la tua risposta stimolato il desiderio di indagare la differenza tra fasci e dylibs. E pagina di manuale di ld citato un'opzione chiamata -bundle_loader

-bundle_loader eseguibile
Questo specifica l'eseguibile che verrà caricando il file di output fascio essendo legata. I simboli non definiti del pacchetto vengono confrontati con l'eseguibile specificato come se fosse uno delle librerie dinamiche con cui il pacchetto era collegato.

(notare che -bundle_loader fallisce quando si costruisce una dylib, funziona solo con fasci) Così la vecchia linea di comando

cc -shared -o <output>.so <input>.c 

è stato trasformato in

cc -bundle -bundle_loader <executable> -o <output>.so <input>.c 

e il fascio di uscita risolto i suoi simboli indefiniti contro quelli dell'eseguibile.