【问题标题】:Why can't I rename a shared library after it's been built?为什么我不能在构建共享库后重命名它?
【发布时间】: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 --versionApple 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


【解决方案1】:

感谢Florian Zwoch's comment,我能够找到解决此问题的方法。重命名 dylib 后运行此命令:

install_name_tool -id libmylib.dylib libmylib.dylib

该命令会更改 dylib 的内部 ID。命令语法为install_name_tool -id &lt;new-id&gt; &lt;dylib-path&gt;

最初,dylib 的 ID 是完全不同的名称.dylib。重命名文件不会更改其内部存储的 ID,必须使用 install_name_tool 单独更新。

【讨论】:

  • 我的回答显示了如何解决问题,但我缺乏必要的知识深度来更好地解释正在发生的事情和原因。如果有人发布了一个更好地解释 dylib 的工作原理、clang 如何构建它们、macOS 如何使用它们以及为什么需要这个额外步骤的答案,我会很乐意接受这个答案。
猜你喜欢
  • 2010-11-08
  • 1970-01-01
  • 2018-11-10
  • 2012-06-22
  • 1970-01-01
  • 2015-10-03
  • 1970-01-01
  • 2016-09-04
  • 2012-09-20
相关资源
最近更新 更多