2010-08-18 6 views
8

Piszę framework (o nazwie Lighthouse.framework), który z kolei używa kodu z innego frameworka (a dokładniej RegexKit.framework). Mam skopiowane RegexKit.framework w moim ramy tak, że ma strukturę tak:Czy mogę dołączyć ramy w innym systemie?

Lighthouse.framework/ 
    Versions/ 
    A/ 
     Frameworks/ 
     RegexKit.framework 
     Lighthouse 

Jednak kiedy próbuję uruchomić aplikację, która wykorzystuje Lighthouse.framework (mój ramowa), otrzymuję następujący błąd:

dyld: Library not loaded: @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit

Referenced from: /Users/mdippery/Developer/Projects/Current/lighthouse/build/Debug/Lighthouse.framework/Versions/A/Lighthouse

Reason: image not found

Oczywiście program ładujący nie znajduje RegexKit.

Here're ścieżki ładowarka spodziewa się załadować, dzięki uprzejmości otool:

build/Debug/Lighthouse.framework/Versions/A/Lighthouse: 
    /Users/mdippery/Library/Frameworks/Lighthouse.framework/Versions/A/Lighthouse (compatibility version 1.0.0, current version 1.0.0) 
    /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 12.0.0) 
    @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit (compatibility version 0.4.0, current version 0.6.0) 
    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4) 
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0) 
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 476.19.0) 
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 677.26.0) 

Mogę to ramy w innym ram? Czy to właściwy sposób? Jak mogę rozwiązać mój błąd?

+0

Oto, jak można dołączyć ramy w innym systemie. http://stackoverflow.com/a/27638841/1582217 Nazywa się to ramą parasolową. –

+0

możliwy duplikat [Jak utworzyć ramę parasolową w systemie iOS sdk?] (Http://stackoverflow.com/questions/27484997/how-to-create-an-umbrella-framework-in-ios-sdk) –

Odpowiedz

1

Znalazłem poprawkę dla tego problemu. Włączyłem kilka pomysłów z odpowiedzi na sbooth, ale poprawka była prostsza. Uruchomiłem ten skrypt:

install_name_tool -change @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit @loader_path/Frameworks/RegexKit.framework/Versions/A/RegexKit "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.framework/Versions/A/${PRODUCT_NAME}" 

jako faza Run Build Script.

Należy pamiętać, że w przypadku ogólnym trzeba zmienić @executable_path/../ na @loader_path/ i wszystko jest w porządku.

+0

Skąd ustawiłeś ten skrypt budujący? W produkcie ramowym lub w produkcie Aggregate? –

1

Tak, możesz.

Potrzebna jest dołączona struktura, aby "wiedzieć", jaka będzie jego zainstalowana lokalizacja w momencie jej budowy; w przeciwnym razie, dyld nie będzie w stanie znaleźć go w czasie wykonywania, jak widzieliście.

Odpowiednimi ustawieniami w XCode, jeśli dobrze pamiętam, są "Katalog instalacyjny" i "Nazwa instalacji ramowej". Ta ostatnia prawdopodobnie nie będzie miała znaczenia dla twojego użycia, ale będziesz potrzebować tego pierwszego, aby być czymś podobnym do: @executable_path/../Frameworks/Lighthouse.framework/Versions/A/Frameworks/RegexKit.framework/Versions/A/

+0

Czy I ustawić katalog instalacyjny podczas budowania Lighthouse.framework (dla Lighthouse.framework)? Próbowałem, ale to nie zadziałało (chociaż może zrobiłem coś nie tak). – mipadi

+0

@mipadi: Jeśli nie tworzysz 'RegExKit.framework', nie będziesz mógł tego zrobić. Dlaczego chcesz, aby RegExKit był zawarty w innym frameworku? To, co robisz, będzie działało dobrze bez tego. –

+0

Byłoby miło, gdyby konsumenci z mojej frameworka musieli jedynie uwzględnić moją strukturę, a nie uwzględniać zależności moich frameworków. – mipadi

8

Najprostszym sposobem jest użycie @rpath. Konfiguracja powinna wyglądać następująco:

  1. Set RegExKit.framework za katalog instalacji do @rpath
  2. zestaw Lighthouse.frameworks męska katalogu instalacyjnego do @rpath
  3. Set Lighthouse.framework na Runpath ścieżek wyszukiwania na @ loader_path/ram
  4. Upewnić się, że RegExKit.framework jest kopiowany do podkatalogu Lighthouse.framework za ramowego (użyć fazę zwyczaj budowania do tego)

Ostatecznie, wszystkie aplikacje Linkin g do pliku Lighthouse.framework powinien ustawić Ścieżki wyszukiwania ścieżki do @ ścieżka_loader /../ Frameworks

+0

Nie buduję RegexKit.framework (używam wstępnie skompilowanego pliku binarnego). Czy nadal mogę ustawić dla niego katalog instalacyjny (nie widziałem sposobu, aby to zrobić)? – mipadi

+1

Możesz użyć do tego funkcji install_name_tool - coś takiego jak nazwa_instalacji_do_zmian @ ścieżka_wykonywania /../ Frameworks @ rpath/Frameworks – sbooth