From 69c6e063771ba1ca175b2e2103148a6c9fbfd192 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sat, 19 Sep 2026 16:22:54 +0000 Subject: [PATCH] TST: exercise transitive RPATH lookup with a shared library chain --- .../sharedlib-chain/chainhead/__init__.py | 3 +++ .../sharedlib-chain/chainhead/leaf/leaf.c | 7 ++++++ .../chainhead/leaf/meson.build | 9 +++++++ .../sharedlib-chain/chainhead/meson.build | 16 +++++++++++++ .../chainhead/middle/meson.build | 10 ++++++++ .../sharedlib-chain/chainhead/middle/middle.c | 9 +++++++ .../sharedlib-chain/chainhead/module.c | 24 +++++++++++++++++++ tests/packages/sharedlib-chain/meson.build | 14 +++++++++++ tests/packages/sharedlib-chain/pyproject.toml | 7 ++++++ tests/test_wheel.py | 17 +++++++++++++ 10 files changed, 116 insertions(+) create mode 100644 tests/packages/sharedlib-chain/chainhead/__init__.py create mode 100644 tests/packages/sharedlib-chain/chainhead/leaf/leaf.c create mode 100644 tests/packages/sharedlib-chain/chainhead/leaf/meson.build create mode 100644 tests/packages/sharedlib-chain/chainhead/meson.build create mode 100644 tests/packages/sharedlib-chain/chainhead/middle/meson.build create mode 100644 tests/packages/sharedlib-chain/chainhead/middle/middle.c create mode 100644 tests/packages/sharedlib-chain/chainhead/module.c create mode 100644 tests/packages/sharedlib-chain/meson.build create mode 100644 tests/packages/sharedlib-chain/pyproject.toml diff --git a/tests/packages/sharedlib-chain/chainhead/__init__.py b/tests/packages/sharedlib-chain/chainhead/__init__.py new file mode 100644 index 000000000..775d000c4 --- /dev/null +++ b/tests/packages/sharedlib-chain/chainhead/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2026 The meson-python developers +# +# SPDX-License-Identifier: MIT diff --git a/tests/packages/sharedlib-chain/chainhead/leaf/leaf.c b/tests/packages/sharedlib-chain/chainhead/leaf/leaf.c new file mode 100644 index 000000000..2f54e3b25 --- /dev/null +++ b/tests/packages/sharedlib-chain/chainhead/leaf/leaf.c @@ -0,0 +1,7 @@ +// SPDX-FileCopyrightText: 2026 The meson-python developers +// +// SPDX-License-Identifier: MIT + +int leaf(void) { + return 7; +} diff --git a/tests/packages/sharedlib-chain/chainhead/leaf/meson.build b/tests/packages/sharedlib-chain/chainhead/leaf/meson.build new file mode 100644 index 000000000..59fd2b072 --- /dev/null +++ b/tests/packages/sharedlib-chain/chainhead/leaf/meson.build @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: 2026 The meson-python developers +# +# SPDX-License-Identifier: MIT + +leaf = shared_library( + 'leaf', 'leaf.c', + install: true, + install_dir: py.get_install_dir() / 'chainhead/lib', +) diff --git a/tests/packages/sharedlib-chain/chainhead/meson.build b/tests/packages/sharedlib-chain/chainhead/meson.build new file mode 100644 index 000000000..43c28705f --- /dev/null +++ b/tests/packages/sharedlib-chain/chainhead/meson.build @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: 2026 The meson-python developers +# +# SPDX-License-Identifier: MIT + +subdir('leaf') +subdir('middle') + +py.install_sources('__init__.py', subdir: 'chainhead') + +py.extension_module( + 'chain', 'module.c', + link_with: middle, + install: true, + subdir: 'chainhead', + install_rpath: '$ORIGIN/lib', +) diff --git a/tests/packages/sharedlib-chain/chainhead/middle/meson.build b/tests/packages/sharedlib-chain/chainhead/middle/meson.build new file mode 100644 index 000000000..471d373e1 --- /dev/null +++ b/tests/packages/sharedlib-chain/chainhead/middle/meson.build @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2026 The meson-python developers +# +# SPDX-License-Identifier: MIT + +middle = shared_library( + 'middle', 'middle.c', + link_with: leaf, + install: true, + install_dir: py.get_install_dir() / 'chainhead/lib', +) diff --git a/tests/packages/sharedlib-chain/chainhead/middle/middle.c b/tests/packages/sharedlib-chain/chainhead/middle/middle.c new file mode 100644 index 000000000..6b2626a03 --- /dev/null +++ b/tests/packages/sharedlib-chain/chainhead/middle/middle.c @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: 2026 The meson-python developers +// +// SPDX-License-Identifier: MIT + +extern int leaf(void); + +int middle(void) { + return leaf() + 1; +} diff --git a/tests/packages/sharedlib-chain/chainhead/module.c b/tests/packages/sharedlib-chain/chainhead/module.c new file mode 100644 index 000000000..dcb72a9de --- /dev/null +++ b/tests/packages/sharedlib-chain/chainhead/module.c @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2026 The meson-python developers +// +// SPDX-License-Identifier: MIT + +#include + +extern int middle(void); + +static PyObject *value(PyObject *self, PyObject *args) { + return PyLong_FromLong(middle()); +} + +static PyMethodDef methods[] = { + {"value", value, METH_NOARGS, NULL}, + {NULL, NULL, 0, NULL}, +}; + +static struct PyModuleDef module = { + PyModuleDef_HEAD_INIT, "chain", NULL, -1, methods, +}; + +PyMODINIT_FUNC PyInit_chain(void) { + return PyModule_Create(&module); +} diff --git a/tests/packages/sharedlib-chain/meson.build b/tests/packages/sharedlib-chain/meson.build new file mode 100644 index 000000000..6d84eafe9 --- /dev/null +++ b/tests/packages/sharedlib-chain/meson.build @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2026 The meson-python developers +# +# SPDX-License-Identifier: MIT + +project('sharedlib-chain', 'c', version: '1.0.0') + +py = import('python').find_installation(pure: false) + +# Request RPATH rather than RUNPATH when supported by the linker. +if meson.get_compiler('c').has_link_argument('-Wl,--disable-new-dtags') + add_project_link_arguments('-Wl,--disable-new-dtags', language: 'c') +endif + +subdir('chainhead') diff --git a/tests/packages/sharedlib-chain/pyproject.toml b/tests/packages/sharedlib-chain/pyproject.toml new file mode 100644 index 000000000..435419311 --- /dev/null +++ b/tests/packages/sharedlib-chain/pyproject.toml @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2026 The meson-python developers +# +# SPDX-License-Identifier: MIT + +[build-system] +build-backend = 'mesonpy' +requires = ['meson-python'] diff --git a/tests/test_wheel.py b/tests/test_wheel.py index a7cb150dc..e484c6d6c 100644 --- a/tests/test_wheel.py +++ b/tests/test_wheel.py @@ -309,6 +309,23 @@ def test_rpath_install_precedence(venv, wheel_same_name_sharedlibs, tmp_path): assert int(output) == 42 +@pytest.mark.skipif(MESON_VERSION < (1, 6, 0), reason='meson too old') +@pytest.mark.skipif(sys.platform in {'win32', 'cygwin'}, reason='requires RPATH support') +@pytest.mark.filterwarnings('ignore:translated "install_rpath" argument for ') +def test_rpath_transitive_lookup(venv, wheel_sharedlib_chain, tmp_path): + artifact = wheel.wheelfile.WheelFile(wheel_sharedlib_chain) + artifact.extractall(tmp_path) + + origin = '@loader_path' if sys.platform == 'darwin' else '$ORIGIN' + rpath = mesonpy._rpath.get_rpath(tmp_path / 'chainhead' / f'chain{EXT_SUFFIX}') + assert f'{origin}/lib' in rpath + + venv.pip('install', wheel_sharedlib_chain) + # RUNPATH cannot supply the extension's search path to its indirect dependency on glibc. + output = venv.python('-c', 'from chainhead import chain; print(chain.value())') + assert int(output) == 8 + + @pytest.mark.skipif(sys.platform in {'win32', 'cygwin'}, reason='requires executable bit support') def test_executable_bit(wheel_executable_bit): artifact = wheel.wheelfile.WheelFile(wheel_executable_bit)