如何在Mac OSX下使用gcc设置可执行文件的运行时路径(-rpath)?

max*_*zig 42 macos linker gcc shared-libraries dyld

我想在编译时在Mac OSX下设置可执行文件的运行时路径(对于链接器),这样在程序启动时动态链接器可以找到非标准位置的共享库.

在Linux下,可以使用-Xlinker -rpath -Xlinker /path/to(或使用-Wl,-rpath,/path/to),在Solaris下,您可以添加-R/path/to到编译器命令行.

我发现一些信息,Mac OS X gcc自10.5以来就支持-rpath,即自2008年以来.

我尝试用最小的例子来实现它 - 没有成功:

$ cat blah.c 
int blah(int b)
{
  return b+1;
}
Run Code Online (Sandbox Code Playgroud)

和:

$ cat main.c 

#include <stdio.h>

int blah(int);

int main ()
{
  printf("%d\n", blah(22));
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译它像这样:

$ gcc -c  blah.c
$ gcc -dynamiclib blah.o -o libblah.dylib
$ gcc main.c -lblah -L`pwd`  -Xlinker -rpath -Xlinker `pwd`/t
Run Code Online (Sandbox Code Playgroud)

现在测试:

$ mkdir t
$ mv libblah.dylib t
$ ./a.out
dyld: Library not loaded: libblah.dylib
  Referenced from: /Users/max/test/./a.out
  Reason: image not found
Trace/BPT trap
Run Code Online (Sandbox Code Playgroud)

因此问题:如何在Mac OSX下设置链接器的运行时路径?

顺便说一句,设置DYLD_LIBRARY_PATH工作 - 但我不想使用这个黑客.

编辑:关于otool -L:

$ otool -L a.out 
a.out:
        libblah.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
Run Code Online (Sandbox Code Playgroud)

似乎otool -L只打印了可执行文件链接的库名称(以及链接时可能的位置),并且没有运行时路径信息.

Ben*_*rel 36

通过实验找到,并检查由Xcode生成的命令行,以获得Dave Driblin参考rpath演示项目:

otool -L显示链接库的安装名称.要开始@rpath工作,您需要更改库的安装名称:

$ gcc -dynamiclib blah.o -install_name @rpath/t/libblah.dylib -o libblah.dylib
$ mkdir t ; mv libblah.dylib t/
$ gcc main.c -lblah -L`pwd`/t -Xlinker -rpath -Xlinker `pwd`
Run Code Online (Sandbox Code Playgroud)

  • 是的,这很有效.鉴于在其他类Unix操作系统上存在-rpath的语义,苹果偏离实现似乎有点尴尬.至少他们应该在他们的gcc man-page版本中记录它. (3认同)