gpt4 book ai didi

macos - clang,在链接时更改依赖共享库安装名称

转载 作者:行者123 更新时间:2023-12-02 06:09:14 27 4
gpt4 key购买 nike

相关,但不回答问题:

在 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

不想更改(绝对路径、@RPATH,...)的 install_namelibfoo.dylib 使用 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

程序无法运行:

$ ./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)

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

$ 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 选项可以添加到命令中:

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

避免运行:

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

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

最佳答案

我已经为此苦苦挣扎了一段时间,并认为我终于弄清楚了如何在不使用 install_name_tool 的情况下做到这一点,至少对于 Mac OS 10.9 及更高版本(据我所知)已经测试过)。

虽然您可能已经弄清楚了这一点,但我将其发布在这里,以防其他人需要它。

基本上你有两个选择:

  1. 您可以在编译库时执行此操作,并根据 @executable_path 定义其 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'
  • 或者您可以使用 @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'

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

    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加载它的位置。

    check here有关 @executable_path@rpath@load_path(我在这里没有使用)的详细解释。

    关于macos - clang,在链接时更改依赖共享库安装名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27506450/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com