Skip to content

RPATH goes missing when using both install_rpath and an internal shared library dependency #711

Closed

Description

@rgommers

This is a case that probably hasn't been exercised before: a Python extension module that links against both a shared library that's part of the package and a shared library built in a subproject that's folded into the wheel by meson-python.

I ran into this in SciPy when adding a subproject. This worked as advertised, except for this scipy.special._ufuncs extension module, which depends on this libsf_error shared library as well as on the library in the subproject.
What one sees then is that the installed wheel can no longer find libsf_error.so, because the RPATH entry for install_rpath: '$ORIGIN' goes missing.

With a default SciPy build (no subproject), the Library rpath|runpath entries on the _ufuncs target in the build and install directories looks like this (has $ORIGIN as it should):

$ readelf -d build/scipy/special/_ufuncs.cpython-312-x86_64-linux-gnu.so | rg "Library r"
 0x000000000000000f (RPATH)              Library rpath: [/home/rgommers/mambaforge/envs/scipy-dev-py312/lib:$ORIGIN/]

$ readelf -d build-install/lib/python3.12/site-packages/scipy/special/_ufuncs.cpython-312-x86_64-linux-gnu.so | rg "Library r"
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN:/home/rgommers/mambaforge/envs/scipy-dev-py312/lib]

On the branch with the subproject, we see this instead:

$ readelf -d build-whl/scipy/special/_ufuncs.cpython-312-x86_64-linux-gnu.so | rg Library
 0x000000000000001d (RUNPATH)            Library runpath: [/home/rgommers/code/pixi-dev-scipystack/scipy/.pixi/envs/openblas-src/lib:$ORIGIN/../../.scipy.mesonpy.libs:$ORIGIN/../../.scipy.mesonpy.libs:$ORIGIN/../../.scipy.mesonpy.libs:$ORIGIN/../../.scipy.mesonpy.libs]

$ readelf -d site-packages/scipy/special/_ufuncs.cpython-312-x86_64-linux-gnu.so | rg "Library r"
 0x000000000000001d (RUNPATH)            Library runpath: [/home/rgommers/code/pixi-dev-scipystack/scipy/.pixi/envs/openblas-src/lib:$ORIGIN/../../.scipy.mesonpy.libs:$ORIGIN/../../.scipy.mesonpy.libs:$ORIGIN/../../.scipy.mesonpy.libs:$ORIGIN/../../.scipy.mesonpy.libs]

The duplication of the .scipy.mesonpy.libs entries is a minor stylistic issue, we may be able to de-duplicate but it doesn't matter. What does matter is that $ORIGIN is no longer present.

This looks like a bug in the fix_rpath implementation at:

def fix_rpath(filepath: Path, libs_relative_path: str) -> None:
old_rpath = _get_rpath(filepath)
new_rpath = []
for path in old_rpath:
if path.startswith('$ORIGIN/'):
path = '$ORIGIN/' + libs_relative_path
new_rpath.append(path)
if new_rpath != old_rpath:
_set_rpath(filepath, new_rpath)

The problem seems clear: all RPATH entries are cleared, and the ones that are added back all get libs_relative_path appended (i.e. to the subproject-relocated location). Any existing RPATHs within the package, like '$ORIGIN', will get lost.

