Skip to content

Commit b967753

Browse files
python3-modules: build pillow without FreeType
With the sync no longer breaking on it, sles-12sp5 gets as far as compiling pillow - and fails there: src/_imagingft.c: error: implicit declaration of function 'FT_Set_Named_Instance' pillow 12.0.0 removed the FREETYPE_MAJOR/MINOR guards around the variable font API (python-pillow/Pillow#9159), so _imagingft now calls FT_Done_MM_Var and FT_Set_Named_Instance unconditionally and needs FreeType >= 2.9.1. pillow's setup.py only probes whether FreeType is present, never which version, so it enables the module regardless. sles-12sp5 ships FreeType 2.6.3 and nothing newer is installable: freetype2-devel-2.6.3-7.15.1 (the only version in our sles12sp5 repo) FREETYPE_MAJOR 2 / FREETYPE_MINOR 6 / FREETYPE_PATCH 3 ftmm.h declares neither of the two functions libfreetype.so.6 exports neither of them Note the last line: the runtime library is equally old, so building against a newer FreeType without also shipping it would only move the failure to the customer's machine - the SONAME stayed libfreetype.so.6 across all these versions, and we link with -z now, so it would fail at import rather than lazily. We never render text with PIL - it is used for image IO only, there is no ImageFont, ImageDraw or truetype anywhere in the repo - so disable the feature instead of shipping a FreeType. master already disables avif the same way, because libavif is unavailable on debian-12. Where the option goes matters: pip applies --config-settings only to requirements named on the command line, never to the ones it reads from a "-r" file, and both builds install from "-r". So it has to be attached to the requirement itself rather than to the pip invocation. For Bazel that is the generated per-module requirements file. For the .venv it means installing pillow up front, because the requirements file pipenv hands to pip is not ours to extend and pipenv has no Pipfile syntax for per-package pip options. Requirement and hashes come from Pipfile.lock, so pillow stays pinned and hash checked, and the sync afterwards finds it already satisfied and leaves it alone. (get_pip_options() keeps its numpy entry, which is ineffective for the same reason, but changing how numpy builds is out of scope here.) Verified by rebuilding the venv from scratch with PIP_NO_BINARY=pillow, so that pillow is built from source exactly as on sles-12sp5: PIL reports freetype2 False with no _imagingft*.so, while a normal wheel based rebuild is unaffected. "make test-mypy" still reports no issues in 7436 source files. Change-Id: I02a16f5f1007b0f8befd9f0c1f68a4c8822a0f65
1 parent 359768b commit b967753

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

Makefile

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,15 @@ Pipfile.lock: Pipfile
439439
# only bites on distros without a matching wheel, which made it look like a
440440
# sles-12sp5 specific failure.
441441
#
442+
# pillow gets installed up front, because it needs the same "build without
443+
# FreeType" treatment the Bazel build applies (see the rationale in
444+
# omd/packages/python3-modules/build-python3-modules.bzl): on sles-12sp5 it has no
445+
# wheel and the system FreeType 2.6.3 is too old for pillow 12. It cannot be done
446+
# as part of the sync, because pip applies --config-settings only to requirements
447+
# named on the command line, never to the ones it reads from the "-r" file pipenv
448+
# hands it. Requirement and hashes come from Pipfile.lock, so this stays pinned and
449+
# hash checked, and the sync afterwards just finds it already satisfied.
450+
#
442451
# We still need our own packages laid out so that mypy can type check them:
443452
# https://github.com/python/mypy/issues/13392
444453
# --config-settings editable_mode=compat is setuptools' supported replacement
@@ -455,7 +464,13 @@ Pipfile.lock: Pipfile
455464
echo "Cleaning up .venv before sync..."; \
456465
$(RM) -r .venv; \
457466
fi; \
458-
( PIP_CONSTRAINT=temporary_pipenv_constraints.txt SKIP_MAKEFILE_CALL=1 VIRTUAL_ENV="" $(PIPENV) sync --python $(PYTHON_MAJOR_DOT_MINOR) --dev \
467+
( SKIP_MAKEFILE_CALL=1 VIRTUAL_ENV="" $(PIPENV) run python -c "" \
468+
&& echo "Installing pillow without FreeType support..." \
469+
&& PILLOW_REQUIREMENTS=$$(mktemp) \
470+
&& .venv/bin/python -c 'import json; e = json.load(open("Pipfile.lock"))["default"]["pillow"]; print("pillow" + e["version"], "--config-settings freetype=disable", *("--hash=" + h for h in e["hashes"]))' > $$PILLOW_REQUIREMENTS \
471+
&& PIP_CONSTRAINT=temporary_pipenv_constraints.txt .venv/bin/python -m pip install --quiet --no-deps -r $$PILLOW_REQUIREMENTS \
472+
&& $(RM) $$PILLOW_REQUIREMENTS \
473+
&& PIP_CONSTRAINT=temporary_pipenv_constraints.txt SKIP_MAKEFILE_CALL=1 VIRTUAL_ENV="" $(PIPENV) sync --python $(PYTHON_MAJOR_DOT_MINOR) --dev \
459474
&& echo "Reinstalling editable packages in compat mode..." \
460475
&& .venv/bin/python -m pip install --quiet --no-deps --no-build-isolation --config-settings editable_mode=compat \
461476
$$(.venv/bin/python -c 'import json; print(" ".join("-e " + e["path"] for s in ("default", "develop") for e in json.load(open("Pipfile.lock"))[s].values() if e.get("editable")))') \

omd/packages/python3-modules/build-python3-modules.bzl

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,22 @@ def get_pip_options(module_name):
99
"numpy": '--config-settings=setup-args="-Dallow-noblas=true"',
1010
}.get(module_name, "")
1111

12+
def get_requirement_options(module_name):
13+
"""Options that have to be attached to the requirement itself.
14+
15+
pip applies --config-settings only to requirements named on the command line, never
16+
to the ones it reads from a "-r" file. We install every module via "-r", so passing
17+
them through get_pip_options() above would silently have no effect.
18+
"""
19+
return {
20+
# pillow 12.0.0 removed the FREETYPE_MAJOR/MINOR guards around the variable font
21+
# API (https://github.com/python-pillow/Pillow/pull/9159), so building _imagingft
22+
# now needs FreeType >= 2.9.1. sles-12sp5 only has 2.6.3 and nothing newer is
23+
# installable there. We never render text with PIL - it is only used for image IO -
24+
# so we simply disable it.
25+
"pillow": " --config-settings freetype=disable",
26+
}.get(module_name, "")
27+
1228
def create_requirements_file(name, outs):
1329
"""This macro is creating a requirements file per module.
1430
"""
@@ -17,7 +33,7 @@ def create_requirements_file(name, outs):
1733
outs = outs,
1834
cmd = """
1935
echo "%s" > $@
20-
""" % packages[name],
36+
""" % (packages[name] + get_requirement_options(name)),
2137
)
2238

2339
def build_python_module(name, srcs, outs, cmd, **kwargs):

0 commit comments

Comments
 (0)