Skip to content

mcpp pack 对 kind = "shared" 的库没有剥离构建机的 RUNPATH,产物不可移植 #460

Description

@Aimol-l

描述

打包 kind = "shared" 的库目标时,产出的 .so 里保留了指向构建机 ~/.mcpp/
工具链目录的 RUNPATH。这导致产物不可移植:在别的机器上,动态链接器运行时无法解析
.so 自身的依赖(libstdc++、libgomp),因为 RUNPATH 指向的绝对路径只存在于构建机。

可执行文件没有这个问题——mcpp pack 会打包它们的运行库并设置 RUNPATH=$ORIGIN
kind = "shared" 似乎缺少这一步「重定位」。

复现步骤

  1. 一个带共享库目标的项目:

    [targets.mylib]
    kind   = "shared"
    soname = "libmylib.so.1"
  2. 打包:

    mcpp pack mylib --target x86_64-linux-gnu
  3. 查看打包出的 .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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions