MacOS修改.dylib文件依赖库路径

MacOS修改.dylib文件依赖库路径,第1张

1.使用otool -L 查看运行程序依赖路径

    例1:otool -L xxx.app/Contents/MacOS/xxx

    例2:otool -L xxx.dylib.com

2.修改.app工程.dylib库依赖路径:install_name_tool -change 旧.dylib库路径 新.dylib库路径 xxx.app/Contents/MacOS/xxx

     例:install_name_tool -change /usr/local/libcrypto.1.0.0.dylib  /Library/xxx/xxx/extlib/libcrypto.1.0.0.dylib  樱山xxx.app/Contents/MacOS/xxx

     注:@executable_path:可执行文件所在的目录。可使用@executable_path设置引用库的相对路径,@executable_path/../../../extlib/libcrypto.1.0.0.dylib

      @loader_path.     @rpath

3.修改.dylib库依赖路径:install_name_tool -id 要使用的路径 旧路孙晌径

     例脊凯中:install_name_tool -id /Library/xxx/xxx/extlib/libcrypto.1.0.0.dylib  libcrypto.1.0.0.dylib

-dynamiclib 表示将A.c  B.c编译成一个动态

-o libA.dylib 用于指定生成的动态库的名称

 -L. 指定当前目录为链接时动态库的查找目录

-lA 指定要链接的动态库为libA.dylib

-lB 指定要链接的动态库为libB.dylib

-o main 指定生成的可执行文件名称为main

直接点击运行可执行文件时出碧野锋现dyld: Library not loaded:  

在当前目录下执行main,注意要加上 ./

(Note:只有动态库才有install_name,应用程序如果引用了某一个动态库,则会在链接时记录该动态库的install_name)

每个动态库(dylib)都有一个install_name,可以认为是动态库初次安装时的默认路径,这个install_name保存在dylib文件中。 

otool -L main

查看dylib的install_name

 otool -D <dylib>

install_name_tool -id <new name><dylib>

更新 install_name_tool of libA.dylib 到 ../libA.dylib

Example: install_name_tool -id ../libA.dylib libA.dylib

install_name_tool -change <old value><new value><executable>

Example: install_name_tool -change libA.dylib ../libA.dylib main

注意:还有一个方法,如果dylib的install_name不正确,将环境变量$DYLD_LIBRARY_PATH设置为dylib所在的路径可以让可执行文件成功找到dylib.

1、 编译:gcc Main.c -L. -lA -lB -o main

2、执行:悔晌./main

3、动态库移动到上一级目录:mv libA.dylib ..

4、编译失败:gcc Main.c -L. -lA -lB -o main

5、动态库移动回当前目录:mv ../libA.dylib .

6、再次编译成功:gcc Main.c -L. -lA -lB -o main

7、再执行:./脊蠢main 

在执行上述链接过程时,编译器顺便将动态库libA.dylib、libB.dylib 的install_name记录到了main程序中,用来在运行时查找并引用该动态库。

后续

在自己的Mac上写了一个基于OpenCV的简单程巧贺辩序;需要传给其他人共同调试,但是可执行文件在他人的Mac上无法运行;执行时会提示:

这样就引申出来一个问题: 在xcode下编译出的程序,在开发机器上运行是没有问题的。但是给其他用户用,就可能出问题。因为用户不一定有这个库。

有两种方法可以解决这个问题;一是给其他用户也安装依赖的库文件;二是将所有的dylib随行发布,消除依赖。

第一种方案不考虑,大部分时候这样做并不现实;下面说说如何随行发布dylib。

单纯将依赖的dylib文件拷贝到可执行文件目录下一同传输过去是不能消除依赖的;执行的时候还是报错;

在编译一个动态库的时候, 你需要指定 INSTALL_PATH. 也就是它的安装路径;编译完成后如果一个可执行程序使用了该动态库, 那么在编译可执行程序的孝缺时候, 动态库的 INSTALL_PATH 会被记录到可执行程序中, 用来定位这个动态库。

因此我们首先需要将用到的dylib文件都拷贝到可执行文件目录下,然后改变动态库的INSTALL_PATH;将其改到可执行文件所在目录;

需要注意的是 :如果依赖多个动态库,用到的动态库已会依赖其他动态库,因此用到的所有的动态库的依赖动态库路径都需要修改。

以OpenCV为例子,假设最终编译出来的可执行文件为 macimgproc ;执行命令: otool -L macimgproc 可看到如下的输出:

说明macimgproc依赖所有的OpenCV动态库文件;因此首先需要将所有动态库文件拷贝到macimgproc所在目录,然后需要将macimgproc文件中的所有 /usr/local/opt/opencv/lib/libopencv_xxx 修改为 @executable_path/libopencv_xxx ;

@executable_path 表示可执行文件所在目录;指示所有OpenCV动态库从可执行文件所在目录查找;

更多 @executable_path 的介绍以及其他变量参见文章 @rpath, @loader_path, @executable_path 。

使用命令 install_name_tool -change {old.dylib} {new.dylib} {filename} 修改动态库的INSTALL_PATH,例如:

执行后重新 otool -L macimgproc 可看到如下的输出:

依次修改所有依赖即可。

整个OpenCV库大概有19个dylib文件,因此写了一个简单的批量拍烂修改脚本:

http://blog.csdn.net/openglnewbee/article/details/17783909

如何使用第三方的dylib

@rpath, @loader_path, @executable_path

Apple Developer:Overview of Dynamic Libraries

Apple Developer: Run-Path Dependent Libraries


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12211877.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存