描述
打包 kind = "shared" 的库目标时,产出的 .so 里保留了指向构建机 ~/.mcpp/
工具链目录的 RUNPATH。这导致产物不可移植:在别的机器上,动态链接器运行时无法解析
.so 自身的依赖(libstdc++、libgomp),因为 RUNPATH 指向的绝对路径只存在于构建机。
可执行文件没有这个问题——mcpp pack 会打包它们的运行库并设置 RUNPATH=$ORIGIN。
但 kind = "shared" 似乎缺少这一步「重定位」。
复现步骤
-
一个带共享库目标的项目:
[targets.mylib]
kind = "shared"
soname = "libmylib.so.1"
-
打包:
mcpp pack mylib --target x86_64-linux-gnu
-
查看打包出的 .so:
readelf -d target/dist/<pkg>/lib/x86_64-linux-gnu/libmylib.so | grep RUNPATH
输出:
0x000000000000001d (RUNPATH) Library runpath:
[/home/<user>/.mcpp/registry/data/xpkgs/xim-x-glibc/2.44/lib64:
/home/<user>/.mcpp/registry/data/xpkgs/xim-x-gcc/16.1.0/lib64:
/home/<user>/.mcpp/registry/subos/default/lib]
期望行为
打包出的 .so 应该是可重定位的——没有 RUNPATH(或为 $ORIGIN)——从而依赖消费方
二进制的 RPATH(mcpp 会为消费方二进制设置好)来解析 C++/OpenMP 运行时。
实际行为
.so 保留了构建机的绝对 ~/.mcpp/ 路径。别的机器上的消费者运行时报:
error while loading shared libraries: libstdc++.so.6: cannot open shared object file
因为 .so 的依赖无法通过这个过期的 RUNPATH 找到。
环境
- mcpp 2026.8.18.3
- Arch Linux x86_64,glibc 2.43
- 工具链 gcc@16.1.0
规避方案
分发前手动剥离 RUNPATH:
patchelf --remove-rpath target/dist/<pkg>/lib/x86_64-linux-gnu/libmylib.so
描述
打包
kind = "shared"的库目标时,产出的.so里保留了指向构建机~/.mcpp/工具链目录的
RUNPATH。这导致产物不可移植:在别的机器上,动态链接器运行时无法解析.so自身的依赖(libstdc++、libgomp),因为 RUNPATH 指向的绝对路径只存在于构建机。可执行文件没有这个问题——
mcpp pack会打包它们的运行库并设置RUNPATH=$ORIGIN。但
kind = "shared"似乎缺少这一步「重定位」。复现步骤
一个带共享库目标的项目:
打包:
查看打包出的
.so:输出:
期望行为
打包出的
.so应该是可重定位的——没有RUNPATH(或为$ORIGIN)——从而依赖消费方二进制的 RPATH(mcpp 会为消费方二进制设置好)来解析 C++/OpenMP 运行时。
实际行为
.so保留了构建机的绝对~/.mcpp/路径。别的机器上的消费者运行时报:因为
.so的依赖无法通过这个过期的 RUNPATH 找到。环境
规避方案
分发前手动剥离 RUNPATH: