2009-09-27 12 views
13

Ho un programma (in particolare la mia voce per il SO DevDays Countdown app challenge) che si basa su diverse librerie dinamiche, vale a dire libSDL, libSDL_ttf e altri. Ho queste librerie installate sotto /opt/local/lib tramite MacPorts, e molte persone non le hanno installate (e alcune potrebbero averle installate, ma non in quella posizione).Come distribuire un Mac OS X con librerie dipendenti?

Come distribuire il mio programma in modo che le persone senza queste librerie installate possano eseguirlo immediatamente? Ovviamente dovrò distribuire i vari file .dylib, ma farlo non è sufficiente. Il caricatore dinamico cerca ancora le librerie installate nei luoghi in cui le ho installate. C'è un modo per dire al caricatore dinamico di cercare nella directory corrente dell'eseguibile, come quello che fa Windows con le DLL? Le persone non dovrebbero dover modificare alcuna variabile di ambiente (ad esempio DYLD_LIBRARY_PATH), poiché ancora una volta voglio che funzioni correttamente.

risposta

5

Come hai detto, non stai usando Xcode, quindi è un po 'difficile. Ecco le opzioni in mio ordine di preferenza:

  1. Passare a Xcode. Usa quadri. Le librerie SDL sono già disponibili come framework e ho visto più di un paio di giochi commerciali con un libsdl.framework all'interno del pacchetto dell'app.

  2. Utilizzare i framework, ma conservare i Makefile. Scarica le versioni del framework delle tue librerie SDL (o creale tu stesso) e collega con loro con il flag del linkframework. Distribuisci i framework con la tua app o non, e comunica ai tuoi utenti di metterli in ~/Library/Frameworks o in/Library/Frameworks. Non mi preoccuperei di un programma di installazione per questo.

  3. Collegamento statico a SDL. Nel Makefile, dovrai elencare il percorso delle librerie statiche piuttosto che usare il flag -l, ad esempio, esegui "ld blah blah /opt/local/lib/libsdl.a". Non c'è modo che io sappia dire -l preferire le librerie statiche rispetto alle librerie condivise, e credimi, ho cercato.

+0

Dopo averci pensato, penso che sto andando con il collegamento statico per la distribuzione. Se distribuirò comunque le librerie dinamiche, ciò vanifica molti degli scopi del loro utilizzo, quindi potrei anche evitare di affrontare il problema con il caricatore dinamico. –

+1

4. usando l'opzione 2. sopra, posiziona i framework all'interno del tuo .app bundle (file .dmg) e cambia i percorsi eseguibili con install_name_tool. Ecco alcuni esempi di come viene utilizzato install_name_tool: http://qt-project.org/doc/qt-4.8/deployment-mac.html. Dietrich, potresti inserire questo nella tua risposta per favore? –

+0

@ MilanBabuškov: Sembra che questo sia già incorporato nella risposta qui sotto. Non vedo la necessità di duplicare le informazioni. –

3

Collegamento statico delle librerie.

+0

Questo per il riutilizzo del codice. –

+6

Le librerie collegate staticamente contano come "riutilizzo del codice", poiché il codice della libreria deve ancora essere scritto/testato/debuggato una sola volta, indipendentemente dal numero di applicazioni che ne fanno uso. Anche se è vero che più copie del codice compilato possono finire sul disco dell'utente, non è un grosso problema come in passato, visto che i dischi rigidi sono così grandi. –

13

L'approccio di base è spedirli nel pacchetto .app. Quindi modificherete la posizione in cui il linker cerca le librerie condivise per includerle.

I passi sono:

  1. Creare un nuovo file di copia costruire fase al vostro obiettivo che copia i file nella directory quadri del bundle .app.

  2. Modificare la configurazione di generazione impostazione "RunPath Percorsi di ricerca" per includere @executable_path/../Frameworks

Se costruisci il tuo eseguibile con questi cambiamenti e poi guardare, si dovrebbe trovare che le dylibs esistono nella directory Foo.app/Contents/Framework e funzionante otool -L Foo.app/Contents/MacOS/Foo dovrebbe produrre e inserire prefisso da @rpath per quei dylibs.

Da questo Cocoabuilder post:

In generale, è preferibile rispetto @loader_path@executable_path, come
permette quadri di lavorare sia in un eseguibile e un fascio,
di plugin, o sub-framework embedded. L'unico lato negativo è che @loader_path
richiede 10.4 o più recente. Se hai 10.5 o più recente, @rpath è pari a
meglio di @loader_path.

+0

Non sto usando Xcode (no .app bundle), semplicemente vecchio gcc e make. Sto anche usando OS X 10.4; secondo http://developer.apple.com/it/mac/library/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html, i percorsi di ricerca del runpath sono supportati solo su 10.5 e successivi. –

+1

Credo che @executable_path funzionerà anche su 10.4 (@loader_path e @rpath non lo faranno). Si potrebbe anche leggere questo: http://blog.onesadcookie.com/2008/01/installname-magic.html – nall

+0

Se non si utilizza Xcode, la soluzione migliore potrebbe essere quella di utilizzare Autotools e amici. –