Il existe deux façons de créer un bundle d'applications sur MacOSX, le Easy et le Ugly.
Le moyen le plus simple consiste simplement à utiliser XCode. Terminé.
Le problème est que parfois vous ne pouvez pas.
Dans mon cas, je construis une application qui crée d'autres applications. Je ne peux pas supposer que l'utilisateur a installé XCode. J'utilise également MacPorts pour créer les bibliothèques dont dépend mon application. Je dois m'assurer que ces dylibs sont fournis avec l'application avant de la distribuer.
Clause de non-responsabilité: je ne suis absolument pas qualifié pour écrire cet article, tout ce qu'il contient a été lu dans les documents Apple, en sélectionnant les applications existantes et les essais et erreurs. Cela fonctionne pour moi, mais c'est probablement faux. Veuillez m'envoyer un courriel si vous avez des corrections.
La première chose que vous devez savoir est qu'un bundle d'applications n'est qu'un répertoire.
Examinons la structure d'un hypothétique foo.app.
foo.app/
Contenu/
Info.plist
MacOS /
toto
Ressources/
foo.icns
Info.plist est un simple fichier XML. Vous pouvez le modifier avec un éditeur de texte ou l'application Property List Editor fournie avec XCode. (Il se trouve dans le répertoire / Developer / Applications / Utilities /).
Les éléments clés que vous devez inclure sont:
CFBundleName - Le nom de l'application.
CFBundleIcon - Un fichier Icon supposé être dans le répertoire Contents / Resources. Utilisez l'application Icon Composer pour créer l'icône. (Il se trouve également dans le répertoire / Developer / Applications / Utilities /) Vous pouvez simplement faire glisser et déposer un png sur sa fenêtre et devrait générer automatiquement les niveaux mip pour vous.
CFBundleExecutable - Nom du fichier exécutable supposé se trouver dans le sous-dossier Contents / MacOS /.
Il y a beaucoup plus d'options, celles énumérées ci-dessus ne sont que le strict minimum. Voici une documentation Apple sur le
fichier Info.plist et la
structure du bundle App .
En outre, voici un exemple d'Info.plist.
<? xml version = "1.0" encoding = "UTF-8"?>
<! DOCTYPE plist PUBLIC "- // Apple Computer // DTD PLIST 1.0 // EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version = "1.0">
<dict>
<key> CFBundleGetInfoString </key>
<string> Foo </string>
<key> CFBundleExecutable </key>
<string> toto </string>
<key> CFBundleIdentifier </key>
<string> com.your-company-name.www </string>
<key> CFBundleName </key>
<string> toto </string>
<key> CFBundleIconFile </key>
<string> foo.icns </string>
<key> CFBundleShortVersionString </key>
<string> 0.01 </string>
<key> CFBundleInfoDictionaryVersion </key>
<string> 6.0 </string>
<key> CFBundlePackageType </key>
<string> APPL </string>
<key> IFMajorVersion </key>
<integer> 0 </integer>
<key> IFMinorVersion </key>
<integer> 1 </integer>
</dict>
</plist>
Dans un monde parfait, vous pouvez simplement déposer votre exécutable dans le répertoire Contents / MacOS / et c'est terminé. Cependant, si votre application a des dépendances dylib non standard, cela ne fonctionnera pas. Comme Windows, MacOS est livré avec son propre type spécial de DLL Hell .
Si vous utilisez MacPorts pour créer des bibliothèques avec lesquelles vous liez, les emplacements des dylibs seront codés en dur dans votre exécutable. Si vous exécutez l'application sur une machine qui a les dylibs exactement au même endroit, elle fonctionnera correctement. Cependant, la plupart des utilisateurs ne les auront pas installés; quand ils double-cliquent sur votre application, cela plante.
Avant de distribuer votre exécutable, vous devrez collecter toutes les dylibs qu'il charge et les copier dans le bundle d'applications. Vous devrez également éditer l'exécutable pour qu'il recherche les dylibs au bon endroit. c'est à dire où vous les avez copiés.
L'édition manuelle d'un exécutable semble dangereuse, non? Heureusement, il existe des outils de ligne de commande pour vous aider.
otool -L nom_exécutable
Cette commande répertorie tous les dylibs dont dépend votre application. Si vous en voyez qui ne sont PAS dans le dossier System / Library ou usr / lib, ce sont ceux que vous devrez copier dans le bundle d'applications. Copiez-les dans le dossier / Contents / MacOS /. Ensuite, vous devrez éditer l'exécutable pour utiliser les nouveaux dylibs.
Tout d'abord, vous devez vous assurer que vous liez à l'aide de l'indicateur -headerpad_max_install_names. Cela garantit simplement que si le nouveau chemin dylib est plus long que le précédent, il y aura de la place pour cela.
Deuxièmement, utilisez l'outil nom_installation_tool pour modifier chaque chemin dylib.
outil_nom_installation -modifier le chemin_existant_à_dylib @ chemin_exécutable / blah.dylib nom_exécutable
À titre d'exemple pratique, disons que votre application utilise libSDL et que otool répertorie son emplacement sous la forme "/opt/local/lib/libSDL-1.2.0.dylib".
Copiez-le d'abord dans le bundle d'applications.
cp /opt/local/lib/libSDL-1.2.0.dylib foo.app/Contents/MacOS/
Modifiez ensuite l'exécutable pour utiliser le nouvel emplacement (REMARQUE: assurez-vous de l'avoir créé avec l'indicateur -headerpad_max_install_names)
outil_nom_installation -change /opt/local/lib/libSDL-1.2.0.dylib @ chemin_exécutable / libSDL-1.2.0.dylib foo.app/Contents/MacOS/foo
Ouf, nous avons presque fini. Il y a maintenant un petit problème avec le répertoire de travail actuel.
Lorsque vous démarrez votre application, le répertoire actuel sera le répertoire ci-dessus où se trouve l'application. Par exemple: si vous placez le fichier foo.app dans le dossier / Applcations, le répertoire actuel lorsque vous lancerez l'application sera le dossier / Applications. Pas le /Applications/foo.app/Contents/MacOS/ comme vous vous en doutez.
Vous pouvez modifier votre application pour en tenir compte, ou vous pouvez utiliser ce petit script de lancement magique qui changera le répertoire actuel et lancera votre application.
#! / bin / bash
cd "$ {0% / *}"
./foo
Assurez-vous d'ajuster le fichier Info.plist afin que CFBundleExecutable pointe vers le script de lancement et non vers l'exécutable précédent.
Ok, tout est fait maintenant. Heureusement, une fois que vous connaissez tout cela, vous les enterrez dans un script de construction.