How can I bundle a shared library in a wheel with mesonpy? #410
Replies: 7 comments 20 replies
-
Good question @oscarbenjamin. A few initial thoughts:
Your test package looks quite good to me, the way it handles GMP as dependency seems right. The question is how to fix it - there's probably a better way than your patch above. |
Beta Was this translation helpful? Give feedback.
-
The reason why your patched meson-python produces a wheel that works is because either the Python extension module is compiled statically against GMP or because the Python extension is linked dynamically and you have GMP installed on the system where you are running it. If you don't need GMP bundled with the Python wheel (if you can assume a compatible version of GMP is installed on the target system, or if you link statically to it), the way to make your current solution work is to do not install the GMP subproject. I'm not so sure how to do this in practice when you are dealing with an |
Beta Was this translation helpful? Give feedback.
-
Looking a the source of the error reported by meson-python, this is the install manifest for the project:
meson-python does not know where to place the files that are copied into the generic
At the moment I don't see how a solution could look like. |
Beta Was this translation helpful? Give feedback.
-
The problem is I want different things in different situations:
Potentially the answer to all of these is that is not really for mesonpy to build/bundle the library in the wheel and I am just not quite using it in the expected way. Perhaps I can open the question up a bit:
Looking at meson + meson-python made me wonder if it can somehow help with some of these things. The approach that I went for here seemed to give reasonable answers to some of the questions above because it means I can manage dependencies in the meson build configuration, users can have them be built if needed, the dependencies are contained to a venv etc. Linking statically also answers those questions in the same way but has the downside that if I have many extension modules depending on GMP (and other C libraries) then I will end up duplicating the GMP etc library code across those many extension modules. |
Beta Was this translation helpful? Give feedback.
-
Having looked into this in more detail I don't think that the approach that I was attempting to follow of building and bundling external dependency shared libraries into the wheel with mesonpy is workable. At least I think that significant changes in mesonpy would be needed to make this work. Currently the expectation is that building uses a PEP 517 build frontend like When we want to ship wheels that bundle the dependencies we arrange to have the non-Python dependencies installed system-wide first, invoke the PEP 517 build and then repair afterwards. The repair step bundles the shared libraries but also performs the necessary name mangling or RPATH modifications so that the bundled libraries can be used without conflicting with system libs. Even if the user does not have GMP installed when the wheel is built it is possible that they would install GMP later. It is not appropriate for mesonpy to install the libraries system-wide. It is also not enough just to bundle the shared library files without also taking steps to ensure that those libraries and the extension modules linking to them are isolated from system libs. If we want mesonpy to build the non-Python dependencies then we need it to include part of what the repair step is doing so it needs to perform a subset of what auditwheel/delocate/delvewheel currently do. This seems like a change of scope for mesonpy and its role as a PEP 517 backend that is invoked by commands like What could work is if this was all using static linking but I think that is not a good fit for python-flint which has many extension modules all linking to the fairly large I would like to use meson to manage building the dependencies in a development checkout and also as an option for users who want to setup the dependencies easily when building from source. I think though that what we need for that is a separate meson build configuration like having a subdirectory
Then perhaps if using |
Beta Was this translation helpful? Give feedback.
-
I am revisiting this after a discussion with someone trying to install python-flint (flintlib/python-flint#193). A user wants to install a newer version of python-flint but we don't provide wheels for their platform (Linux aarch64 because GitHub Actions does not support this yet). They have previously built from source fine though and would be happy to do so again. However they have the wrong version of Flint installed. Their Flint installation is part of a bundle of other software that uses an older version of Flint. They can't just install a newer version of Flint system-wide because it would break all of the other software. We handle this situation nicely with the binary wheels on PyPI because auditwheel mangles and bundles I said in my last comment that it seems like meson-python should possibly not be expected to do this building and bundling of non-Python libraries. However I should amend that statement at least to say that it is perhaps not a good idea to do that by default. At the very least it would be good to be able to have an option like: # Build and bundle Flint 3.1 into the Python installation:
pip install --config-settings=setup-args=-Dbuild_flint==3.1 python-flint I think that this can't work right now though because meson-python does not provide a facility to mangle and bundle the shared libraries but it is clear to me now that this would be a useful thing to be able to do. |
Beta Was this translation helpful? Give feedback.
-
Hi, has there been any progress on this? I have a similar use case. I have a subproject ( Example: python = import('python').find_installation(pure: false)
mylib_proj = subproject('mylib', ...)
mylib_dep = mylib_proj.get_variable('mylib_dep') # Shared mylib lib dependency
python.extension_module(..., dependency: mylib_dep, install: true, subdir: 'myModule') The subproject's call to However, when I build the wheel only the Python extension |
Beta Was this translation helpful? Give feedback.
-
I am trying to use meson-python to build a cython extension module that links against GMP. What I have so far is here:
https://github.com/oscarbenjamin/mesontest
It can be tested with:
git clone https://github.com/oscarbenjamin/mesontest.git cd mesontest/ python -m build
Currently if there is a system install of GMP that should succeed. However if there is no system install of GMP then it will download GMP and build it as a meson subproject. While meson builds GMP correctly mesonpy fails to package the files into a wheel:
Since GMP is an autotools project I'm using meson's
unstable-external_project
feature to build it as a subproject with:I can build fine with meson/ninja:
That creates the expected files:
I think somehow mesonpy needs to be told what to do with these files. Ideally the gmp
.so
files would get bundled into the wheel or at least that is what I would want to happen when running this in cibuildwheel but maybe there it should be done by cibuildwheel rather than by mesonpy...The examples for mesonpy only show two very complicated projects and then a simple one that links a library statically:
https://meson-python.readthedocs.io/en/latest/projects-using-meson-python.html#projects-using-meson-python
I am actually not sure if the build I have is linking statically or dynamically because I have tried many configurations and have never seen the gmp so get bundled into the wheel. I can actually patch mesonpy to make it work:
With that I can build a wheel and install and use it:
Am I misunderstanding here how mesonpy is supposed to work or should it be able to handle this?
Is it better not to try to have meson build GMP and just say that it is the user's responsibility to have GMP installed before building the extension module?
Beta Was this translation helpful? Give feedback.
All reactions