2009-09-27 31 views
13

Tôi có một chương trình (cụ thể là mục nhập của tôi cho SO DevDays Countdown app challenge) dựa trên một số thư viện động, cụ thể là libSDL, libSDL_ttf và các thư viện khác. Tôi có các thư viện này được cài đặt theo /opt/local/lib qua MacPorts và nhiều người sẽ không cài đặt các thư viện này (và một số có thể đã cài đặt chúng nhưng không được cài đặt ở vị trí đó).Cách phân phối Mac OS X với các thư viện phụ thuộc?

Làm cách nào để phân phối chương trình của mình để những người không có các thư viện này được cài đặt có thể chạy chương trình này? Rõ ràng tôi sẽ phải phân phối các tập tin .dylib khác nhau, nhưng làm điều này là không đủ. Trình tải động vẫn tìm các thư viện được cài đặt tại các vị trí tôi đã cài đặt chúng tại. Có cách nào để nói cho bộ tải động để tìm trong thư mục hiện hành của thực thi, giống như những gì Windows không với DLL? Mọi người không cần phải sửa đổi bất kỳ biến môi trường nào (ví dụ: DYLD_LIBRARY_PATH), vì tôi lại muốn điều này hoạt động ngoài hộp.

Trả lời

5

Như bạn đã đề cập, bạn không sử dụng Xcode, vì vậy hơi khó. Dưới đây là các tùy chọn theo thứ tự ưu tiên của tôi:

  1. Chuyển sang Xcode. Sử dụng khung công tác. Các thư viện SDL có sẵn như là các khuôn khổ đã có, và tôi đã nhìn thấy nhiều hơn một vài trò chơi thương mại với một libsdl.framework bên trong gói ứng dụng.

  2. Sử dụng khung công tác, nhưng giữ Makefiles của bạn. Tải xuống các phiên bản khung của thư viện SDL của bạn (hoặc tự xây dựng chúng) và liên kết với chúng bằng cờ liên kết -framework. Phân phối các khung công tác với ứng dụng của bạn hoặc không, và yêu cầu người dùng của bạn đưa chúng vào một trong ~/Library/Frameworks hoặc trong/Library/Frameworks. Tôi sẽ không bận tâm với một trình cài đặt cho việc này.

  3. Liên kết tĩnh với SDL. Trong Makefile, bạn sẽ phải liệt kê đường dẫn của các thư viện tĩnh thay vì sử dụng cờ -l, ví dụ, bạn chạy "ld blah blah /opt/local/lib/libsdl.a". Không có cách nào tôi biết để nói với -l thích tĩnh hơn các thư viện được chia sẻ, và tin tôi đi, tôi đã nhìn.

+0

Sau khi suy nghĩ về nó, tôi nghĩ rằng tôi sẽ đi với liên kết tĩnh để phân phối. Nếu tôi sẽ phân phối các thư viện động anyways, mà đánh bại một số mục đích của việc sử dụng chúng, vì vậy tôi cũng có thể tránh được nỗi đau của đối phó với bộ nạp động. –

+1

4. sử dụng tùy chọn 2. ở trên, đặt các khung bên trong gói .app của bạn (tệp .dmg) và thay đổi đường dẫn các nhu cầu thực thi với install_name_tool. Dưới đây là một số ví dụ về cách install_name_tool được sử dụng: http://qt-project.org/doc/qt-4.8/deployment-mac.html. Dietrich, bạn có thể kết hợp điều này vào câu trả lời của bạn được không? –

+0

@ MilanBabuškov: Có vẻ như điều này đã được đưa vào câu trả lời dưới đây. Tôi thấy không cần sao chép thông tin. –

3

Liên kết tĩnh các thư viện.

+0

Rất nhiều để tái sử dụng mã. –

+6

Các thư viện được liên kết tĩnh được tính là "tái sử dụng mã", vì mã thư viện vẫn chỉ phải được viết/kiểm tra/sửa lỗi một lần, bất kể có bao nhiêu ứng dụng sẽ sử dụng nó. Trong khi đó là sự thật rằng nhiều bản sao của mã biên dịch có thể kết thúc trên đĩa của người dùng, đó không phải là một vấn đề lớn như nó được sử dụng để được bây giờ mà các ổ đĩa cứng là quá lớn. –

13

Cách tiếp cận cơ bản cho điều này là gửi chúng trong gói .app. Sau đó, bạn sẽ sửa đổi vị trí mà trình liên kết tìm kiếm các thư viện được chia sẻ để bao gồm điều này.

Các bước thực hiện:

  1. Tạo một file bản sao mới xây dựng giai đoạn tới mục tiêu của bạn là bản sao các tập tin vào thư mục Khung của bó .app.

  2. Chỉnh sửa các thiết lập "Runpath Search Paths" build cấu hình để bao gồm @executable_path/../Frameworks

Nếu bạn xây dựng thực thi của bạn với những thay đổi và sau đó nhìn, bạn sẽ thấy rằng các dylibs tồn tại trong Foo.app/Contents/Framework thư mục và chạy otool -L Foo.app/Contents/MacOS/Foo nên thu nhập và nhập tiền tố bởi @rpath cho các dylib đó.

Từ Cocoabuilder post này:

Nói chung, @loader_path được ưa thích hơn @executable_path, vì nó
cho phép các khung làm việc trong cả hai khả năng thực hiện một bó,
plugin, hoặc sub-framework nhúng. Nhược điểm duy nhất là @loader_path
yêu cầu 10.4 hoặc mới hơn. Nếu bạn sử dụng phiên bản 10.5 trở lên, @rpath thậm chí là
tốt hơn @loader_path.

+0

Tôi không sử dụng Xcode (không có gói ứng dụng.), Chỉ cần đồng bộ cũ gcc và thực hiện. Tôi cũng đang sử dụng OS X 10.4; theo http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html, đường dẫn tìm kiếm đường chạy chỉ được hỗ trợ trên 10.5 trở lên. –

+1

Tôi tin rằng @executable_path sẽ hoạt động ngay cả trên 10.4 (@ loader_path và @rpath sẽ không). Bạn cũng có thể đọc: http://blog.onesadcookie.com/2008/01/installname-magic.html – nall

+0

Nếu bạn không sử dụng Xcode, đặt cược tốt nhất của bạn có thể là sử dụng Autotools và bạn bè. –

Các vấn đề liên quan