wie erstellt man .app Pakete?

Scyx

Scyx

Aktives Mitglied
Thread Starter
Dabei seit
26.02.2004
Beiträge
133
Reaktionspunkte
0
Hallo,

es wäre mal interessant zu wissen, wie man diese .apps erstellt :)
Das ist so ein geniales System bei Mac OS X, von daher würd ich das gerne benutzen um selbst-übersetzte Programme so zu packen und evtl. auch anderen zugänglich zu machen. Einige Komilitonen würde das sehr freuen, wenn sie sich dann nicht mit dem Übersetzen abmühen müssten ;)

Wer Literaturtipps hat, vllt. sogar HowTos inkl. Link, immer her damit bitte :)
Falls es spezielle Dinge gibt, die man beachten sollte (Compiler, OS X Version usw.) bitte auch posten.

MfG

Scyx
 
Danke.
Muss man dafür XCode nutzen, oder gibt es da auch andere Wege, das vllt. konsolenbasiert zu machen?
Da es Mac OS X typisch ist, liegt es nahe, dass man das wohl auch nur mit deren Tool machen kann. Aber eine "unabhängige" Lösung ist mir irgendwie lieber, einfach aus Prinzip ;)

MfG

Scyx
 
Ich verschieb Dich mal eben in den Entwicklerbereich.
Grundsätzlich kommt es darauf an, um was für Programme es geht bzw. in welcher Sprache die geschrieben sind.
 
Hauptsächlich C++, teilweise wohl auch python.
Was in Zukunft für Sprachen hinzukommen weiss ich halt noch nicht :)
Wie nennt man denn die .app Pakete? Die haben doch bestimmt einen speziellen Namen.
@bernie313: Kannst Du das evtl. etwas präzisieren, wo ich einen Artikel über die .app Pakete-Erstellung mit XCode finde?
Es geht auch darum, dass das Programm usw. alles mit configure, make und make install erstellt wird, also im Prinzip schon fertig ist. Das einzige was dann halt noch fehlt, ist aus alle dem Zeug so ein .app Paket zu erzeugen.

MfG

Scyx
 
Python ist eine Skript Sprache, da muss man (normalerweise) nichts packen.

c++ wird i.d.R. für Kommandozeilentools eingesetzt. Da kann man fertige Binaries weitergeben. U.U muss man aufpassen, dass bei komplexen Programmen, zusätzliche libraries weitergegeben werden müssen oder man muss halt alles statisch linken. Trotzdem wird da wohl nur in Ausnahmefällen eine *.app draus werden.

Wie dem auch sei.
Wenn Du Deinen Kommilitonen das Bauen der Programme vereinfachen möchtest, bist Du vielleicht auch mit Shellskripten gut bedient, die die erforderlichen Sourcen aus dem Internet (evtl. von Deinem Webspace) laden, konfigurieren und installieren.
Man aber auch was mit dem PackageMaker machen.
 
Also, das hilft mir leider auch nicht weiter :)
Aber in der Zwischenzeit hab ich eine Page gefunden, in der das Ganze anhand eines Beispiels für ein Java Programm erklärt wird.
Übrigens, der Ausdruck den ich gesucht hab ist "Application Bundle". die Apple Online Hilfe hilft mir da auch ein gutes Stück weiter, aber leider finde ich das wichtigste bisher noch nicht.
Denn ich hab hier im Moment ein Programm, dass ich in so ein Application bundle packen will. Leider benötigt es beim Aufruf 2 Pfade, die mittels LSEnvironment in der Info.plist gesetzt werden müssen. Da das bundle aber verschiebbar sein soll bräuchte ich eine Variable, die den aktuelle Pfad des bundles zurückliefert, ähnlich der $APP_PACKAGE für Java Bundles. Da es sich hier aber um ein C++ Prog handelt, wollte ich mal fragen, ob es sowas auch ohne Java gibt? $PWD funktioniert leider auch nicht :)

MfG

Scyx
 
Scyx schrieb:
Hallo,

es wäre mal interessant zu wissen, wie man diese .apps erstellt :)
Das ist so ein geniales System bei Mac OS X, von daher würd ich das gerne benutzen um selbst-übersetzte Programme so zu packen und evtl. auch anderen zugänglich zu machen. Einige Komilitonen würde das sehr freuen, wenn sie sich dann nicht mit dem Übersetzen abmühen müssten ;)

