Istnieją dwa sposoby tworzenia pakietu aplikacji w systemie MacOSX: łatwy i brzydki.
Najłatwiejszym sposobem jest użycie XCode. Gotowe.
Problem polega na tym, że czasami nie możesz.
W moim przypadku tworzę aplikację, która tworzy inne aplikacje. Nie mogę założyć, że użytkownik ma zainstalowany XCode. Używam również MacPorts do tworzenia bibliotek, od których zależy moja aplikacja. Muszę się upewnić, że te dylibs zostaną dołączone do aplikacji, zanim ją rozpowszechnię.
Zastrzeżenie: nie mam żadnych kwalifikacji do napisania tego posta, wszystko, co jest, zostało przejrzane z dokumentów Apple, oddzielając istniejące aplikacje i próbę i błąd. U mnie działa, ale najprawdopodobniej jest źle. Proszę napisz do mnie, jeśli masz jakieś poprawki.
Pierwszą rzeczą, którą powinieneś wiedzieć, jest to, że pakiet aplikacji to tylko katalog.
Przeanalizujmy strukturę hipotetycznego pliku foo.app.
foo.app/
Zawartość/
Info.plist
System operacyjny Mac/
bla
Zasoby/
foo.icns
Info.plist to zwykły plik XML. Możesz go edytować za pomocą edytora tekstu lub aplikacji Property List Editor, która jest dostarczana w pakiecie z XCode. (Znajduje się w katalogu / Developer / Applications / Utilities /).
Najważniejsze rzeczy, które musisz uwzględnić, to:
CFBundleName - nazwa aplikacji.
CFBundleIcon - Zakłada się, że plik ikony znajduje się w katalogu Contents / Resources. Użyj aplikacji Icon Composer, aby utworzyć ikonę. (Jest również w katalogu / Developer / Applications / Utilities /) Możesz po prostu przeciągnąć i upuścić png na jego okno i powinien automatycznie wygenerować dla ciebie poziomy mip.
CFBundleExecutable - nazwa pliku wykonywalnego, który prawdopodobnie znajduje się w podfolderze Contents / MacOS /.
Opcji jest dużo więcej, te wymienione powyżej to tylko absolutne minimum. Oto dokumentacja firmy Apple dotycząca
pliku Info.plist i
struktury pakietu aplikacji .
Oto przykładowa 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">
<dykt>
<key> CFBundleGetInfoString </key>
<string> Foo </string>
<key> CFBundleExecutable </key>
<string> foo </string>
<key> CFBundleIdentifier </key>
<string> com.nazwa-twojej-firmy.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 </entry>
<key> IFMajorVersion </key>
<integer> 0 </integer>
<key> IFMinorVersion </key>
<integer> 1 </integer>
</dict>
</plist>
W idealnym świecie możesz po prostu wrzucić swój plik wykonywalny do Contents / MacOS / dir i gotowe. Jeśli jednak Twoja aplikacja ma niestandardowe zależności dylib, nie będzie działać. Podobnie jak Windows, MacOS jest wyposażony w specjalny rodzaj biblioteki DLL Hell .
Jeśli używasz MacPorts do budowania bibliotek, z którymi łączysz się, lokalizacje dylibs zostaną zakodowane na stałe w pliku wykonywalnym. Jeśli uruchomisz aplikację na komputerze, który ma dylibs w dokładnie tej samej lokalizacji, będzie działać poprawnie. Jednak większość użytkowników nie będzie ich instalować; po dwukrotnym kliknięciu aplikacji po prostu ulegnie awarii.
Zanim rozpowszechnisz swój plik wykonywalny, musisz zebrać wszystkie pliki dylibs, które ładuje, i skopiować je do pakietu aplikacji. Będziesz także musiał edytować plik wykonywalny, aby szukał dylib we właściwym miejscu. tj. gdzie je skopiowałeś.
Ręczna edycja pliku wykonywalnego brzmi niebezpiecznie, prawda? Na szczęście istnieją narzędzia wiersza poleceń, które mogą pomóc.
otool -L nazwa_pliku
To polecenie wyświetli listę wszystkich dylibs, od których zależy Twoja aplikacja. Jeśli zobaczysz takie, które NIE znajdują się w folderze System / Library lub usr / lib, to te, które musisz skopiować do pakietu aplikacji. Skopiuj je do folderu / Contents / MacOS /. Następnie musisz edytować plik wykonywalny, aby używał nowych dylibs.
Po pierwsze, musisz upewnić się, że łączysz się za pomocą flagi -headerpad_max_install_names. To tylko zapewnia, że jeśli nowa ścieżka dylib jest dłuższa niż poprzednia, będzie na nią miejsce.
Po drugie, użyj narzędzia install_name_tool, aby zmienić każdą ścieżkę dylib.
install_name_tool -change existing_path_to_dylib @ executable_path / blah.dylib executable_name
Jako praktyczny przykład, powiedzmy, że Twoja aplikacja używa libSDL , a otool wyświetla swoją lokalizację jako „/opt/local/lib/libSDL-1.2.0.dylib”.
Najpierw skopiuj go do pakietu aplikacji.
cp /opt/local/lib/libSDL-1.2.0.dylib foo.app/Contents/MacOS/
Następnie edytuj plik wykonywalny, aby używał nowej lokalizacji (UWAGA: upewnij się, że zbudowałeś go z flagą -headerpad_max_install_names)
install_name_tool -change /opt/local/lib/libSDL-1.2.0.dylib @ executable_path / libSDL-1.2.0.dylib foo.app/Contents/MacOS/foo
Uff, prawie skończyliśmy. Teraz jest mały problem z bieżącym katalogiem roboczym.
Po uruchomieniu aplikacji bieżącym katalogiem będzie katalog powyżej, w którym znajduje się aplikacja. Na przykład: jeśli umieścisz foo.app w folderze / Applcations, wówczas bieżącym katalogiem po uruchomieniu aplikacji będzie folder / Applications. Nie /Applications/foo.app/Contents/MacOS/, jak można się spodziewać.
Możesz zmienić swoją aplikację, aby to uwzględnić, lub możesz użyć tego magicznego małego skryptu uruchamiania, który zmieni bieżący katalog i uruchomi Twoją aplikację.
#! / bin / bash
cd „$ {0% / *}”
./bla
Upewnij się, że dostosowałeś plik Info.plist tak, aby CFBundleExecutable wskazywało na skrypt uruchamiania, a nie na poprzedni plik wykonywalny.
OK, wszystko gotowe. Na szczęście, kiedy już znasz te wszystkie rzeczy, zakopujesz to w skrypcie kompilacji.