rougier / freetype-py

Python binding for the freetype library
Other
304 stars 88 forks source link

Please provide non-bundled wheels #183

Closed zahlman closed 7 months ago

zahlman commented 7 months ago

I managed to create a pure-Python wheel from source... as desired, it includes only Python source code, and successfully uses the system Freetype shared library via ctypes.

However, this process was quite unpleasant. pip install --no-binary :all: freetype-py doesn't work like one would hope, at least not with contemporary Pip etc. What happens is that Pip tries to set up build isolation and then also install CMake etc. from source in the isolated environment, which fails. I tried again with pip wheel --no-binary freetype-py freetype-py and it works, but it's very slow and unresponsive - it silently downloads and sets up CMake (from a wheel) in the isolated environment.

CMake is a massive dependency - over ten times the size of Setuptools and over a hundred times the size of the resulting installation. It's also completely unnecessary just for packing the ['freetype', 'freetype.ft_enums'] packages into a wheel - pip wheel can do that, never mind Setuptools. Even today the download of a wheel like CMake's is non-trivial for some.

As wheels are preferred even for pure-Python projects, I'd like to request publishing a wheel with just the Python source code needed to talk to the system FreeType. I could do it myself but I wouldn't want to step on this project's toes. It's fine if it uses a completely different PyPI name to avoid user error.

HinTak commented 7 months ago

When did anything needing CMake? Upstream freetype is still autotool based...

anthrotype commented 7 months ago

if you ask pip to install --no-binary :all: you're asking to not use any binary wheels at all, which is why it attempts to build everything from source, including the build requirements like cmake. It's preferable to restrict the option to --no-binary freetype-py, which you say worked, despite still setting up the temporary isolated environment and unnecessarily installing cmake (from a wheel, not from source this time). You can also turn off the PEP518 build isolation with this option, it should be quicker to install then (we can probably document this in README):

pip install --no-build-isolation --no-binary freetype-py freetype-py

@HinTak yes, Cmake is a build requirement for building the freetype shared library that we include in the freetype-py wheels published on PyPI, when FREETYPEPY_BUNDLE_FT=1 is set (see setup.py and setup-build-freetype.py scripts).

I think there is a way to only set specific build dependencies conditionally for sdist vs wheel, see: https://setuptools.pypa.io/en/latest/build_meta.html#dynamic-build-dependencies-and-other-build-meta-tweaks

we could use approach above to only include cmake among wheel build deps if the FREETYPEPY_BUNDLE_FT variable is set.

anthrotype commented 7 months ago

I could do it myself but I wouldn't want to step on this project's toes.

yeah, please don't do that, it'd just create more confusion

anthrotype commented 7 months ago

Upstream freetype is still autotool based...

true, but freetype also has https://gitlab.com/freetype/freetype/-/blob/master/CMakeLists.txt and that was easier to use from python than autotools to build wheels for Mac, Linux and Windows

anthrotype commented 7 months ago

As wheels are preferred even for pure-Python projects

freetype-py is not a classic pure-python project, it uses ctypes to dynamically load an external shared library. Most users would find it more convenient to be able to simply pip install freetype-py and get the FreeType library already bundled with it, instead of relying on the system one (which might not always be up to date or available at all, e.g. windows).

We could in theory also upload the pure python wheel to PyPI, but even in that case it would be downloaded by pip only when the more specific platform-architecture-based binary wheels do not match the current one, most of the time the latter will take precedence over the more general pure wheel. I think you can force pip to download a specific wheel e.g. --platform none but I doubt it makes it any easier or speedier than simply installing with --no-binary from the sdist.

anthrotype commented 7 months ago

Just pip install --no-binary freetype-py freetype-py to install the pure-python freetype-py (that attempts to load system-wide freetype) from the source distribution available on PyPI. After #184, cmake won't be installed (unless needed when FREETYPEPY_BUNDLE_FT env var is set).

HinTak commented 6 months ago

I cross-compile(d) freetype for windows/mac os x via autotools quite routinely for FontVal, but been gaining a lot of experience with github's CI in the last 6 months, which builds things natively (on somewhat old/dated virtual hosts provided by github for widest backward compatibility support. This has its own security-related problems with older version of software).

I would really think two separate binary packages (one for Windows and one for mac; Linux isn't needed as freetype is always built-in) would be appropriate. The Windows build does not even need to be a package - single DLL copied to current location would do.