Могу ли я включить фреймворк в другой фреймворк? - PullRequest
8 голосов
/ 19 августа 2010

Я пишу фреймворк (называемый Lighthouse.framework), который, в свою очередь, использует код из другого фреймворка (точнее, RegexKit.framework). Я скопировал RegexKit.framework в свой собственный фреймворк, чтобы он имел следующую структуру:

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

Однако, когда я пытаюсь запустить приложение, которое использует Lighthouse.framework (мой фреймворк), я получаю следующую ошибку:

dyld: библиотека не загружена: @executable_path /../ Frameworks / RegexKit.framework / Versions / A / RegexKit

Ссылка: /Users/mdippery/Developer/Projects/Current/lighthouse/build/Debug/Lighthouse.framework/Versions/A/Lighthouse

Причина: изображение не найдено

Очевидно, что загрузчик не находит RegexKit.

Вот пути, которые загрузчик ожидает загрузить, любезно 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)

Могу ли я включить фреймворк в другой фреймворк? Это правильный способ сделать это? Как я могу устранить свою ошибку?

Ответы [ 3 ]

8 голосов
/ 19 августа 2010

Самый простой способ - использовать @rpath.Ваша конфигурация должна выглядеть следующим образом:

  1. Установить для каталога установки RegExKit.framework значение @ rpath
  2. Установить для каталога установки Lighthouse.frameworks значение @ rpath
  3. Установить путь запуска Lighthouse.frameworkПоиск путей к @ loader_path / Frameworks
  4. Убедитесь, что RegExKit.framework скопирован в подпапку Lighthouse.framework Framework (для этого используйте настраиваемую фазу сборки)

Наконец, любые приложения, ссылающиеся наLighthouse.framework должен установить для путей поиска Runpath значение @loader_path /../ Frameworks

1 голос
/ 20 августа 2010

Я обнаружил исправление этой проблемы.Я включил некоторые идеи из ответа Сбота, но исправить было проще.Я запустил этот сценарий:

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}"

как этап сценария запуска сборки.

Обратите внимание, что для общего случая необходимо изменить @executable_path/../ на @loader_path/, и всехорошо.

1 голос
/ 19 августа 2010

Да, вы можете.

Тем не менее, вам нужен включенный фреймворк, чтобы «знать», каким будет его установленное местоположение во время его сборки; в противном случае, dyld не сможет найти его во время выполнения, как вы видели.

Соответствующими настройками в XCode, если я правильно помню, являются «Каталог установки» и «Имя установки платформы». Последнее, вероятно, не будет иметь значения для вашего использования, но вам нужно, чтобы первое было чем-то вроде: @executable_path/../Frameworks/Lighthouse.framework/Versions/A/Frameworks/RegexKit.framework/Versions/A/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...