มีสองวิธีในการสร้าง App Bundle บน MacOSX คือ Easy และ Ugly
วิธีง่ายๆก็แค่ใช้ XCode เสร็จแล้ว
ปัญหาคือบางครั้งคุณทำไม่ได้
ในกรณีของฉันฉันกำลังสร้างแอปที่สร้างแอปอื่น ๆ ฉันไม่สามารถสันนิษฐานได้ว่าผู้ใช้ติดตั้ง XCode ไว้ ฉันยังใช้MacPortsเพื่อสร้างไลบรารีที่แอปของฉันขึ้นอยู่ด้วย ฉันต้องแน่ใจว่า dylibs เหล่านี้มาพร้อมกับแอพก่อนที่จะแจกจ่าย
ข้อจำกัดความรับผิดชอบ:ฉันไม่มีคุณสมบัติที่จะเขียนโพสต์นี้โดยสิ้นเชิงทุกอย่างในนั้นได้รับการรวบรวมจากเอกสารของ Apple โดยแยกแอปที่มีอยู่ออกจากกันและการลองผิดลองถูก มันได้ผลสำหรับฉัน แต่มักจะผิด โปรดส่งอีเมลถึงฉันหากคุณมีการแก้ไขใด ๆ
สิ่งแรกที่คุณควรรู้คือ App Bundle เป็นเพียงไดเร็กทอรี
ลองตรวจสอบโครงสร้างของ foo.app สมมุติ
foo.app/
สารบัญ /
Info.plist
MacOS /
ฟู
แหล่งข้อมูล /
foo.icns
Info.plist เป็นไฟล์ XML ธรรมดา คุณสามารถแก้ไขได้ด้วยโปรแกรมแก้ไขข้อความหรือแอปตัวแก้ไขรายการคุณสมบัติที่มาพร้อมกับ XCode (อยู่ในไดเร็กทอรี / Developer / Applications / Utilities /)
สิ่งสำคัญที่คุณต้องมี ได้แก่ :
CFBundleName - ชื่อแอป
CFBundleIcon - ไฟล์ไอคอนที่ถือว่าอยู่ใน Contents / Resources dir ใช้แอพ Icon Composer เพื่อสร้างไอคอน (นอกจากนี้ยังอยู่ในไดเร็กทอรี / Developer / Applications / Utilities /) คุณสามารถลากและวาง png ลงในหน้าต่างและควรสร้างระดับ mip ให้โดยอัตโนมัติ
CFBundleExecutable - ชื่อของไฟล์ปฏิบัติการที่ถือว่าอยู่ใน Contents / MacOS / โฟลเดอร์ย่อย
มีตัวเลือกอื่น ๆ อีกมากมายตัวเลือกที่ระบุไว้ข้างต้นเป็นเพียงขั้นต่ำเท่านั้น นี่คือบางส่วนเอกสารแอปเปิ้ลใน
Info.plist
ไฟล์และ
โครงสร้างกำ
App
นี่คือตัวอย่าง 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">
<dict>
<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>
ในโลกที่สมบูรณ์แบบคุณสามารถวางไฟล์ปฏิบัติการลงใน Contents / MacOS / dir แล้วทำ อย่างไรก็ตามหากแอปของคุณมีการอ้างอิง dylib ที่ไม่ได้มาตรฐานก็จะใช้ไม่ได้ เช่น Windows, MacOS มาพร้อมกับมันเป็นชนิดพิเศษของตัวเองของDLL นรก
หากคุณใช้MacPortsเพื่อสร้างไลบรารีที่คุณเชื่อมโยงตำแหน่งของ dylibs จะถูกเข้ารหัสไว้ในไฟล์ปฏิบัติการของคุณ หากคุณเรียกใช้แอปบนเครื่องที่มี dylib ในตำแหน่งเดียวกันแอปจะทำงานได้ดี อย่างไรก็ตามผู้ใช้ส่วนใหญ่จะไม่ได้ติดตั้ง เมื่อพวกเขาคลิกสองครั้งที่แอปของคุณมันก็จะพัง
ก่อนที่คุณจะแจกจ่ายไฟล์ปฏิบัติการคุณจะต้องรวบรวม dylib ทั้งหมดที่โหลดมาและคัดลอกลงใน App Bundle คุณจะต้องแก้ไขไฟล์ปฏิบัติการเพื่อที่จะมองหา dylibs ในตำแหน่งที่ถูกต้อง นั่นคือที่ที่คุณคัดลอกไป
การแก้ไขด้วยมือที่เรียกใช้งานได้ฟังดูอันตรายใช่ไหม โชคดีที่มีเครื่องมือบรรทัดคำสั่งที่จะช่วยได้
otool -L executable_name
คำสั่งนี้จะแสดงรายการ dylib ทั้งหมดที่แอปของคุณขึ้นอยู่ หากคุณเห็นสิ่งที่ไม่ได้อยู่ในโฟลเดอร์ System / Library หรือ usr / lib นั่นคือสิ่งที่คุณต้องคัดลอกลงใน App Bundle คัดลอกลงใน / Contents / MacOS / โฟลเดอร์ ถัดไปคุณจะต้องแก้ไขไฟล์ปฏิบัติการเพื่อใช้ dylib ใหม่
ขั้นแรกคุณต้องแน่ใจว่าคุณเชื่อมโยงโดยใช้แฟล็ก -headerpad_max_install_names แค่นี้ก็ทำให้แน่ใจได้ว่าถ้าเส้นทาง dylib ใหม่ยาวกว่าเดิมก็จะมีที่ว่างสำหรับมัน
ประการที่สองใช้ install_name_tool เพื่อเปลี่ยนเส้นทาง dylib แต่ละรายการ
install_name_tool -change existing_path_to_dylib @ executable_path / blah.dylib executable_name
ตัวอย่างที่ใช้ได้จริงสมมติว่าแอปของคุณใช้libSDLและ otool แสดงตำแหน่งเป็น "/opt/local/lib/libSDL-1.2.0.dylib"
ก่อนอื่นให้คัดลอกลงใน App Bundle
cp /opt/local/lib/libSDL-1.2.0.dylib foo.app/Contents/MacOS/
จากนั้นแก้ไขไฟล์ปฏิบัติการเพื่อใช้ตำแหน่งใหม่ (หมายเหตุ: ตรวจสอบให้แน่ใจว่าคุณสร้างขึ้นด้วยแฟล็ก -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
เกือบเสร็จแล้ว ขณะนี้มีปัญหาเล็กน้อยกับไดเร็กทอรีการทำงานปัจจุบัน
เมื่อคุณเริ่มแอปของคุณไดเร็กทอรีปัจจุบันจะเป็นไดเร็กทอรีด้านบนที่แอปพลิเคชันตั้งอยู่ ตัวอย่างเช่นหากคุณวาง foo.app ในโฟลเดอร์ / Applcations ไดเร็กทอรีปัจจุบันเมื่อคุณเปิดแอปจะเป็นโฟลเดอร์ / Applications ไม่ใช่ /Applications/foo.app/Contents/MacOS/ อย่างที่คุณคาดหวัง
คุณสามารถปรับเปลี่ยนแอปของคุณให้เป็นบัญชีสำหรับสิ่งนี้หรือคุณสามารถใช้สคริปต์ตัวเรียกใช้งานมหัศจรรย์นี้ที่จะเปลี่ยนไดเรกทอรีปัจจุบันและเปิดแอปของคุณ
#! / bin / ทุบตี
ซีดี "$ {0% / *}"
./foo
ตรวจสอบให้แน่ใจว่าคุณได้ปรับไฟล์ Info.plist เพื่อให้CFBundleExecutableชี้ไปที่สคริปต์เรียกใช้งานไม่ใช่ไปยังไฟล์ปฏิบัติการก่อนหน้านี้
โอเคเสร็จแล้ว โชคดีที่เมื่อคุณรู้สิ่งเหล่านี้ทั้งหมดแล้วคุณจะฝังมันไว้ในบิลด์สคริปต์