Merge pull request #7658 from nulano/build-editable

This commit is contained in:
Hugo van Kemenade 2024-03-30 11:10:46 +02:00 committed by GitHub
commit 0b1d0c23de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 55 additions and 47 deletions

View File

@ -5,6 +5,7 @@ on:
paths: paths:
- ".ci/requirements-cibw.txt" - ".ci/requirements-cibw.txt"
- ".github/workflows/wheel*" - ".github/workflows/wheel*"
- "setup.py"
- "wheels/*" - "wheels/*"
- "winbuild/build_prepare.py" - "winbuild/build_prepare.py"
- "winbuild/fribidi.cmake" - "winbuild/fribidi.cmake"
@ -14,6 +15,7 @@ on:
paths: paths:
- ".ci/requirements-cibw.txt" - ".ci/requirements-cibw.txt"
- ".github/workflows/wheel*" - ".github/workflows/wheel*"
- "setup.py"
- "wheels/*" - "wheels/*"
- "winbuild/build_prepare.py" - "winbuild/build_prepare.py"
- "winbuild/fribidi.cmake" - "winbuild/fribidi.cmake"

View File

@ -11,41 +11,12 @@ backend_class = build_wheel.__self__.__class__
class _CustomBuildMetaBackend(backend_class): class _CustomBuildMetaBackend(backend_class):
def run_setup(self, setup_script="setup.py"): def run_setup(self, setup_script="setup.py"):
if self.config_settings: if self.config_settings:
for key, values in self.config_settings.items():
if not isinstance(values, list):
values = [values]
for value in values:
sys.argv.append(f"--pillow-configuration={key}={value}")
def config_has(key, value):
settings = self.config_settings.get(key)
if settings:
if not isinstance(settings, list):
settings = [settings]
return value in settings
flags = []
for dependency in (
"zlib",
"jpeg",
"tiff",
"freetype",
"raqm",
"lcms",
"webp",
"webpmux",
"jpeg2000",
"imagequant",
"xcb",
):
if config_has(dependency, "enable"):
flags.append("--enable-" + dependency)
elif config_has(dependency, "disable"):
flags.append("--disable-" + dependency)
for dependency in ("raqm", "fribidi"):
if config_has(dependency, "vendor"):
flags.append("--vendor-" + dependency)
if self.config_settings.get("platform-guessing") == "disable":
flags.append("--disable-platform-guessing")
if self.config_settings.get("debug") == "true":
flags.append("--debug")
if flags:
sys.argv = sys.argv[:1] + ["build_ext"] + flags + sys.argv[1:]
return super().run_setup(setup_script) return super().run_setup(setup_script)
def build_wheel( def build_wheel(
@ -54,5 +25,15 @@ class _CustomBuildMetaBackend(backend_class):
self.config_settings = config_settings self.config_settings = config_settings
return super().build_wheel(wheel_directory, config_settings, metadata_directory) return super().build_wheel(wheel_directory, config_settings, metadata_directory)
def build_editable(
self, wheel_directory, config_settings=None, metadata_directory=None
):
self.config_settings = config_settings
return super().build_editable(
wheel_directory, config_settings, metadata_directory
)
build_wheel = _CustomBuildMetaBackend().build_wheel
_backend = _CustomBuildMetaBackend()
build_wheel = _backend.build_wheel
build_editable = _backend.build_editable

View File

@ -266,9 +266,10 @@ After navigating to the Pillow directory, run::
Build Options Build Options
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
* Environment variable: ``MAX_CONCURRENCY=n``. Pillow can use * Config setting: ``-C parallel=n``. Can also be given
multiprocessing to build the extension. Setting ``MAX_CONCURRENCY`` with environment variable: ``MAX_CONCURRENCY=n``. Pillow can use
sets the number of CPUs to use, or can disable parallel building by multiprocessing to build the extension. Setting ``-C parallel=n``
sets the number of CPUs to use to ``n``, or can disable parallel building by
using a setting of 1. By default, it uses 4 CPUs, or if 4 are not using a setting of 1. By default, it uses 4 CPUs, or if 4 are not
available, as many as are present. available, as many as are present.
@ -293,14 +294,13 @@ Build Options
used to compile the standard Pillow wheels. Compiling libraqm requires used to compile the standard Pillow wheels. Compiling libraqm requires
a C99-compliant compiler. a C99-compliant compiler.
* Build flag: ``-C platform-guessing=disable``. Skips all of the * Config setting: ``-C platform-guessing=disable``. Skips all of the
platform dependent guessing of include and library directories for platform dependent guessing of include and library directories for
automated build systems that configure the proper paths in the automated build systems that configure the proper paths in the
environment variables (e.g. Buildroot). environment variables (e.g. Buildroot).
* Build flag: ``-C debug=true``. Adds a debugging flag to the include and * Config setting: ``-C debug=true``. Adds a debugging flag to the include and
library search process to dump all paths searched for and found to library search process to dump all paths searched for and found to stdout.
stdout.
Sample usage:: Sample usage::

View File

@ -27,6 +27,9 @@ def get_version():
return locals()["__version__"] return locals()["__version__"]
configuration = {}
PILLOW_VERSION = get_version() PILLOW_VERSION = get_version()
FREETYPE_ROOT = None FREETYPE_ROOT = None
HARFBUZZ_ROOT = None HARFBUZZ_ROOT = None
@ -333,15 +336,24 @@ class pil_build_ext(build_ext):
+ [("add-imaging-libs=", None, "Add libs to _imaging build")] + [("add-imaging-libs=", None, "Add libs to _imaging build")]
) )
@staticmethod
def check_configuration(option, value):
return True if value in configuration.get(option, []) else None
def initialize_options(self): def initialize_options(self):
self.disable_platform_guessing = None self.disable_platform_guessing = self.check_configuration(
"platform-guessing", "disable"
)
self.add_imaging_libs = "" self.add_imaging_libs = ""
build_ext.initialize_options(self) build_ext.initialize_options(self)
for x in self.feature: for x in self.feature:
setattr(self, f"disable_{x}", None) setattr(self, f"disable_{x}", self.check_configuration(x, "disable"))
setattr(self, f"enable_{x}", None) setattr(self, f"enable_{x}", self.check_configuration(x, "enable"))
for x in ("raqm", "fribidi"): for x in ("raqm", "fribidi"):
setattr(self, f"vendor_{x}", None) setattr(self, f"vendor_{x}", self.check_configuration(x, "vendor"))
if self.check_configuration("debug", "true"):
self.debug = True
self.parallel = configuration.get("parallel", [None])[-1]
def finalize_options(self): def finalize_options(self):
build_ext.finalize_options(self) build_ext.finalize_options(self)
@ -987,6 +999,12 @@ ext_modules = [
Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]), Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]),
] ]
# parse configuration from _custom_build/backend.py
while sys.argv[-1].startswith("--pillow-configuration="):
_, key, value = sys.argv.pop().split("=", 2)
configuration.setdefault(key, []).append(value)
try: try:
setup( setup(
cmdclass={"build_ext": pil_build_ext}, cmdclass={"build_ext": pil_build_ext},

View File

@ -87,11 +87,18 @@ are set by running ``winbuild\build\build_env.cmd`` and install Pillow with pip:
winbuild\build\build_env.cmd winbuild\build\build_env.cmd
python.exe -m pip install -v -C raqm=vendor -C fribidi=vendor . python.exe -m pip install -v -C raqm=vendor -C fribidi=vendor .
To build a wheel instead, run:: You can also install Pillow in `editable mode`_::
winbuild\build\build_env.cmd
python.exe -m pip install -v -C raqm=vendor -C fribidi=vendor -e .
To build a binary wheel instead, run::
winbuild\build\build_env.cmd winbuild\build\build_env.cmd
python.exe -m pip wheel -v -C raqm=vendor -C fribidi=vendor . python.exe -m pip wheel -v -C raqm=vendor -C fribidi=vendor .
.. _editable mode: https://setuptools.pypa.io/en/stable/userguide/development_mode.html
Testing Pillow Testing Pillow
-------------- --------------