两个 Xcode 的实用工具: otool 和 install_name_tool

96
aaaron7
2016.03.11 00:39* 字数 807

otoolinstall_name_tool 是 Xcode 自带的两个工具,提供了对库文件(.so,.dylib,etc..) 进行查看与修改的功能。完整的功能可以直接在 Terminal 运行查看。这里就介绍两个很实用的场景。

Incompatible library version 错误

我们编译一些工具的时候,有时候会提示 Incompatible library version 提示某个 dependence 的库文件版本不对。这个时候我们就可以使用 otool 帮助我们查看具体某个库文件的版本,来 debug 是不是编译时候找个库文件找错了。

拿 libffi.dylib 这个库来说,执行 otool -L /usr/lib/libffi.dylib, 会输出以下内容:

/usr/lib/libffi.dylib:
 /usr/lib/libffi.dylib (compatibility version 1.0.0, current version 1.0.0)
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.0.0)

可以看到,不仅输出了这个库的版本,还能输出该库的依赖,这在某些场景下非常有用,因为 otool 不仅能分析库文件,还能分析可执行文件。

dyld: Library not loaded: xxx 错误

上一个错误一般是编译阶段,这个错误一般出现在运行阶段。代表找不到可执行文件的某个依赖的库。比如如下输出:

dyld: Library not loaded: cbits.so
  Referenced from: /Users/aaaron7/Documents/book/ios_beginner_guide/interpreter/.stack-work/install/x86_64-osx/lts-5.2/7.10.3/bin/interpreter-exe
  Reason: image not found

./run.sh: line 1:  7313 Trace/BPT trap: 5       stack exec interpreter-exe

当我尝试运行 interpreter-exe 这个可执行文件时,系统找不到这个程序依赖的一个库 cbits.so。 于是程序失败。

假设我们已经知道 cbits.so 在哪。要如何解决这个问题呢?

首先,我们先用 otool 查看一下这个可执行文件的依赖情况,otool -L .stack-work/install/x86_64-osx/lts-5.2/7.10.3/bin/interpreter-exe, 输出如下内容:

.stack-work/install/x86_64-osx/lts-5.2/7.10.3/bin/interpreter-exe:
 cbits.so (compatibility version 0.0.0, current version 0.0.0)
 /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
 /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
 @rpath/libffi.dylib (compatibility version 7.0.0, current version 7.2.0)
 /usr/lib/libedit.3.dylib (compatibility version 2.0.0, current version 3.0.0)
 /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
 /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)

能看到加载失败的 cbits.so 并没有路径信息,这可能有很多种原因造成。那能不能不重新编译程序来修复这个问题呢? 这个时候我们就要请出 install_name_tool.

install_name_tool 功能也很多,最核心就是用来替换依赖的名字。简单的来讲,我们可以用它来把 cbits.so 的路径加上去。输入 install_name_tool -change cbits.so /path/to/cbits.so interpreter-exe

命令的意思非常明显,把原来的 cbits.so 替换为带路径的版本,第三个参数是要修改的可执行文件名。

这个时候用 otool 再查看一个可执行文件,路径应该已经修改了,理论上也就能够运行了。


想看更多内容? 可以关注我的知乎

FP 与 Compiler