2012-09-27 12 views
6

Próbuję znaleźć najlepszy sposób na spakowanie statycznej biblioteki (pozwala to nazwać ją Lib1), która zawiera opcjonalną klasę (na przykład ClassA), który sam wymaga drugiej biblioteki statycznej (Lib2). Innymi słowy, Lib2 jest potrzebny tylko wtedy, gdy odwołanie do klasy A w kodzie projektu. Wydaje się, że rzeczy działają dobrze, chyba że Lib1 jest używany w projekcie, który nie używa klasy A (a więc nie obejmuje biblioteki Lib2), ale wymaga flagi -ObjC linker (z powodu innych zależności projektu, nie mojej).ObjC: Jak skompilować bibliotekę statyczną, która zawiera opcjonalne klasy zależne od biblioteki innej firmy

Próbuję wymyślić proste rozwiązanie dla trzech następujących scenariuszy:
1) Projekt obejmuje moje statyczne lib, nie korzysta z opcjonalnego klasę, nie precyzuje -ObjC flagę
2) projekt zawiera moją statyczną bibliotekę, NIE używa klasy opcjonalnej, ale wymaga flagi -ObjC
3) zawiera moją statyczną bibliotekę + drugą statyczną bibliotekę i używa opcjonalnej klasy (nie dbamy o flagę -ObjC na ten punkt)

Czy jest tam flaga linkera, aby usunąć moją opcjonalną klasę z końcowej aplikacji projektu, aby nie wymagała drugiej statycznej biblioteki? Sądzę, że moje inne alternatywy to wydawanie wielu wersji mojej statycznej biblioteki, która zawiera klasę opcji (standardowy wybór), taką, która nie działa (alternatywa dla projektów z wymaganiami -ObjC) lub może dostarczać plik pośredniczący, który dostarcza puste implementacje wszystkich klas wymaganych od drugiej biblioteki statycznej? Wygląda na to, że może to być typowy problem w świecie bibliotek statycznych ... czy istnieje najlepsza praktyka w tym scenariuszu?

Dzięki!


Rozwiązanie:

1) Zaproponuj do moich -ObjC użytkowników, którzy używają -force_load zamiast. (dzięki Rob!)
2) Dla użytkowników, którzy nie mogą wykonać 1, będę mieć alternatywną kompilację, która nie obejmuje klasy A

Odpowiedz

6

Najlepszą praktyką jest zawsze posiadanie końcowego łącza binarnego wymaganego przez wszystkie statyczne biblioteki . Nigdy nie należy pakować jednej biblioteki statycznej w drugą. Absolutnie nigdy nie należy pakować dobrze znanej (tj. Otwartej) biblioteki statycznej do statycznej biblioteki, którą wysyłasz. Może to wywołać niesamowite bóle głowy dla końcowego użytkownika, ponieważ mogą skończyć z wieloma wersjami tego samego kodu. Śledzenie błędów, które mogą z tego wyniknąć, jest szalenie trudne. Jeśli będą mieli szczęście, będą po prostu mylące błędy kompilatora. Jeśli mają pecha, ich kod będzie działał w nieprzewidywalny sposób i losowo się zawiesi.

Wysyłaj wszystkie statyczne biblioteki osobno. Powiedz swoim klientom, które z nich muszą połączyć w różnych konfiguracjach. Próby uniknięcia tego po prostu utrudniają życie.

niektórych innych dyskusjach, które mogą być użyteczne:


Flaga -ObjC powinna zapobiegać automatycznemu odpędzaniu z ClassA w całości, niezależnie od tego, czy jest używana, czy nie (więcej szczegółów można znaleźć w artykule TN1490).

Jeśli ClassA nigdy nie jest używany, z wyjątkiem pewnych okoliczności i chcesz zaoszczędzić miejsce, prawdopodobnie powinieneś przenieść ClassA do swojej własnej biblioteki statycznej. Lub użyj #ifdef, aby warunkowo go skompilować.

Alternatywnie można usunąć flagę -ObjC i użyć -force_load do samodzielnego załadowania jednostek kompilujących tylko kategorię (co jest problemem, do którego adres używany jest -ObjC).

+0

Dzięki za linki, pomogły mi w pełni zrozumieć makijaż statycznej biblioteki! –

+0

Nie pakuję żadnych statycznych bibliotek do mojej statycznej biblioteki. W mojej statycznej bibliotece lib (nazywam ją Lib1) mam klasę (na przykład ClassA), która zależy od innej statycznej biblioteki lib (Lib2), która jest połączona z aplikacją. Klasa A nigdy nie będzie używana bez uwzględnienia Lib2. Wygląda na to, że kompilator/linker jest wystarczająco inteligentny, aby usunąć klasę A z ostatecznej aplikacji, jeśli nie była używana. Jeśli jednak określono flagę -ObjC linker, kompilator/linker spróbuje rozwiązać zależności klasy Lib2 ClassA, ale nie może ... niezależnie od tego, czy ClassA kiedykolwiek była odwoływana w aplikacji. Miałem nadzieję na flagę magicznego linkera, która ośmieliłaby aktualizację ClassA –

+1

. Naprawienie tego nie jest łatwe. ObjC jest wysoce dynamiczny, a jego całkowicie normalne względem klas odniesienia w czasie wykonywania w sposób, który linker nie widzi w czasie łącza (ładowanie nib jest wykonywane w ten sposób). Bardzo trudno jest linkerowi uzyskać to prawo, jeśli umieścisz wszystko w tym samym pliku bez podania indywidualnych parametrów -force_load zamiast dużego parametru -ObjC. –

Powiązane problemy