嗯,同事弄了一个opencv的动态库,在我这里能正常编译过,但是一运行就是
dyld: Library not loaded: @rpath/libopencv_world.4.2.dylib
花了不少时间,啥啥办法都试过了。最后在要放弃的时候,成功了
mark下
-
先按照静态库的方式添加到build settings的header search path(头文件路径)和library search path(库文件路径)中 同时添加动态库到build phases中的link binary with libraries(库文件)中 在build phases中点击左上角的加号“+”,增加“new copy files phase” 将“destination”改为“frameworks” 拖入“libopencv_world.4.2.dylib”(如果run的时候报错找不到这个库,修改为对应的库就行) 设置build settings中的“dynamic library install name”为@rprth/libopencv_world.4.2.dylib(与步骤4的库名一致) 添加build settings中的“run path”为@loader_path/../Frameworks(与步骤4的库名一致)
macOS的dylib采取了比较特殊的机制,每个文件都内置有完整的路径名,如果不把dylib文件放置到这个路径上去,应用调用dylib的时候就会报错找不到库文件。
官方推荐的解决的方法是将库文件及头文件打包编译为Frameworks,随后引入到项目中。
注意到错误中有一个:@rpath。很好奇,于是深入了解了一下
@executable_path 可执行程序的路径
@rpath 可执行程序内部设置的一组路径
@loader_path 加载模块的路径(可能是exe的路径,也可能是dylib的路径)
有意思吧,很多博客说“@executable_path/../Frameworks/”,我相信很多人没有找到在哪里
是这样滴,看这个路径
/Users/用户名/Library/Developer/Xcode/DerivedData/AlgorithmTestDemo_MacCoca-gcdxpunseubbsjbymodzicdwpavp/
Build/Products/Release/AlgorithmTestDemo_MacCoca.app/Contents/Frameworks
太长了,我给了一个随意的回车,方便大家查看。解释一下:
用户名:就是你自己的mac的名字啦
Library是一个隐藏文件,“shift+commond+ . ” 可以查看
然后一直往下打开,你就会看到这个叫做“Frameworks”的文件夹了,也就是步骤3中我们添加的。
(1)那么“@executable_path/../Frameworks/”,为什么呢?看位置
我们的可执行文件的真实位置就在这个MacOS里面,所以“@executable_path”就是这个MacOS里面了喽!解决一个
(2)再来看“@loader_path”。这个path应用的非常多,可以通过这个path来设置动态库的install path name。但是它有自己的局限性,就是当一个动态库同时被多个程序引用时,如果位置不一样的话仍然需要手动修改。
(3)最后@rpath。它是run path的缩写。本质上它不是一个明确的path,甚至可以说它不是一个path。它只是一个变量,或者叫占位符。这个变量通过XCode中的run path选项设置值,或者通过install_name_tool的-add_rpath设置值。设置好run path之后,所有的@rpath都会被替换掉。此外,run path是可以设置多个值的,这样看来就和Windows下的PATH变量差不多了。run path指定的多个值就可可以完美解决掉很多问题了。
参考链接:
http://www.tanhao.me/pieces/1361.html/