是否有可能让clang ++链接dylib相对而不使用install_name_tool?

时间:2015-08-05 05:20:51

标签: macos shared-libraries dylib clang++

摘要

将可执行文件与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>

TL; DR

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

1 个答案:

答案 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