Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Expected behavior for RPATH handling

未关闭
#903 3 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
45/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
活跃
技术栈
python

调研方向

首先查看 gh-788 以及 Linux 和 macOS 行为的场景表。确定现有测试包后,使用它们覆盖列出的情况;完成的标准是预期行为已达成一致、场景已完成测试,并且该表已作为新的文档页面添加。

由索引模型根据 Issue 内容生成。

描述

documentation enhancement tests

Writing this up as a new issue while in the middle of reviewing gh-788. This is quite complicated, and we don't have good test coverage. So this issue aims to lay out as many relevant scenarios as possible, with the expected behavior on Linux and macOS for each case. Reviewing that is a lot easier than reviewing code for which we don't yet have tests.

Once we agree that the behavior is right, we can decide on test packages to add. Also, I'd like to add a table like this in a new page in the docs; I think the audience for this is relatively small, but when you do need this info, you really need it - and I don't know of any other source where this is covered well.


The tables explain desired behavior of extension modules in a wheel built with meson-python (i.e., before auditwheel or delocate repair).

  • D is the wheel's relocated-library directory, named .<distribution_name>.mesonpy.libs. The examples assume it is beside the directory containing the extension, so the extension reaches it through $ORIGIN/../D on Linux or @loader_path/../D on macOS. Extensions in deeper directories require the corresponding relative path to D.
  • E is an absolute external dependency prefix, outside the source and build trees. It remains available after installation.
  • The tables list the paths relevant to each scenario. “None” means no project-specific search paths; unrelated external runtime paths remain unchanged.

Installed code must work after removing the source and build directories, without loader-path environment overrides. The empty-RUNPATH scenario explicitly requires a loader failure instead. Build-path removal assumes Meson provides the necessary metadata, or has already taken care of the removal itself.

All scenarios must also work when building another wheel from the same build directory, without changing the resulting search paths

Shared behavior

Scenario Linux extension paths macOS extension LC_RPATH paths Notes
Extension without dependencies on additional project-built shared libraries None None Basic regression, ensure nothing is added.
One library is moved into D $ORIGIN/../D @loader_path/../D Update its consumer to find the library at its installed location.
Two libraries from different build directories move into the same D $ORIGIN/../D, once @loader_path/../D, one command Add the destination search path once, without duplicates.
Extension → first library → second library; both libraries are moved into D $ORIGIN/../D @loader_path/../D The first library also needs $ORIGIN/. on Linux or @loader_path/. on macOS. Repair the entire dependency chain, not just the extension.
Extension → sibling library, using a platform-correct installation path $ORIGIN @loader_path Keep the sibling library discoverable after installation.
Extension → sibling library → second library in sub/ $ORIGIN @loader_path The sibling library needs $ORIGIN/sub on Linux or @loader_path/sub on macOS to load its own dependency.
Extension directly depends on both a sibling library and a library in sub/; an existing working layout $ORIGIN, $ORIGIN/sub @loader_path, @loader_path/sub Preserve both paths and continued functionality. Neither library needs its own project search path.
Extension depends on two relocated libraries in D and an in-package library in private/ $ORIGIN/private, $ORIGIN/../D @loader_path/private, @loader_path/../D Keep working paths to both groups.
An external library is linked by absolute filename or through -L/-l, with an explicit runtime path supplied by -Wl,-rpath,E/lib E/lib E/lib Preserve the explicitly requested external runtime path for either linking form. The -L directory alone does not imply a path that must be preserved.
Link flags explicitly request a relative runtime path with -Wl,-rpath,$ORIGIN/user (Linux) or -Wl,-rpath,@loader_path/user (macOS), and an absolute path with -Wl,-rpath,E/lib; other libraries are relocated into D $ORIGIN/user, E/lib, $ORIGIN/../D @loader_path/user, E/lib, @loader_path/../D Preserve the requested relative or absolute paths and add the relocation path. This applies whether the flags come from target linker arguments, environment flags, or pkg-config, and also to bundled libraries needing path updates. A binary need not request both relative and absolute paths.
install_rpath requests $ORIGIN/one:$ORIGIN/two:$ORIGIN/one on Linux, or @loader_path/one:@loader_path/two:@loader_path/one on macOS $ORIGIN/one, $ORIGIN/two @loader_path/one, @loader_path/two, as separate commands Keep each distinct installation path once.
The same path appears in both build and installation metadata $ORIGIN/keep, once @loader_path/keep, once The explicit installation request takes precedence over removal of the same build path.
A build-only path remains, but no installation path is requested None None Remove the build-only path without leaving padding or accidental empty entries. See the intentional empty-RUNPATH exception below.

Linux: RPATH and RUNPATH

