【发布时间】:2015-10-27 17:26:43
【问题描述】:
总结
在将可执行文件与 dylib 链接时,install_name_tool 是使 dylib 路径相对于可执行文件的唯一方法,还是在 clang 的链接步骤中有这样做的方法?
设置
给定以下项目结构:
- Project Root
| compile.sh
- lib_src
| myprint.cpp
| myprint.h
- main_src
| main.cpp
使用这些文件:https://gist.github.com/JohannesMP/8fa140b60b8ffeb2cae0
运行 compile.sh(为了简单起见,在此处使用而不是 make 文件)会生成以下文件:
- Project Root
| main (a unix executable linked to myprint.dylib)
| myprint.dylib (a dynamic library that main uses)
使用./main 运行程序而cd'd 进入项目工作正常,但尝试从其他任何地方运行它,例如通过简单地双击它,将导致以下错误:
dyld: Library not loaded: myprint.dylib
Referenced from: /Users/Jo/Sandbox/libtest/main
Reason: image not found
Trace/BPT trap: 5
当使用 otool 检查 main 时,我可以看到这是因为 myprint.dylib 的路径不是根据可执行文件定义的:
$ otool -L main
main:
myprint.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
一般修复
据我所知,解决此问题的建议方法是使用 install_name_tool -change 并修改路径以使用 @executable_path:
install_name_tool -change myprint.dylib @executable_path/myprint.dylib main
问题
虽然上述修复显然有效,但对我来说似乎有点不直观,没有办法告诉 clang 以它已经使用 @executable_path 开始的方式链接 main。使用任意数量的 dylib 编译程序时,必须对每个单独的 dylib 进行编译,这似乎很奇怪。
这真的是唯一的方法吗?这是 cmake 和 xcode 在幕后所做的吗?有什么理由不能让clang++ 链接相对而不是绝对默认?
我发现了一些工具可以简化这个过程,例如mac dylib bundler,但我很好奇是否有人对为什么这样做有任何见解。
TL;DR
有没有办法change just this line 避免不得不运行install_name_tool -change?
【问题讨论】:
标签: macos shared-libraries dylib clang++