Es gibt zwei Möglichkeiten, ein App-Bundle unter MacOSX zu erstellen: Easy und Ugly.
Der einfache Weg ist, einfach XCode zu verwenden. Getan.
Das Problem ist manchmal, dass Sie nicht können.
In meinem Fall erstelle ich eine App, die andere Apps erstellt. Ich kann nicht davon ausgehen, dass der Benutzer XCode installiert hat. Ich verwende auch MacPorts , um die Bibliotheken zu erstellen, von denen meine App abhängt. Ich muss sicherstellen, dass diese Dylibs mit der App gebündelt werden, bevor ich sie verteile.
Haftungsausschluss: Ich bin völlig unqualifiziert, diesen Beitrag zu schreiben. Alles, was darin enthalten ist, wurde aus Apple-Dokumenten hervorgegangen, wobei vorhandene Apps und Versuche und Irrtümer auseinander genommen wurden. Es funktioniert bei mir, ist aber höchstwahrscheinlich falsch. Bitte mailen Sie mir, wenn Sie Korrekturen haben.
Als erstes sollten Sie wissen, dass ein App-Bundle nur ein Verzeichnis ist.
Lassen Sie uns die Struktur einer hypothetischen foo.app untersuchen.
foo.app/
Inhalt/
Info.plist
Mac OS/
foo
Ressourcen/
foo.icns
Info.plist ist eine einfache XML-Datei. Sie können es mit einem Texteditor oder der im Lieferumfang von XCode enthaltenen App App Property List Editor bearbeiten. (Es befindet sich im Verzeichnis / Developer / Applications / Utilities /).
Die wichtigsten Dinge, die Sie einbeziehen müssen, sind:
CFBundleName - Der Name der App.
CFBundleIcon - Eine Symboldatei , die sich im Verzeichnis Inhalt / Ressourcen befindet. Verwenden Sie die Icon Composer-App, um das Symbol zu erstellen. (Es befindet sich auch im Verzeichnis / Developer / Applications / Utilities /.) Sie können einfach ein PNG per Drag & Drop in das Fenster ziehen und sollten automatisch die Mip-Levels für Sie generieren.
CFBundleExecutable - Name der ausführbaren Datei, die sich vermutlich im Inhalts- / MacOS- / Unterordner befindet.
Es gibt viel mehr Optionen, die oben aufgeführten sind nur das absolute Minimum. Hier finden Sie einige Apple-Dokumentationen zur
Info.plist-
Datei und zur
App-Bundle-Struktur .
Hier ist auch ein Beispiel für eine Info.plist.
<? xml version = "1.0" encoding = "UTF-8"?>
<! DOCTYPE plist PUBLIC "- // Apple Computer // DTD PLIST 1.0 // DE" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version = "1.0">
<Diktat>
<key> CFBundleGetInfoString </ key>
<string> Foo </ string>
<key> CFBundleExecutable </ key>
<string> foo </ string>
<key> CFBundleIdentifier </ key>
<string> com.Ihr-Firmenname.www </ string>
<key> CFBundleName </ key>
<string> foo </ 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>
<Ganzzahl> 0 </ Ganzzahl>
<key> IFMinorVersion </ key>
<Ganzzahl> 1 </ Ganzzahl>
</ dict>
</ plist>
In einer perfekten Welt können Sie Ihre ausführbare Datei einfach in Contents / MacOS / dir ablegen und fertig sein. Wenn Ihre App jedoch nicht standardmäßige Dylib-Abhängigkeiten aufweist, funktioniert sie nicht. Wie Windows verfügt auch MacOS über eine spezielle DLL-Hölle .
Wenn Sie MacPorts verwenden , um Bibliotheken zu erstellen, mit denen Sie verknüpfen, werden die Speicherorte der Dylibs in Ihrer ausführbaren Datei fest codiert. Wenn Sie die App auf einem Computer ausführen, auf dem sich die Dylibs genau am selben Ort befinden, läuft sie einwandfrei. Die meisten Benutzer haben sie jedoch nicht installiert. Wenn sie auf Ihre App doppelklicken, stürzt sie einfach ab.
Bevor Sie Ihre ausführbare Datei verteilen, müssen Sie alle geladenen Dylibs sammeln und in das App-Bundle kopieren. Sie müssen auch die ausführbare Datei bearbeiten, damit sie an der richtigen Stelle nach den Dylibs sucht. dh wohin Sie sie kopiert haben.
Handbearbeitung einer ausführbaren Datei klingt gefährlich, oder? Zum Glück gibt es Kommandozeilen-Tools, die helfen.
otool -L ausführbarer_name
Dieser Befehl listet alle Dylibs auf, von denen Ihre App abhängt. Wenn Sie solche sehen, die sich NICHT im Ordner System / Library oder usr / lib befinden, müssen Sie diese in das App-Bundle kopieren. Kopieren Sie sie in den Ordner / Contents / MacOS /. Als nächstes müssen Sie die ausführbare Datei bearbeiten, um die neuen Dylibs zu verwenden.
Zunächst müssen Sie sicherstellen, dass Sie mit dem Flag -headerpad_max_install_names verknüpfen. Dies stellt nur sicher, dass, wenn der neue Dylib-Pfad länger als der vorherige ist, Platz dafür vorhanden ist.
Verwenden Sie zweitens das Installationsname-Tool, um jeden Dylib-Pfad zu ändern.
Installationsname_Tool -Ändern Sie den vorhandenen_Pfad_zu_Dylib @ ausführbaren_Pfad / blah.dylib ausführbaren_Namen
Nehmen wir als praktisches Beispiel an, Ihre App verwendet libSDL und otool listet den Speicherort als "/opt/local/lib/libSDL-1.2.0.dylib" auf.
Kopieren Sie es zuerst in das App-Bundle.
cp /opt/local/lib/libSDL-1.2.0.dylib foo.app/Contents/MacOS/
Bearbeiten Sie dann die ausführbare Datei, um den neuen Speicherort zu verwenden (HINWEIS: Stellen Sie sicher, dass Sie sie mit dem Flag -headerpad_max_install_names erstellt haben).
install_name_tool -change /opt/local/lib/libSDL-1.2.0.dylib @ executeable_path / libSDL-1.2.0.dylib foo.app/Contents/MacOS/foo
Puh, wir sind fast fertig. Jetzt gibt es ein kleines Problem mit dem aktuellen Arbeitsverzeichnis.
Wenn Sie Ihre App starten, ist das aktuelle Verzeichnis das Verzeichnis über dem sich die Anwendung befindet. Beispiel: Wenn Sie die Datei foo.app im Ordner / Applcations ablegen, ist das aktuelle Verzeichnis beim Starten der App der Ordner / Applications. Nicht die /Applications/foo.app/Contents/MacOS/, wie Sie vielleicht erwarten.
Sie können Ihre App ändern, um dies zu berücksichtigen, oder Sie können dieses magische kleine Startskript verwenden, das das aktuelle Verzeichnis ändert und Ihre App startet.
#! / bin / bash
cd "$ {0% / *}"
./foo
Stellen
Sie sicher, dass Sie die Datei Info.plist so anpassen, dass CFBundleExecutable auf das Startskript und nicht auf die vorherige ausführbare Datei verweist.
Ok, alles jetzt erledigt. Glücklicherweise begraben Sie, sobald Sie all dieses Zeug kennen, es in einem Build-Skript.