2011-08-01 17 views
11

Câu hỏi này đã được hỏi trước đây, nhưng đào sâu vào tài liệu cho các công cụ phát triển khác nhau có vẻ như là có thể, không rõ ràng.Cách tạo thư viện tĩnh cho iOS mà không cần đặt tất cả các ký hiệu công khai

Động lực: Tạo thư viện tĩnh để các nhà phát triển iOS khác sử dụng. Một số biểu tượng trong thư viện sẽ gây ra vấn đề nếu xuất khẩu vì vậy tôi muốn làm cho chúng trở thành biểu tượng chỉ dành cho nội bộ. Với thư viện động, điều này thật dễ dàng, chỉ cần sử dụng đối số -exported_symbols_listlibtool (ld) và liệt kê những đối tượng bạn muốn công khai. Tài liệu libtool sẽ không cho phép đối số này cho các thư viện tĩnh.

Thư viện có một số tệp ObjectiveC .m sử dụng mã từ nhau. Chỉ một lớp trong nhóm cần được công khai cho người dùng của tệp thư viện tĩnh cuối cùng.

Đã thử libtool -exported_symbols_list publicsymbols.exp nhưng đối số đó cho libtool không được hỗ trợ với -static cho thư viện tĩnh.

Không thể đặt biểu tượng ở chế độ riêng tư với các thuộc tính (nếu điều đó thậm chí hoạt động) vì chúng là cần thiết bởi các tệp .m khác trong nhóm.

trông giống như ld thể mất vài file .o và liên kết chúng lại với nhau thành một file .o mới (thông qua đối số -r) và nó không có "năng động chỉ" từ chối trách nhiệm cho lập luận -exported_symbols_list (mà chỉ có thể là tài liệu không rõ ràng ...).

cũng giống như một thử nghiệm tôi xây dựng dự án của tôi với Xcode vì vậy tôi đã tất cả các file .o thực hiện, và sau đó cố gắng gọi ld trên dòng lệnh, như vậy:

ld -r -x -all_load -static -arch armv6 -syslibroot {path} 
    -filelist /Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Distribution-iphoneos/ABCLib-device.build/Objects-normal/armv6/ABCsdk.LinkFileList 
    -exported_symbols_list {exp file path} -o outputfile.o 

nơi {path} loại mọi thứ có đường dẫn dài đến những nơi thích hợp trong đó.

nhưng tôi nhận được lỗi như sau:

/usr/bin/ld_classic: /Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Distribution-iphoneos/ABCLib-device. xây dựng/Đối tượng bình thường/ARMv6/ABCmain.o không tương thích, tập tin chứa loại không được hỗ trợ của phần 3 (_ TEXT, _picsymbolstub4) trong lệnh tải 0 (phải ghi rõ "-dynamic" sẽ được sử dụng)

nên có điều gì đó có vẻ sai ở đó ...

Bất cứ ai cũng biết một cách thông minh để thực hiện công việc này? Cảm ơn.

+0

Bạn cần ẩn biểu tượng nào? – Macmade

+0

Các ký hiệu có thể xung đột nếu chúng có cùng thư viện con đã được liên kết với ứng dụng của chúng (JSONkit nói). Tôi có thể, rõ ràng, chỉ cần bao gồm các tệp JSONKit và nói để bao gồm chúng cũng nếu chúng chưa có trong dự án của bạn, nhưng tôi hy vọng một tệp .h và .a duy nhất sẽ được thêm vào dự án để tích hợp sạch hơn . – Dad

Trả lời

14

Điều này thực sự là không thể, tôi xin lỗi để nói. Nó phải làm với cách các thư viện tĩnh hoạt động. Thư viện tĩnh nhỏ hơn một bó đối tượng *.o tệp được nhóm lại với nhau, nhưng thư viện động là một hình ảnh nhị phân có thể tải, giống như tệp thực thi.

Giả sử bạn có bốn tác phẩm,

  • common.c định nghĩa common, đó là "private"
  • fn1.c định nghĩa fn1, trong đó kêu gọi common.
  • fn2.c xác định fn2, gọi số common.
  • other.c định nghĩa other.

