2009-09-27 7 views
13

J'ai un programme (spécifiquement mon entrée pour le SO DevDays Countdown app challenge) qui repose sur plusieurs bibliothèques dynamiques, à savoir libSDL, libSDL_ttf, et autres. J'ai ces bibliothèques installées sous /opt/local/lib via MacPorts, et beaucoup de gens ne les auront pas installés (et certains pourraient les avoir installés, mais pas à cet endroit).Comment distribuer un Mac OS X avec des bibliothèques dépendantes?

Comment puis-je distribuer mon programme afin que les personnes sans ces bibliothèques installées puissent le lancer immédiatement? Évidemment, je vais devoir distribuer les différents fichiers .dylib, mais cela est insuffisant. Le chargeur dynamique recherche toujours les bibliothèques installées aux emplacements où je les ai installés. Existe-t-il un moyen de dire au chargeur dynamique de regarder dans le répertoire courant de l'exécutable, comme ce que Windows fait avec les DLL? Les utilisateurs ne devraient pas avoir à modifier les variables d'environnement (par exemple, DYLD_LIBRARY_PATH), car je souhaite à nouveau que cela fonctionne correctement.

Répondre

5

Comme vous l'avez mentionné, vous n'utilisez pas Xcode, donc c'est un peu difficile. Voici les options dans mon ordre de préférence:

  1. Passez à Xcode. Utiliser des cadres. Les bibliothèques SDL sont déjà disponibles en tant que frameworks, et j'ai vu plus de quelques jeux commerciaux avec un libsdl.framework dans le bundle de l'application.

  2. Utilisez des cadres, mais conservez vos fichiers Makefile. Téléchargez les versions du framework de vos bibliothèques SDL (ou créez-les vous-même), et créez un lien avec elles avec l'indicateur -framework linker. Distribuez les frameworks avec votre application ou non, et dites à vos utilisateurs de les placer dans ~/Library/Frameworks ou dans/Library/Frameworks. Je ne voudrais pas déranger avec un installateur pour cela.

  3. Lien statique avec le langage SDL. Dans le Makefile, vous devrez lister le chemin des bibliothèques statiques plutôt que d'utiliser l'indicateur -l, par exemple, vous exécutez "ld blah blah /opt/local/lib/libsdl.a". Il n'y a aucun moyen que je sache dire de préférer les bibliothèques statiques aux bibliothèques partagées, et croyez-moi, j'ai regardé.

+0

Après y avoir réfléchi, je pense que je vais aller avec la liaison statique pour la distribution. Si je distribue les librairies dynamiques de toute façon, cela va à l'encontre de plusieurs des objectifs de leur utilisation, aussi évite-t-on d'avoir mal avec le chargeur dynamique. –

+1

4. en utilisant l'option 2. ci-dessus, placez les frameworks dans votre bundle .app (fichier .dmg) et modifiez les chemins des chemins exécutables avec install_name_tool. Voici quelques exemples d'utilisation de install_name_tool: http://qt-project.org/doc/qt-4.8/deployment-mac.html. Dietrich, pourriez-vous incorporer cela dans votre réponse s'il vous plaît? –

+0

@ MilanBabuškov: Il semble que cela soit déjà incorporé dans la réponse ci-dessous. Je ne vois aucun besoin de dupliquer l'information. –

3

Lier statiquement les bibliothèques.

+0

Tellement pour la réutilisation de code. –

+6

Les bibliothèques liées statiquement comptent comme «réutilisation de code», puisque le code de la bibliothèque doit encore être écrit/testé/débogué une seule fois, quel que soit le nombre d'applications qui l'utilisent. Même s'il est vrai que plusieurs copies du code compilé peuvent se retrouver sur le disque de l'utilisateur, ce n'est pas un gros problème comme c'était le cas maintenant que les disques durs sont si gros. –

13

L'approche de base à ceci est de les expédier dans le paquet .app. Vous allez ensuite modifier l'emplacement que l'éditeur de liens recherche dans les bibliothèques partagées pour l'inclure.

Les étapes sont les suivantes:

  1. Créer une nouvelle copie de fichiers construire la phase à votre cible qui copie les fichiers dans le répertoire cadres du faisceau .app.

  2. Modifier la configuration de construction réglage « RUNPATH Chemins de recherche » pour inclure @executable_path/../Frameworks

Si vous construisez votre exécutable avec ces modifications et regardez, vous devriez trouver que les dylibs existent dans le répertoire Foo.app/Contents/Framework et le fonctionnement otool -L Foo.app/Contents/MacOS/Foo devrait donner et l'entrée préfixée par @rpath pour ces dylibs.

De cette Cocoabuilder post:

En général, on préfère @loader_path plus @executable_path, car il permet
intégré des cadres de travailler en un exécutable et un paquet,
plug-in ou sous-cadre. Le seul inconvénient est que @loader_path
nécessite 10.4 ou plus récent. Si vous êtes sur 10.5 ou plus récent, @rpath est même
mieux que @loader_path.

+0

Je n'utilise pas Xcode (pas de bundle .app), tout simplement vieux gcc et make. J'utilise aussi OS X 10.4; selon http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html, les chemins de recherche runpath ne sont pris en charge que sur 10.5 et plus. –

+1

Je crois que @executable_path fonctionnera même sur 10.4 (@loader_path et @rpath ne le feront pas). Vous pouvez également lire ceci: http://blog.onesadcookie.com/2008/01/installname-magic.html – nall

+0

Si vous n'utilisez pas Xcode, le mieux est d'utiliser Autotools et vos amis. –