求助 cmake 编译 @rpath 问题

2023-04-16 10:25:50 +08:00
 wowbaby

这块不熟,我现在遇到的问题

libheif 依赖 aom 而 aom 编译后的文件使用了 @rpath, 导致环境变量中必须设置 export DYLD_LIBRARY_PATH="/usr/local/aom/3.6.0/lib/:$DYLD_LIBRARY_PATH" 后 libheif 可以正常 找到 aom 的 dylib ,这倒是没有问题,但问题是我编译安装其它软件时,所有依赖 libheif 的编译,都会提示:

dyld: Library not loaded: @rpath/libaom.3.dylib Referenced from: /usr/local/libheif/1.15.2/lib/libheif.1.dylib Reason: image not found

cmake 编译如何去除这个 @rpath 改为绝对路径, 如 @rpath/libaom.3.dylib 改为 /usr/local/aom/3.6.0/lib/libaom.3.dylib

有一些参数,目前试过没有成功 CMAKE_SKIP_BUILD_RPATH CMAKE_BUILD_WITH_INSTALL_RPATH CMAKE_INSTALL_RPATH_USE_LINK_PATH

git clone https://aomedia.googlesource.com/aom cd aom mkdir -p ../aom_build cd ../aom_build

cmake /Users/xx/Downloads/aom -DCMAKE_INSTALL_PREFIX=/usr/local/aom/3.6.0 -DENABLE_DOCS=0 -DENABLE_EXAMPLES=1 -DENABLE_TESTDATA=0 -DENABLE_TESTS=0 -DENABLE_TOOLS=0 -DBUILD_SHARED_LIBS=1 -DCONFIG_TUNE_BUTTERAUGLI=1 -DCONFIG_TUNE_VMAF=1 这里改怎么设置

aom:

otool -L /usr/local/aom/3.6.0/bin/aomenc
/usr/local/aom/3.6.0/bin/aomenc:
	@rpath/libaom.3.dylib (compatibility version 3.0.0, current version 3.6.0) #要改这里为绝对路径
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 800.7.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)

heif:


otool -L /usr/local/libheif/1.15.2/bin/heif-enc
/usr/local/libheif/1.15.2/bin/heif-enc:
	/usr/local/libheif/1.15.2/lib/libheif.1.dylib (compatibility version 17.0.0, current version 17.2.0)
	@rpath/libaom.3.dylib (compatibility version 3.0.0, current version 3.6.0)
	/usr/local/opt/libvmaf/lib/libvmaf.1.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/local/opt/jpeg-xl@0.6.1/lib/libjxl.0.6.dylib (compatibility version 0.6.0, current version 0.6.1)
	/usr/local/opt/libde265/lib/libde265.0.dylib (compatibility version 2.0.0, current version 2.4.0)
	/usr/local/opt/x265/lib/libx265.199.dylib (compatibility version 199.0.0, current version 199.0.0)
	/usr/local/opt/jpeg-turbo/lib/libjpeg.8.dylib (compatibility version 8.0.0, current version 8.2.2)
	/usr/local/opt/libpng/lib/libpng16.16.dylib (compatibility version 56.0.0, current version 56.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)

1236 次点击
所在节点    程序员
5 条回复
yzwduck
2023-04-16 12:36:28 +08:00
有一个不修改 CMake 的思路: 在编译完 libaom 后, 手动执行 install_name_tool -id /usr/local/aom/3.6.0/lib/libaom.3.dylib /path/to/libaom.dylib

具体用法参见 man install_name_tool

手边暂时没有 mac 电脑, 没有办法实测有没有其他的坑.
wowbaby
2023-04-16 13:31:43 +08:00
@yzwduck 之前已经试过了 install_name_tool 有些地方修改不能成功,最后默认安装到 /usr/local 解决了,单还是想弄清这个问题,
指定安装位置
export PATH="/usr/local/aom/3.6.0/bin:$PATH"
export LDFLAGS="$LDFLAGS -L/usr/local/aom/3.6.0/lib"
export CPPFLAGS="$CPPFLAGS -I/usr/local/aom/3.6.0/include"
export PKG_CONFIG_PATH="/usr/local/aom/3.6.0/lib/pkgconfig:$PKG_CONFIG_PATH"
export DYLD_LIBRARY_PATH="/usr/local/aom/3.6.0/lib/:$DYLD_LIBRARY_PATH"

加入以上环境变量 依赖 aom 的软件 @rpath/libaom.3.dylib 也找不到
yzwduck
2023-04-16 14:18:28 +08:00
可能是执行 install_name_tool 的时机不对.

MachO 外部依赖项的路径是编译链接时的动态库里存储的 id 值, 所以需要在编译链接 heif-enc 之前修改 libaom.3.dylib 的 id.
执行时机正确的话, otool -L libaom.3.dylib 和 heif-enc 的输出里不会出现 rpath.

你指定的 5 个环境变量中, 前 4 个与 rpath 没有关联: PATH 只影响 execve, 下面 3 个是修改编译选项的, 不像会修改 rpath 的链接路径.
我不确定 rpath 是否会从 DYLD_LIBRARY_PATH 搜索路径 (我猜不会), 以及在正式签名等场合下 DYLD_LIBRARY_PATH 是会被忽略的, 最好不要去依赖它.
weidaizi
2023-04-17 12:34:04 +08:00
看来一下 OP 的需求,改为 '/usr/local/aom/3.6.0/lib/libaom.3.dylib' ,这个路径不太符合 unix 规范。
用 rpath 的目的就是为了无论是放在 /usr, /usr/local 还是 /opt 中,都不需要使用 LD_LIBRARY_PATH 。但是你需要按照文件夹规范来放

一般情况下,你放在 /usr/local 中应该直接展开,不带包 aom/3.6.0 这个东西,看起来应该是这样:
```
/usr/local/lib/libheif
/usr/local/lib/libaom
...
```

如果是单独的 fat 包,举个例子比如 java 吧,放在 /opt 当中,尽可能的把依赖打进去,看起来是这样的
```
/opt/jdk-17.0.1/bin/jar
/opt/jdk-17.0.1/lib/libjli.so
......
```

只要运行 `objdump -x jar | grep 'R.*PATH'`,就可以看到输出
```
RUNPATH $ORIGIN:$ORIGIN/../lib
```

只要你的目录符合 unix 规范,无论你是独立的放在 /opt/xxx 当中,还是展开放到 /usr 当中,都是没问题的
wowbaby
2023-04-22 10:24:12 +08:00
@weidaizi /usr/local/aom/3.6.0/lib/ 这样是方便管理,因为包实在太多了,实则通过软链到 /usr/local/lib 也没有问题或直接装默认路径

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/932872

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX