Angenommen, ich habe eine osX-App ohne Verwendung von Xcode erstellt. Nach dem Kompilieren mit GCC erhalte ich eine ausführbare Datei, die mit mehreren anderen Bibliotheken verknüpft ist. Einige dieser Bibliotheken sind möglicherweise wieder dynamisch mit anderen nicht standardmäßigen Systembibliotheken verknüpft
Gibt es ein Tool, das ein OSX-App-Bundle erstellt, indem zuerst die erforderlichen Verzeichnisstrukturen erstellt und dann rekursiv Links kopiert / überprüft / repariert werden, um sicherzustellen, dass alle dynamischen Abhängigkeiten auch im App-Bundle enthalten sind?
Ich denke, ich kann versuchen, so etwas zu schreiben, aber ich habe mich gefragt, ob so etwas schon existiert.
Antworten:
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.
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.
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.
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.
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.
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).
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.
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.
quelle
Ich habe tatsächlich ein sehr praktisches Tool gefunden, das etwas Anerkennung verdient ... NEIN - ich habe es nicht entwickelt;)
https://github.com/auriamg/macdylibbundler/
Es löst alle Abhängigkeiten auf und "repariert" Ihre ausführbare Datei sowie Ihre Dylib-Dateien, damit sie in Ihrem App-Bundle reibungslos funktionieren.
... prüft auch die Abhängigkeiten Ihrer abhängigen dynamischen Bibliotheken: D.
quelle
Die einfachste Lösung ist: Erstellen Sie einmal ein Xcode-Projekt, ohne etwas zu ändern (dh behalten Sie die einfache Ein-Fenster-App, die Xcode für Sie erstellt), erstellen Sie es und kopieren Sie das für Sie erstellte Bundle. Bearbeiten Sie dann die Dateien (insbesondere die Info.plist) entsprechend Ihrem Inhalt und legen Sie Ihre eigene Binärdatei im Verzeichnis Contents / MacOS / ab.
quelle
Ich benutze dies in meinem Makefile ... Es erstellt ein App-Bundle. Lesen Sie es und verstehen Sie es, denn Sie benötigen eine PNG-Symboldatei in einem Macosx / Ordner zusammen mit den hier enthaltenen Dateien PkgInfo und Info.plist ...
"es funktioniert auf meinem Computer" ... ich benutze dies für mehrere Apps auf Mavericks ...
Info.plist
PkgInfo
quelle
Es gibt einige Open Source-Tools, mit denen Sie App-Bundles mit abhängigen Bibliotheken für bestimmte Umgebungen erstellen können, z. B. py2app für Python-basierte Anwendungen. Wenn Sie keine allgemeinere finden, können Sie sie möglicherweise an Ihre Bedürfnisse anpassen.
quelle
Ich wünschte, ich hätte diesen Beitrag früher gefunden ...
Hier ist meine skizzenhafte Art, dieses Problem mithilfe einer
Run script
Phase zu lösen, die jedes Mal aufgerufen wird, wenn ich eineRelease
Version meiner App erstelle :Hoffe, dass dies für jemanden nützlich sein könnte.
quelle