Wer Literaturtipps hat, vllt. sogar HowTos inkl. Link, immer her damit bitte :)
Falls es spezielle Dinge gibt, die man beachten sollte (Compiler, OS X Version usw.) bitte auch posten.

Ich verstehe Deine Frage nicht. Das Konzept heisst "Bundles", Xcode erzeugt sie relativ automatisch für OS X Projekte.

Was für eine Codebasis willst Du warum in .app Bundles packen?

Aber zum Lesen:
Anatomy of a Modern Bundle

Alex
 
Ich hab hier ein Programm (C++), das eigentlich für Linux gedacht ist, aber auch auf dem Mac kompiliert (mit ein paar Änderungen)
Nach dem Kompilieren hab ich dann alles was ich brauch. Executable, Shared libs usw.
All dies möchte ich jetzt in ein Bundle packen.
Ein bundle ist, laut der Online Hilfe, ja nichts anderes als ein Ordner mit einer bestimmten Verzeichnishierarchie und bestimmten Dateien (Info.plist, APPL???, ...)
Das Programm was ich da kompiliert habe (mit configure, make und make install, also ohne XCode o.Ä.) möchte ich jetzt zu einem solchen bundle schnüren. Sprich, executable unter Prog.app/Contents/MacOS/executable, libs unter Prog.app/Contentes/Resources/libs/ und dann noch data unter Prog.app/Contents/Resources/data/.
Das Programm braucht aber die Pfade für data/ und die libs in seiner Umgebung. Für solche Fälle kann man ja in Info.plist LSEnvironment benutzen, um verschiedene Pfade zu setzen.
Das Problem dabei ist aber, dass LSEnvironment absolute Pfade braucht, aber um ein echtes Bundle zu erzeugen, das auch verschiebbar sein soll, muss das Ganze irgendwie relativ sein oder sich den aktuellen Pfad von Prog.app irgendwie besorgen.
Nun frage ich mich, welche Möglichkeit man da hat. Gibt es da was vergleichbares wie $PWD, so dass man da eintragen kann:
<key>LSEnvironment</key>
<dict>
<key>PROG_DATA_PATH</key>
<string>$PWD/data/</string>
<key>DYLD_LIBRARY_PATH</key>
<string>$PWD/lib/Darwin-7.9.0-g++_3.3.0</string>

?
Hoffe, dass jetzt verständlich ist, was ich meine.

MfG

Scyx
 
Ja, ist verständlich. Leider kann ich Dir mit LSEnvironment auch nicht helfen.

:(

Alex
 
Wenn man ein Java bundle packt, dan gibt's da eine Variable $APP_PACKAGE die den Pfad des bundles liefert, damit da alles richtig gefunden wird. Aber für bundles von anderem Code scheint es so was leider nicht zu geben. Die ganz einfache Möglichkeit wäre dem Benutzer dann zu sagen, "Geh in die Info.plist und ändere dort den Pfad". Aber das passt absolut nicht zu Mac OS X :)

MfG

Scyx

[edit]
Ich hab mal noch etwas weiter gestöbert und bin dann auf CFBundle und CFBundelCopyBundleURL() gestoßen. Leider sind all die Beispiele nur in Verbindung mit "Programmen" und ich weiss nicht, wie ich so ein "Programm" (Bsp. s. 19 vom "Bundle Programming Guide") in eine Info.plist integrieren kann.
Kann das bitte vllt. jemand erklären?
 
Zuletzt bearbeitet:
alternative Lösung

Hallo,

ich hab da mal etwas rumgebastelt und eine alternative Lösung "wäre" das Application bundle wiederum in ein bundle zu packen, allerdings in diesem dann unter Resources.
Die executable für dieses start.app wäre dann z.B. ein Shell-Skript, die die Variablen setzt und das eigentlich bundle unter Resources/ aufruft.
Jedoch gibt es da ein Problem.
Da das ganze ja "automatisch" gehen soll, muss es seinen aktuellen Pfad selbst bestimmen. Dafür kann man ja $PWD verwenden.
Wenn man das Skript dann direkt startet aus 'nem Terminal.app, funktioniert's auch. Aber ein starten von start.app gelingt leider nicht, da er die Variablen nicht richtig setzt.
Egal wie ich versuche an das aktuelle Verzeichnis zu kommen(printenv PWD, pwd, $PWD), ich bekomme immer / als Pfad. Wenn ich den korrekten Pfad einer Variable in dem Skript zu weise und dieses Variable dann verwende funktioniert es.
Funktioniert dieses "automatische" Vorgehen nicht wenn man etwas mit dem Launcher oder "open" öffnet, sprich öffnen die die Programme immer unter /? Das wäre aber recht komisch.

MfG

Scyx
 
Vielleicht hilft dies

Ich habe auch mal in ein .app-Paket geschaut und mir erfolgreich eine Klickbare Java-Applikation gebaut. Dazu benutze ich ein Shell-Script um an die genannte PWD-Variable zu kommen:

Im Ordner 'test.app/Contents' liegt folgende ausführbare Textdatei 'test'
#!/bin/sh
WD=`echo $0 | sed -n -e 's/\(.*\)\/test/\1/gp'`
cd "${WD}"
java -Djava.ext.dirs=lib com.pkg.MeineJavaApplikation

sowie ein Ordner lib mit den benötigten .jar-Dateien.
In der Variable $0 steht immer der Pfad auf das Shellscript. Mit Hilfe von sed beiße ich den Namen der Scriptdatei ('test') ab, damit ich CDen kann. Nun befinde ich mich im Contents Ordner und kann alle folgenden Aktionen mit relativen Pfaden ausführen. Dies sollte insofern auch mit anderen Applikationen funktionieren.

Auch in C/C++ Programmen wird meines Wissens nach in main() als erstes string/char[] argument der Programmpfad übergeben und könnte entsprechend ausgewertet werden.

Vielleicht kann ja jemand was damit anfangen ;)
 
