clang,在链接时更改依赖的共享库安装名称 [英] clang, change dependent shared library install name at link time

查看:257
本文介绍了clang,在链接时更改依赖的共享库安装名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关,但不回答问题:

在OSX上,我有一个由打包程序管理器提供的动态库,该库安装在非 标准目录,其中install_name只是文件名.例如:

On OSX, I have a dynamic library provided by a packager manager, installed in a non standard directory, which install_name is just the filename. For example:

$ ROOT=$PWD
$ mkdir $ROOT/foo 
$ cd $ROOT/foo
$ echo 'int foo(int a, int b){return a+b;}' > foo.c
$ clang foo.c -dynamiclib -install_name libfoo.dylib -o libfoo.dylib

不想更改(绝对路径,@ RPATH等)的install_name libfoo.dylib使用install_name_tool -id.

I don't want to change (absolute path, @RPATH, ...) the install_name of libfoo.dylib using install_name_tool -id.

现在,我将程序与库链接起来,例如:

Now I link a program with the library, for example:

$ mkdir $ROOT/bar
$ cd $ROOT/bar
$ echo 'int foo(int,int); int main(){return foo(2,4);}' > main.c
$ clang main.c -L../foo -lfoo   

程序无法运行:

$ ./a.out
dyld: Library not loaded: libfoo.dylib
  Referenced from: $ROOT/bar/./a.out
  Reason: image not found
Trace/BPT trap: 5

因为:

$ otool -L ./a.out
./a.out:
        libfoo.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

我可以更改依赖库的路径:

I can change the path of the dependant library:

$ install_name_tool -change libfoo.dylib ../foo/libfoo.dylib a.out

如此:

$ otool -L ./a.out
./a.out:
        ../foo/libfoo.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

该程序可以执行:

$ ./a.out
$ echo $?
6

我可以在命令中添加一个clang选项吗?

Is there a clang option I can add to the command:

$ clang main.c -L../foo -lfoo 

避免必须运行:

$ install_name_tool -change libfoo.dylib ../foo/libfoo.dylib a.out

注意:我不想修改DYLD_LIBRARY_PATH或其他环境变量.

Note: I don't want to modify DYLD_LIBRARY_PATH or such other environment variable.

?

推荐答案

一段时间以来,我一直对此持反对态度,并认为我终于弄清楚了如何在不使用install_name_tool的情况下做到这一点,至少对于Mac而言OS 10.9和更高版本(据我测试).

I've been hitting my head against this for some time and think I have finally figured out how to do this without using install_name_tool, at least for Mac OS 10.9 and later (as far as I've tested).

虽然您可能已经知道了这一点,但如果有人需要它,我会在此处发布.

While you may have already figured this out, I'm posting it here in case anyone else needs it.

基本上,您有两个选择:

Basically you have two options:

  1. 您可以在编译库时执行此操作,并根据@executable_path
  2. 定义其install_name

ROOT=$PWD
mkdir $ROOT/foo
mkdir $ROOT/bar

cd $ROOT/foo
echo 'int foo(int a, int b){return a+b;}' > foo.c
clang foo.c -dynamiclib -install_name @executable_path/../foo/libfoo.dylib -o libfoo.dylib

cd $ROOT/bar
echo 'int foo(int,int); int main(){return foo(2,4);}' > main.c
clang main.c -L../foo -lfoo -o main

./main
echo $?
# output is '6'

  1. 或者您可以使用@rpath分两步来完成,然后在编译可执行文件时对其进行设置:
  1. Or you can do it in two steps using @rpath, which you then set when you compile the executable:

ROOT=$PWD
mkdir $ROOT/foo
mkdir $ROOT/bar

cd $ROOT/foo
echo 'int foo(int a, int b){return a+b;}' > foo.c
clang foo.c -dynamiclib -install_name @rpath/libfoo.dylib -o libfoo.dylib

cd $ROOT/bar
echo 'int foo(int,int); int main(){return foo(2,4);}' > main.c
clang main.c -L../foo -lfoo -rpath @executable_path/../foo/ -o main

./main
echo $?
# output is '6'

两种情况下的最终结果都是相同的:

The end result will be the same in both cases:

bar $ otool -L main
main:
  @executable_path/../foo/libfoo.dylib (compatibility version 0.0.0, current version 0.0.0)
  /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

第二个可能更可取,因为您可以编译一次该库,并让使用它的任何可执行文件定义使用其自己的rpath从哪里加载该库.

The second one is probably preferable, since then you can compile the library once, and have any executable that uses it define where it will load it from using its own rpath.

在此处检查以获取@executable_path@rpath@load_path(我在这里没有使用).

Please check here for detailed explanations of @executable_path, @rpath and @load_path (which I did not use here).

这篇关于clang,在链接时更改依赖的共享库安装名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