use*_*629 10 macos install-name-tool dynamic-library
相关,但不回答这个问题:
在OSX上,我有一个由打包管理器提供的动态库,安装在非标准目录中,install_name只是文件名.例如:
$ 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
Run Code Online (Sandbox Code Playgroud)
我不想改变(绝对路径,@ RPATH,...)libfoo.dylib的install_name使用install_name_tool -id
.
现在我将程序与库链接,例如:
$ 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
Run Code Online (Sandbox Code Playgroud)
该程序无法运行:
$ ./a.out
dyld: Library not loaded: libfoo.dylib
Referenced from: $ROOT/bar/./a.out
Reason: image not found
Trace/BPT trap: 5
Run Code Online (Sandbox Code Playgroud)
因为:
$ 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)
Run Code Online (Sandbox Code Playgroud)
我可以更改依赖库的路径:
$ install_name_tool -change libfoo.dylib ../foo/libfoo.dylib a.out
Run Code Online (Sandbox Code Playgroud)
所以:
$ 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)
Run Code Online (Sandbox Code Playgroud)
并且程序可以执行:
$ ./a.out
$ echo $?
6
Run Code Online (Sandbox Code Playgroud)
是否有可以添加到命令的clang选项:
$ clang main.c -L../foo -lfoo
Run Code Online (Sandbox Code Playgroud)
避免不得不运行:
$ install_name_tool -change libfoo.dylib ../foo/libfoo.dylib a.out
Run Code Online (Sandbox Code Playgroud)
注意:我不想修改DYLD_LIBRARY_PATH
或其他环境变量.
?
Joh*_*nes 14
一段时间以来,我一直在反对这一点,并且认为我终于想出了如何在不使用的情况下做到这一点install_name_tool
,至少对于Mac OS 10.9及更高版本(据我测试过).
虽然您可能已经想到了这一点,但我会在这里发布,以防其他人需要它.
基本上你有两个选择:
install_name
并根据其定义库@executable_path
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'
Run Code Online (Sandbox Code Playgroud)
@rpath
,然后在编译可执行文件时设置: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'
Run Code Online (Sandbox Code Playgroud)
两种情况下的最终结果都是相同的:
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)
Run Code Online (Sandbox Code Playgroud)
第二个可能是可取的,因为那时你可以编译一次库,并使用它的任何可执行文件定义它将使用它自己加载它的位置rpath
.
请点击这里进行的详细说明@executable_path
,@rpath
以及@load_path
(我这里没有使用).
归档时间: |
|
查看次数: |
4958 次 |
最近记录: |