Activity

  1. rgommers commented on Dec 6, 2024

    @rgommers
    ContributorAuthor

    Adding the relevant content from the build-whl/meson-info/intro-install_plan.json install metadata file:

    {
      "targets": {
        "/home/.../build-whl/subprojects/openblas/lapack-netlib/SRC/libscipy_lapack.so": {
          "destination": "{libdir_shared}/libscipy_lapack.so",
          "tag": "runtime",
          "subproject": "openblas",
          "install_rpath": null
        },
    
        "/home/.../build-whl/scipy/special/libsf_error_state.so": {
          "destination": "{py_platlib}/scipy/special/libsf_error_state.so",
          "tag": "runtime",
          "subproject": null,
          "install_rpath": null
        },
    
        "/home/.../build-whl/scipy/special/_ufuncs.cpython-312-x86_64-linux-gnu.so": {
          "destination": "{py_platlib}/scipy/special/_ufuncs.cpython-312-x86_64-linux-gnu.so",
          "tag": "runtime",
          "subproject": null,
          "install_rpath": "$ORIGIN"
        },
  2. rgommers commented on Dec 6, 2024

    @rgommers
    ContributorAuthor

    I think the correct behavior for fix_rpath is:

    1. If the install target has no RPATH entries, do nothing

    2. If the install target has >=1 RPATH entries, then:

      • Add a single new relative entry pointing to .<project-name>.mesonpy.libs
      • Remove entries starting with $ORIGIN but pointing outside of the package's own tree and into subprojects (e.g., $ORIGIN/../../subprojects). Those are the ones being relocated.
      • Keep other entries that start with $ORIGIN unchanged
      • Keep other entries that don't start with $ORIGIN also unchanged (that is already the case)
  3. dnicolodi commented on Feb 13, 2025

    @dnicolodi
    Member

    I've tried to brush up on the reason why the RPATH adjustment code does what it does. IIRC, what it needs to do is to remove RPATH entries added by meson that point to the build tree and add an RPATH entry that points to .<project-name>.mesonpy.libs. Removing all RPATH entries that start with $ORIGIN was an attempt for an heuristic to determine which RPATH entries have been added by meson. We would need to find a better one. I'm not sure what that could be. meson keeps a list of the RPATH entries it added, but meson-python does not have access to it.

  4. rgommers commented on Feb 13, 2025

    @rgommers
    ContributorAuthor

    intro-install_plan.json does contain the install_rpath entries originating from meson.build, so I think we can process those. Snippet from a SciPy build:

        "/Users/rgommers/code/pixi-dev/scipy/scipy/build/scipy/special/libsf_error_state.dylib": {
          "destination": "{py_platlib}/scipy/special/libsf_error_state.dylib",
          "tag": "runtime",
          "subproject": null,
          "install_rpath": null
        },
        "/Users/rgommers/code/pixi-dev/scipy/scipy/build/scipy/special/_special_ufuncs.cpython-312-darwin.so": {
          "destination": "{py_platlib}/scipy/special/_special_ufuncs.cpython-312-darwin.so",
          "tag": "runtime",
          "subproject": null,
          "install_rpath": "$ORIGIN"
        },

    This metadata matches with https://github.com/scipy/scipy/blob/1336806190a3810342a6cd74e3aee49d49e3ce20/scipy/special/meson.build#L83. All extension modules and shared libraries have the install_rpath metadata, it's either null or a string.

  5. dnicolodi commented on Feb 13, 2025

    @dnicolodi
    Member

    Oh, right, I added that to the meson introspection data exactly for this purpose mesonbuild/meson#13625 🙂 This does not solve the issue for RPATH entries added passing linker arguments, but meson already emits a warning for these and we can say that these are not supported. I guess that what we should do is thus to remove all RPATH entries that are not listed in the introspection data. I'll have a look at this later today.

  6. added this to the v0.18.0 milestone on Feb 13, 2025
  7. rgommers commented on Feb 13, 2025

    @rgommers
    ContributorAuthor

    Thanks! Always nice to discover you solved the problem you think you're having yourself months ago:)

  8. eli-schwartz commented on Feb 13, 2025

    @eli-schwartz
    Member

    There are reasons why someone might want to pass rpath via LDFLAGS but none of them are applicable to internal dependencies. They will always be for directories that aren't inside the meson source/build trees.

  9. added 6 commits that reference this issue on Feb 13, 2025
    3f9393d
    89aee9c
    f487199
    f4f04e3
    cfad83c
    4f361a9
  10. 16 remaining items

  11. added a commit that references this issue on Jun 14, 2025
    515d454
  12. added a commit that references this issue on Jun 29, 2026
    5873ad3
  13. linked a pull request that will close this issueFixes relative to RPATH handling #788on Jun 29, 2026
  14. added a commit that references this issue on Jul 5, 2026
    8ddb3ef
  15. stephanlachnit commented on Aug 6, 2026

    @stephanlachnit

    Also ran into this - this was quite though to figure out, would be good if this would be fixed.

  16. added 7 commits that reference this issue on Sep 18, 2026
    ff0a673
    88a1749
    3cb4d37
    a48068b
    b6d077c
    3c0151e
    2539458
  17. added this to the v0.22.0 milestone on Sep 25, 2026
  18. added a commit that references this issue on Sep 25, 2026
    8cab4b8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions