-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cython C-API is broken in published wheels (and in the build_wheels.yml CI workflow) #447
Comments
This is a fundamental flaw with binary wheels, a C-API, and gmpy2. An extension that uses gmpy2's CAPI must(*) use the same GMP, MPFR, and MPC libraries. The name-mangling that occurs on Linux and MacOS makes that somewhere between complicated and impossible. The assumption was that Python and the extensions use the same OS provided libraries. So the Cython tests can practically only be done when gmpy2 with the OS provided GMP, MPFR, and MPC libraries. I think we could require that the development version of gmpy2 can be successfully compiled on the most recent Ubuntu LTS version. A workflow that tests gmpy2 against the most recent Ubuntu LTS and its libraries would be the best place to test Cython and the C-API. Windows binary wheels are different. I'm currently including the header files, the DLLs, and the LIB definition files MSVC compiler under the gmpy2 directory. It should work with Cython and other extensions but I still need to test it. (*) "Must" may be too strong of a word. It may work. But we can't guarantee it. |
Hmm, I don't think it's impossible. If you put header files to the gmpy2 package - they will be found. To find libraries (gmpy2.libs) - users could use LD_LIBRARY_PATH & set library_dirs option of the Extension class.
We run these tests (pip_install_gmpy2.yml, but not for Ubuntu yet). But I don't see too much value in untested wheels with C-API for Cython... |
I was able to successfully compile and run |
@casevh, if this was about 8a39f52 - I doubt this commit does fix anything. Cython tests works in the pip_install_gmpy2 for Windows too: gmpy/.github/workflows/pip_install_gmpy2.yml Lines 82 to 107 in 8a39f52
What doesn't work (and this issue is about): cython tests after installation of binary wheels in a clean environment. |
Ok, I have successful cython tests locally (Linux) after installation of repaired (of repaired :)) wheels:
As you can see, (1) header files were added. And (2) also symlinks to workaround library name mangling. include_dirs/library_dirs of the test_cython extension should include gmpy2.libs: diff --git a/test_cython/setup_cython.py b/test_cython/setup_cython.py
index ad2de54..1e15895 100644
--- a/test_cython/setup_cython.py
+++ b/test_cython/setup_cython.py
@@ -1,19 +1,15 @@
from setuptools import Extension, setup
from Cython.Build import cythonize
-import platform
import sys
import os
import gmpy2
-ON_WINDOWS = platform.system() == 'Windows'
extensions = [
Extension("test_cython", ["test_cython.pyx"],
- include_dirs=sys.path + ([os.path.dirname(gmpy2.__file__)] if ON_WINDOWS else []),
- library_dirs=sys.path + ([os.path.dirname(gmpy2.__file__)] if ON_WINDOWS else []),
- libraries=['mpc','mpfr','gmp']
- )
-]
+ include_dirs=sys.path + ([os.path.dirname(gmpy2.__file__), gmpy2.__path__[0] + '/../gmpy2.libs/']),
+ library_dirs=sys.path + ([os.path.dirname(gmpy2.__file__), gmpy2.__path__[0] + '/../gmpy2.libs/']),
+ libraries=['mpc','mpfr','gmp'])]
setup(
name="cython_gmpy_test", But, probably, we should instead set PYTHONPATH to gmpy2.libs. Similar workaround should work for MacOS (no name mangling, but a different directory: .dylibs) and Windows. |
I've been debugging this while you were making also debugging it. I converged to roughly the same changes as you did. Just some comments.
The combination of a C-API for gmpy2, name-mangling of libraries in a binary wheel, libraries that maintain their own state, and the preference to use binary wheels versus Linux pre-compiled versions or compiling from source is a challenging problem. Thanks for working on the fixes. I'll look at them tomorrow. |
Actually they aren't symlinks anymore after
Yes, I realize there are reasons for this. On another hand I doubt it's too easy to interfere with the OS provided libraries (gmpy2.libs is a very non-standard place to search for headers/libraries).
That's something we could document. Other third-party cython extensions, intended to interoperate with gmpy2 could use libraries from our wheels just as shown above. I will work on above solution for Linux/MacOS wheels and hopefully will come with a pr in a few days. An easy way: remove cython-related stuff from binary wheels and warn users that to have cython interface - they must build the package from sources. |
And on Windows, "gmpy2.h" just contains "../src/gmpy2.h". It's technically not a symlink anymore...
Is it possible do disable the name mangling when creating a Linux binary wheel? If so, could we use one consistent set of name-mangled libraries for an entire release cycle? For Windows, I plan to use the same GMP, MPFR, and MPC libraries for the entire 2.2.x release cycle. A change to those libraries would force a version change.
Remove the C-API when a binary wheel is created? Or is it possible to identify if gmpy2 was distributed as a binary wheel (look for gmpy2.libs??) and not import _C_API into the main gmpy2 namespace? |
Hmm, seems to be a platform-specific issue.
This is non-opt feature of auditwheel.
Just remove headers. Then we can decide to not import C-API at runtime. |
The problem is that we bundle libraries.
Then, first, probably we should also supply relevant header files (gmp.h, etc). Next, document how user can specify a custom path (gmpy2.libs) to libraries in the setup.py.
The text was updated successfully, but these errors were encountered: