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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions