是否可以让 clang link dylib 相对而不使用 install_name_tool?

Is it possible to have clang++ link dylib's relatively and not use install_name_tool?

总结

当 link 使用 dylib 执行可执行文件时,install_name_tool 是使 dylib 路径相对于可执行文件的唯一方法,或者在 clang 的 [=71 中是否有这样做的方法=]步数?


设置

给定以下项目结构:

 - 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 只是 link main 已经使用了 [=23] =] 开始。似乎很奇怪,当编译一个包含任意数量的 dylib 的程序时,必须对每个 dylib 都这样做。

真的只有这样吗?这是 cmake 和 xcode 在幕后所做的吗?为什么我们不能默认 clang++ link 相对而不是绝对?

我找到了一些可以简化该过程的工具,例如 mac dylib bundler,但我很好奇是否有人对 为什么 有任何见解这样做。


TL;DR

有没有办法 change just this line 避免 运行 install_name_tool -change

确实可以:

编译我的库时,我将其 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 的详细说明,请查看此 wiki:https://wincent.com/wiki/@executable_path,_@load_path_and_@rpath