Skip to content

libdir inexplicitly overriden when installing a shared library from a subproject #817

@MKuranowski

Description

@MKuranowski

I'm building a ctypes-based Python wrapper for a library provided as a subproject.

I would expect such a project to have a simple layout of foo/__init__.py, foo/wrapper.py and foo/libfoo.so, like in https://github.com/joerick/python-ctypes-package-sample or even https://github.com/peppedilillo/meson-ctypes-test.

The compiled library does the following in subprojects/foo/meson.build:

foo_tgt = custom_target(
  'foo',
  output: 'libfoo.so',
  command: [...],
  install: true,
  install_dir: get_option('libdir'),
)

It's a custom_target, because it's actually another wrapper, but the same issue persists with shared_library.

My meson.build looks like this:

project('foo-python')

py = import('python').find_installation(pure: false)
py.install_sources(
  'foo/__init__.py',
  'foo/wrapper.py',
  preserve_path: true,
)

subproject(
  'foo',
  default_options: {
    'libdir': py.get_install_dir() / 'foo',
  },
)

foo/wrapper.py attempts to load the shared library with a simple ctypes.cdll.LoadLibrary(str(Path(__file__).with_name("libfoo.so"))).

And even though I explicitly specify the libdir, the built wheel contains the .so file in a completely arbitrary location:

$ python -m build -w
...
Successfully built foo-0.1.0-cp313-cp313-linux_x86_64.whl
$ unzip -l dist/foo-0.1.0-cp313-cp313-linux_x86_64.whl
Archive:  dist/foo-0.1.0-cp313-cp313-linux_x86_64.whl
  Length      Date    Time    Name
---------  ---------- -----   ----
      149  2025-11-01 14:50   foo-0.1.0.dist-info/METADATA
       88  2025-11-01 14:50   foo-0.1.0.dist-info/WHEEL
  1360680  2025-11-01 14:49   .foo.mesonpy.libs/libfoo.so
      532  2025-11-01 14:17   foo/__init__.py
    22526  2025-11-01 14:18   foo/wrapper.py
      507  2025-11-01 14:50   foo-0.1.0.dist-info/RECORD
---------                     -------
  1389847                     7 files

In this case I would expect libfoo.so to be placed in foo/libfoo.so.

This issue only persists when using subprojects. Without them, it's possible to simply do custom_target(..., install: true, install_dir: py.get_install_dir() / 'foo') (or the same with shared_library), as evidenced in https://github.com/peppedilillo/meson-ctypes-test (also related - #573).

Seems to also be related to #770.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions