Это ошибка времени выполнения, вызванная Dynamic Linker
dyld: Library not loaded: @rpath/...
...
Reason: image not found
Ошибка Library not loaded
с @rpath
указывает, что Dynamic Linker
не удается найти двоичный файл.
Проверьте, был ли динамический каркас добавлен в General -> Embedded Binaries
Проверьте @rpath
настройку между потребителем (приложение) и производителем (динамическая структура):
- Динамическая структура:
Build Settings -> Dynamic Library Install Name
- Заявка:
Build Settings -> Runpath Search Paths
Build Phases -> Embed Frameworks -> Destination, Subpath
Динамический компоновщик
Dynamic Library Install Name(LD_DYLIB_INSTALL_NAME)
который используется loadable bundle
( Dynamic framework
как производная), где dyld
вступают в игру
Dynamic Library Install Name
- путь к двоичному файлу (не .framework). Да, они имеют такое же имя, но MyFramework.framework
это packaged bundle
с MyFramework
двоичным файлом и ресурсами внутри.
Этот путь к директории может быть абсолютным или относительным (например @executable_path
, @loader_path
, @rpath
). Относительный путь более предпочтителен, потому что он изменяется вместе с привязкой, которая полезна, когда вы распространяете свой пакет как один каталог
абсолютный путь - пример Framework1
//Framework1 Dynamic Library Install Name
/some_path/Framework1.framework/subfolder1
@executable_path
@executable_path - относительно записи двоичного файла - Пример
использования Framework2
: встроить Dynamic framework
в приложение
//Application bundle(`.app` package) absolute path
/some_path/Application.аpp
//Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework2 binary absolute path
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
//Framework2 @executable_path == Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework2 Dynamic Library Install Name
@executable_path/../Frameworks/Framework2.framework/subfolder1
//Framework2 binary resolved absolute path by dyld
/some_path/Application.аpp/subfolder1/../Frameworks/Framework2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
@loader_path
@loader_path - относительно пакета, который является владельцем этого двоичного варианта
использования: фреймворк со встроенным фреймворком - Framework3_1 с Framework3_2 внутри
//Framework3_1 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1
//Framework3_2 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/Frameworks/Framework3_2.framework/subfolder1
//Framework3_1 @executable_path == Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework3_1 @loader_path == Framework3_1 @executable_path
/some_path/Application.аpp/subfolder1
//Framework3_2 @executable_path == Application binary absolute path
/some_path/Application.аpp/subfolder1
//Framework3_2 @loader_path == Framework3_1 binary absolute path
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1
//Framework3_2 Dynamic Library Install Name
@loader_path/../Frameworks/Framework3_2.framework/subfolder1
//Framework3_2 binary resolved absolute path by dyld
/some_path/Application.аpp/Frameworks/Framework3_1.framework/subfolder1/../Frameworks/Framework3_2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework3_1.framework/Frameworks/Framework3_2.framework/subfolder1
@rpath - Путь поиска Runpath
Пример Framework2
Ранее нам приходилось настраивать Framework для работы с dyld. Это не удобно, потому что один и тот же Framework не может быть использован с другими конфигурациями
@rpath
является составной концепцией, которая опирается на внешнюю (Application) и вложенную (Dynamic Framework) части:
Заявка:
Динамическая структура:
//Application Runpath Search Paths
@executable_path/../Frameworks
//Framework2 Dynamic Library Install Name
@rpath/Framework2.framework/subfolder1
//Framework2 binary resolved absolute path by dyld
//Framework2 @rpath is replaced by each element of Application Runpath Search Paths
@executable_path/../Frameworks/Framework2.framework/subfolder1
/some_path/Application.аpp/Frameworks/Framework2.framework/subfolder1
*../
- перейти к родителю текущего каталога
otool
- инструмент для отображения объектных файлов
//-L print shared libraries used
//Application otool -L
@rpath/Framework2.framework/subfolder1/Framework2
//Framework2 otool -L
@rpath/Framework2.framework/subfolder1/Framework2
//-l print the load commands
//Application otool -l
LC_LOAD_DYLIB
@rpath/Framework2.framework/subfolder1/Framework2
LC_RPATH
@executable_path/../Frameworks
//Framework2 otool -l
LC_ID_DYLIB
@rpath/Framework2.framework/subfolder1/Framework2
install_name_tool
изменить динамические имена установки разделяемой библиотеки с помощью -rpath
CocoaPods
использует use_frameworks!
[О] для регулированияDynamic Linker
[Словарь]
Link Binary with Libraries
и каким-то образом Xcode знает, как скопировать их в ваш пакет приложений, тогда как для пользовательских фреймворков этого просто не происходит.