Zuletzt bearbeitet:
jpv: Das hatte ich auch so versucht. Allerdings hatte ich die eigentliche executable in .../Contents/Resources verschoben und das Skript dann anstelle der executable in .../Contents/MacOS/ gesetzt.
Der Aufruf ging auch so weit, nur das Setzen von Variablen, die dieses Programm aufgrund der shared libraries braucht, ging halt nicht auf die gewohnte Weise. Sprich, Doppelklick im Finder oder "open -a xyz.app" im Terminal.app funktionierten nicht.
Das Skript selbst im Terminal.app zu starten ging, die Variablen wurden dann auch gesetzt.
Für java-Applikationen gibt's da aber auch 'ne Möglichkeit das in der Info.plist zu setzen soweit ich mich da eingelesen hatte. Aber bei C++ Programmen funktionierte das halt leider nicht.

Eine Frage hätte ich da noch zu dem Skript.
Das liegt einfach in package.app/Contents/ und ist ausführbar? Das braucht keinen besonderen Namen oder muss irgendwo "bekannt" gemacht werden?

MfG Scyx
 
Der Name muß anscheinend genau dem Namen der .app-Datei entsprechen.
Also 'test.app/Contents/test' oder 'SuperProgramm.app/Contents/SuperProgramm'.
Das kann auch ein Shellscript sein - also eine Textdatei, die mit chmod 755 test ausführbar gemacht wurde.
Wenn diese Datei direkt in Contents liegt, benötigt man auch keine 'Info.plist'.
Wenn die Datei in '/test.app/Contents/MacOS' liegt, sollte $0 trotzdem gesetzt sein. Um den Basispfad zu bekommen, muß man den sed-Ausdruck entsprechend anpassen. Das habe ich allerdings gar nicht probiert ...

Eine Testapplikation mit

'test.app/Contents/test'
#!/bin/sh
echo $0 >/Users/ich/Desktop/test.txt


Hatte mir ursprünglich den Hinweis gegeben.

Viel Spaß und schönes WE :)
 
Ok, das Problem scheint zu sein, dass das starten per Finder bewirkt, dass $0 zu ./Prog expandiert und nicht zu /Applications/Prog.app/Contents/MacOS/Prog.
Muss man da was in der Shell umstellen, damit er den absoluten Pfad benutzt? Ohne den Pfad automatisch zu erhalten geht's aber defintiv nicht :)
Der Befehl "pwd" funktioniert wohl auch nur beim starten mit Terminal.app, ist daher für diese Zwecke unbrauchbar.

MfG

Scyx
 