Trong thư viện động, trình liên kết kết hợp mọi thứ vào một đoạn mã lớn. Thư viện xuất other, fn1fn2. Bạn phải tải toàn bộ thư viện hoặc không có thư viện nào, nhưng cả hai chương trình đều có thể tải nó mà không cần đặt nhiều bản sao vào bộ nhớ. Điểm nhập vào common chỉ đơn giản là thiếu từ bảng biểu tượng - bạn không thể gọi nó từ bên ngoài thư viện vì trình liên kết không thể tìm thấy nó.

Lưu ý rằng ứng dụng và thư viện được chia sẻ có cùng định dạng: một ứng dụng về cơ bản là thư viện được chia sẻ chỉ xuất một biểu tượng, main. (Điều này không chính xác nhưng đúng.)

Trong thư viện tĩnh, trình liên kết không bao giờ chạy. Tất cả các tệp đều được biên dịch thành các tệp * .o và được lưu vào thư mục * .a thư viện. Các tham chiếu nội bộ sẽ không được giải quyết.

Giả sử ứng dụng của bạn gọi fn1. Trình liên kết thấy một cuộc gọi chưa được giải quyết tới fn1 và sau đó xem qua các thư viện. Nó tìm thấy một định nghĩa cho fn1 trong fn1.o. Sau đó, trình liên kết sẽ thông báo một cuộc gọi chưa được giải quyết tới common, vì vậy nó trông giống như vậy. Chương trình này sẽ không nhận được mã từ fn2.c hoặc other.c, bởi vì nó không sử dụng các định nghĩa từ các tệp đó.

Thư viện tĩnh rất cũ và chúng không có bất kỳ tính năng nào của thư viện động. Bạn có thể nghĩ về một thư viện tĩnh về cơ bản là một tệp zip đầy mã nguồn được biên dịch, không giống như một thư viện động được liên kết với nhau. Không ai bận tâm mở rộng định dạng lưu trữ để thêm khả năng hiển thị biểu tượng. Khi bạn liên kết với một thư viện tĩnh, bạn sẽ nhận được kết quả tương tự như khi bạn đã thêm mã nguồn của thư viện vào chương trình của bạn.

Phiên bản ngắn: Thư viện động có một bảng biểu tượng của tất cả các biểu tượng đã xuất, nhưng không có biểu tượng riêng tư nào. Trong cùng một cách, một tệp đối tượng có một danh sách tất cả các biểu tượng extern của nó nhưng không có biểu tượng nào trong số static. Nhưng một thư viện tĩnh không có bảng biểu tượng, nó chỉ là một kho lưu trữ. Vì vậy, không có cơ chế để làm cho mã riêng thành một thư viện tĩnh (ngoài việc xác định các đối tượng static, nhưng điều đó không làm việc cho các lớp Objective-C).

Nếu chúng tôi biết lý do bạn cố gắng thực hiện điều này, có lẽ chúng tôi có thể đưa ra đề xuất cho bạn. (Có phải vì lý do bảo mật không? Tất cả các câu hỏi này đều có giải pháp.)

+0

Tôi không muốn viết một câu trả lời mới, bởi vì bạn đã viết một lời giải thích tuyệt vời ở đây, nhưng có vẻ như giải pháp, sau đó, sẽ kết hợp tất cả các tệp nguồn vào một tệp được biên dịch thành một đơn vị duy nhất. (Tự động, không phải thủ công.) Dự án SQLite thực hiện một việc như thế này. – benzado

+0

@ benzado: Điều đó không hiệu quả đối với các lớp Objective C. –

+0

Đủ công bằng, vì vậy ngay cả khi anh ta có thể ẩn các ký hiệu khác (chức năng, hằng số) thì tên lớp vẫn sẽ bị lộ ra, vì vậy không có vấn đề gì. – benzado

0

XCode BuildSetting có thể thực hiện việc này! 1. Set Perform Single-Object Prelink-YES 2. Set Exported Symbols File-path_for_symbols_file

có lẽ bạn nên loại bỏ -static, -exported_symbols_list không thể làm việc lib tĩnh, nhưng có thể có hiệu lực vào tập tin đối tượng.

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