Ada dua cara untuk membuat bundel aplikasi di MacOSX, Mudah dan Jelek.
Cara termudah adalah dengan menggunakan Xcode. Selesai.
Masalahnya terkadang Anda tidak bisa.
Dalam kasus saya, saya sedang membangun aplikasi yang membangun aplikasi lain. Saya tidak dapat berasumsi bahwa pengguna telah menginstal XCode. Saya juga menggunakan MacPorts untuk membangun perpustakaan tempat aplikasi saya bergantung. Saya perlu memastikan bahwa dylib ini digabungkan dengan aplikasi sebelum saya mendistribusikannya.
Penafian: Saya benar-benar tidak memenuhi syarat untuk menulis posting ini, semua yang ada di dalamnya telah dikilaukan dari dokumen Apple, memilah-milah aplikasi yang ada dan coba-coba. Ini berhasil untuk saya, tetapi kemungkinan besar salah. Silakan email saya jika Anda memiliki koreksi.
Hal pertama yang harus Anda ketahui adalah bahwa app bundle hanyalah sebuah direktori.
Mari kita periksa struktur hipotetis foo.app.
foo.app/
Isi/
Info.plist
MacOS /
foo
Sumber daya /
foo.icns
Info.plist adalah file XML biasa. Anda dapat mengeditnya dengan editor teks atau aplikasi Editor Daftar Properti yang dibundel dengan XCode. (Ada di / Developer / Applications / Utilities / direktori).
Hal-hal utama yang perlu Anda sertakan adalah:
CFBundleName - Nama aplikasi.
CFBundleIcon - File Ikon yang diasumsikan ada di direktori Contents / Resources. Gunakan aplikasi Icon Composer untuk membuat ikon. (Ini juga ada di / Developer / Applications / Utilities / direktori) Anda cukup menarik dan melepas png ke jendelanya dan secara otomatis akan menghasilkan mip-level untuk Anda.
CFBundleExecutable - Nama file yang dapat dieksekusi yang diasumsikan berada di sub-folder Contents / MacOS /.
Ada lebih banyak pilihan, yang tercantum di atas hanyalah minimum. Berikut beberapa dokumentasi Apple tentang
file Info.plist dan
struktur App bundle .
Juga, Ini contoh 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">
<dikt>
<key> CFBundleGetInfoString </key>
<string> Foo </ string>
<key> CFBundleExecutable </key>
<string> foo </ string>
<key> CFBundleIdentifier </key>
<string> com.your-company-name.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>
<integer> 0 </integer>
<key> IFMinorVersion </key>
<integer> 1 </integer>
</dict>
</plist>
Di dunia yang sempurna Anda bisa memasukkan file yang dapat dieksekusi ke dalam Contents / MacOS / dir dan selesai. Namun, jika aplikasi Anda memiliki dependensi dylib non-standar, itu tidak akan berfungsi. Seperti Windows, MacOS hadir dengan DLL Hell jenis khusus itu sendiri .
Jika Anda menggunakan MacPorts untuk membangun pustaka yang Anda tautkan, lokasi dylib akan di-hardcode ke dalam file yang dapat dieksekusi. Jika Anda menjalankan aplikasi pada mesin yang dylibnya berada di lokasi yang sama persis, aplikasi akan berjalan dengan baik. Namun, sebagian besar pengguna tidak akan menginstalnya; ketika mereka mengklik dua kali aplikasi Anda, itu hanya akan mogok.
Sebelum mendistribusikan file executable, Anda harus mengumpulkan semua dylib yang dimuatnya dan menyalinnya ke app bundle. Anda juga perlu mengedit file yang dapat dieksekusi agar itu akan mencari dylib di tempat yang benar. yaitu tempat Anda menyalinnya.
Mengedit tangan yang dapat dieksekusi terdengar berbahaya bukan? Untungnya ada alat baris perintah untuk membantu.
otool -L nama_eksekusi
Perintah ini akan mencantumkan semua dylib yang bergantung pada aplikasi Anda. Jika Anda melihat ada yang TIDAK ada di folder System / Library atau usr / lib, itu adalah yang harus Anda salin ke app bundle. Salin ke folder / Contents / MacOS /. Selanjutnya, Anda harus mengedit file yang dapat dieksekusi untuk menggunakan dylib baru.
Pertama, Anda perlu memastikan bahwa Anda menautkan menggunakan tanda -headerpad_max_install_names. Ini hanya memastikan bahwa jika jalur dylib baru lebih panjang dari yang sebelumnya, akan ada ruang untuk itu.
Kedua, gunakan install_name_tool untuk mengubah setiap jalur dylib.
install_name_tool -ubah existing_path_to_dylib @ executable_path / blah.dylib executable_name
Sebagai contoh praktis, Misalkan aplikasi Anda menggunakan libSDL , dan otool mencantumkan lokasinya sebagai "/opt/local/lib/libSDL-1.2.0.dylib".
Salin dulu ke app bundle.
cp /opt/local/lib/libSDL-1.2.0.dylib foo.app/Contents/MacOS/
Kemudian edit file yang dapat dieksekusi untuk menggunakan lokasi baru (CATATAN: pastikan Anda membuatnya dengan 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
Wah, kita hampir selesai. Sekarang ada masalah kecil dengan direktori kerja saat ini.
Saat Anda memulai aplikasi, direktori saat ini adalah direktori di atas tempat aplikasi berada. Misalnya: Jika Anda menempatkan foo.app di folder / Applcations, maka direktori saat ini saat Anda meluncurkan aplikasi adalah folder / Applications. Bukan /Applications/foo.app/Contents/MacOS/ seperti yang Anda harapkan.
Anda dapat mengubah aplikasi Anda ke akun untuk ini, atau Anda dapat menggunakan skrip peluncur kecil ajaib ini yang akan mengubah direktori saat ini dan meluncurkan aplikasi Anda.
#! / bin / bash
cd "$ {0% / *}"
./foo
Pastikan Anda menyesuaikan file Info.plist sehingga CFBundleExecutable menunjuk ke skrip peluncuran dan bukan ke eksekusi sebelumnya.
Oke, sudah selesai sekarang. Untungnya, setelah Anda mengetahui semua hal ini, Anda menguburnya dalam skrip build.