Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ on:
- ".github/generate-sbom.py"
- ".github/workflows/wheels*"
- "pyproject.toml"
- "setup.py"
- "_custom_build/pillow_ext.py"
- "wheels/*"
- "winbuild/build_prepare.py"
- "winbuild/fribidi.cmake"
Expand Down
4 changes: 3 additions & 1 deletion _custom_build/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ def run_setup(self, setup_script="setup.py"):
for value in values:
sys.argv.append(f"--pillow-configuration={key}={value}")

return super().run_setup(setup_script)
import pillow_ext

pillow_ext.run()

def build_wheel(
self, wheel_directory, config_settings=None, metadata_directory=None
Expand Down
120 changes: 60 additions & 60 deletions setup.py → _custom_build/pillow_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,6 @@

configuration: dict[str, list[str]] = {}

# 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)

default = int(configuration.get("parallel", ["0"])[-1])
ParallelCompile("MAX_CONCURRENCY", default).install()


def get_version() -> str:
version_file = "src/PIL/_version.py"
Expand All @@ -57,20 +49,6 @@ def get_version() -> str:
ZLIB_ROOT = None
FUZZING_BUILD = "LIB_FUZZING_ENGINE" in os.environ

if sys.platform == "win32" and sys.version_info >= (3, 16):
import atexit

atexit.register(
lambda: warnings.warn(
f"Pillow {PILLOW_VERSION} does not support Python "
f"{sys.version_info.major}.{sys.version_info.minor} and does not provide "
"prebuilt Windows binaries. We do not recommend building from source on "
"Windows.",
RuntimeWarning,
)
)


_IMAGING = ("decode", "encode", "map", "display", "outline", "path")

_LIB_IMAGING = (
Expand Down Expand Up @@ -1073,40 +1051,62 @@ def debug_build() -> bool:
return hasattr(sys, "gettotalrefcount") or FUZZING_BUILD


libraries: list[tuple[str, _BuildInfo]] = [
("pil_imaging_mode", {"sources": ["src/libImaging/Mode.c"]}),
]
def run() -> None:
global configuration
configuration = {}
while sys.argv and sys.argv[-1].startswith("--pillow-configuration="):
_, key, value = sys.argv.pop().split("=", 2)
configuration.setdefault(key, []).append(value)

files: list[str | os.PathLike[str]] = ["src/_imaging.c"]
files.extend("src/" + src_file + ".c" for src_file in _IMAGING)
files.extend(
os.path.join("src/libImaging", src_file + ".c") for src_file in _LIB_IMAGING
)
ext_modules = [
Extension("PIL._imaging", files),
Extension("PIL._imagingft", ["src/_imagingft.c"]),
Extension("PIL._imagingcms", ["src/_imagingcms.c"]),
Extension("PIL._webp", ["src/_webp.c"]),
Extension("PIL._avif", ["src/_avif.c"]),
Extension("PIL._imagingtk", ["src/_imagingtk.c", "src/Tk/tkImaging.c"]),
Extension(
"PIL._imagingmath",
["src/_imagingmath.c"],
libraries=None if sys.platform == "win32" else ["m"],
),
Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]),
]


try:
setup(
cmdclass={"build_ext": pil_build_ext},
ext_modules=ext_modules,
libraries=libraries,
zip_safe=not (debug_build() or PLATFORM_MINGW),
default = int(configuration.get("parallel", ["0"])[-1])
ParallelCompile("MAX_CONCURRENCY", default).install()

if sys.platform == "win32" and sys.version_info >= (3, 16):
import atexit

atexit.register(
lambda: warnings.warn(
f"Pillow {PILLOW_VERSION} does not support Python "
f"{sys.version_info.major}.{sys.version_info.minor} and does not "
"provide prebuilt Windows binaries. We do not recommend building from "
"source on Windows.",
RuntimeWarning,
)
)

libraries: list[tuple[str, _BuildInfo]] = [
("pil_imaging_mode", {"sources": ["src/libImaging/Mode.c"]}),
]

files: list[str | os.PathLike[str]] = ["src/_imaging.c"]
files.extend("src/" + src_file + ".c" for src_file in _IMAGING)
files.extend(
os.path.join("src/libImaging", src_file + ".c") for src_file in _LIB_IMAGING
)
except RequiredDependencyException as err:
msg = f"""
ext_modules = [
Extension("PIL._imaging", files),
Extension("PIL._imagingft", ["src/_imagingft.c"]),
Extension("PIL._imagingcms", ["src/_imagingcms.c"]),
Extension("PIL._webp", ["src/_webp.c"]),
Extension("PIL._avif", ["src/_avif.c"]),
Extension("PIL._imagingtk", ["src/_imagingtk.c", "src/Tk/tkImaging.c"]),
Extension(
"PIL._imagingmath",
["src/_imagingmath.c"],
libraries=None if sys.platform == "win32" else ["m"],
),
Extension("PIL._imagingmorph", ["src/_imagingmorph.c"]),
]

try:
setup(
cmdclass={"build_ext": pil_build_ext},
ext_modules=ext_modules,
libraries=libraries,
zip_safe=not (debug_build() or PLATFORM_MINGW),
)
except RequiredDependencyException as err:
msg = f"""

The headers or library files could not be found for {str(err)},
a required dependency when compiling Pillow from source.
Expand All @@ -1115,14 +1115,14 @@ def debug_build() -> bool:
https://pillow.readthedocs.io/en/latest/installation/basic-installation.html

"""
sys.stderr.write(msg)
raise RequiredDependencyException(msg)
except DependencyException as err:
msg = f"""
sys.stderr.write(msg)
raise RequiredDependencyException(msg)
except DependencyException as err:
msg = f"""

The headers or library files could not be found for {str(err)},
which was requested by the option flag '-C {str(err)}=enable'

"""
sys.stderr.write(msg)
raise DependencyException(msg)
sys.stderr.write(msg)
raise DependencyException(msg)
2 changes: 1 addition & 1 deletion docs/installation/building-from-source.rst
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ If the prerequisites are installed in the standard library locations
for your machine (e.g. :file:`/usr` or :file:`/usr/local`), no
additional configuration should be required. If they are installed in
a non-standard location, you may need to configure setuptools to use
those locations by editing :file:`setup.py` or
those locations by editing :file:`_custom_build/pillow_ext.py` or
:file:`pyproject.toml`, or by adding environment variables on the command
line::

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ skip_install = true
deps =
-r .ci/requirements-mypy.txt
commands =
mypy conftest.py selftest.py setup.py checks docs src winbuild Tests {posargs}
mypy conftest.py selftest.py _custom_build/pillow_ext.py checks docs src winbuild Tests {posargs}
Loading