RPATH and RUNPATH are ELF dynamic tags, also used on platforms other than Linux; their search behavior depends on the dynamic loader. The runtime descriptions below refer to Linux with glibc: RUNPATH takes precedence over RPATH in the same binary, and applies only to direct dependencies, whereas RPATH supports transitive lookup. Linux with musl does not make that transitivity distinction: both tag types can supply paths for indirect dependencies. Preserving the input tag type remains a requirement, even where conversion would not change the observed runtime behavior. macOS uses Mach-O LC_RPATH commands and has no RPATH/RUNPATH distinction.

Scenario Linux extension paths macOS extension LC_RPATH paths Notes
Editing paths in a binary containing either RPATH or RUNPATH Updated paths in the original tag type Not applicable Do not silently convert RPATH to RUNPATH or vice versa.
Explicit installation paths compete with preserved paths; private/ and external/ contain libraries with the same SONAME $ORIGIN/private before $ORIGIN/external; preserve input tag type Not applicable Search installation paths first, so the library in private/ takes precedence over the same-SONAME library in external/.
Executable → middle library → leaf library; the executable uses transitive RPATH DT_RPATH: $ORIGIN/lib Not applicable Both libraries are in lib/ and have no project paths. The executable's RPATH must resolve the indirect dependency.
Executable → middle library → leaf library; the executable uses direct-dependency RUNPATH DT_RUNPATH: $ORIGIN/lib Not applicable The middle library needs $ORIGIN for its leaf dependency. Preserve its input tag type; the entire chain must load.
Executable uses RPATH; the middle library uses RUNPATH and must update its path to the installed leaf DT_RPATH: $ORIGIN/middle Not applicable Middle: DT_RUNPATH containing $ORIGIN/../installed-leaf. Preserve both tag types and load the complete chain.
Executable uses RUNPATH; the middle library uses RPATH and must update its path to the installed leaf DT_RUNPATH: $ORIGIN/middle Not applicable Middle: DT_RPATH containing $ORIGIN/../installed-leaf. Preserve both tag types and load the complete chain.
One binary contains both tags, pointing at different copies of the same library DT_RUNPATH: $ORIGIN/runpath-choice; optional inactive DT_RPATH: $ORIGIN/rpath-choice Not applicable Load the library found through RUNPATH; the competing copy reachable only through RPATH must be ignored. Remove build-only RUNPATH entries without merging the ignored RPATH into it. The ignored RPATH may be retained or removed.
Both tags exist, but RUNPATH is empty Empty DT_RUNPATH tag; optional inactive DT_RPATH: $ORIGIN/rpath-choice Not applicable Preserve the empty RUNPATH so RPATH stays ignored. A dependency available only through RPATH must remain undiscoverable: this deliberately requires a loader failure.
Removing build-only paths leaves no paths No RPATH or RUNPATH tag Not applicable Remove the tag instead of leaving an empty search entry. The deliberately empty RUNPATH above is an explicit exception.

macOS: LC_RPATH

These cases exercise separate Mach-O load commands and install_name_tool behavior.

Scenario macOS extension LC_RPATH paths Notes
Legacy installation paths use literal $ORIGIN, including on macOS @loader_path; also @loader_path/sub when required Preserve working behavior with native macOS anchors, including subdirectory paths. Literal $ORIGIN is not a usable macOS result.
Several installation paths are requested @loader_path/one, @loader_path/two, as separate commands Do not encode the macOS paths as one colon-containing command.
An extension already contains two LC_RPATH commands for @loader_path/dupa; this path should be preserved and no libraries are relocated @loader_path/dupa, one command Reduce the two existing commands to one, even when no other path edits are needed.
An extension contains two LC_RPATH commands for the same build-only path, @loader_path/dupa None Remove every copy of @loader_path/dupa successfully.
Keep existing paths containing spaces, parentheses, and trailing whitespace; add @loader_path/new path/(library) and remove the build-only @loader_path/remove this (build) @loader_path/some path/(library), @loader_path/trailing (one trailing space), @loader_path/new path/(library) Preserve the exact retained strings, add the new path once, and remove @loader_path/remove this (build) completely.

Full disclosure: I started this table by hand, then did a lot of testing and synthesis with an AI tool (Codex/Astra), which turned up a few more cases that are new rows in the table above (in particular for mixed RPATH/RUNPATH, after I prompted it for that - we've had issues with that before, e.g. gh-125). Text is mine, and reviewed/polished as carefully as I could for clarity and correctness. I'll comment on the testing results of trying to test gh-788 for these behaviors on that PR, rather than here.

主要语言
Python
星标
181
派生
94
平均合并
18 小时 23 分钟
30 天内合并 PR
12

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

mesonbuild/meson-python 的其他 Issue

查看 mesonbuild/meson-python 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。