Welche MacOSX-Version benutzt Du denn? Ich nutze 10.4.6, wo der Pfad beim Starten aus dem Finder absolut mitgegeben wird. Meine letzten Versuche dieser Art mit 10.2/10.3 liegen schon etwas zurück. Ich würde nicht ausschließen, daß sich da zwischenzeitlich etwas geändert hat.

Ich habe mal ein Script geschrieben, daß bei mir eine Finderklickbare Anwendung auf den Desktop des aktuellen Nutzers schreibt:

#!/bin/sh
cd Desktop
mkdir -p programm.app/Contents/MacOS
echo '#!/bin/sh' >programm.app/Contents/MacOS/programm
echo WD=\`echo \$0 \| sed -n -e \'s/\\\(.\*\\\)\\/MacOS\\/programm/\\1/gp\'\` >>programm.app/Contents/MacOS/programm
echo echo \${WD} \>\$HOME/Desktop/pwd.txt >>programm.app/Contents/MacOS/programm
chmod 755 programm.app/Contents/MacOS/programm
open programm.app


Wenn Du diesen Text in eine Datei 'script.command' kopierst und diese Datei in der Console mit chmod 755 script.command ausführbar machst, sollte ein Klickbares Script bereitliegen.
'.command'-Dateien werden von Terminal.app im Ordner des aktuell angemeldeten Nutzers ausgeführt. Dieses Skript produziert bei mir zuerst programm.app auf dem Schriebtisch, welches seinerseits mit open ausgeführt die Datei pwd.txt auf dem Schreibtisch erzeugt.

Vielleicht hilfts,
Grüße, jpv
 
Achso, wenn pwd zu ./Prog aufgelöst wird, bedeutet dies, daß das Programm in dem Ordner ausgeführt wird, in dem es liegt. Findet es sich in Prog.app/Contents/MacOS/Prog, so sollte ein relativer Pfad ../Resources/extradatei.txt auf die entsprechende Datei im Resources-Ordner zeigen:

Prog.app/Contents/MacOS/Prog
Prog.app/Contents/Resources/extradatei.txt

Wenn Du im sed-Befehl '\/MacOS' wegläßt, sollte auch der reguläre Ausdruck wieder matchen. Dann kannst Du mit einem 'cd ..' in der Script-Datei wieder in den Contents-Ordner wechseln.
 
entsprechend angepaßt sähe das Script folgendermaßen aus:

#!/bin/sh
PRGNAME=programm
cd Desktop
mkdir -p ${PRGNAME}.app/Contents/MacOS
echo '#!/bin/sh' >${PRGNAME}.app/Contents/MacOS/${PRGNAME}
echo WD=\`echo \$0 \| sed -n -e \'s/\\\(.\*\\\)\\/${PRGNAME}/\\1/gp\'\` >>${PRGNAME}.app/Contents/MacOS/${PRGNAME}
echo cd \${WD} >>${PRGNAME}.app/Contents/MacOS/${PRGNAME}
echo cd .. >>${PRGNAME}.app/Contents/MacOS/${PRGNAME}
echo echo \${WD} \>\$HOME/Desktop/pwd.txt >>${PRGNAME}.app/Contents/MacOS/${PRGNAME}
echo pwd \>\>\$HOME/Desktop/pwd.txt >>${PRGNAME}.app/Contents/MacOS/${PRGNAME}
chmod 755 ${PRGNAME}.app/Contents/MacOS/${PRGNAME}
open ${PRGNAME}.app
 
Ich nutze Mac OS X 10.3.9.
Ich hab nun eine Möglichkeit gefunden, um den Pfad korrekt zu bekommen :)
@jpv: Wie's mit der Funktionalität deines Vorschlags unter 10.3.9 aussieht, werd ich bei Gelegenheit mal testen, das was ich gefunden habe ist vllt. etwas "leichter" :)
WD=$(echo ${0/\.\//$PWD} | sed -e 's/\/MacOS\/ProgramName//') gibt einem den absoluten Pfad, bis rein zu ProgramName.app/Contents. sed ist eine feine Sache, danke noch für die Hinweise.

Man kann evtl. noch eine Abfrage einfügen, die dann testet, ob man nicht bereits den absoluten Pfad hat, aber theoretisch sollte es auch ohne funktionieren. Wenn nicht, bitte Bescheid sagen.

MfG

Scyx
 
Zurück
Oben Unten