Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 141 additions & 57 deletions .github/workflows/pixi.lock

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions .github/workflows/pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ ninja = "*"
pkg-config = "*"
cmake = "*"
patchelf = "*"
c-compiler = "*"
cxx-compiler = "*"
geos = "*"
pip = "*"
python-build = "*"
cython = "*"
pytest = "*"
pytest-mock = "*"
wheel = "*"

[feature.compilers.dependencies]
c-compiler = "*"
cxx-compiler = "*"

[environments]
default = { features = ["compilers"], solve-group = "test" }
system-compilers = { features = [], solve-group = "test" }

[tasks]
test = { cmd = "pytest", cwd = "../.." }
12 changes: 11 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,16 @@ jobs:
run: mypy -p mesonpy

pixi:
name: ${{ matrix.name }}
runs-on: ubuntu-24.04-arm
strategy:
fail-fast: false
matrix:
include:
- name: pixi
environment: default
- name: pixi-system-compilers
environment: system-compilers
steps:
- name: Checkout
uses: actions/checkout@v7
Expand All @@ -347,11 +356,12 @@ jobs:
with:
pixi-version: v0.77.1
manifest-path: .github/workflows/pixi.toml
environments: ${{ matrix.environment }}
cache: false

- name: Run tests
working-directory: .github/workflows
run: pixi run test
run: pixi run --environment ${{ matrix.environment }} test

uv-sync:
runs-on: ubuntu-latest
Expand Down
10 changes: 10 additions & 0 deletions mesonpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,16 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]],
if sys.platform == 'darwin':
install_rpath = [_translate_rpath(path, dst) for path in install_rpath]

# Remove absolute paths from ``build_rpath``. Meson adds
# RPATH entries for shared libraries compiled as part of the
# project and shared libraries from dependencies installed in
# non-standard locations. The first are relative paths using
# the ``$ORIGIN`` or ``@loader_path`` anchor. The seconds are
# absolute paths. For the resulting binaries to be able to
# dynamically link to local dependencies, we want to remove
# the first but keep the seconds.
build_rpath = [path for path in build_rpath if not path.startswith('/')]

wheel_files[path].append(_Entry(dst, src, install_rpath, build_rpath))

return wheel_files
Expand Down
23 changes: 23 additions & 0 deletions tests/packages/link-against-external-lib/external.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2026 The meson-python developers
//
// SPDX-License-Identifier: MIT

#include <Python.h>
#include <geos_c.h>

static PyObject *version(PyObject *self, PyObject *args) {
return PyUnicode_FromString(GEOSversion());
}

static PyMethodDef methods[] = {
{"version", version, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL},
};

static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT, "external", NULL, -1, methods,
};

PyMODINIT_FUNC PyInit_external(void) {
return PyModule_Create(&module);
}
16 changes: 16 additions & 0 deletions tests/packages/link-against-external-lib/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2026 The meson-python developers
#
# SPDX-License-Identifier: MIT

project('link-against-external-lib', 'c', version: '1.0.0')

py = import('python').find_installation(pure: false)

external = dependency('geos', method: 'pkg-config')

py.extension_module(
'external',
'external.c',
dependencies: external,
install: true
)
7 changes: 7 additions & 0 deletions tests/packages/link-against-external-lib/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2026 The meson-python developers
#
# SPDX-License-Identifier: MIT

[build-system]
build-backend = 'mesonpy'
requires = ['meson-python']
17 changes: 17 additions & 0 deletions tests/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import re
import shutil
import stat
import subprocess
import sys
import textwrap

Expand Down Expand Up @@ -260,6 +261,22 @@ def check(rpath, *expected):
check(rpath, 'custom-rpath', f'{origin}/../.link_against_local_lib.mesonpy.libs')


@pytest.mark.skipif(sys.platform in {'win32', 'cygwin'}, reason='requires RPATH support')
@pytest.mark.skipif(shutil.which('pkg-config') is None, reason='requires pkg-config')
def test_link_against_external_lib_rpath(package_link_against_external_lib, tmp_path, venv):
if subprocess.run(['pkg-config', '--exists', 'geos']).returncode:
pytest.skip('requires GEOS')
version = subprocess.check_output(['pkg-config', '--modversion', 'geos'], text=True).strip()

# Use an installed dependency without supplying an explicit RPATH.
# Check its version too, to detect fallback to a different system copy.
filename = mesonpy.build_wheel(tmp_path)
venv.pip('install', tmp_path / filename)
output = venv.python('-c', 'import external; print(external.version())')
# GEOSversion() appends the C API version after "-CAPI-".
assert output.strip().split('-CAPI-')[0] == version


@pytest.mark.skipif(sys.platform in {'win32', 'cygwin'}, reason='requires RPATH support')
def test_link_against_local_lib_rpath_ldflags(package_link_against_local_lib, tmp_path, monkeypatch):
origin = '@loader_path' if sys.platform == 'darwin' else '$ORIGIN'
Expand Down
Loading