运行时错误:dyld:库未加载:@rpath/<some_path>
这是由动态链接器引起的运行时错误
dyld: Library not loaded: @rpath/<some_path>
Referenced from: <some_path>
Reason: image not found
错误库没有加载@rpath表示动态链接器找不到二进制文件。
Check if the dynamic framework was added to the front target General -> Frameworks, Libraries, and Embedded Content (Embedded Binaries). It is very simple to drag-and-drop a framework to project with Copy items if needed[About] and miss to add the framework as implicit dependency in
Frameworks, Libraries, and Embedded Content(or check in Add to targets). In this case during compile time Xcode build it as success but when you run it you get runtime error
Check the @rpath setup between consumer(application) and producer(dynamic framework):
动态框架:
构建设置->动态库安装名称
应用程序:
构建设置->运行路径搜索路径
构建阶段->嵌入框架->目标,子路径
框架的Mach-O文件[关于]-动态库和应用程序的框架,库和嵌入式内容[关于]-不嵌入。
动态链接器
Dynamic Library Install Name(LD_DYLIB_INSTALL_NAME) which is used by loadable bundle(Dynamic framework as a derivative) where dyld come into play
Dynamic Library Install Name - path to binary file(not .framework). Yes, they have the same name, but MyFramework.framework is a packaged bundle with MyFramework binary file and resources inside.
This path to directory can be absolute or relative(e.g. @executable_path, @loader_path, @rpath). Relative path is more preferable because it is changed together with an anchor that is useful when you distribute your bundle as a single directory
绝对路径——Framework1示例
//Framework1 Dynamic Library Install Name
/some_path/Framework1.framework/subfolder1
相对路径允许您以动态的方式定义路径。
@executable_path
@executable_path -相对于加载框架的可执行二进制文件
用例:应用程序内部的动态框架(应用程序二进制路径
是@executable_path)或更复杂的应用程序扩展[关于]的例子,它是包含动态框架的应用程序的一部分。@executable_path用于应用程序目标(应用程序二进制路径为@executable_path)和应用程序扩展目标(应用程序扩展二进制路径为@executable_path)
//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 -相对于导致框架被加载的bundle。如果它是一个应用程序,那么它将与@executable_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 -跑道路径搜索路径
Framework2例子
以前我们必须设置一个框架来使用dyld。这并不方便,因为相同的框架不能与不同的配置一起使用。由于此设置是在框架目标端进行的,因此不可能为不同的消费者(应用程序)配置相同的框架。
@rpath是一个复合概念,它依赖于外部(应用程序)和嵌套(动态框架)部分:
Application:
Runpath Search Paths(LD_RUNPATH_SEARCH_PATHS) - @rpath - defines a list of templates which will be substituted with @rpath. Consumer uses @rpath word to point on this list
@executable_path/../Frameworks
Review Build Phases -> Embed Frameworks -> Destination, Subpath to be sure where exactly the embed framework is located
Dynamic Framework:
Dynamic Library Install Name(LD_DYLIB_INSTALL_NAME) - points that @rpath is used together with local bundle path to a binary
@rpath/Framework2.framework/subfolder1
//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
* . ./ -进入当前目录的父目录
对象文件显示工具
//-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![关于]规范动态链接器
(词汇)
(Java ClassLoader)