mesonbuild / meson-python

Meson PEP 517 Python build backend
https://mesonbuild.com/meson-python/
MIT License
120 stars 60 forks source link

Unable to map files without a starting placeholder in the Meson metadata (regression) #341

Closed FFY00 closed 1 year ago

FFY00 commented 1 year ago

When writing a test to check something else, I hit a case where Meson still uses the full path in the metadata, instead of having a placeholder. This happens because I install from py.get_path('purelib').

The heuristics that used to deal with this were removed in #280. We were under the impression these issues were fixed in newer Meson versions, but apparently using paths returned from functions, at least in install_subdir, is still broken. I should have tried this when reviewing the PR, sorry. IIRC, I did try another similar snippet, which IIRC was working, but I shouldn't have stopped there. We should have had a test covering this already too.

Reproducible:

# SPDX-FileCopyrightText: 2022 The meson-python developers
#
# SPDX-License-Identifier: MIT

project('install-subdir-python-path', version: '1.0.0')

py = import('python').find_installation()

install_subdir(
  'foo',
  install_dir: py.get_path('purelib'),
)
* Building wheel...
+ meson setup --prefix=/usr /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/builddir --native-file=/home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/builddir/meson-python-native-file.ini -Ddebug=false -Db_ndebug=if-release -Doptimization=2 --python.purelibdir /usr/lib/python3.10/site-packages --python.platlibdir /usr/lib/python3.10/site-packages
The Meson build system
Version: 1.0.1
Source dir: /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude
Build dir: /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/builddir
Build type: native build
Project name: install-subdir-python-path
Project version: 1.0.0
Host machine cpu family: x86_64
Host machine cpu: x86_64
Program python found: YES (/usr/bin/python)
Build targets in project: 0

install-subdir-python-path 1.0.0

  User defined options
    Native files     : /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/builddir/meson-python-native-file.ini
    debug            : false
    optimization     : 2
    prefix           : /usr
    python.platlibdir: /usr/lib/python3.10/site-packages
    python.purelibdir: /usr/lib/python3.10/site-packages
    b_ndebug         : if-release

Found ninja-1.11.1 at /usr/bin/ninja
! Using Meson to generate the project metadata (no `project` section in pyproject.toml)
+ /usr/bin/ninja
ninja: no work to do.
+ meson install --only-changed --destdir /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/.mesonpy-7s72kj4n/install
ninja: Entering directory `/home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/builddir'
ninja: no work to do.
Installing subdir /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/foo to /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/.mesonpy-7s72kj4n/install/usr/lib/python3.10/site-packages/foo
Installing /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/foo/file2 to /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/.mesonpy-7s72kj4n/install/usr/lib/python3.10/site-packages/foo
Installing /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/foo/bar/file1 to /home/anubis/git/mesonpy/tests/packages/install-subdir-exclude/.mesonpy-7s72kj4n/install/usr/lib/python3.10/site-packages/foo/bar
meson-python: warning: Could not map installation path to an equivalent wheel directory: '/usr/lib/python3.10/site-packages/foo'
Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
    main()
  File "/usr/lib/python3.10/site-packages/pyproject_hooks/_in_process/_in_process.py", line 335, in main
    json_out['return_val'] = hook(**hook_input['kwargs'])
  File "/usr/lib/python3.10/site-packages/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
    return _build_backend().build_wheel(wheel_directory, config_settings,
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 1034, in wrapper
    return func(*args, **kwargs)
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 1098, in build_wheel
    return project.wheel(out).name
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 967, in wheel
    file = self._wheel_builder.build(directory)
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 490, in build
    wheel_file = pathlib.Path(directory, f'{self.name}.whl')
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 274, in name
    tag=self.tag,
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 259, in tag
    if self.is_pure:
  File "/usr/lib/python3.10/functools.py", line 981, in __get__
    val = self.func(instance)
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 292, in is_pure
    if self._wheel_files['platlib']:
  File "/usr/lib/python3.10/functools.py", line 981, in __get__
    val = self.func(instance)
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 233, in _wheel_files
    return _map_to_wheel(self._sources)
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 167, in _map_to_wheel
    directory, path = _map_meson_destination(target['destination'])
  File "/home/anubis/git/mesonpy/mesonpy/__init__.py", line 158, in _map_meson_destination
    raise RuntimeError('Meson installation path {destination!r} does not start with a placeholder. Meson bug!')
RuntimeError: Meson installation path {destination!r} does not start with a placeholder. Meson bug!

ERROR Backend subprocess exited when trying to invoke build_wheel
dnicolodi commented 1 year ago

This is expected. See the documentation for get_path(): https://mesonbuild.com/Python-module.html#get_path It returns an absolute path as defined by the sysconfig Python module. You should not use it to derive installation paths, at least not when building wheels. You should use get_install_dir() instead.

dnicolodi commented 1 year ago

It is possible to pass absolute paths as installation paths. meson-python cannot deal with those, but when writing build definitions to be used to build wheels, this is a bug in the meson.build, not in meson-python.

dnicolodi commented 1 year ago

Also, note that py.get_path() does not respect --prefix, thus it would not work with the heuristic either, thus the build definition is technically not correct (or at least it would do something unexpected) also outside meson-python.

FFY00 commented 1 year ago

Closing this as per https://github.com/mesonbuild/meson-python/issues/344#issuecomment-1468737855.

@dnicolodi thanks!