2012-09-27 44 views
6

Tôi đang cố gắng tìm cách tốt nhất để đóng gói một thư viện tĩnh (cho phép gọi là Lib1) bao gồm một lớp tùy chọn (ví dụ: ClassA), bản thân nó yêu cầu một thư viện tĩnh thứ hai (Lib2). Nói cách khác, Lib2 chỉ cần thiết nếu ClassA được tham chiếu trong mã của dự án. Mọi thứ dường như hoạt động tốt, trừ khi Lib1 được sử dụng trong một dự án không sử dụng ClassA (và do đó không bao gồm Lib2), nhưng yêu cầu cờ liên kết -ObjC (vì các phụ thuộc dự án khác, không phải của tôi).ObjC: Cách biên dịch thư viện tĩnh bao gồm các lớp tùy chọn phụ thuộc vào thư viện của bên thứ ba

Tôi đang cố gắng để tìm ra một giải pháp dễ dàng cho ba kịch bản sau đây:
1) dự án bao gồm lib tĩnh của tôi, KHÔNG sử dụng lớp tùy chọn, không xác định cờ -ObjC
2) dự án bao gồm lib tĩnh của tôi, KHÔNG sử dụng lớp tùy chọn, nhưng yêu cầu -ObjC flag
3) dự án bao gồm thư viện tĩnh static + thứ hai của tôi và DOES sử dụng lớp tùy chọn (chúng tôi không quan tâm đến cờ -ObjC tại điểm này)

Có một lá cờ liên kết để tách lớp tùy chọn ra khỏi ứng dụng dự án cuối cùng để không yêu cầu lib tĩnh thứ hai không? Tôi đoán các lựa chọn thay thế khác của tôi là phát hành nhiều phiên bản lib tĩnh của tôi, một phiên bản bao gồm lớp tùy chọn (lựa chọn tiêu chuẩn), không có (lựa chọn thay thế, cho các dự án có yêu cầu -BjC), hoặc có thể cung cấp tệp sơ khai, cung cấp các triển khai rỗng của tất cả các lớp cần thiết từ thư viện tĩnh thứ hai? Điều này có vẻ như nó có thể là một vấn đề phổ biến trong thế giới thư viện tĩnh ... là có một thực hành tốt nhất cho kịch bản này?

Cảm ơn!


Giải pháp:

1) Đề nghị cho người dùng -ObjC của tôi mà họ sử dụng -force_load để thay thế. (nhờ Rob!)
2) Đối với người dùng không thể thực hiện 1, tôi sẽ có một bản dựng thay thế không bao gồm ClassA

Trả lời

6

Cách tốt nhất là luôn có liên kết nhị phân cuối cùng tất cả các lib tĩnh cần thiết . Bạn không bao giờ nên gộp một thư viện tĩnh vào thư viện khác. Bạn hoàn toàn không bao giờ nên gộp một thư viện tĩnh nổi tiếng (ví dụ: mã nguồn mở) vào một thư viện tĩnh mà bạn gửi. Điều này có thể gây ra đau đầu đáng kinh ngạc cho người tiêu dùng cuối cùng bởi vì họ có thể kết thúc với nhiều phiên bản của cùng một mã. Theo dõi các lỗi có thể đến từ điều này là cực kỳ khó khăn. Nếu họ may mắn, họ sẽ chỉ nhận được các lỗi biên dịch khó hiểu. Nếu họ không may mắn, mã của họ sẽ hoạt động theo những cách không thể đoán trước và ngẫu nhiên sụp đổ.

Gửi tất cả các thư viện tĩnh một cách riêng biệt. Cho khách hàng của bạn biết họ cần liên kết với ai để có các cấu hình khác nhau. Cố gắng tránh điều này chỉ làm cho cuộc sống của họ trở nên khó khăn.

Một số cuộc thảo luận khác có thể hữu ích:


Cờ -ObjC phải ngăn chặn việc tự động tước của ClassA hoàn toàn, dù được sử dụng hay không (xem TN1490 để biết thêm chi tiết).

Nếu ClassA không bao giờ được sử dụng ngoại trừ trong một số trường hợp nhất định và bạn muốn tiết kiệm dung lượng, có lẽ bạn nên di chuyển ClassA vào thư viện tĩnh của chính nó. Hoặc sử dụng #ifdef để biên dịch điều kiện.

Cách khác, bạn có thể xóa cờ -ObjC và sử dụng -force_load để tải riêng bất kỳ đơn vị biên dịch chỉ loại nào (đây là vấn đề -ObjC được sử dụng để giải quyết).

+0

Cảm ơn bạn đã liên kết, họ đã giúp tôi hiểu rõ hơn về trang điểm của một lib tĩnh! –

+0

Tôi không thực sự gói bất kỳ lib tĩnh nào vào lib tĩnh của mình. Trong lib tĩnh của tôi (gọi nó là Lib1), tôi có một lớp (nói ClassA) mà phụ thuộc vào một lib tĩnh (Lib2) đang được liên kết vào ứng dụng. ClassA sẽ không bao giờ được sử dụng nếu không có Lib2. Dường như trình biên dịch/trình liên kết đủ thông minh để loại bỏ ClassA khỏi ứng dụng cuối cùng, nếu nó không được sử dụng. Tuy nhiên, nếu cờ liên kết -ObjC được chỉ định, trình biên dịch/trình liên kết cố gắng giải quyết các phụ thuộc Lib2 của ClassA, nhưng không thể ... bất kể ClassA có được tham chiếu trong ứng dụng hay không. Tôi đã hy vọng cho một lá cờ liên kết ma thuật mà sẽ loại bỏ ClassA –

+1

Cập nhật với một số suy nghĩ. Không dễ để sửa lỗi này. ObjC rất năng động và hoàn toàn bình thường khi tham chiếu các lớp trong thời gian chạy theo cách mà trình liên kết không thể nhìn thấy ở thời gian liên kết (tải nib được thực hiện theo cách này). Rất khó để người liên kết có được quyền này nếu bạn đặt tất cả mọi thứ trong cùng một tệp mà không truyền tham số -force_load riêng lẻ thay vì tham số -ObjC lớn. –

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