将可执行文件与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
进入项目的程序运行正常,但尝试从其他任何地方运行它,例如只需双击它,将导致以下错误:
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只是以已经使用main
开头的方式链接@executable_path
。在编译具有任意数量的dylib的程序时,似乎很奇怪,必须为每一个程序完成。
这真的是唯一的方法吗?这是cmake和xcode在幕后做的事情吗?有没有理由我们不能只相对而不是绝对地clang++
链接?
我找到了一些使这个过程更容易的工具,例如mac dylib bundler,但我很好奇是否有人对为什么这样做有任何见解。< / p>
有没有办法让change just this line避免运行install_name_tool -change
?
答案 0 :(得分:2)
确实有可能:
在编译我的库时,我将其install_name
设置为@rpath
:
clang++ -dynamiclib lib_src/myprint.cpp -o myprint.dylib -install_name @rpath/myprint.dylib
然后在编译可执行文件时,我将rpath
设置为@executable_path
,这可以在一个步骤中完成:
clang++ main_src/main.cpp -o main -I ./lib_src myprint.dylib -rpath @executable_path
有关@rpath
和@executable_path
的详细说明,请查看此维基:https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath