【发布时间】:2017-03-18 17:39:05
【问题描述】:
这是一个简单的例子:
lib.c:
#include <stdio.h>
void hello_world(void) {
puts("Hello, world!");
}
program.c:
void hello_world(void);
int main() {
hello_world();
return 0;
}
如果我正常编译库并链接它,一切正常:
$ cc lib.c -fPIC -shared -o libmylib.dylib
$ cc program.c -L. -lmylib
$ ./a.out
Hello, world!
但是如果我在构建它之后(但在构建程序之前)重命名库,它就不起作用了:
$ cc lib.c -fPIC -shared -o totally_different_name.dylib
$ mv totally_different_name.dylib libmylib.dylib
$ cc program.c -L. -lmylib
$ ./a.out
dyld: Library not loaded: totally_different_name.dylib
Referenced from: /private/tmp/./a.out
Reason: image not found
[1] 13229 abort ./a.out
为什么会这样? dyld 为什么要查找原始库名?
这在 Linux 上可以正常工作,但是当我在 macOS 上尝试时,它完全失败了(我不知道这是 macOS 与 Linux 的事情,还是 clang 与 gcc 的事情,因为我在 macOS 上使用了 clang,而在Linux)。
如果相关,cc --version 是 Apple LLVM version 8.0.0 (clang-800.0.42.1) x86_64-apple-darwin16.4.0。
【问题讨论】:
-
LD_LIBRARY_PATH=. ./a.out有影响吗? -
@dhke:不,也不是
DYLD_LIBRARY_PATH。 -
otool -L ./a.out应该为您提供程序声明的依赖项列表。至少这可能有助于缩小问题范围。 -
在 macOS 上,库本身也有自己的名称编码。
otool -L应该显示这个。第一行是库本身。您可能也必须使用install_name_tool更改此名称。 -
@FlorianZwoch:确实,
otool -L输出的第一行是库的原始名称。感谢使用install_name_tool的提示!
标签: macos