Có hai cách để tạo một gói ứng dụng trên MacOSX, Easy và Ugly.
Cách đơn giản là sử dụng XCode. Làm xong.
Vấn đề là đôi khi bạn không thể.
Trong trường hợp của tôi, tôi đang xây dựng một ứng dụng xây dựng các ứng dụng khác. Tôi không thể cho rằng người dùng đã cài đặt XCode. Tôi cũng đang sử dụng MacPorts để xây dựng các thư viện mà ứng dụng của tôi phụ thuộc vào. Tôi cần đảm bảo rằng những dylibs này được đi kèm với ứng dụng trước khi tôi phân phối nó.
Tuyên bố từ chối trách nhiệm: Tôi hoàn toàn không đủ tư cách để viết bài đăng này, mọi thứ trong đó đều được xem xét từ tài liệu của Apple, chọn các ứng dụng hiện có và thử nghiệm và sửa lỗi. Nó phù hợp với tôi, nhưng rất có thể là sai. Vui lòng gửi email cho tôi nếu bạn có bất kỳ chỉnh sửa nào.
Điều đầu tiên bạn nên biết là gói ứng dụng chỉ là một thư mục.
Hãy xem xét cấu trúc của một foo.app giả định.
foo.app/
Nội dung /
Info.plist
Hệ điều hành Mac/
foo
Tài nguyên/
foo.icns
Info.plist là một tệp XML thuần túy. Bạn có thể chỉnh sửa nó bằng trình soạn thảo văn bản hoặc ứng dụng Trình chỉnh sửa danh sách thuộc tính đi kèm với XCode. (Nó nằm trong thư mục / Developer / Applications / Utilities /).
Những điều chính bạn cần bao gồm là:
CFBundleName - Tên của ứng dụng.
CFBundleIcon - Một tệp Biểu tượng giả định nằm trong Dir Nội dung / Tài nguyên. Sử dụng ứng dụng Icon Composer để tạo biểu tượng. (Nó cũng nằm trong thư mục / Developer / Applications / Utilities /) Bạn có thể chỉ cần kéo và thả một png vào cửa sổ của nó và sẽ tự động tạo các mức mip cho bạn.
CFBundleExecutable - Tên của tệp thực thi được giả định nằm trong Contents / MacOS / thư mục con.
Có rất nhiều tùy chọn khác, những tùy chọn được liệt kê ở trên chỉ là mức tối thiểu. Dưới đây là một số tài liệu của Apple về
tệp Info.plist và
cấu trúc gói Ứng dụng .
Ngoài ra, đây là một Info.plist mẫu.
<? xml version = "1.0" encoding = "UTF-8"?>
<! DOCTYPE plist PUBLIC "- // Máy tính Apple // DTD PLIST 1.0 // EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version = "1.0">
<sắc lệnh>
<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> ÁP DỤNG </string>
<key> IFMajorVersion </key>
<integer> 0 </integer>
<key> IFMinorVersion </key>
<integer> 1 </integer>
</dict>
</plist>
Trong một thế giới hoàn hảo, bạn chỉ cần thả tệp thực thi của mình vào Contents / MacOS / dir và được thực hiện. Tuy nhiên, nếu ứng dụng của bạn có bất kỳ phụ thuộc dylib không chuẩn nào thì ứng dụng sẽ không hoạt động. Giống như Windows, MacOS đi kèm với loại DLL Hell đặc biệt của riêng nó .
Nếu bạn đang sử dụng MacPorts để xây dựng các thư viện mà bạn liên kết với, vị trí của các dylibs sẽ được mã hóa cứng thành tệp thực thi của bạn. Nếu bạn chạy ứng dụng trên một máy có dylibs ở cùng một vị trí, nó sẽ chạy tốt. Tuy nhiên, hầu hết người dùng sẽ không cài đặt chúng; khi họ nhấp đúp vào ứng dụng của bạn, nó sẽ bị lỗi.
Trước khi phân phối tệp thực thi, bạn sẽ cần thu thập tất cả các dylibs mà nó tải và sao chép chúng vào gói ứng dụng. Bạn cũng sẽ cần chỉnh sửa tệp thực thi để nó tìm kiếm các dylibs ở đúng vị trí. tức là nơi bạn đã sao chép chúng vào.
Chỉnh sửa bằng tay một tệp thực thi nghe có vẻ nguy hiểm phải không? May mắn thay, có các công cụ dòng lệnh để trợ giúp.
otool -L tên_cấu tạo
Lệnh này sẽ liệt kê tất cả các dylibs mà ứng dụng của bạn phụ thuộc vào. Nếu bạn thấy bất kỳ tệp nào KHÔNG nằm trong thư mục Hệ thống / Thư viện hoặc usr / lib, thì đó là những tệp bạn cần sao chép vào gói ứng dụng. Sao chép chúng vào thư mục / Contents / MacOS /. Tiếp theo, bạn sẽ cần chỉnh sửa tệp thực thi để sử dụng dylibs mới.
Trước tiên, bạn cần đảm bảo rằng bạn liên kết bằng cờ -headerpad_max_install_names. Điều này chỉ đảm bảo rằng nếu đường dẫn dylib mới dài hơn đường dẫn trước đó, sẽ có chỗ cho nó.
Thứ hai, sử dụng install_name_tool để thay đổi từng đường dẫn dylib.
install_name_tool -change current_path_to_dylib @ executable_path / blah.dylib Operating_name
Ví dụ thực tế, giả sử ứng dụng của bạn sử dụng libSDL và otool liệt kê vị trí của nó là "/opt/local/lib/libSDL-1.2.0.dylib".
Trước tiên, hãy sao chép nó vào gói ứng dụng.
cp /opt/local/lib/libSDL-1.2.0.dylib foo.app/Contents/MacOS/
Sau đó, chỉnh sửa tệp thực thi để sử dụng vị trí mới (LƯU Ý: đảm bảo rằng bạn đã tạo nó bằng cờ -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
Chà, chúng ta sắp xong rồi. Bây giờ có một vấn đề nhỏ với thư mục làm việc hiện tại.
Khi bạn khởi động ứng dụng, thư mục hiện tại sẽ là thư mục phía trên nơi chứa ứng dụng. Ví dụ: Nếu bạn đặt foo.app trong thư mục / Applcations thì thư mục hiện tại khi bạn khởi chạy ứng dụng sẽ là thư mục / Applications. Không phải là /Application/foo.app/Contents/MacOS/ như bạn có thể mong đợi.
Bạn có thể thay đổi ứng dụng của mình để giải quyết vấn đề này hoặc bạn có thể sử dụng tập lệnh trình khởi chạy nhỏ kỳ diệu này sẽ thay đổi thư mục hiện tại và khởi chạy ứng dụng của bạn.
#! / bin / bash
cd "$ {0% / *}"
./foo
Đảm bảo bạn điều chỉnh tệp Info.plist để CFBundleExecutable trỏ đến tập lệnh khởi chạy chứ không phải tập lệnh thực thi trước đó.
Ok, tất cả đã xong. May mắn thay, một khi bạn biết tất cả những thứ này, bạn sẽ chôn nó trong một kịch bản xây dựng.