在 Mac 上用到一些开源的程序,经常需要自己编译,这个时候一般会使用 macports 所提供的工具链进行编译。
在编译的过程中,开源程序所引用的各种其他库,例如 libssl、libz、libgd 之类的,一般都会在 /opt/local/lib 下,而如果把这个编译好的二进制文件给其他人用时,如果其他人没有安装 macports,那么就会缺失这些共享库,从而导致编译好的二进制程序无法运行。
具体原因就是因为 Mac 下链接共享库时,会在链接时将共享库的路径写入到最终的二进制文件中,而默认情况下,这个路径是绝对路径,例如 /opt/local/lib/libz.1.dylib。
所幸苹果提供了 install_name_tool 这个工具来修改共享库的路径。
下面这个脚本就是用来批量替换二进制文件中的共享库路径。
这个脚本会在当前目录下创建 lib 目录,将二进制文件所依赖的 /opt/local/lib 中的共享库复制到 lib 目录中,并修改二进制文件中保存的共享库的路径。
脚本的使用方法,将上面的脚本保存为 fixlibpath.sb,并加上可执行权限,放到要修正的二进制文件所在的目录:
chmod +x fixlibpath.sh
./fixlibpath.sh mybinary
还有共享库会依赖其他共享库的情况,所以也需要对 lib 中复制过来的共享库进行同样的处理:
for f in lib/*; do
./fixlibpath.sh $f
done
可以观察一下脚本的输出,如果输出的内容中,每个共享库所依赖的库路径中不存在 /opt/local/lib,那就表示处理完成了。每个共享库都会有一个 /opt/local/lib 路径的,但是名称与这个共享库一样的路径,这个是不用处理的。
要测试处理完成的二进制文件是否正常,可以将该二进制文件和 lib 目录复制到一台没有安装 macports 或者没有 macports 安装相关共享库的机器上运行,如果能正常运行就表示处理成功了。
参考资料
- http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html
- http://stackoverflow.com/questions/4677044/how-to-use-dylib-in-mac-os-x-c#answer-11585225
--- EOF ---
0 条评论。