* [Buildroot] [PATCH 1/2] package/python-pipcl: new host package
@ 2026-09-30 12:00 Raphaël Mélotte via buildroot
2026-09-30 12:00 ` [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 Raphaël Mélotte via buildroot
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Raphaël Mélotte via buildroot @ 2026-09-30 12:00 UTC (permalink / raw)
To: buildroot; +Cc: James Hilliard, Raphaël Mélotte, Thomas Petazzoni
pipcl used to be bundled in python-pymupdf, but is now available as a
separate package.
Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
---
DEVELOPERS | 1 +
package/Config.in | 1 +
package/python-pipcl/Config.in | 7 +++++++
package/python-pipcl/python-pipcl.hash | 5 +++++
package/python-pipcl/python-pipcl.mk | 15 +++++++++++++++
5 files changed, 29 insertions(+)
create mode 100644 package/python-pipcl/Config.in
create mode 100644 package/python-pipcl/python-pipcl.hash
create mode 100644 package/python-pipcl/python-pipcl.mk
diff --git a/DEVELOPERS b/DEVELOPERS
index d62bfaafb3..217fce03a9 100644
--- a/DEVELOPERS
+++ b/DEVELOPERS
@@ -2849,6 +2849,7 @@ F: package/mupdf/
F: package/python-boto3/
F: package/python-botocore/
F: package/python-jmespath/
+F: package/python-pipcl/
F: package/python-pymupdf/
F: package/python-rsa/
F: package/python-s3transfer/
diff --git a/package/Config.in b/package/Config.in
index dcca214383..cd1f4eb36d 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -1293,6 +1293,7 @@ menu "External python modules"
source "package/python-pigpio/Config.in"
source "package/python-pillow/Config.in"
source "package/python-pip/Config.in"
+ source "package/python-pipcl/Config.in"
source "package/python-platformdirs/Config.in"
source "package/python-pluggy/Config.in"
source "package/python-ply/Config.in"
diff --git a/package/python-pipcl/Config.in b/package/python-pipcl/Config.in
new file mode 100644
index 0000000000..1cac85352d
--- /dev/null
+++ b/package/python-pipcl/Config.in
@@ -0,0 +1,7 @@
+config BR2_PACKAGE_PYTHON_PIPCL
+ bool "python-pipcl"
+ help
+ Python packaging operations, including PEP-517 support, for
+ use by a setup.py script.
+
+ https://github.com/ArtifexSoftware/pipcl
diff --git a/package/python-pipcl/python-pipcl.hash b/package/python-pipcl/python-pipcl.hash
new file mode 100644
index 0000000000..f01af0ccee
--- /dev/null
+++ b/package/python-pipcl/python-pipcl.hash
@@ -0,0 +1,5 @@
+# md5, sha256 from https://pypi.org/pypi/pipcl/json
+md5 76883243610278b77725feb1813141f8 pipcl-12.tar.gz
+sha256 c7545480cfa808500d8b606da73db7f89a872258bcdb293716126e2ccff1a5c6 pipcl-12.tar.gz
+# Locally computed sha256 checksums
+sha256 57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 COPYING
diff --git a/package/python-pipcl/python-pipcl.mk b/package/python-pipcl/python-pipcl.mk
new file mode 100644
index 0000000000..c0e97eeeb3
--- /dev/null
+++ b/package/python-pipcl/python-pipcl.mk
@@ -0,0 +1,15 @@
+################################################################################
+#
+# python-pipcl
+#
+################################################################################
+
+PYTHON_PIPCL_VERSION = 12
+PYTHON_PIPCL_SOURCE = pipcl-$(PYTHON_PIPCL_VERSION).tar.gz
+PYTHON_PIPCL_SITE = https://files.pythonhosted.org/packages/64/1a/9ab2b272def9db9c80bf18fe8282119c2c4c074cc542030a28e4136dd13b
+PYTHON_PIPCL_SETUP_TYPE = pep517
+PYTHON_PIPCL_LICENSE = AGPL-3.0+
+PYTHON_PIPCL_LICENSE_FILES = COPYING
+HOST_PYTHON_PIPCL_DEPENDENCIES = host-python-packaging
+
+$(eval $(host-python-package))
--
2.54.0
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
^ permalink raw reply related [flat|nested] 11+ messages in thread* [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 2026-09-30 12:00 [Buildroot] [PATCH 1/2] package/python-pipcl: new host package Raphaël Mélotte via buildroot @ 2026-09-30 12:00 ` Raphaël Mélotte via buildroot 2026-10-01 5:52 ` Waldemar Brodkorb 2026-10-04 15:41 ` Thomas Petazzoni via buildroot 2026-10-04 15:38 ` [Buildroot] [PATCH 1/2] package/python-pipcl: new host package Thomas Petazzoni via buildroot 2026-10-05 15:40 ` [Buildroot] [PATCH v2 " Raphaël Mélotte via buildroot 2 siblings, 2 replies; 11+ messages in thread From: Raphaël Mélotte via buildroot @ 2026-09-30 12:00 UTC (permalink / raw) To: buildroot; +Cc: James Hilliard, Raphaël Mélotte Release notes: https://mupdf.com/releases https://pymupdf.readthedocs.io/en/latest/changes.html Note that this bump fixes multiple security vulnerabilities, and at least the following ones: - CVE-2025-46206 - CVE-2025-71382 - CVE-2026-7233 - CVE-2026-40505 With this new python-pymupdf (and mupdf) version, we can no longer build the old implementation (the 'a' implementation). We now need to build mupdf's python binding, which require host-clang (and its python bindings) to be built. Also note that python-mupdf's version still needs to stay close to mupdf's version, they can only be updated together. A number of mupdf patches were needed: - To allow changing the build-time log level from an environment variable. - To be able to provide the libclang include directories. This is needed because our default libclang include directories are not properly set. - To be able to link against mupdf with no versioning number. - To fix build errors when generating the python bindings for python-pymupdf with clang 22. - To fix build errors with uClibc. - To make it possible to build without a venv. python-pymupdf also needed a (backported) patch to fix building with swig 4.5+. In mupdf, setting JLIB_log_levels is not strictly necessary, but it greatly helps debugging build issues. It also only has an impact at build time anyway. To make it easier to debug potential future CI build failures, we enable it unconditionally. brotli is also added as a new optional dependency, supported since mupdf v1.26.0. Starting from version 1.28.1 pipcl is no longer bundled and needs to be installed separately, so add host-python-pipcl when we build the python bindings. Starting from version 1.28.2, mupdf added the unconditional use of a venv, so disable it with MUPDF_NO_AUTOVENV. In python-pymupdf, !BR2_STATIC_LIBS is now required by mupdf anyway, so update the comment accordingly. pipcl (required to build python-pymupdf) used to be bundled in python-pymupdf but is now available as a separate package, so use it. This also allows us to use 'pep517' as the setup type. The test is also updated to use the new implementation. For both packages, the patches that are now upstream are also removed. The tarball filename for python-pymupdf has changed upstream so it is also updated accordingly. These new versions no longer fit in the 120M rootfs configured for the runtime test, so double its size. The mupdf builds are quite finicky on at least swig and libclang versions, so applying these changes on the Buildroot LTS branches should only be done with careful consideration (and making sure that it builds and passes the runtime test). Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> --- ...-incorrect-error-case-free-of-pixmap.patch | 53 -------- ...-jlib-fix-setting-filename-log-level.patch | 48 +++++++ ...y-to-provide-libclang-include-dirs-e.patch | 53 ++++++++ ...e-non-versioned-symlink-to-the-build.patch | 35 +++++ ...-log-level-through-environement-vari.patch | 53 ++++++++ ...rted-operand-type-when-setting-log-l.patch | 44 ++++++ ....py-class_add_iterator-assert-on-fin.patch | 41 ++++++ ...se.py-has_refs-recover-definition-cu.patch | 92 +++++++++++++ ...se.py-get_members-recover-definition.patch | 53 ++++++++ ...se.py-get_members-test-cursor.kind-n.patch | 78 +++++++++++ ...se.py-get_members-descend-into-anony.patch | 80 +++++++++++ ...-fitz-random.c-fix-build-with-uClibc.patch | 66 +++++++++ .../0012-scripts-make-venv-optional.patch | 52 ++++++++ package/mupdf/Config.in | 8 ++ package/mupdf/mupdf.hash | 6 +- package/mupdf/mupdf.mk | 55 ++++++-- ...w-providing-python-config-externally.patch | 125 ------------------ .../0001-src-extra-i-fix-for-swig-4-5.patch | 25 ++++ package/python-pymupdf/Config.in | 4 +- package/python-pymupdf/python-pymupdf.hash | 4 +- package/python-pymupdf/python-pymupdf.mk | 16 ++- .../tests/package/sample_python_pymupdf.py | 2 +- .../tests/package/test_python_pymupdf.py | 2 +- 23 files changed, 791 insertions(+), 204 deletions(-) delete mode 100644 package/mupdf/0001-Fix-incorrect-error-case-free-of-pixmap.patch create mode 100644 package/mupdf/0001-jlib-fix-setting-filename-log-level.patch create mode 100644 package/mupdf/0002-scripts-add-a-way-to-provide-libclang-include-dirs-e.patch create mode 100644 package/mupdf/0003-setup.py-add-the-non-versioned-symlink-to-the-build.patch create mode 100644 package/mupdf/0004-jlib-fix-setting-log-level-through-environement-vari.patch create mode 100644 package/mupdf/0005-jlib-fix-unsupported-operand-type-when-setting-log-l.patch create mode 100644 package/mupdf/0006-scripts-wrap-cpp.py-class_add_iterator-assert-on-fin.patch create mode 100644 package/mupdf/0007-scripts-wrap-parse.py-has_refs-recover-definition-cu.patch create mode 100644 package/mupdf/0008-scripts-wrap-parse.py-get_members-recover-definition.patch create mode 100644 package/mupdf/0009-scripts-wrap-parse.py-get_members-test-cursor.kind-n.patch create mode 100644 package/mupdf/0010-scripts-wrap-parse.py-get_members-descend-into-anony.patch create mode 100644 package/mupdf/0011-source-fitz-random.c-fix-build-with-uClibc.patch create mode 100644 package/mupdf/0012-scripts-make-venv-optional.patch delete mode 100644 package/python-pymupdf/0001-pipcl.py-allow-providing-python-config-externally.patch create mode 100644 package/python-pymupdf/0001-src-extra-i-fix-for-swig-4-5.patch diff --git a/package/mupdf/0001-Fix-incorrect-error-case-free-of-pixmap.patch b/package/mupdf/0001-Fix-incorrect-error-case-free-of-pixmap.patch deleted file mode 100644 index f78c429cef..0000000000 --- a/package/mupdf/0001-Fix-incorrect-error-case-free-of-pixmap.patch +++ /dev/null @@ -1,53 +0,0 @@ -From d4743b6092d513321c23c6f7fe5cff87cde043c1 Mon Sep 17 00:00:00 2001 -From: Robin Watts <Robin.Watts@artifex.com> -Date: Mon, 12 Jan 2026 19:08:56 +0000 -Subject: Bug 709029: Fix incorrect error-case free of pixmap. - -Don't free a pixmap we don't own! - -CVE: CVE-2026-25556 -Upstream: https://cgit.ghostscript.com/cgi-bin/cgit.cgi/mupdf.git/commit/?id=d4743b6092d513321c23c6f7fe5cff87cde043c1 -Signed-off-by: Thomas Perale <thomas.perale@mind.be> ---- - source/fitz/util.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - -diff --git a/source/fitz/util.c b/source/fitz/util.c -index 7710124cc..90226a5c1 100644 ---- a/source/fitz/util.c -+++ b/source/fitz/util.c -@@ -119,7 +119,15 @@ fz_new_pixmap_from_display_list_with_separations(fz_context *ctx, fz_display_lis - else - fz_clear_pixmap_with_value(ctx, pix, 0xFF); - -- return fz_fill_pixmap_from_display_list(ctx, list, ctm, pix); -+ fz_try(ctx) -+ fz_fill_pixmap_from_display_list(ctx, list, ctm, pix); -+ fz_catch(ctx) -+ { -+ fz_drop_pixmap(ctx, pix); -+ fz_rethrow(ctx); -+ } -+ -+ return pix; - } - - fz_pixmap * -@@ -136,14 +144,9 @@ fz_fill_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, fz_matr - fz_close_device(ctx, dev); - } - fz_always(ctx) -- { - fz_drop_device(ctx, dev); -- } - fz_catch(ctx) -- { -- fz_drop_pixmap(ctx, pix); - fz_rethrow(ctx); -- } - - return pix; - } --- -cgit v1.2.3 - diff --git a/package/mupdf/0001-jlib-fix-setting-filename-log-level.patch b/package/mupdf/0001-jlib-fix-setting-filename-log-level.patch new file mode 100644 index 0000000000..2a0e62b870 --- /dev/null +++ b/package/mupdf/0001-jlib-fix-setting-filename-log-level.patch @@ -0,0 +1,48 @@ +From 553bb924e032646739362c586adbcd5e931f02b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 24 Feb 2025 13:06:00 +0100 +Subject: [PATCH] jlib: fix setting filename log level +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Building using JLIB_log_levels for filenames only currently fails. + +For example, building with the following command: +make JLIB_log_levels=cpp.py=-5 python + +... leads to the following trace: + + File "/home/rme/Documents/mupdf/scripts/jlib.py", line 427, in log + level += log_levels_find( caller) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "/home/rme/Documents/mupdf/scripts/jlib.py", line 350, in log_levels_find + if item_filename and not filename.startswith( item_filename): + +This is because ffl is always a list (unpacked in case len==2), and +the filename is the first element of this list. +To fix it, only keep the first element of ffl when there is exactly +one. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/58 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/jlib.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/jlib.py b/scripts/jlib.py +index 8d7ecc6cd..4c7e2a0f0 100644 +--- a/scripts/jlib.py ++++ b/scripts/jlib.py +@@ -509,7 +509,7 @@ def log_levels_add_env( name='JLIB_log_levels'): + if 0: # lgtm [py/unreachable-statement] + pass + elif len( ffl) == 1: +- filename = ffl ++ filename = ffl[0] + function = None + elif len( ffl) == 2: + filename, function = ffl +-- +2.48.1 + diff --git a/package/mupdf/0002-scripts-add-a-way-to-provide-libclang-include-dirs-e.patch b/package/mupdf/0002-scripts-add-a-way-to-provide-libclang-include-dirs-e.patch new file mode 100644 index 0000000000..c2728a4fac --- /dev/null +++ b/package/mupdf/0002-scripts-add-a-way-to-provide-libclang-include-dirs-e.patch @@ -0,0 +1,53 @@ +From 0e1f9060e1110a293df2f62912aba234b0904309 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Thu, 20 Feb 2025 12:50:01 +0100 +Subject: [PATCH] scripts: add a way to provide libclang include dirs + externally +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When cross-compiling, libclang doesn't necessarily have the right +include directories configured by default. +See for example: https://bugs.ghostscript.com/show_bug.cgi?id=708041 + +Since we also have no way to figure out the right include directories +from our scripts, add a new environment variable that can be used to +provide them externally. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/63 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/cpp.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/scripts/wrap/cpp.py b/scripts/wrap/cpp.py +index 604c1ee..cd79b9c 100644 +--- a/scripts/wrap/cpp.py ++++ b/scripts/wrap/cpp.py +@@ -6,6 +6,7 @@ import io + import os + import pickle + import re ++import shlex + import textwrap + + import jlib +@@ -5579,6 +5580,14 @@ def cpp_source( + '-D', 'MUPDF_WRAP_LIBCLANG', + '-D', 'FZ_FUNCTION=', + ] ++ ++ # In some circumstances (e.g. when cross-compiling when ++ # libclang doesn't have the right include directories by ++ # default) the includes are provided externally: ++ libclang_args = os.environ.get('MUPDF_LIBCLANG_ARGS', '') ++ if libclang_args: ++ args += shlex.split(libclang_args) ++ + tu = index.parse( + temp_h, + args = args, +-- +2.54.0 + diff --git a/package/mupdf/0003-setup.py-add-the-non-versioned-symlink-to-the-build.patch b/package/mupdf/0003-setup.py-add-the-non-versioned-symlink-to-the-build.patch new file mode 100644 index 0000000000..efca7b7750 --- /dev/null +++ b/package/mupdf/0003-setup.py-add-the-non-versioned-symlink-to-the-build.patch @@ -0,0 +1,35 @@ +From b8efb551ba65f6f0d737ca3760fe5e2dbac5743c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Tue, 3 Sep 2024 15:35:33 +0200 +Subject: [PATCH] setup.py: add the non-versioned symlink to the build +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Starting from bf1c28cc4f2dd4bd17e35783fa3c1f98ded22296, the generated +mupdf libraries are versioned. This means that if we want to link +against them without knowing their version number (i.e. using +'-lmupdf'), we also need to install the symlink to the wheel. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/59 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + setup.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/setup.py b/setup.py +index 49199f5..3252412 100755 +--- a/setup.py ++++ b/setup.py +@@ -357,6 +357,8 @@ def build(): + names = [ + pipcl.get_soname(f'{build_dir()}/libmupdf.so'), # C. + pipcl.get_soname(f'{build_dir()}/libmupdfcpp.so'), # C++. ++ f'{build_dir()}/libmupdf.so', # C symlink. ++ f'{build_dir()}/libmupdfcpp.so', # C++ symlink. + f'{build_dir()}/_mupdf.so', # Python internals. + f'{build_dir()}/mupdf.py', # Python. + ] +-- +2.54.0 + diff --git a/package/mupdf/0004-jlib-fix-setting-log-level-through-environement-vari.patch b/package/mupdf/0004-jlib-fix-setting-log-level-through-environement-vari.patch new file mode 100644 index 0000000000..386dd2050e --- /dev/null +++ b/package/mupdf/0004-jlib-fix-setting-log-level-through-environement-vari.patch @@ -0,0 +1,53 @@ +From e033e1a8b8a1674e1e7ee6638008bd005b511920 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 24 Feb 2025 22:29:13 +0100 +Subject: [PATCH] jlib: fix setting log level through environement variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, setting a log level through the JLIB_log_levels environment +fails in this way: + File "/home/rme/Documents/mupdf/scripts/jlib.py", line 185, in __call__ + ret += ' (+%s)' % time_duration( time.time() - self.t0, s_format='%.1f') + ^^^^^^^^^^^^^ +This is because at the time log_levels_add_env() is invoked, +time_duration is not defined yet. + +To fix it, just move the invocation further down, after time_duration +is defined. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/58 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/jlib.py | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/scripts/jlib.py b/scripts/jlib.py +index 4c7e2a0f0..788a4bec8 100644 +--- a/scripts/jlib.py ++++ b/scripts/jlib.py +@@ -743,10 +743,6 @@ def text_split_last_of( text, substrings): + return text[ :pos], text[ pos:] + + +- +-log_levels_add_env() +- +- + def force_line_buffering(): + ''' + Ensure `sys.stdout` and `sys.stderr` are line-buffered. E.g. makes things +@@ -1246,6 +1242,9 @@ def time_duration( seconds, verbose=False, s_format='%i'): + return ret + + ++log_levels_add_env() ++ ++ + def date_time( t=None): + if t is None: + t = time.time() +-- +2.48.1 + diff --git a/package/mupdf/0005-jlib-fix-unsupported-operand-type-when-setting-log-l.patch b/package/mupdf/0005-jlib-fix-unsupported-operand-type-when-setting-log-l.patch new file mode 100644 index 0000000000..819f2d0a55 --- /dev/null +++ b/package/mupdf/0005-jlib-fix-unsupported-operand-type-when-setting-log-l.patch @@ -0,0 +1,44 @@ +From a568ae50e32e8b209edc9720360d873b10769f60 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 24 Feb 2025 22:48:36 +0100 +Subject: [PATCH] jlib: fix unsupported operand type when setting log level +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes the following issue when log_levels_find() is used (for +example when setting a log level delta using JLIB_log_levels): +[...] + scripts/jlib.py:424:log(): level += log_levels_find( caller) + scripts/jlib.py:334:log_levels_find(): tb = traceback.extract_stack( None, 1+caller) +TypeError: unsupported operand type(s) for +: 'int' and 'FrameInfo' + +Note that this fix get JLIB_log_levels working, but it might be +incorrect. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/58 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/jlib.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/scripts/jlib.py b/scripts/jlib.py +index 788a4bec8..452b3ae00 100644 +--- a/scripts/jlib.py ++++ b/scripts/jlib.py +@@ -331,7 +331,11 @@ def log_levels_find( caller): + if not s_log_levels_items: + return 0 + +- tb = traceback.extract_stack( None, 1+caller) ++ if isinstance(caller, inspect.FrameInfo): ++ tb = traceback.extract_stack( None, 1) ++ else: ++ tb = traceback.extract_stack( None, 1+caller) ++ + if len(tb) == 0: + return 0 + filename, line, function, text = tb[0] +-- +2.48.1 + diff --git a/package/mupdf/0006-scripts-wrap-cpp.py-class_add_iterator-assert-on-fin.patch b/package/mupdf/0006-scripts-wrap-cpp.py-class_add_iterator-assert-on-fin.patch new file mode 100644 index 0000000000..c4f2c4e3ab --- /dev/null +++ b/package/mupdf/0006-scripts-wrap-cpp.py-class_add_iterator-assert-on-fin.patch @@ -0,0 +1,41 @@ +From 176e9a4eac3375b19d53e15a24ddfdae5767e04f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:44:40 +0200 +Subject: [PATCH] scripts/wrap/cpp.py: class_add_iterator(): assert on + find_name() failure. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +parse.find_name() returns None when the requested dotted member path +isn't found, e.g. because the corresponding classextras.iterator_next +entry is stale or a libclang change broke traversal into an anonymous +struct/union. Immediately using the result as `c.type.kind` then fails +with an opaque "AttributeError: 'NoneType' object has no attribute +'type'" that gives no indication of which struct or field lookup +failed. + +Assert explicitly and name the struct and field path involved, so a +future failure here is easier to debug from the messageq. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/cpp.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/scripts/wrap/cpp.py b/scripts/wrap/cpp.py +index cd79b9c..c1bd3b6 100644 +--- a/scripts/wrap/cpp.py ++++ b/scripts/wrap/cpp.py +@@ -2536,6 +2536,7 @@ def class_add_iterator( tu, struct_cursor, struct_name, classname, extras, refch + # <it_begin>. + if it_begin: + c = parse.find_name( struct_cursor, it_begin) ++ assert c, f'Failed to find {it_begin=} in {struct_name=} ({struct_cursor.spelling=})' + assert c.type.kind == state.clang.cindex.TypeKind.POINTER + it_internal_type = state.get_name_canonical( c.type.get_pointee()).spelling + it_internal_type = util.clip( it_internal_type, 'struct ') +-- +2.54.0 + diff --git a/package/mupdf/0007-scripts-wrap-parse.py-has_refs-recover-definition-cu.patch b/package/mupdf/0007-scripts-wrap-parse.py-has_refs-recover-definition-cu.patch new file mode 100644 index 0000000000..be9b58425c --- /dev/null +++ b/package/mupdf/0007-scripts-wrap-parse.py-has_refs-recover-definition-cu.patch @@ -0,0 +1,92 @@ +From 6ec47b449386c7d7f3105d3e33c2095cd1a73c09 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:41:16 +0200 +Subject: [PATCH] scripts/wrap/parse.py: has_refs(): recover definition cursor + for clang-22. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +clang.cindex.Type.get_declaration() is documented to return "the +cursor for the declaration of the given type", but is not guaranteed +to return the *defining* declaration when a type is forward-declared +in one header:(e.g. `typedef struct fz_pixmap fz_pixmap;` in +fitz/color.h) and defined elsewhere (`struct fz_pixmap { ... }` in +fitz/pixmap.h). + +Older libclang versions apparently happened to resolve straight +through to the defining cursor here, so has_refs()'s +`base_type_cursor.is_definition()` check was reliably true whenever a +definition existed in the translation unit. Under libclang from clang +22.1.3, get_declaration() can instead return a non-defining +declaration cursor even though the full definition is present, so +is_definition() now incorrectly reports false for types such as +fz_pixmap and fz_stream. This falls through to has_refs()'s hard-coded +fallback table, which has no entry for these types, and trips the +final `assert ret` with "has fz_keep_...() but have not found +size/location of .refs member." + +This libclang behavior can be reproduced with the following minimal +example: + min.h (2 lines): + typedef struct Foo Foo; /* forward declaration, e.g. in a "public" header */ + struct Foo { int x; }; /* definition, e.g. in a different "private" header */ + + min.py (6 lines): + import clang.cindex + + tu = clang.cindex.Index.create().parse('min.h', args=['-x', 'c']) + typedef_decl = next(c for c in tu.cursor.get_children() if c.kind == clang.cindex.CursorKind.TYPEDEF_DECL) + struct_decl = typedef_decl.underlying_typedef_type.get_declaration() + + print('cursor:', struct_decl.location, 'is_definition:', struct_decl.is_definition()) + print('children:', [c.spelling for c in struct_decl.get_children()]) + +Which gives: + clang 18 (libclang==18.1.1): + cursor: <SourceLocation file 'min.h', line 2, column 8> is_definition: True + children: ['x'] + + clang 22 (libclang-ng==22.1.4.2): + cursor: <SourceLocation file 'min.h', line 1, column 16> is_definition: False + children: [] + +To fix it, call cursor.get_definition() that explicitly looks up the +actual defining cursor for a declaration/reference cursor anywhere in +the TU when the initial cursor is not itself a definition. This makes +has_refs() work the same way regardless of which cursor +get_declaration() happens to hand back. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/parse.py | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/scripts/wrap/parse.py b/scripts/wrap/parse.py +index c3bd1278c..d8c09f2a9 100644 +--- a/scripts/wrap/parse.py ++++ b/scripts/wrap/parse.py +@@ -252,6 +252,19 @@ def has_refs( tu, type_): + if verbose: + jlib.log( 'There is a keep() fn for this type so it uses reference counting: {keep_name=}') + base_type_cursor = get_base_type( type_).get_declaration() ++ if not base_type_cursor.is_definition(): ++ # get_declaration() is not guaranteed to return the ++ # defining cursor when the type is declared in one ++ # place (e.g. an opaque forward-declaring typedef) ++ # and defined elsewhere - depending on libclang ++ # version, it may instead return a non-defining ++ # declaration cursor even though a definition exists ++ # in the TU. get_definition() explicitly looks up the ++ # actual definition cursor, so use it to recover in ++ # that case. ++ definition_cursor = base_type_cursor.get_definition() ++ if definition_cursor is not None and definition_cursor.is_definition(): ++ base_type_cursor = definition_cursor + if base_type_cursor.is_definition(): + if verbose: + jlib.log( 'Type definition is available so we look for .refs member: {key=} {type_.spelling=} {fileline(base_type_cursor)=}') +-- +2.54.0 + diff --git a/package/mupdf/0008-scripts-wrap-parse.py-get_members-recover-definition.patch b/package/mupdf/0008-scripts-wrap-parse.py-get_members-recover-definition.patch new file mode 100644 index 0000000000..bdd3ca81d9 --- /dev/null +++ b/package/mupdf/0008-scripts-wrap-parse.py-get_members-recover-definition.patch @@ -0,0 +1,53 @@ +From 8e780ba4b057e2c2174bbd3f4c123ced32dd78f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:43:52 +0200 +Subject: [PATCH] scripts/wrap/parse.py: get_members(): recover definition + cursor for clang-22. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes the same issue as the preceding has_refs() fix, but for +get_members()'s own typedef-to-struct resolution: +cursor.underlying_typedef_type.get_declaration() is not guaranteed to +return the defining cursor for the struct, only some declaration of +it. Under libclang from clang 22.1.3 this can be a +non-defining (forward-declaration) cursor even when a full definition +exists in the TU, which left cursor2.get_children() empty and made +get_members() yield no members at all for affected types - e.g. +class_accessors() would then hit "assert n, f'No fields found for +{struct_cursor.spelling}.'" for fz_pixmap. + +Recover via get_definition() (clang_getCursorDefinition), which looks up +the actual definition cursor for a declaration cursor across the whole +TU, independent of what get_declaration() happened to return. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/parse.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/scripts/wrap/parse.py b/scripts/wrap/parse.py +index d8c09f2a9..ed1737b34 100644 +--- a/scripts/wrap/parse.py ++++ b/scripts/wrap/parse.py +@@ -120,6 +120,15 @@ def get_members( type_or_cursor, include_empty=False): + cursor2 = cursor.underlying_typedef_type.get_declaration() + else: + cursor2 = cursor ++ if not cursor2.is_definition(): ++ # get_declaration() is not guaranteed to return the defining cursor ++ # - depending on libclang version, it may instead return a ++ # non-defining declaration cursor (e.g. a forward-declaring typedef) ++ # even though a definition exists elsewhere in the TU. Recover the ++ # actual definition cursor if we can find one. ++ definition_cursor2 = cursor2.get_definition() ++ if definition_cursor2 is not None and definition_cursor2.is_definition(): ++ cursor2 = definition_cursor2 + + if 0: + # Diagnostics to show the difference between +-- +2.54.0 + diff --git a/package/mupdf/0009-scripts-wrap-parse.py-get_members-test-cursor.kind-n.patch b/package/mupdf/0009-scripts-wrap-parse.py-get_members-test-cursor.kind-n.patch new file mode 100644 index 0000000000..d47729101f --- /dev/null +++ b/package/mupdf/0009-scripts-wrap-parse.py-get_members-test-cursor.kind-n.patch @@ -0,0 +1,78 @@ +From d4b9583147fe8b15b284f4fbbfd9fe2b02723fec Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:41:46 +0200 +Subject: [PATCH] scripts/wrap/parse.py: get_members(): test cursor.kind, not + cursor.type.kind. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +get_members() resolves a typedef to its underlying type's declaration +before looking at its children: + + if cursor.type.kind in (TypeKind.TYPEDEF, TypeKind.ELABORATED): + cursor2 = cursor.underlying_typedef_type.get_declaration() + +The intent seems to be "if <cursor> is itself a typedef declaration, +follow it to the real declaration", but the condition instead tests +the *type* of the entity the cursor declares. Those are not the same +thing: a FIELD_DECL cursor for a plain data member can have a type +whose .kind is ELABORATED - this is normal for a field whose type is +an anonymous struct/union defined inline, e.g. `union { struct {...} +t; ...} u;`. The old condition therefore matched such fields too, and +went on to call `.underlying_typedef_type` on a cursor that is not a +TYPEDEF_DECL at all. + +clang_getTypedefDeclUnderlyingType() is documented to return an +invalid type if the cursor does not reference a typedef +declaration (clang/include/clang-c/Index.h) - but the result for a +field cursor is unusable: on clang 18, the invalid type's +.get_declaration() comes back as a NO_DECL_FOUND cursor with no +location, whose .get_children() is unconditionally empty. +get_members() falls through to its type_.get_fields() fallback in that +case, which happens to still find the real members, so this was +previously masked rather than fixed. + +On clang 22, this same call is not reached in the first place: clang +22 removed ElaboratedType from the AST (see the "Clang Python Bindings +Potentially Breaking Changes" entry in the Clang 22.1.0 release notes: +"TypeKind ELABORATED is not used anymore, per clang AST changes +removing ElaboratedTypes"), so a field whose type is an anonymous +struct/union now reports TypeKind.RECORD instead of +TypeKind.ELABORATED, and the old condition is simply false. This +commit should therefore be needed only for clang<22.1.0. + +Fix by checking cursor.kind == CursorKind.TYPEDEF_DECL, which matches +only genuine typedef declarations (e.g. `typedef struct fz_pixmap +fz_pixmap;`) and leaves plain fields - whose type merely happens to be +elaborated/anonymous - to fall through to direct child inspection, +which is what actually finds their members. + +Combined with the next commit (which makes get_members() descend into +the placeholder cursor libclang gives us for an anonymous struct/union +field), this makes get_members() resolve such fields the same way, for +the same reason, on both clang 18 and clang 22, rather than clang 18 +only working by accident. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/parse.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/wrap/parse.py b/scripts/wrap/parse.py +index ed1737b34..8881c68d0 100644 +--- a/scripts/wrap/parse.py ++++ b/scripts/wrap/parse.py +@@ -116,7 +116,7 @@ def get_members( type_or_cursor, include_empty=False): + cursor = type_or_cursor + else: + assert 0 +- if cursor.type.kind in (state.clang.cindex.TypeKind.TYPEDEF, state.clang.cindex.TypeKind.ELABORATED): ++ if cursor.kind == state.clang.cindex.CursorKind.TYPEDEF_DECL: + cursor2 = cursor.underlying_typedef_type.get_declaration() + else: + cursor2 = cursor +-- +2.54.0 + diff --git a/package/mupdf/0010-scripts-wrap-parse.py-get_members-descend-into-anony.patch b/package/mupdf/0010-scripts-wrap-parse.py-get_members-descend-into-anony.patch new file mode 100644 index 0000000000..79baa39e39 --- /dev/null +++ b/package/mupdf/0010-scripts-wrap-parse.py-get_members-descend-into-anony.patch @@ -0,0 +1,80 @@ +From b5174269f72f5634b418a7c5216026d6bf2f4ccb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:44:16 +0200 +Subject: [PATCH] scripts/wrap/parse.py: get_members(): descend into anonymous + struct/union. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +fz_stext_block contains a field whose type is an anonymous union with +named nested-struct members, e.g.: + + union { + struct { fz_stext_line *first_line, *last_line; int flags; } t; + struct { fz_matrix transform; fz_image *image; } i; + ... + } u; + +Under libclang from clang 22.1.3, calling get_children() on the FIELD_DECL +cursor for 'u' yields a single child that is the anonymous union's own +UNION_DECL cursor (with a synthesised .spelling like "(unnamed union at +fitz/structured-text.h:444:2)"), rather than yielding 'u's real members +('t', 'i', 's', 'v', 'b') directly. (The pre-existing, long-disabled +diagnostics code in this function already notes a related but different +symptom seen on older libclang: an extra empty-spelling child for the +same kind of anonymous union.) + +This broke find_name()'s lookup of dotted paths like 'u.t.first_line', +which fz_stext_block's classextras.iterator_next relies on, causing +class_add_iterator() to fail with "Failed to find it_begin='u.t.first_line' +in struct_name='fz_stext_block'" (from the assert added in an earlier +commit). + +When we see exactly one child and it is itself a STRUCT_DECL/UNION_DECL - +which does not happen for an ordinary named-type member, only for a field +whose type is defined anonymously inline - descend into that child to +find the real members. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/parse.py | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/scripts/wrap/parse.py b/scripts/wrap/parse.py +index 8881c68d0..b9a65ace2 100644 +--- a/scripts/wrap/parse.py ++++ b/scripts/wrap/parse.py +@@ -162,8 +162,27 @@ def get_members( type_or_cursor, include_empty=False): + for i in ret_type: + jlib.log( ' ret_type: {i}') + ++ children = list(cursor2.get_children()) ++ if (cursor2.kind == state.clang.cindex.CursorKind.FIELD_DECL ++ and len(children) == 1 ++ and children[0].kind in ( ++ state.clang.cindex.CursorKind.STRUCT_DECL, ++ state.clang.cindex.CursorKind.UNION_DECL, ++ ) ++ ): ++ # <cursor2> is a field whose type is an anonymous struct/union ++ # defined inline (e.g. 'union { ... } u;'). A normal field with a ++ # named member type has no such child, so seeing exactly one ++ # STRUCT_DECL/UNION_DECL child here means some libclang versions are ++ # giving us the anonymous struct/union's own declaration cursor ++ # (with a synthesised, non-empty .spelling describing the anonymous ++ # type, e.g. '(unnamed union at ...)'), instead of directly giving ++ # us that struct/union's members. Descend into it to find the real ++ # members. ++ children = list(children[0].get_children()) ++ + ret = list() +- for cursor3 in cursor2.get_children(): ++ for cursor3 in children: + if include_empty or cursor3.spelling: + ret.append(cursor3) + if not ret: +-- +2.54.0 + diff --git a/package/mupdf/0011-source-fitz-random.c-fix-build-with-uClibc.patch b/package/mupdf/0011-source-fitz-random.c-fix-build-with-uClibc.patch new file mode 100644 index 0000000000..8ed01dcd8a --- /dev/null +++ b/package/mupdf/0011-source-fitz-random.c-fix-build-with-uClibc.patch @@ -0,0 +1,66 @@ +From 65dccf58c115090ce008ae517e2835226f3764ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Tue, 29 Sep 2026 18:30:40 +0200 +Subject: [PATCH] source/fitz/random.c: fix build with uClibc +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +uClibc does not have getentropy(). uClibc-ng has it starting from +version 1.0.54, and only when it is built with UCLIBC_LINUX_SPECIFIC +[1]. + +In addition, uClibc-ng declares getentropy() in <unistd.h> only if +_DEFAULT_SOURCE is defined [2]. Unlike glibc, uClibc-ng does not +define _DEFAULT_SOURCE by default [3], and we do not define it. +<sys/random.h> always declares getentropy() [4]. + +To build with all versions of uClibc and uClibc-ng, check the +__UCLIBC_* macros: +- Before 1.0.54, or without __UCLIBC_LINUX_SPECIFIC__, use the + fallback. +- Otherwise, include <sys/random.h> to get the getentropy() + declaration. + +[1] https://github.com/wbx-github/uclibc-ng/blob/master/libc/sysdeps/linux/common/Makefile.in +[2] https://github.com/wbx-github/uclibc-ng/blob/master/include/unistd.h +[3] https://github.com/wbx-github/uclibc-ng/blob/master/include/features.h +[4] https://github.com/wbx-github/uclibc-ng/blob/master/libc/sysdeps/linux/common/sys/random.h + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709779 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + source/fitz/random.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/source/fitz/random.c b/source/fitz/random.c +index ad92c6369..51b016217 100644 +--- a/source/fitz/random.c ++++ b/source/fitz/random.c +@@ -34,6 +34,14 @@ + #else + #include <unistd.h> // for getentropy() + #endif ++#ifdef __UCLIBC__ ++#if __UCLIBC_MAJOR__ < 1 || (__UCLIBC_MAJOR__ == 1 && __UCLIBC_MINOR__ == 0 && __UCLIBC_SUBLEVEL__ < 54) || \ ++ !defined(__UCLIBC_LINUX_SPECIFIC__) ++#define NO_GETENTROPY // uClibc-ng before 1.0.54, or without UCLIBC_LINUX_SPECIFIC, does not have getentropy() ++#else ++#include <sys/random.h> // unistd.h declares getentropy() only with _DEFAULT_SOURCE ++#endif ++#endif + #endif + + #ifdef _WIN32 +@@ -95,6 +103,8 @@ void fz_memrnd(fz_context *ctx, unsigned char *data, int len) + // Android before 9.0 does not have getentropy(), but does have + // arc4random_buf that sources from /dev/urandom. + arc4random_buf(entropy, sizeof entropy); ++#elif defined(NO_GETENTROPY) ++ getentropy_fallback(entropy, sizeof entropy); + #else + if (getentropy(entropy, sizeof entropy) < 0) + getentropy_fallback(entropy, sizeof entropy); +-- +2.54.0 + diff --git a/package/mupdf/0012-scripts-make-venv-optional.patch b/package/mupdf/0012-scripts-make-venv-optional.patch new file mode 100644 index 0000000000..327dde645a --- /dev/null +++ b/package/mupdf/0012-scripts-make-venv-optional.patch @@ -0,0 +1,52 @@ +From c55d406be771b626d5a2a4870203c700a34d4b1d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Tue, 29 Sep 2026 21:32:59 +0200 +Subject: [PATCH] scripts: make venv optional +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit e7901bed9b85031b6e6769e49c4ba3a2cbb5033f ("scripts/:fix +venv-related failures in python/c# bindings tests.") introduced the +unconditional use of a venv. This is not always +possible/desirable (e.g. when building in Buildroot). + +To make it possible to skip the use of a venv, introduce the +MUPDF_NO_AUTOVENV variable. + +The default behavior remains the same as before. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709778 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/__main__.py | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/scripts/wrap/__main__.py b/scripts/wrap/__main__.py +index 4440a70..7e5dc38 100644 +--- a/scripts/wrap/__main__.py ++++ b/scripts/wrap/__main__.py +@@ -918,13 +918,14 @@ import sysconfig + import tempfile + import textwrap + +-sys.path.insert(0, os.path.normpath(f'{__file__}/../..')) +-try: +- import autovenv +-finally: +- del sys.path[0] ++if os.environ.get('MUPDF_NO_AUTOVENV') != '1': ++ sys.path.insert(0, os.path.normpath(f'{__file__}/../..')) ++ try: ++ import autovenv ++ finally: ++ del sys.path[0] + +-autovenv.enter() ++ autovenv.enter() + + # Install/import pipcl. We don't pass 'pipcl' to above call to autovenv.enter() + # because this would do `pip install pipcl`, which seems to fail if we are +-- +2.54.0 + diff --git a/package/mupdf/Config.in b/package/mupdf/Config.in index 5c0a127a90..4a9b4f487f 100644 --- a/package/mupdf/Config.in +++ b/package/mupdf/Config.in @@ -20,3 +20,11 @@ comment "mupdf needs a toolchain w/ C++, gcc >= 4.9" depends on BR2_TOOLCHAIN_HAS_SYNC_4 depends on !BR2_INSTALL_LIBSTDCPP || \ !BR2_TOOLCHAIN_GCC_AT_LEAST_4_9 + +if BR2_PACKAGE_MUPDF +config BR2_PACKAGE_MUPDF_PYTHON_BINDINGS + bool "python bindings for mupdf" + depends on !BR2_STATIC_LIBS + depends on BR2_PACKAGE_PYTHON3 + select BR2_PACKAGE_HOST_SWIG +endif diff --git a/package/mupdf/mupdf.hash b/package/mupdf/mupdf.hash index 80de6f3b2c..7313548b5e 100644 --- a/package/mupdf/mupdf.hash +++ b/package/mupdf/mupdf.hash @@ -1,8 +1,6 @@ # From https://mupdf.com/releases: -sha1 d79600bccd70ab9d0e8ee19dae4e275f2af95ced mupdf-1.23.9-source.tar.lz - -# Locally computed: -sha256 2c2f89deb9f425ba637dac226191d547f2b40975c4d21a340965f52c001e15c5 mupdf-1.23.9-source.tar.lz +sha1 1f0a14123a2410c3bdb63cb6bbef69d0f2518f6e mupdf-1.28.5-source.tar.lz +sha256 f33f3c672033324c38c7c9a1444c28436ede9669a28e2da672df7f6c62b8cfc8 mupdf-1.28.5-source.tar.lz # Hash for license files: sha256 57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 COPYING diff --git a/package/mupdf/mupdf.mk b/package/mupdf/mupdf.mk index c538b9bec8..864d9f23f7 100644 --- a/package/mupdf/mupdf.mk +++ b/package/mupdf/mupdf.mk @@ -5,7 +5,7 @@ ################################################################################ # python-pymupdf's version be compatible with mupdf's version -MUPDF_VERSION = 1.23.9 +MUPDF_VERSION = 1.28.5 MUPDF_SOURCE = mupdf-$(MUPDF_VERSION)-source.tar.lz MUPDF_SITE = https://mupdf.com/downloads/archive MUPDF_LICENSE = AGPL-3.0+ @@ -21,15 +21,6 @@ MUPDF_DEPENDENCIES = \ lcms2 openjpeg \ zlib -# Fix is in libfreeglut, but CVE applied to mupdf 1.23.9. -# Buildroot libfreeglut is >3.4.0 then is not affected. -MUPDF_IGNORE_CVES = \ - CVE-2024-24258 \ - CVE-2024-24259 - -# 0001-Fix-incorrect-error-case-free-of-pixmap.patch -MUPDF_IGNORE_CVES += CVE-2026-25556 - # mupdf doesn't use CFLAGS and LIBS but XCFLAGS and XLIBS instead. # with USE_SYSTEM_LIBS it will try to use system libraries instead of the bundled ones. MUPDF_MAKE_ENV = $(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) \ @@ -45,6 +36,44 @@ ifeq ($(BR2_STATIC_LIBS),y) MUPDF_MAKE_OPTS += shared=no else MUPDF_MAKE_OPTS += shared=yes + +ifeq ($(BR2_PACKAGE_MUPDF_PYTHON_BINDINGS),y) +MUPDF_DEPENDENCIES += \ + host-clang \ + host-python-pipcl \ + host-swig \ + python3 + +MUPDF_MAKE_ENV += \ + VENV_FLAG="" \ + MUPDF_NO_AUTOVENV=1 \ + MUPDF_SETUP_USE_CLANG_PYTHON=0 \ + MUPDF_LIBCLANG_ARGS="-I$(STAGING_DIR)/usr/include -I$(HOST_DIR)/lib/clang/$(firstword $(subst ., ,$(HOST_CLANG_VERSION)))/include" \ + PIPCL_PYTHON_CONFIG="$(STAGING_DIR)/usr/bin/python3-config" + +# mupdf generates C++ code for its python bindings. As things can +# easily go wrong, increase the log level as much as we can so that we +# at least always see libclang's diagnostics: +MUPDF_MAKE_ENV += JLIB_log_levels="/:=-5" + +define MUPDF_BUILD_PYTHON_BINDINGS + $(MUPDF_MAKE_ENV) $(MAKE) -C $(@D) $(MUPDF_MAKE_OPTS) python +endef + +define MUPDF_INSTALL_PYTHON_BINDINGS_TO_STAGING + $(MUPDF_MAKE_ENV) $(MAKE) -C $(@D) $(MUPDF_MAKE_OPTS) \ + DESTDIR="$(STAGING_DIR)" pydir=/usr/lib/python$(PYTHON3_VERSION_MAJOR) install-shared-python \ + -o python -o c++ # skip rebuilding bindings +endef +define MUPDF_INSTALL_PYTHON_BINDINGS_TO_TARGET + $(MUPDF_MAKE_ENV) $(MAKE) -C $(@D) $(MUPDF_MAKE_OPTS) \ + DESTDIR="$(TARGET_DIR)" pydir=/usr/lib/python$(PYTHON3_VERSION_MAJOR) install-shared-python \ + -o python -o c++ # skip rebuilding bindings +endef +MUPDF_POST_BUILD_HOOKS += MUPDF_BUILD_PYTHON_BINDINGS +MUPDF_POST_INSTALL_STAGING_HOOKS += MUPDF_INSTALL_PYTHON_BINDINGS_TO_STAGING +MUPDF_POST_INSTALL_TARGET_HOOKS += MUPDF_INSTALL_PYTHON_BINDINGS_TO_TARGET +endif endif ifeq ($(BR2_PACKAGE_XLIB_LIBX11)$(BR2_PACKAGE_XLIB_LIBXEXT),yy) @@ -60,6 +89,12 @@ else MUPDF_MAKE_OPTS += HAVE_GLUT=no endif +ifeq ($(BR2_PACKAGE_BROTLI),y) +MUPDF_DEPENDENCIES += brotli +else +MUPDF_MAKE_OPTS += brotli=no +endif + define MUPDF_BUILD_CMDS $(MUPDF_MAKE_ENV) $(MAKE) -C $(@D) $(MUPDF_MAKE_OPTS) all endef diff --git a/package/python-pymupdf/0001-pipcl.py-allow-providing-python-config-externally.patch b/package/python-pymupdf/0001-pipcl.py-allow-providing-python-config-externally.patch deleted file mode 100644 index 95aa3f7a21..0000000000 --- a/package/python-pymupdf/0001-pipcl.py-allow-providing-python-config-externally.patch +++ /dev/null @@ -1,125 +0,0 @@ -From ca3417b8d605ccdb2e6c516c5e0c79180381627c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> -Date: Sun, 4 Feb 2024 16:13:45 +0100 -Subject: [PATCH] pipcl.py: allow providing python-config externally -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When cross-compiling (e.g. using Buildroot), the python-config -executable that resides next to the host python executable provides -incorrect includes (the ones for the host). - -Since the correct path to python-config cannot be guessed, add an -additional environment variable to allow setting the path to the -correct python-config executable externally. - -Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> -Upstream: https://github.com/pymupdf/PyMuPDF/commit/3a214b0c144d86fd1329b26030f6b9f2a6b27020 ---- - pipcl.py | 72 +++++++++++++++++++++++++++++--------------------------- - setup.py | 3 +++ - 2 files changed, 40 insertions(+), 35 deletions(-) - -diff --git a/pipcl.py b/pipcl.py -index 209f660..c154774 100644 ---- a/pipcl.py -+++ b/pipcl.py -@@ -1789,43 +1789,45 @@ class PythonFlags: - self.ldflags = f'-L {_lib_dir}' - - else: -- # We use python-config which appears to work better than pkg-config -- # because it copes with multiple installed python's, e.g. -- # manylinux_2014's /opt/python/cp*-cp*/bin/python*. -- # -- # But... on non-macos it seems that we should not attempt to specify -- # libpython on the link command. The manylinux docker containers -- # don't actually contain libpython.so, and it seems that this -- # deliberate. And the link command runs ok. -- # -- python_exe = os.path.realpath( sys.executable) -- if darwin(): -- # Basic install of dev tools with `xcode-select --install` doesn't -- # seem to provide a `python3-config` or similar, but there is a -- # `python-config.py` accessible via sysconfig. -+ python_config = os.environ.get("PYMUPDF_PYTHON_CONFIG") -+ if not python_config: -+ # We use python-config which appears to work better than pkg-config -+ # because it copes with multiple installed python's, e.g. -+ # manylinux_2014's /opt/python/cp*-cp*/bin/python*. - # -- # We try different possibilities and use the last one that -- # works. -+ # But... on non-macos it seems that we should not attempt to specify -+ # libpython on the link command. The manylinux docker containers -+ # don't actually contain libpython.so, and it seems that this -+ # deliberate. And the link command runs ok. - # -- python_config = None -- for pc in ( -- f'python3-config', -- f'{sys.executable} {sysconfig.get_config_var("srcdir")}/python-config.py', -- f'{python_exe}-config', -- ): -- e = subprocess.run( -- f'{pc} --includes', -- shell=1, -- stdout=subprocess.DEVNULL, -- stderr=subprocess.DEVNULL, -- check=0, -- ).returncode -- log1(f'{e=} from {pc!r}.') -- if e == 0: -- python_config = pc -- assert python_config, f'Cannot find python-config' -- else: -- python_config = f'{python_exe}-config' -+ python_exe = os.path.realpath( sys.executable) -+ if darwin(): -+ # Basic install of dev tools with `xcode-select --install` doesn't -+ # seem to provide a `python3-config` or similar, but there is a -+ # `python-config.py` accessible via sysconfig. -+ # -+ # We try different possibilities and use the last one that -+ # works. -+ # -+ python_config = None -+ for pc in ( -+ f'python3-config', -+ f'{sys.executable} {sysconfig.get_config_var("srcdir")}/python-config.py', -+ f'{python_exe}-config', -+ ): -+ e = subprocess.run( -+ f'{pc} --includes', -+ shell=1, -+ stdout=subprocess.DEVNULL, -+ stderr=subprocess.DEVNULL, -+ check=0, -+ ).returncode -+ log1(f'{e=} from {pc!r}.') -+ if e == 0: -+ python_config = pc -+ assert python_config, f'Cannot find python-config' -+ else: -+ python_config = f'{python_exe}-config' - log1(f'Using {python_config=}.') - try: - self.includes = run( f'{python_config} --includes', capture=1).strip() -diff --git a/setup.py b/setup.py -index 23a5c78..4b3b5c7 100755 ---- a/setup.py -+++ b/setup.py -@@ -36,6 +36,9 @@ Environmental variables: - PYMUPDF_MUPDF_LIB - Directory containing MuPDF libraries, (libmupdf.so, - libmupdfcpp.so). -+ -+ PYMUPDF_PYTHON_CONFIG -+ Optional path to python-config. - - PYMUPDF_SETUP_IMPLEMENTATIONS - Must be one of 'a', 'b', 'ab'. If unset we use 'ab'. --- -2.41.0 - diff --git a/package/python-pymupdf/0001-src-extra-i-fix-for-swig-4-5.patch b/package/python-pymupdf/0001-src-extra-i-fix-for-swig-4-5.patch new file mode 100644 index 0000000000..1979bf9486 --- /dev/null +++ b/package/python-pymupdf/0001-src-extra-i-fix-for-swig-4-5.patch @@ -0,0 +1,25 @@ +From d2ddf9032d61f8344cd06ab2c4bb077771047e22 Mon Sep 17 00:00:00 2001 +From: Julian Smith <julian.smith@artifex.com> +Date: Sat, 22 Aug 2026 08:11:57 +0100 +Subject: [PATCH] src/extra.i: fix for swig-4.5. + +Python 2's PyString_FromString() is no longer provided by swig code. +Upstream: https://github.com/pymupdf/PyMuPDF/commit/d2ddf9032d61f8344cd06ab2c4bb077771047e22 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + src/extra.i | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/extra.i b/src/extra.i +index f62cdf83c..dd1670a2e 100644 +--- a/src/extra.i ++++ b/src/extra.i +@@ -225,7 +225,7 @@ static void messagev(const char* format, va_list va) + static PyObject* message_fn = PyObject_GetAttrString(pymupdf_module, "message"); + char* text; + vasprintf(&text, format, va); +- PyObject* text_py = PyString_FromString(text); ++ PyObject* text_py = PyUnicode_FromString(text); + PyObject* args = PyTuple_Pack(1, text_py); + PyObject* ret = PyObject_CallObject(message_fn, args); + Py_XDECREF(ret); diff --git a/package/python-pymupdf/Config.in b/package/python-pymupdf/Config.in index e6e7c38c9e..def9054fcf 100644 --- a/package/python-pymupdf/Config.in +++ b/package/python-pymupdf/Config.in @@ -3,10 +3,12 @@ config BR2_PACKAGE_PYTHON_PYMUPDF depends on BR2_INSTALL_LIBSTDCPP # mupdf -> harfbuzz depends on BR2_TOOLCHAIN_HAS_SYNC_4 # mupdf -> harfbuzz depends on BR2_TOOLCHAIN_GCC_AT_LEAST_4_9 # mupdf -> harfbuzz - depends on !BR2_STATIC_LIBS # runtime failure + depends on !BR2_STATIC_LIBS # mupdf python bindings select BR2_PACKAGE_HOST_SWIG select BR2_PACKAGE_FREETYPE select BR2_PACKAGE_MUPDF + select BR2_PACKAGE_MUPDF_PYTHON_BINDINGS + select BR2_PACKAGE_PYTHON_PIPCL select BR2_PACKAGE_PYTHON3_ZLIB # runtime help Python bindings for the PDF rendering library MuPDF. diff --git a/package/python-pymupdf/python-pymupdf.hash b/package/python-pymupdf/python-pymupdf.hash index 341366d46f..01f68da74e 100644 --- a/package/python-pymupdf/python-pymupdf.hash +++ b/package/python-pymupdf/python-pymupdf.hash @@ -1,5 +1,5 @@ # md5, sha256 from https://pypi.org/pypi/pymupdf/json -md5 5c219a0c4cb3d57b60e39cc901ebd220 PyMuPDF-1.23.22.tar.gz -sha256 c41cd91d83696cea67a4b6c65cc1951c2019ac0a561c5a3f543318ede30d3cd0 PyMuPDF-1.23.22.tar.gz +md5 ffd24ff2579b94e30151cf0e6ed95bcc pymupdf-1.28.2.tar.gz +sha256 5e0be7908a715aa20333caddd73f1d6f01e4cd0c26e869fa2dd0b7f344da2249 pymupdf-1.28.2.tar.gz # Locally computed sha256 checksums sha256 57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 COPYING diff --git a/package/python-pymupdf/python-pymupdf.mk b/package/python-pymupdf/python-pymupdf.mk index 1d6ad78bce..a14bad557d 100644 --- a/package/python-pymupdf/python-pymupdf.mk +++ b/package/python-pymupdf/python-pymupdf.mk @@ -5,21 +5,23 @@ ################################################################################ # python-pymupdf's version must be compatible with mupdf's version -PYTHON_PYMUPDF_VERSION = 1.23.22 -PYTHON_PYMUPDF_SOURCE = PyMuPDF-$(PYTHON_PYMUPDF_VERSION).tar.gz -PYTHON_PYMUPDF_SITE = https://files.pythonhosted.org/packages/05/20/a0d1221d8f379afcc12b4d1687a8f4adb69eef659e835d781c3fa331ff46 -PYTHON_PYMUPDF_SETUP_TYPE = setuptools +PYTHON_PYMUPDF_VERSION = 1.28.2 +PYTHON_PYMUPDF_SOURCE = pymupdf-$(PYTHON_PYMUPDF_VERSION).tar.gz +PYTHON_PYMUPDF_SITE = https://files.pythonhosted.org/packages/a3/fb/b6761fa2d5266f2cdb24c3b91f4023070ab7848381417678e7a289a1d52a +PYTHON_PYMUPDF_SETUP_TYPE = pep517 PYTHON_PYMUPDF_LICENSE = AGPL-3.0+ PYTHON_PYMUPDF_LICENSE_FILES = COPYING # No license file included in pip, but it's present on github -PYTHON_PYMUPDF_DEPENDENCIES = freetype host-swig mupdf +PYTHON_PYMUPDF_DEPENDENCIES = freetype host-python-pipcl host-swig mupdf PYTHON_PYMUPDF_BUILD_OPTS = --skip-dependency-check +# LD needs to be overriden because pipcl expects it to be a linker +# driver (e.g. gcc) and not an actual linker. PYTHON_PYMUPDF_ENV = \ + LD=$(TARGET_CC) \ PYMUPDF_INCLUDES="$(STAGING_DIR)/usr/include/freetype2:$(STAGING_DIR)/usr/include" \ PYMUPDF_MUPDF_LIB="$(STAGING_DIR)/usr/lib" \ - PYMUPDF_PYTHON_CONFIG="$(STAGING_DIR)/usr/bin/python3-config" \ - PYMUPDF_SETUP_IMPLEMENTATIONS=a \ + PIPCL_PYTHON_CONFIG="$(STAGING_DIR)/usr/bin/python3-config" \ PYMUPDF_SETUP_MUPDF_BUILD= $(eval $(python-package)) diff --git a/support/testing/tests/package/sample_python_pymupdf.py b/support/testing/tests/package/sample_python_pymupdf.py index ffcbfa1140..574bd27965 100644 --- a/support/testing/tests/package/sample_python_pymupdf.py +++ b/support/testing/tests/package/sample_python_pymupdf.py @@ -1,4 +1,4 @@ -import fitz_old as fitz +import fitz # Write a test PDF file outfile = "python-pymupdf.pdf" diff --git a/support/testing/tests/package/test_python_pymupdf.py b/support/testing/tests/package/test_python_pymupdf.py index 1af3efc8af..ac826f74ab 100644 --- a/support/testing/tests/package/test_python_pymupdf.py +++ b/support/testing/tests/package/test_python_pymupdf.py @@ -9,7 +9,7 @@ class TestPythonPy3PyMuPDF(TestPythonPackageBase): BR2_PACKAGE_PYTHON3=y BR2_PACKAGE_PYTHON_PYMUPDF=y BR2_TARGET_ROOTFS_EXT2=y - BR2_TARGET_ROOTFS_EXT2_SIZE="120M" + BR2_TARGET_ROOTFS_EXT2_SIZE="240M" """ sample_scripts = ["tests/package/sample_python_pymupdf.py"] timeout = 30 -- 2.54.0 _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 2026-09-30 12:00 ` [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 Raphaël Mélotte via buildroot @ 2026-10-01 5:52 ` Waldemar Brodkorb 2026-10-04 15:41 ` Thomas Petazzoni via buildroot 1 sibling, 0 replies; 11+ messages in thread From: Waldemar Brodkorb @ 2026-10-01 5:52 UTC (permalink / raw) To: buildroot; +Cc: Raphaël Mélotte Hi, Raphaël Mélotte via buildroot wrote, > Release notes: > https://mupdf.com/releases > https://pymupdf.readthedocs.io/en/latest/changes.html > > Note that this bump fixes multiple security vulnerabilities, and at > least the following ones: > - CVE-2025-46206 > - CVE-2025-71382 > - CVE-2026-7233 > - CVE-2026-40505 > > With this new python-pymupdf (and mupdf) version, we can no longer > build the old implementation (the 'a' implementation). We now need to > build mupdf's python binding, which require host-clang (and its python > bindings) to be built. > > Also note that python-mupdf's version still needs to stay close to > mupdf's version, they can only be updated together. > > A number of mupdf patches were needed: > - To allow changing the build-time log level from an environment > variable. > - To be able to provide the libclang include directories. This is > needed because our default libclang include directories are not > properly set. > - To be able to link against mupdf with no versioning number. > - To fix build errors when generating the python bindings for > python-pymupdf with clang 22. > - To fix build errors with uClibc. > - To make it possible to build without a venv. > > python-pymupdf also needed a (backported) patch to fix building with > swig 4.5+. > > In mupdf, setting JLIB_log_levels is not strictly necessary, but it > greatly helps debugging build issues. It also only has an impact at > build time anyway. To make it easier to debug potential future CI > build failures, we enable it unconditionally. > brotli is also added as a new optional dependency, supported since > mupdf v1.26.0. > Starting from version 1.28.1 pipcl is no longer bundled and needs to > be installed separately, so add host-python-pipcl when we build the > python bindings. > Starting from version 1.28.2, mupdf added the unconditional use of a > venv, so disable it with MUPDF_NO_AUTOVENV. > > In python-pymupdf, !BR2_STATIC_LIBS is now required by mupdf anyway, > so update the comment accordingly. > pipcl (required to build python-pymupdf) used to be bundled in > python-pymupdf but is now available as a separate package, so use > it. This also allows us to use 'pep517' as the setup type. > The test is also updated to use the new implementation. > > For both packages, the patches that are now upstream are also removed. > > The tarball filename for python-pymupdf has changed upstream so it is > also updated accordingly. > > These new versions no longer fit in the 120M rootfs configured for the > runtime test, so double its size. Thanks for your patch. I was once trying to do an update myself and failed to get python-pymupdf to compile. They changed so much in their new version. Great work! You can add my Tested-By: Waldemar Brodkorb <wbx@openadk.org> Tested mupdf-x11 in fluxbox with qemu-system-x86_64 and glibc toolchain. > The mupdf builds are quite finicky on at least swig and libclang > versions, so applying these changes on the Buildroot LTS branches > should only be done with careful consideration (and making sure that > it builds and passes the runtime test). I tried the update for 2025.02, but get: ./scripts/mupdfwrap.py -d build/shared-release -b 01 (+0.0s): jlib.py:371:log_levels_add: adding level: filename_prefix='/' function_prefix='' (+0.0s): parse.py:16:<module>: Warning, could not import clang: No module named 'clang' (+0.0s): state.py:21:<module>: Warning: failed to import clang.cindex: e=ModuleNotFoundError("No module named 'clang'") (+0.0s): state.py:21:<module>: We need Clang Python to build MuPDF python. (+0.0s): state.py:21:<module>: Install with `pip install libclang` (typically inside a Python venv), So adding it to LTS will be challenging again I think. best regards Waldemar _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 2026-09-30 12:00 ` [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 Raphaël Mélotte via buildroot 2026-10-01 5:52 ` Waldemar Brodkorb @ 2026-10-04 15:41 ` Thomas Petazzoni via buildroot 2026-10-05 12:47 ` Raphaël Mélotte via buildroot 1 sibling, 1 reply; 11+ messages in thread From: Thomas Petazzoni via buildroot @ 2026-10-04 15:41 UTC (permalink / raw) To: Raphaël Mélotte; +Cc: buildroot, James Hilliard Hello Raphaël, Wow, lots of work here. mupdf seems pretty crazy to build, and their usage of clang doesn't seem to be making things simple. Do you expect some/all of your patches to be merged? More comments below (not many). On Wed, Sep 30, 2026 at 02:00:58PM +0200, Raphaël Mélotte via buildroot wrote: > Release notes: > https://mupdf.com/releases > https://pymupdf.readthedocs.io/en/latest/changes.html > > Note that this bump fixes multiple security vulnerabilities, and at > least the following ones: > - CVE-2025-46206 > - CVE-2025-71382 > - CVE-2026-7233 > - CVE-2026-40505 So should this commit be title "security bump to ..." ? > select BR2_PACKAGE_HOST_SWIG > select BR2_PACKAGE_FREETYPE > select BR2_PACKAGE_MUPDF > + select BR2_PACKAGE_MUPDF_PYTHON_BINDINGS > + select BR2_PACKAGE_PYTHON_PIPCL As I reported in my review of the previous patch, this option exists but doesn't do anything as python-pipcl doesn't exist as a target package. I assume this can be dropped? Thanks for your feedback! Thomas -- Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training https://bootlin.com _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 2026-10-04 15:41 ` Thomas Petazzoni via buildroot @ 2026-10-05 12:47 ` Raphaël Mélotte via buildroot 2026-10-05 15:50 ` Thomas Petazzoni via buildroot 0 siblings, 1 reply; 11+ messages in thread From: Raphaël Mélotte via buildroot @ 2026-10-05 12:47 UTC (permalink / raw) To: Thomas Petazzoni; +Cc: buildroot, James Hilliard Hello Thomas, On 10/4/26 5:41 PM, Thomas Petazzoni wrote: > Hello Raphaël, > > Wow, lots of work here. mupdf seems pretty crazy to build, and their > usage of clang doesn't seem to be making things simple. Do you expect > some/all of your patches to be merged? > I still hope they will be eventually (at least the ones that fix build issues), but given that some of them are more than a year old I'm also not that confident they will be unfortunately. > More comments below (not many). > > On Wed, Sep 30, 2026 at 02:00:58PM +0200, Raphaël Mélotte via buildroot wrote: >> Release notes: >> https://mupdf.com/releases >> https://pymupdf.readthedocs.io/en/latest/changes.html >> >> Note that this bump fixes multiple security vulnerabilities, and at >> least the following ones: >> - CVE-2025-46206 >> - CVE-2025-71382 >> - CVE-2026-7233 >> - CVE-2026-40505 > > So should this commit be title "security bump to ..." ? > I did not use it because our documentation says to use it "If the new version only contains security updates compared to the existing one". In this case it's a bump across several major releases, so it definitely contains more than security updates. That said I don't mind updating the commit title to use it if it's preferable. >> select BR2_PACKAGE_HOST_SWIG >> select BR2_PACKAGE_FREETYPE >> select BR2_PACKAGE_MUPDF >> + select BR2_PACKAGE_MUPDF_PYTHON_BINDINGS >> + select BR2_PACKAGE_PYTHON_PIPCL > > As I reported in my review of the previous patch, this option exists > but doesn't do anything as python-pipcl doesn't exist as a target > package. I assume this can be dropped? > Yes indeed, I'll do that in a v2. > Thanks for your feedback! > > Thomas Thanks, Raphaël _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 2026-10-05 12:47 ` Raphaël Mélotte via buildroot @ 2026-10-05 15:50 ` Thomas Petazzoni via buildroot 2026-10-07 10:46 ` Raphaël Mélotte via buildroot 0 siblings, 1 reply; 11+ messages in thread From: Thomas Petazzoni via buildroot @ 2026-10-05 15:50 UTC (permalink / raw) To: Raphaël Mélotte; +Cc: buildroot, James Hilliard On Mon, Oct 05, 2026 at 02:47:37PM +0200, Raphaël Mélotte wrote: > I still hope they will be eventually (at least the ones that fix > build issues), but given that some of them are more than a year old > I'm also not that confident they will be unfortunately. Meh :-/ > > So should this commit be title "security bump to ..." ? > > I did not use it because our documentation says to use it "If the > new version only contains security updates compared to the existing > one". In this case it's a bump across several major releases, so it > definitely contains more than security updates. And is it possible to backport just the security fixes? Otherwise our LTS maintainers will have no choice but to bump the version, but you said yourself that this should be considered very carefully. Thomas -- Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training https://bootlin.com _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 2026-10-05 15:50 ` Thomas Petazzoni via buildroot @ 2026-10-07 10:46 ` Raphaël Mélotte via buildroot 0 siblings, 0 replies; 11+ messages in thread From: Raphaël Mélotte via buildroot @ 2026-10-07 10:46 UTC (permalink / raw) To: Thomas Petazzoni; +Cc: buildroot, James Hilliard Hi Thomas, On 10/5/26 5:50 PM, Thomas Petazzoni wrote: > > And is it possible to backport just the security fixes? Otherwise our > LTS maintainers will have no choice but to bump the version, but you > said yourself that this should be considered very carefully. > That would be ideal yes. I need to check for each of them how easily they can be applied/backported. Kind regards, Raphaël _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Buildroot] [PATCH 1/2] package/python-pipcl: new host package 2026-09-30 12:00 [Buildroot] [PATCH 1/2] package/python-pipcl: new host package Raphaël Mélotte via buildroot 2026-09-30 12:00 ` [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 Raphaël Mélotte via buildroot @ 2026-10-04 15:38 ` Thomas Petazzoni via buildroot 2026-10-05 12:39 ` Raphaël Mélotte via buildroot 2026-10-05 15:40 ` [Buildroot] [PATCH v2 " Raphaël Mélotte via buildroot 2 siblings, 1 reply; 11+ messages in thread From: Thomas Petazzoni via buildroot @ 2026-10-04 15:38 UTC (permalink / raw) To: Raphaël Mélotte; +Cc: buildroot, James Hilliard Hello Raphaël, On Wed, Sep 30, 2026 at 02:00:57PM +0200, Raphaël Mélotte via buildroot wrote: > diff --git a/package/python-pipcl/Config.in b/package/python-pipcl/Config.in > new file mode 100644 > index 0000000000..1cac85352d > --- /dev/null > +++ b/package/python-pipcl/Config.in > @@ -0,0 +1,7 @@ > +config BR2_PACKAGE_PYTHON_PIPCL > + bool "python-pipcl" It does not make sense to have a Config.in option to enable a target package... when you have no target package. > diff --git a/package/python-pipcl/python-pipcl.mk b/package/python-pipcl/python-pipcl.mk > new file mode 100644 > index 0000000000..c0e97eeeb3 > --- /dev/null > +++ b/package/python-pipcl/python-pipcl.mk > @@ -0,0 +1,15 @@ > +################################################################################ > +# > +# python-pipcl > +# > +################################################################################ > + > +PYTHON_PIPCL_VERSION = 12 > +PYTHON_PIPCL_SOURCE = pipcl-$(PYTHON_PIPCL_VERSION).tar.gz > +PYTHON_PIPCL_SITE = https://files.pythonhosted.org/packages/64/1a/9ab2b272def9db9c80bf18fe8282119c2c4c074cc542030a28e4136dd13b > +PYTHON_PIPCL_SETUP_TYPE = pep517 > +PYTHON_PIPCL_LICENSE = AGPL-3.0+ > +PYTHON_PIPCL_LICENSE_FILES = COPYING > +HOST_PYTHON_PIPCL_DEPENDENCIES = host-python-packaging > + > +$(eval $(host-python-package)) ^^^ See here, you've made this a host only package. Best regards, Thomas -- Thomas Petazzoni, co-owner and CEO, Bootlin Embedded Linux and Kernel engineering and training https://bootlin.com _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Buildroot] [PATCH 1/2] package/python-pipcl: new host package 2026-10-04 15:38 ` [Buildroot] [PATCH 1/2] package/python-pipcl: new host package Thomas Petazzoni via buildroot @ 2026-10-05 12:39 ` Raphaël Mélotte via buildroot 0 siblings, 0 replies; 11+ messages in thread From: Raphaël Mélotte via buildroot @ 2026-10-05 12:39 UTC (permalink / raw) To: Thomas Petazzoni; +Cc: buildroot, James Hilliard Hello Thomas, On 10/4/26 5:38 PM, Thomas Petazzoni wrote: > Hello Raphaël, > > On Wed, Sep 30, 2026 at 02:00:57PM +0200, Raphaël Mélotte via buildroot wrote: > >> diff --git a/package/python-pipcl/Config.in b/package/python-pipcl/Config.in >> new file mode 100644 >> index 0000000000..1cac85352d >> --- /dev/null >> +++ b/package/python-pipcl/Config.in >> @@ -0,0 +1,7 @@ >> +config BR2_PACKAGE_PYTHON_PIPCL >> + bool "python-pipcl" > > It does not make sense to have a Config.in option to enable a target > package... when you have no target package. > Indeed, I must have thought pipcl was needed on the target initially, and forgot to remove the option when I made it a host package. I'll send a v2. >> diff --git a/package/python-pipcl/python-pipcl.mk b/package/python-pipcl/python-pipcl.mk >> new file mode 100644 >> index 0000000000..c0e97eeeb3 >> --- /dev/null >> +++ b/package/python-pipcl/python-pipcl.mk >> @@ -0,0 +1,15 @@ >> +################################################################################ >> +# >> +# python-pipcl >> +# >> +################################################################################ >> + >> +PYTHON_PIPCL_VERSION = 12 >> +PYTHON_PIPCL_SOURCE = pipcl-$(PYTHON_PIPCL_VERSION).tar.gz >> +PYTHON_PIPCL_SITE = https://files.pythonhosted.org/packages/64/1a/9ab2b272def9db9c80bf18fe8282119c2c4c074cc542030a28e4136dd13b >> +PYTHON_PIPCL_SETUP_TYPE = pep517 >> +PYTHON_PIPCL_LICENSE = AGPL-3.0+ >> +PYTHON_PIPCL_LICENSE_FILES = COPYING >> +HOST_PYTHON_PIPCL_DEPENDENCIES = host-python-packaging >> + >> +$(eval $(host-python-package)) > > ^^^ > > See here, you've made this a host only package. > > Best regards, > > Thomas Kind regards, Raphaël _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply [flat|nested] 11+ messages in thread
* [Buildroot] [PATCH v2 1/2] package/python-pipcl: new host package 2026-09-30 12:00 [Buildroot] [PATCH 1/2] package/python-pipcl: new host package Raphaël Mélotte via buildroot 2026-09-30 12:00 ` [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 Raphaël Mélotte via buildroot 2026-10-04 15:38 ` [Buildroot] [PATCH 1/2] package/python-pipcl: new host package Thomas Petazzoni via buildroot @ 2026-10-05 15:40 ` Raphaël Mélotte via buildroot 2026-10-05 15:40 ` [Buildroot] [PATCH v2 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 Raphaël Mélotte via buildroot 2 siblings, 1 reply; 11+ messages in thread From: Raphaël Mélotte via buildroot @ 2026-10-05 15:40 UTC (permalink / raw) To: buildroot; +Cc: James Hilliard, Raphaël Mélotte, Thomas Petazzoni pipcl used to be bundled in python-pymupdf, but is now available as a separate package. Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> --- Changes v1 -> v2: - Remove Config.in DEVELOPERS | 1 + package/python-pipcl/python-pipcl.hash | 5 +++++ package/python-pipcl/python-pipcl.mk | 15 +++++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 package/python-pipcl/python-pipcl.hash create mode 100644 package/python-pipcl/python-pipcl.mk diff --git a/DEVELOPERS b/DEVELOPERS index d62bfaafb3..217fce03a9 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -2849,6 +2849,7 @@ F: package/mupdf/ F: package/python-boto3/ F: package/python-botocore/ F: package/python-jmespath/ +F: package/python-pipcl/ F: package/python-pymupdf/ F: package/python-rsa/ F: package/python-s3transfer/ diff --git a/package/python-pipcl/python-pipcl.hash b/package/python-pipcl/python-pipcl.hash new file mode 100644 index 0000000000..f01af0ccee --- /dev/null +++ b/package/python-pipcl/python-pipcl.hash @@ -0,0 +1,5 @@ +# md5, sha256 from https://pypi.org/pypi/pipcl/json +md5 76883243610278b77725feb1813141f8 pipcl-12.tar.gz +sha256 c7545480cfa808500d8b606da73db7f89a872258bcdb293716126e2ccff1a5c6 pipcl-12.tar.gz +# Locally computed sha256 checksums +sha256 57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 COPYING diff --git a/package/python-pipcl/python-pipcl.mk b/package/python-pipcl/python-pipcl.mk new file mode 100644 index 0000000000..c0e97eeeb3 --- /dev/null +++ b/package/python-pipcl/python-pipcl.mk @@ -0,0 +1,15 @@ +################################################################################ +# +# python-pipcl +# +################################################################################ + +PYTHON_PIPCL_VERSION = 12 +PYTHON_PIPCL_SOURCE = pipcl-$(PYTHON_PIPCL_VERSION).tar.gz +PYTHON_PIPCL_SITE = https://files.pythonhosted.org/packages/64/1a/9ab2b272def9db9c80bf18fe8282119c2c4c074cc542030a28e4136dd13b +PYTHON_PIPCL_SETUP_TYPE = pep517 +PYTHON_PIPCL_LICENSE = AGPL-3.0+ +PYTHON_PIPCL_LICENSE_FILES = COPYING +HOST_PYTHON_PIPCL_DEPENDENCIES = host-python-packaging + +$(eval $(host-python-package)) -- 2.54.0 _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Buildroot] [PATCH v2 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 2026-10-05 15:40 ` [Buildroot] [PATCH v2 " Raphaël Mélotte via buildroot @ 2026-10-05 15:40 ` Raphaël Mélotte via buildroot 0 siblings, 0 replies; 11+ messages in thread From: Raphaël Mélotte via buildroot @ 2026-10-05 15:40 UTC (permalink / raw) To: buildroot; +Cc: James Hilliard, Raphaël Mélotte Release notes: https://mupdf.com/releases https://pymupdf.readthedocs.io/en/latest/changes.html Note that this bump fixes multiple security vulnerabilities, and at least the following ones: - CVE-2025-46206 - CVE-2025-71382 - CVE-2026-7233 - CVE-2026-40505 With this new python-pymupdf (and mupdf) version, we can no longer build the old implementation (the 'a' implementation). We now need to build mupdf's python binding, which require host-clang (and its python bindings) to be built. Also note that python-mupdf's version still needs to stay close to mupdf's version, they can only be updated together. A number of mupdf patches were needed: - To allow changing the build-time log level from an environment variable. - To be able to provide the libclang include directories. This is needed because our default libclang include directories are not properly set. - To be able to link against mupdf with no versioning number. - To fix build errors when generating the python bindings for python-pymupdf with clang 22. - To fix build errors with uClibc. - To make it possible to build without a venv. python-pymupdf also needed a (backported) patch to fix building with swig 4.5+. In mupdf, setting JLIB_log_levels is not strictly necessary, but it greatly helps debugging build issues. It also only has an impact at build time anyway. To make it easier to debug potential future CI build failures, we enable it unconditionally. brotli is also added as a new optional dependency, supported since mupdf v1.26.0. Starting from version 1.28.1 pipcl is no longer bundled and needs to be installed separately, so add host-python-pipcl when we build the python bindings. Starting from version 1.28.2, mupdf added the unconditional use of a venv, so disable it with MUPDF_NO_AUTOVENV. In python-pymupdf, !BR2_STATIC_LIBS is now required by mupdf anyway, so update the comment accordingly. pipcl (required to build python-pymupdf) used to be bundled in python-pymupdf but is now available as a separate package, so use it. This also allows us to use 'pep517' as the setup type. The test is also updated to use the new implementation. For both packages, the patches that are now upstream are also removed. The tarball filename for python-pymupdf has changed upstream so it is also updated accordingly. These new versions no longer fit in the 120M rootfs configured for the runtime test, so double its size. The mupdf builds are quite finicky on at least swig and libclang versions, so applying these changes on the Buildroot LTS branches should only be done with careful consideration (and making sure that it builds and passes the runtime test). Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> --- Changes v1 -> v2: - Remove the select of BR2_PACKAGE_PYTHON_PIPCL ...-incorrect-error-case-free-of-pixmap.patch | 53 -------- ...-jlib-fix-setting-filename-log-level.patch | 48 +++++++ ...y-to-provide-libclang-include-dirs-e.patch | 53 ++++++++ ...e-non-versioned-symlink-to-the-build.patch | 35 +++++ ...-log-level-through-environement-vari.patch | 53 ++++++++ ...rted-operand-type-when-setting-log-l.patch | 44 ++++++ ....py-class_add_iterator-assert-on-fin.patch | 41 ++++++ ...se.py-has_refs-recover-definition-cu.patch | 92 +++++++++++++ ...se.py-get_members-recover-definition.patch | 53 ++++++++ ...se.py-get_members-test-cursor.kind-n.patch | 78 +++++++++++ ...se.py-get_members-descend-into-anony.patch | 80 +++++++++++ ...-fitz-random.c-fix-build-with-uClibc.patch | 66 +++++++++ .../0012-scripts-make-venv-optional.patch | 52 ++++++++ package/mupdf/Config.in | 8 ++ package/mupdf/mupdf.hash | 6 +- package/mupdf/mupdf.mk | 55 ++++++-- ...w-providing-python-config-externally.patch | 125 ------------------ .../0001-src-extra-i-fix-for-swig-4-5.patch | 25 ++++ package/python-pymupdf/Config.in | 3 +- package/python-pymupdf/python-pymupdf.hash | 4 +- package/python-pymupdf/python-pymupdf.mk | 16 ++- .../tests/package/sample_python_pymupdf.py | 2 +- .../tests/package/test_python_pymupdf.py | 2 +- 23 files changed, 790 insertions(+), 204 deletions(-) delete mode 100644 package/mupdf/0001-Fix-incorrect-error-case-free-of-pixmap.patch create mode 100644 package/mupdf/0001-jlib-fix-setting-filename-log-level.patch create mode 100644 package/mupdf/0002-scripts-add-a-way-to-provide-libclang-include-dirs-e.patch create mode 100644 package/mupdf/0003-setup.py-add-the-non-versioned-symlink-to-the-build.patch create mode 100644 package/mupdf/0004-jlib-fix-setting-log-level-through-environement-vari.patch create mode 100644 package/mupdf/0005-jlib-fix-unsupported-operand-type-when-setting-log-l.patch create mode 100644 package/mupdf/0006-scripts-wrap-cpp.py-class_add_iterator-assert-on-fin.patch create mode 100644 package/mupdf/0007-scripts-wrap-parse.py-has_refs-recover-definition-cu.patch create mode 100644 package/mupdf/0008-scripts-wrap-parse.py-get_members-recover-definition.patch create mode 100644 package/mupdf/0009-scripts-wrap-parse.py-get_members-test-cursor.kind-n.patch create mode 100644 package/mupdf/0010-scripts-wrap-parse.py-get_members-descend-into-anony.patch create mode 100644 package/mupdf/0011-source-fitz-random.c-fix-build-with-uClibc.patch create mode 100644 package/mupdf/0012-scripts-make-venv-optional.patch delete mode 100644 package/python-pymupdf/0001-pipcl.py-allow-providing-python-config-externally.patch create mode 100644 package/python-pymupdf/0001-src-extra-i-fix-for-swig-4-5.patch diff --git a/package/mupdf/0001-Fix-incorrect-error-case-free-of-pixmap.patch b/package/mupdf/0001-Fix-incorrect-error-case-free-of-pixmap.patch deleted file mode 100644 index f78c429cef..0000000000 --- a/package/mupdf/0001-Fix-incorrect-error-case-free-of-pixmap.patch +++ /dev/null @@ -1,53 +0,0 @@ -From d4743b6092d513321c23c6f7fe5cff87cde043c1 Mon Sep 17 00:00:00 2001 -From: Robin Watts <Robin.Watts@artifex.com> -Date: Mon, 12 Jan 2026 19:08:56 +0000 -Subject: Bug 709029: Fix incorrect error-case free of pixmap. - -Don't free a pixmap we don't own! - -CVE: CVE-2026-25556 -Upstream: https://cgit.ghostscript.com/cgi-bin/cgit.cgi/mupdf.git/commit/?id=d4743b6092d513321c23c6f7fe5cff87cde043c1 -Signed-off-by: Thomas Perale <thomas.perale@mind.be> ---- - source/fitz/util.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - -diff --git a/source/fitz/util.c b/source/fitz/util.c -index 7710124cc..90226a5c1 100644 ---- a/source/fitz/util.c -+++ b/source/fitz/util.c -@@ -119,7 +119,15 @@ fz_new_pixmap_from_display_list_with_separations(fz_context *ctx, fz_display_lis - else - fz_clear_pixmap_with_value(ctx, pix, 0xFF); - -- return fz_fill_pixmap_from_display_list(ctx, list, ctm, pix); -+ fz_try(ctx) -+ fz_fill_pixmap_from_display_list(ctx, list, ctm, pix); -+ fz_catch(ctx) -+ { -+ fz_drop_pixmap(ctx, pix); -+ fz_rethrow(ctx); -+ } -+ -+ return pix; - } - - fz_pixmap * -@@ -136,14 +144,9 @@ fz_fill_pixmap_from_display_list(fz_context *ctx, fz_display_list *list, fz_matr - fz_close_device(ctx, dev); - } - fz_always(ctx) -- { - fz_drop_device(ctx, dev); -- } - fz_catch(ctx) -- { -- fz_drop_pixmap(ctx, pix); - fz_rethrow(ctx); -- } - - return pix; - } --- -cgit v1.2.3 - diff --git a/package/mupdf/0001-jlib-fix-setting-filename-log-level.patch b/package/mupdf/0001-jlib-fix-setting-filename-log-level.patch new file mode 100644 index 0000000000..2a0e62b870 --- /dev/null +++ b/package/mupdf/0001-jlib-fix-setting-filename-log-level.patch @@ -0,0 +1,48 @@ +From 553bb924e032646739362c586adbcd5e931f02b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 24 Feb 2025 13:06:00 +0100 +Subject: [PATCH] jlib: fix setting filename log level +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Building using JLIB_log_levels for filenames only currently fails. + +For example, building with the following command: +make JLIB_log_levels=cpp.py=-5 python + +... leads to the following trace: + + File "/home/rme/Documents/mupdf/scripts/jlib.py", line 427, in log + level += log_levels_find( caller) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "/home/rme/Documents/mupdf/scripts/jlib.py", line 350, in log_levels_find + if item_filename and not filename.startswith( item_filename): + +This is because ffl is always a list (unpacked in case len==2), and +the filename is the first element of this list. +To fix it, only keep the first element of ffl when there is exactly +one. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/58 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/jlib.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/jlib.py b/scripts/jlib.py +index 8d7ecc6cd..4c7e2a0f0 100644 +--- a/scripts/jlib.py ++++ b/scripts/jlib.py +@@ -509,7 +509,7 @@ def log_levels_add_env( name='JLIB_log_levels'): + if 0: # lgtm [py/unreachable-statement] + pass + elif len( ffl) == 1: +- filename = ffl ++ filename = ffl[0] + function = None + elif len( ffl) == 2: + filename, function = ffl +-- +2.48.1 + diff --git a/package/mupdf/0002-scripts-add-a-way-to-provide-libclang-include-dirs-e.patch b/package/mupdf/0002-scripts-add-a-way-to-provide-libclang-include-dirs-e.patch new file mode 100644 index 0000000000..c2728a4fac --- /dev/null +++ b/package/mupdf/0002-scripts-add-a-way-to-provide-libclang-include-dirs-e.patch @@ -0,0 +1,53 @@ +From 0e1f9060e1110a293df2f62912aba234b0904309 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Thu, 20 Feb 2025 12:50:01 +0100 +Subject: [PATCH] scripts: add a way to provide libclang include dirs + externally +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When cross-compiling, libclang doesn't necessarily have the right +include directories configured by default. +See for example: https://bugs.ghostscript.com/show_bug.cgi?id=708041 + +Since we also have no way to figure out the right include directories +from our scripts, add a new environment variable that can be used to +provide them externally. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/63 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/cpp.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/scripts/wrap/cpp.py b/scripts/wrap/cpp.py +index 604c1ee..cd79b9c 100644 +--- a/scripts/wrap/cpp.py ++++ b/scripts/wrap/cpp.py +@@ -6,6 +6,7 @@ import io + import os + import pickle + import re ++import shlex + import textwrap + + import jlib +@@ -5579,6 +5580,14 @@ def cpp_source( + '-D', 'MUPDF_WRAP_LIBCLANG', + '-D', 'FZ_FUNCTION=', + ] ++ ++ # In some circumstances (e.g. when cross-compiling when ++ # libclang doesn't have the right include directories by ++ # default) the includes are provided externally: ++ libclang_args = os.environ.get('MUPDF_LIBCLANG_ARGS', '') ++ if libclang_args: ++ args += shlex.split(libclang_args) ++ + tu = index.parse( + temp_h, + args = args, +-- +2.54.0 + diff --git a/package/mupdf/0003-setup.py-add-the-non-versioned-symlink-to-the-build.patch b/package/mupdf/0003-setup.py-add-the-non-versioned-symlink-to-the-build.patch new file mode 100644 index 0000000000..efca7b7750 --- /dev/null +++ b/package/mupdf/0003-setup.py-add-the-non-versioned-symlink-to-the-build.patch @@ -0,0 +1,35 @@ +From b8efb551ba65f6f0d737ca3760fe5e2dbac5743c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Tue, 3 Sep 2024 15:35:33 +0200 +Subject: [PATCH] setup.py: add the non-versioned symlink to the build +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Starting from bf1c28cc4f2dd4bd17e35783fa3c1f98ded22296, the generated +mupdf libraries are versioned. This means that if we want to link +against them without knowing their version number (i.e. using +'-lmupdf'), we also need to install the symlink to the wheel. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/59 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + setup.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/setup.py b/setup.py +index 49199f5..3252412 100755 +--- a/setup.py ++++ b/setup.py +@@ -357,6 +357,8 @@ def build(): + names = [ + pipcl.get_soname(f'{build_dir()}/libmupdf.so'), # C. + pipcl.get_soname(f'{build_dir()}/libmupdfcpp.so'), # C++. ++ f'{build_dir()}/libmupdf.so', # C symlink. ++ f'{build_dir()}/libmupdfcpp.so', # C++ symlink. + f'{build_dir()}/_mupdf.so', # Python internals. + f'{build_dir()}/mupdf.py', # Python. + ] +-- +2.54.0 + diff --git a/package/mupdf/0004-jlib-fix-setting-log-level-through-environement-vari.patch b/package/mupdf/0004-jlib-fix-setting-log-level-through-environement-vari.patch new file mode 100644 index 0000000000..386dd2050e --- /dev/null +++ b/package/mupdf/0004-jlib-fix-setting-log-level-through-environement-vari.patch @@ -0,0 +1,53 @@ +From e033e1a8b8a1674e1e7ee6638008bd005b511920 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 24 Feb 2025 22:29:13 +0100 +Subject: [PATCH] jlib: fix setting log level through environement variable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently, setting a log level through the JLIB_log_levels environment +fails in this way: + File "/home/rme/Documents/mupdf/scripts/jlib.py", line 185, in __call__ + ret += ' (+%s)' % time_duration( time.time() - self.t0, s_format='%.1f') + ^^^^^^^^^^^^^ +This is because at the time log_levels_add_env() is invoked, +time_duration is not defined yet. + +To fix it, just move the invocation further down, after time_duration +is defined. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/58 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/jlib.py | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/scripts/jlib.py b/scripts/jlib.py +index 4c7e2a0f0..788a4bec8 100644 +--- a/scripts/jlib.py ++++ b/scripts/jlib.py +@@ -743,10 +743,6 @@ def text_split_last_of( text, substrings): + return text[ :pos], text[ pos:] + + +- +-log_levels_add_env() +- +- + def force_line_buffering(): + ''' + Ensure `sys.stdout` and `sys.stderr` are line-buffered. E.g. makes things +@@ -1246,6 +1242,9 @@ def time_duration( seconds, verbose=False, s_format='%i'): + return ret + + ++log_levels_add_env() ++ ++ + def date_time( t=None): + if t is None: + t = time.time() +-- +2.48.1 + diff --git a/package/mupdf/0005-jlib-fix-unsupported-operand-type-when-setting-log-l.patch b/package/mupdf/0005-jlib-fix-unsupported-operand-type-when-setting-log-l.patch new file mode 100644 index 0000000000..819f2d0a55 --- /dev/null +++ b/package/mupdf/0005-jlib-fix-unsupported-operand-type-when-setting-log-l.patch @@ -0,0 +1,44 @@ +From a568ae50e32e8b209edc9720360d873b10769f60 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 24 Feb 2025 22:48:36 +0100 +Subject: [PATCH] jlib: fix unsupported operand type when setting log level +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes the following issue when log_levels_find() is used (for +example when setting a log level delta using JLIB_log_levels): +[...] + scripts/jlib.py:424:log(): level += log_levels_find( caller) + scripts/jlib.py:334:log_levels_find(): tb = traceback.extract_stack( None, 1+caller) +TypeError: unsupported operand type(s) for +: 'int' and 'FrameInfo' + +Note that this fix get JLIB_log_levels working, but it might be +incorrect. + +Upstream: https://github.com/ArtifexSoftware/mupdf/pull/58 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/jlib.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/scripts/jlib.py b/scripts/jlib.py +index 788a4bec8..452b3ae00 100644 +--- a/scripts/jlib.py ++++ b/scripts/jlib.py +@@ -331,7 +331,11 @@ def log_levels_find( caller): + if not s_log_levels_items: + return 0 + +- tb = traceback.extract_stack( None, 1+caller) ++ if isinstance(caller, inspect.FrameInfo): ++ tb = traceback.extract_stack( None, 1) ++ else: ++ tb = traceback.extract_stack( None, 1+caller) ++ + if len(tb) == 0: + return 0 + filename, line, function, text = tb[0] +-- +2.48.1 + diff --git a/package/mupdf/0006-scripts-wrap-cpp.py-class_add_iterator-assert-on-fin.patch b/package/mupdf/0006-scripts-wrap-cpp.py-class_add_iterator-assert-on-fin.patch new file mode 100644 index 0000000000..c4f2c4e3ab --- /dev/null +++ b/package/mupdf/0006-scripts-wrap-cpp.py-class_add_iterator-assert-on-fin.patch @@ -0,0 +1,41 @@ +From 176e9a4eac3375b19d53e15a24ddfdae5767e04f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:44:40 +0200 +Subject: [PATCH] scripts/wrap/cpp.py: class_add_iterator(): assert on + find_name() failure. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +parse.find_name() returns None when the requested dotted member path +isn't found, e.g. because the corresponding classextras.iterator_next +entry is stale or a libclang change broke traversal into an anonymous +struct/union. Immediately using the result as `c.type.kind` then fails +with an opaque "AttributeError: 'NoneType' object has no attribute +'type'" that gives no indication of which struct or field lookup +failed. + +Assert explicitly and name the struct and field path involved, so a +future failure here is easier to debug from the messageq. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/cpp.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/scripts/wrap/cpp.py b/scripts/wrap/cpp.py +index cd79b9c..c1bd3b6 100644 +--- a/scripts/wrap/cpp.py ++++ b/scripts/wrap/cpp.py +@@ -2536,6 +2536,7 @@ def class_add_iterator( tu, struct_cursor, struct_name, classname, extras, refch + # <it_begin>. + if it_begin: + c = parse.find_name( struct_cursor, it_begin) ++ assert c, f'Failed to find {it_begin=} in {struct_name=} ({struct_cursor.spelling=})' + assert c.type.kind == state.clang.cindex.TypeKind.POINTER + it_internal_type = state.get_name_canonical( c.type.get_pointee()).spelling + it_internal_type = util.clip( it_internal_type, 'struct ') +-- +2.54.0 + diff --git a/package/mupdf/0007-scripts-wrap-parse.py-has_refs-recover-definition-cu.patch b/package/mupdf/0007-scripts-wrap-parse.py-has_refs-recover-definition-cu.patch new file mode 100644 index 0000000000..be9b58425c --- /dev/null +++ b/package/mupdf/0007-scripts-wrap-parse.py-has_refs-recover-definition-cu.patch @@ -0,0 +1,92 @@ +From 6ec47b449386c7d7f3105d3e33c2095cd1a73c09 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:41:16 +0200 +Subject: [PATCH] scripts/wrap/parse.py: has_refs(): recover definition cursor + for clang-22. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +clang.cindex.Type.get_declaration() is documented to return "the +cursor for the declaration of the given type", but is not guaranteed +to return the *defining* declaration when a type is forward-declared +in one header:(e.g. `typedef struct fz_pixmap fz_pixmap;` in +fitz/color.h) and defined elsewhere (`struct fz_pixmap { ... }` in +fitz/pixmap.h). + +Older libclang versions apparently happened to resolve straight +through to the defining cursor here, so has_refs()'s +`base_type_cursor.is_definition()` check was reliably true whenever a +definition existed in the translation unit. Under libclang from clang +22.1.3, get_declaration() can instead return a non-defining +declaration cursor even though the full definition is present, so +is_definition() now incorrectly reports false for types such as +fz_pixmap and fz_stream. This falls through to has_refs()'s hard-coded +fallback table, which has no entry for these types, and trips the +final `assert ret` with "has fz_keep_...() but have not found +size/location of .refs member." + +This libclang behavior can be reproduced with the following minimal +example: + min.h (2 lines): + typedef struct Foo Foo; /* forward declaration, e.g. in a "public" header */ + struct Foo { int x; }; /* definition, e.g. in a different "private" header */ + + min.py (6 lines): + import clang.cindex + + tu = clang.cindex.Index.create().parse('min.h', args=['-x', 'c']) + typedef_decl = next(c for c in tu.cursor.get_children() if c.kind == clang.cindex.CursorKind.TYPEDEF_DECL) + struct_decl = typedef_decl.underlying_typedef_type.get_declaration() + + print('cursor:', struct_decl.location, 'is_definition:', struct_decl.is_definition()) + print('children:', [c.spelling for c in struct_decl.get_children()]) + +Which gives: + clang 18 (libclang==18.1.1): + cursor: <SourceLocation file 'min.h', line 2, column 8> is_definition: True + children: ['x'] + + clang 22 (libclang-ng==22.1.4.2): + cursor: <SourceLocation file 'min.h', line 1, column 16> is_definition: False + children: [] + +To fix it, call cursor.get_definition() that explicitly looks up the +actual defining cursor for a declaration/reference cursor anywhere in +the TU when the initial cursor is not itself a definition. This makes +has_refs() work the same way regardless of which cursor +get_declaration() happens to hand back. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/parse.py | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/scripts/wrap/parse.py b/scripts/wrap/parse.py +index c3bd1278c..d8c09f2a9 100644 +--- a/scripts/wrap/parse.py ++++ b/scripts/wrap/parse.py +@@ -252,6 +252,19 @@ def has_refs( tu, type_): + if verbose: + jlib.log( 'There is a keep() fn for this type so it uses reference counting: {keep_name=}') + base_type_cursor = get_base_type( type_).get_declaration() ++ if not base_type_cursor.is_definition(): ++ # get_declaration() is not guaranteed to return the ++ # defining cursor when the type is declared in one ++ # place (e.g. an opaque forward-declaring typedef) ++ # and defined elsewhere - depending on libclang ++ # version, it may instead return a non-defining ++ # declaration cursor even though a definition exists ++ # in the TU. get_definition() explicitly looks up the ++ # actual definition cursor, so use it to recover in ++ # that case. ++ definition_cursor = base_type_cursor.get_definition() ++ if definition_cursor is not None and definition_cursor.is_definition(): ++ base_type_cursor = definition_cursor + if base_type_cursor.is_definition(): + if verbose: + jlib.log( 'Type definition is available so we look for .refs member: {key=} {type_.spelling=} {fileline(base_type_cursor)=}') +-- +2.54.0 + diff --git a/package/mupdf/0008-scripts-wrap-parse.py-get_members-recover-definition.patch b/package/mupdf/0008-scripts-wrap-parse.py-get_members-recover-definition.patch new file mode 100644 index 0000000000..bdd3ca81d9 --- /dev/null +++ b/package/mupdf/0008-scripts-wrap-parse.py-get_members-recover-definition.patch @@ -0,0 +1,53 @@ +From 8e780ba4b057e2c2174bbd3f4c123ced32dd78f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:43:52 +0200 +Subject: [PATCH] scripts/wrap/parse.py: get_members(): recover definition + cursor for clang-22. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes the same issue as the preceding has_refs() fix, but for +get_members()'s own typedef-to-struct resolution: +cursor.underlying_typedef_type.get_declaration() is not guaranteed to +return the defining cursor for the struct, only some declaration of +it. Under libclang from clang 22.1.3 this can be a +non-defining (forward-declaration) cursor even when a full definition +exists in the TU, which left cursor2.get_children() empty and made +get_members() yield no members at all for affected types - e.g. +class_accessors() would then hit "assert n, f'No fields found for +{struct_cursor.spelling}.'" for fz_pixmap. + +Recover via get_definition() (clang_getCursorDefinition), which looks up +the actual definition cursor for a declaration cursor across the whole +TU, independent of what get_declaration() happened to return. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/parse.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/scripts/wrap/parse.py b/scripts/wrap/parse.py +index d8c09f2a9..ed1737b34 100644 +--- a/scripts/wrap/parse.py ++++ b/scripts/wrap/parse.py +@@ -120,6 +120,15 @@ def get_members( type_or_cursor, include_empty=False): + cursor2 = cursor.underlying_typedef_type.get_declaration() + else: + cursor2 = cursor ++ if not cursor2.is_definition(): ++ # get_declaration() is not guaranteed to return the defining cursor ++ # - depending on libclang version, it may instead return a ++ # non-defining declaration cursor (e.g. a forward-declaring typedef) ++ # even though a definition exists elsewhere in the TU. Recover the ++ # actual definition cursor if we can find one. ++ definition_cursor2 = cursor2.get_definition() ++ if definition_cursor2 is not None and definition_cursor2.is_definition(): ++ cursor2 = definition_cursor2 + + if 0: + # Diagnostics to show the difference between +-- +2.54.0 + diff --git a/package/mupdf/0009-scripts-wrap-parse.py-get_members-test-cursor.kind-n.patch b/package/mupdf/0009-scripts-wrap-parse.py-get_members-test-cursor.kind-n.patch new file mode 100644 index 0000000000..d47729101f --- /dev/null +++ b/package/mupdf/0009-scripts-wrap-parse.py-get_members-test-cursor.kind-n.patch @@ -0,0 +1,78 @@ +From d4b9583147fe8b15b284f4fbbfd9fe2b02723fec Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:41:46 +0200 +Subject: [PATCH] scripts/wrap/parse.py: get_members(): test cursor.kind, not + cursor.type.kind. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +get_members() resolves a typedef to its underlying type's declaration +before looking at its children: + + if cursor.type.kind in (TypeKind.TYPEDEF, TypeKind.ELABORATED): + cursor2 = cursor.underlying_typedef_type.get_declaration() + +The intent seems to be "if <cursor> is itself a typedef declaration, +follow it to the real declaration", but the condition instead tests +the *type* of the entity the cursor declares. Those are not the same +thing: a FIELD_DECL cursor for a plain data member can have a type +whose .kind is ELABORATED - this is normal for a field whose type is +an anonymous struct/union defined inline, e.g. `union { struct {...} +t; ...} u;`. The old condition therefore matched such fields too, and +went on to call `.underlying_typedef_type` on a cursor that is not a +TYPEDEF_DECL at all. + +clang_getTypedefDeclUnderlyingType() is documented to return an +invalid type if the cursor does not reference a typedef +declaration (clang/include/clang-c/Index.h) - but the result for a +field cursor is unusable: on clang 18, the invalid type's +.get_declaration() comes back as a NO_DECL_FOUND cursor with no +location, whose .get_children() is unconditionally empty. +get_members() falls through to its type_.get_fields() fallback in that +case, which happens to still find the real members, so this was +previously masked rather than fixed. + +On clang 22, this same call is not reached in the first place: clang +22 removed ElaboratedType from the AST (see the "Clang Python Bindings +Potentially Breaking Changes" entry in the Clang 22.1.0 release notes: +"TypeKind ELABORATED is not used anymore, per clang AST changes +removing ElaboratedTypes"), so a field whose type is an anonymous +struct/union now reports TypeKind.RECORD instead of +TypeKind.ELABORATED, and the old condition is simply false. This +commit should therefore be needed only for clang<22.1.0. + +Fix by checking cursor.kind == CursorKind.TYPEDEF_DECL, which matches +only genuine typedef declarations (e.g. `typedef struct fz_pixmap +fz_pixmap;`) and leaves plain fields - whose type merely happens to be +elaborated/anonymous - to fall through to direct child inspection, +which is what actually finds their members. + +Combined with the next commit (which makes get_members() descend into +the placeholder cursor libclang gives us for an anonymous struct/union +field), this makes get_members() resolve such fields the same way, for +the same reason, on both clang 18 and clang 22, rather than clang 18 +only working by accident. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/parse.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/wrap/parse.py b/scripts/wrap/parse.py +index ed1737b34..8881c68d0 100644 +--- a/scripts/wrap/parse.py ++++ b/scripts/wrap/parse.py +@@ -116,7 +116,7 @@ def get_members( type_or_cursor, include_empty=False): + cursor = type_or_cursor + else: + assert 0 +- if cursor.type.kind in (state.clang.cindex.TypeKind.TYPEDEF, state.clang.cindex.TypeKind.ELABORATED): ++ if cursor.kind == state.clang.cindex.CursorKind.TYPEDEF_DECL: + cursor2 = cursor.underlying_typedef_type.get_declaration() + else: + cursor2 = cursor +-- +2.54.0 + diff --git a/package/mupdf/0010-scripts-wrap-parse.py-get_members-descend-into-anony.patch b/package/mupdf/0010-scripts-wrap-parse.py-get_members-descend-into-anony.patch new file mode 100644 index 0000000000..79baa39e39 --- /dev/null +++ b/package/mupdf/0010-scripts-wrap-parse.py-get_members-descend-into-anony.patch @@ -0,0 +1,80 @@ +From b5174269f72f5634b418a7c5216026d6bf2f4ccb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Mon, 27 Jul 2026 12:44:16 +0200 +Subject: [PATCH] scripts/wrap/parse.py: get_members(): descend into anonymous + struct/union. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +fz_stext_block contains a field whose type is an anonymous union with +named nested-struct members, e.g.: + + union { + struct { fz_stext_line *first_line, *last_line; int flags; } t; + struct { fz_matrix transform; fz_image *image; } i; + ... + } u; + +Under libclang from clang 22.1.3, calling get_children() on the FIELD_DECL +cursor for 'u' yields a single child that is the anonymous union's own +UNION_DECL cursor (with a synthesised .spelling like "(unnamed union at +fitz/structured-text.h:444:2)"), rather than yielding 'u's real members +('t', 'i', 's', 'v', 'b') directly. (The pre-existing, long-disabled +diagnostics code in this function already notes a related but different +symptom seen on older libclang: an extra empty-spelling child for the +same kind of anonymous union.) + +This broke find_name()'s lookup of dotted paths like 'u.t.first_line', +which fz_stext_block's classextras.iterator_next relies on, causing +class_add_iterator() to fail with "Failed to find it_begin='u.t.first_line' +in struct_name='fz_stext_block'" (from the assert added in an earlier +commit). + +When we see exactly one child and it is itself a STRUCT_DECL/UNION_DECL - +which does not happen for an ordinary named-type member, only for a field +whose type is defined anonymously inline - descend into that child to +find the real members. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709448 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/parse.py | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/scripts/wrap/parse.py b/scripts/wrap/parse.py +index 8881c68d0..b9a65ace2 100644 +--- a/scripts/wrap/parse.py ++++ b/scripts/wrap/parse.py +@@ -162,8 +162,27 @@ def get_members( type_or_cursor, include_empty=False): + for i in ret_type: + jlib.log( ' ret_type: {i}') + ++ children = list(cursor2.get_children()) ++ if (cursor2.kind == state.clang.cindex.CursorKind.FIELD_DECL ++ and len(children) == 1 ++ and children[0].kind in ( ++ state.clang.cindex.CursorKind.STRUCT_DECL, ++ state.clang.cindex.CursorKind.UNION_DECL, ++ ) ++ ): ++ # <cursor2> is a field whose type is an anonymous struct/union ++ # defined inline (e.g. 'union { ... } u;'). A normal field with a ++ # named member type has no such child, so seeing exactly one ++ # STRUCT_DECL/UNION_DECL child here means some libclang versions are ++ # giving us the anonymous struct/union's own declaration cursor ++ # (with a synthesised, non-empty .spelling describing the anonymous ++ # type, e.g. '(unnamed union at ...)'), instead of directly giving ++ # us that struct/union's members. Descend into it to find the real ++ # members. ++ children = list(children[0].get_children()) ++ + ret = list() +- for cursor3 in cursor2.get_children(): ++ for cursor3 in children: + if include_empty or cursor3.spelling: + ret.append(cursor3) + if not ret: +-- +2.54.0 + diff --git a/package/mupdf/0011-source-fitz-random.c-fix-build-with-uClibc.patch b/package/mupdf/0011-source-fitz-random.c-fix-build-with-uClibc.patch new file mode 100644 index 0000000000..8ed01dcd8a --- /dev/null +++ b/package/mupdf/0011-source-fitz-random.c-fix-build-with-uClibc.patch @@ -0,0 +1,66 @@ +From 65dccf58c115090ce008ae517e2835226f3764ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Tue, 29 Sep 2026 18:30:40 +0200 +Subject: [PATCH] source/fitz/random.c: fix build with uClibc +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +uClibc does not have getentropy(). uClibc-ng has it starting from +version 1.0.54, and only when it is built with UCLIBC_LINUX_SPECIFIC +[1]. + +In addition, uClibc-ng declares getentropy() in <unistd.h> only if +_DEFAULT_SOURCE is defined [2]. Unlike glibc, uClibc-ng does not +define _DEFAULT_SOURCE by default [3], and we do not define it. +<sys/random.h> always declares getentropy() [4]. + +To build with all versions of uClibc and uClibc-ng, check the +__UCLIBC_* macros: +- Before 1.0.54, or without __UCLIBC_LINUX_SPECIFIC__, use the + fallback. +- Otherwise, include <sys/random.h> to get the getentropy() + declaration. + +[1] https://github.com/wbx-github/uclibc-ng/blob/master/libc/sysdeps/linux/common/Makefile.in +[2] https://github.com/wbx-github/uclibc-ng/blob/master/include/unistd.h +[3] https://github.com/wbx-github/uclibc-ng/blob/master/include/features.h +[4] https://github.com/wbx-github/uclibc-ng/blob/master/libc/sysdeps/linux/common/sys/random.h + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709779 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + source/fitz/random.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/source/fitz/random.c b/source/fitz/random.c +index ad92c6369..51b016217 100644 +--- a/source/fitz/random.c ++++ b/source/fitz/random.c +@@ -34,6 +34,14 @@ + #else + #include <unistd.h> // for getentropy() + #endif ++#ifdef __UCLIBC__ ++#if __UCLIBC_MAJOR__ < 1 || (__UCLIBC_MAJOR__ == 1 && __UCLIBC_MINOR__ == 0 && __UCLIBC_SUBLEVEL__ < 54) || \ ++ !defined(__UCLIBC_LINUX_SPECIFIC__) ++#define NO_GETENTROPY // uClibc-ng before 1.0.54, or without UCLIBC_LINUX_SPECIFIC, does not have getentropy() ++#else ++#include <sys/random.h> // unistd.h declares getentropy() only with _DEFAULT_SOURCE ++#endif ++#endif + #endif + + #ifdef _WIN32 +@@ -95,6 +103,8 @@ void fz_memrnd(fz_context *ctx, unsigned char *data, int len) + // Android before 9.0 does not have getentropy(), but does have + // arc4random_buf that sources from /dev/urandom. + arc4random_buf(entropy, sizeof entropy); ++#elif defined(NO_GETENTROPY) ++ getentropy_fallback(entropy, sizeof entropy); + #else + if (getentropy(entropy, sizeof entropy) < 0) + getentropy_fallback(entropy, sizeof entropy); +-- +2.54.0 + diff --git a/package/mupdf/0012-scripts-make-venv-optional.patch b/package/mupdf/0012-scripts-make-venv-optional.patch new file mode 100644 index 0000000000..327dde645a --- /dev/null +++ b/package/mupdf/0012-scripts-make-venv-optional.patch @@ -0,0 +1,52 @@ +From c55d406be771b626d5a2a4870203c700a34d4b1d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> +Date: Tue, 29 Sep 2026 21:32:59 +0200 +Subject: [PATCH] scripts: make venv optional +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit e7901bed9b85031b6e6769e49c4ba3a2cbb5033f ("scripts/:fix +venv-related failures in python/c# bindings tests.") introduced the +unconditional use of a venv. This is not always +possible/desirable (e.g. when building in Buildroot). + +To make it possible to skip the use of a venv, introduce the +MUPDF_NO_AUTOVENV variable. + +The default behavior remains the same as before. + +Upstream: https://bugs.ghostscript.com/show_bug.cgi?id=709778 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + scripts/wrap/__main__.py | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/scripts/wrap/__main__.py b/scripts/wrap/__main__.py +index 4440a70..7e5dc38 100644 +--- a/scripts/wrap/__main__.py ++++ b/scripts/wrap/__main__.py +@@ -918,13 +918,14 @@ import sysconfig + import tempfile + import textwrap + +-sys.path.insert(0, os.path.normpath(f'{__file__}/../..')) +-try: +- import autovenv +-finally: +- del sys.path[0] ++if os.environ.get('MUPDF_NO_AUTOVENV') != '1': ++ sys.path.insert(0, os.path.normpath(f'{__file__}/../..')) ++ try: ++ import autovenv ++ finally: ++ del sys.path[0] + +-autovenv.enter() ++ autovenv.enter() + + # Install/import pipcl. We don't pass 'pipcl' to above call to autovenv.enter() + # because this would do `pip install pipcl`, which seems to fail if we are +-- +2.54.0 + diff --git a/package/mupdf/Config.in b/package/mupdf/Config.in index 5c0a127a90..4a9b4f487f 100644 --- a/package/mupdf/Config.in +++ b/package/mupdf/Config.in @@ -20,3 +20,11 @@ comment "mupdf needs a toolchain w/ C++, gcc >= 4.9" depends on BR2_TOOLCHAIN_HAS_SYNC_4 depends on !BR2_INSTALL_LIBSTDCPP || \ !BR2_TOOLCHAIN_GCC_AT_LEAST_4_9 + +if BR2_PACKAGE_MUPDF +config BR2_PACKAGE_MUPDF_PYTHON_BINDINGS + bool "python bindings for mupdf" + depends on !BR2_STATIC_LIBS + depends on BR2_PACKAGE_PYTHON3 + select BR2_PACKAGE_HOST_SWIG +endif diff --git a/package/mupdf/mupdf.hash b/package/mupdf/mupdf.hash index 80de6f3b2c..7313548b5e 100644 --- a/package/mupdf/mupdf.hash +++ b/package/mupdf/mupdf.hash @@ -1,8 +1,6 @@ # From https://mupdf.com/releases: -sha1 d79600bccd70ab9d0e8ee19dae4e275f2af95ced mupdf-1.23.9-source.tar.lz - -# Locally computed: -sha256 2c2f89deb9f425ba637dac226191d547f2b40975c4d21a340965f52c001e15c5 mupdf-1.23.9-source.tar.lz +sha1 1f0a14123a2410c3bdb63cb6bbef69d0f2518f6e mupdf-1.28.5-source.tar.lz +sha256 f33f3c672033324c38c7c9a1444c28436ede9669a28e2da672df7f6c62b8cfc8 mupdf-1.28.5-source.tar.lz # Hash for license files: sha256 57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 COPYING diff --git a/package/mupdf/mupdf.mk b/package/mupdf/mupdf.mk index c538b9bec8..864d9f23f7 100644 --- a/package/mupdf/mupdf.mk +++ b/package/mupdf/mupdf.mk @@ -5,7 +5,7 @@ ################################################################################ # python-pymupdf's version be compatible with mupdf's version -MUPDF_VERSION = 1.23.9 +MUPDF_VERSION = 1.28.5 MUPDF_SOURCE = mupdf-$(MUPDF_VERSION)-source.tar.lz MUPDF_SITE = https://mupdf.com/downloads/archive MUPDF_LICENSE = AGPL-3.0+ @@ -21,15 +21,6 @@ MUPDF_DEPENDENCIES = \ lcms2 openjpeg \ zlib -# Fix is in libfreeglut, but CVE applied to mupdf 1.23.9. -# Buildroot libfreeglut is >3.4.0 then is not affected. -MUPDF_IGNORE_CVES = \ - CVE-2024-24258 \ - CVE-2024-24259 - -# 0001-Fix-incorrect-error-case-free-of-pixmap.patch -MUPDF_IGNORE_CVES += CVE-2026-25556 - # mupdf doesn't use CFLAGS and LIBS but XCFLAGS and XLIBS instead. # with USE_SYSTEM_LIBS it will try to use system libraries instead of the bundled ones. MUPDF_MAKE_ENV = $(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) \ @@ -45,6 +36,44 @@ ifeq ($(BR2_STATIC_LIBS),y) MUPDF_MAKE_OPTS += shared=no else MUPDF_MAKE_OPTS += shared=yes + +ifeq ($(BR2_PACKAGE_MUPDF_PYTHON_BINDINGS),y) +MUPDF_DEPENDENCIES += \ + host-clang \ + host-python-pipcl \ + host-swig \ + python3 + +MUPDF_MAKE_ENV += \ + VENV_FLAG="" \ + MUPDF_NO_AUTOVENV=1 \ + MUPDF_SETUP_USE_CLANG_PYTHON=0 \ + MUPDF_LIBCLANG_ARGS="-I$(STAGING_DIR)/usr/include -I$(HOST_DIR)/lib/clang/$(firstword $(subst ., ,$(HOST_CLANG_VERSION)))/include" \ + PIPCL_PYTHON_CONFIG="$(STAGING_DIR)/usr/bin/python3-config" + +# mupdf generates C++ code for its python bindings. As things can +# easily go wrong, increase the log level as much as we can so that we +# at least always see libclang's diagnostics: +MUPDF_MAKE_ENV += JLIB_log_levels="/:=-5" + +define MUPDF_BUILD_PYTHON_BINDINGS + $(MUPDF_MAKE_ENV) $(MAKE) -C $(@D) $(MUPDF_MAKE_OPTS) python +endef + +define MUPDF_INSTALL_PYTHON_BINDINGS_TO_STAGING + $(MUPDF_MAKE_ENV) $(MAKE) -C $(@D) $(MUPDF_MAKE_OPTS) \ + DESTDIR="$(STAGING_DIR)" pydir=/usr/lib/python$(PYTHON3_VERSION_MAJOR) install-shared-python \ + -o python -o c++ # skip rebuilding bindings +endef +define MUPDF_INSTALL_PYTHON_BINDINGS_TO_TARGET + $(MUPDF_MAKE_ENV) $(MAKE) -C $(@D) $(MUPDF_MAKE_OPTS) \ + DESTDIR="$(TARGET_DIR)" pydir=/usr/lib/python$(PYTHON3_VERSION_MAJOR) install-shared-python \ + -o python -o c++ # skip rebuilding bindings +endef +MUPDF_POST_BUILD_HOOKS += MUPDF_BUILD_PYTHON_BINDINGS +MUPDF_POST_INSTALL_STAGING_HOOKS += MUPDF_INSTALL_PYTHON_BINDINGS_TO_STAGING +MUPDF_POST_INSTALL_TARGET_HOOKS += MUPDF_INSTALL_PYTHON_BINDINGS_TO_TARGET +endif endif ifeq ($(BR2_PACKAGE_XLIB_LIBX11)$(BR2_PACKAGE_XLIB_LIBXEXT),yy) @@ -60,6 +89,12 @@ else MUPDF_MAKE_OPTS += HAVE_GLUT=no endif +ifeq ($(BR2_PACKAGE_BROTLI),y) +MUPDF_DEPENDENCIES += brotli +else +MUPDF_MAKE_OPTS += brotli=no +endif + define MUPDF_BUILD_CMDS $(MUPDF_MAKE_ENV) $(MAKE) -C $(@D) $(MUPDF_MAKE_OPTS) all endef diff --git a/package/python-pymupdf/0001-pipcl.py-allow-providing-python-config-externally.patch b/package/python-pymupdf/0001-pipcl.py-allow-providing-python-config-externally.patch deleted file mode 100644 index 95aa3f7a21..0000000000 --- a/package/python-pymupdf/0001-pipcl.py-allow-providing-python-config-externally.patch +++ /dev/null @@ -1,125 +0,0 @@ -From ca3417b8d605ccdb2e6c516c5e0c79180381627c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rapha=C3=ABl=20M=C3=A9lotte?= <raphael.melotte@mind.be> -Date: Sun, 4 Feb 2024 16:13:45 +0100 -Subject: [PATCH] pipcl.py: allow providing python-config externally -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When cross-compiling (e.g. using Buildroot), the python-config -executable that resides next to the host python executable provides -incorrect includes (the ones for the host). - -Since the correct path to python-config cannot be guessed, add an -additional environment variable to allow setting the path to the -correct python-config executable externally. - -Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> -Upstream: https://github.com/pymupdf/PyMuPDF/commit/3a214b0c144d86fd1329b26030f6b9f2a6b27020 ---- - pipcl.py | 72 +++++++++++++++++++++++++++++--------------------------- - setup.py | 3 +++ - 2 files changed, 40 insertions(+), 35 deletions(-) - -diff --git a/pipcl.py b/pipcl.py -index 209f660..c154774 100644 ---- a/pipcl.py -+++ b/pipcl.py -@@ -1789,43 +1789,45 @@ class PythonFlags: - self.ldflags = f'-L {_lib_dir}' - - else: -- # We use python-config which appears to work better than pkg-config -- # because it copes with multiple installed python's, e.g. -- # manylinux_2014's /opt/python/cp*-cp*/bin/python*. -- # -- # But... on non-macos it seems that we should not attempt to specify -- # libpython on the link command. The manylinux docker containers -- # don't actually contain libpython.so, and it seems that this -- # deliberate. And the link command runs ok. -- # -- python_exe = os.path.realpath( sys.executable) -- if darwin(): -- # Basic install of dev tools with `xcode-select --install` doesn't -- # seem to provide a `python3-config` or similar, but there is a -- # `python-config.py` accessible via sysconfig. -+ python_config = os.environ.get("PYMUPDF_PYTHON_CONFIG") -+ if not python_config: -+ # We use python-config which appears to work better than pkg-config -+ # because it copes with multiple installed python's, e.g. -+ # manylinux_2014's /opt/python/cp*-cp*/bin/python*. - # -- # We try different possibilities and use the last one that -- # works. -+ # But... on non-macos it seems that we should not attempt to specify -+ # libpython on the link command. The manylinux docker containers -+ # don't actually contain libpython.so, and it seems that this -+ # deliberate. And the link command runs ok. - # -- python_config = None -- for pc in ( -- f'python3-config', -- f'{sys.executable} {sysconfig.get_config_var("srcdir")}/python-config.py', -- f'{python_exe}-config', -- ): -- e = subprocess.run( -- f'{pc} --includes', -- shell=1, -- stdout=subprocess.DEVNULL, -- stderr=subprocess.DEVNULL, -- check=0, -- ).returncode -- log1(f'{e=} from {pc!r}.') -- if e == 0: -- python_config = pc -- assert python_config, f'Cannot find python-config' -- else: -- python_config = f'{python_exe}-config' -+ python_exe = os.path.realpath( sys.executable) -+ if darwin(): -+ # Basic install of dev tools with `xcode-select --install` doesn't -+ # seem to provide a `python3-config` or similar, but there is a -+ # `python-config.py` accessible via sysconfig. -+ # -+ # We try different possibilities and use the last one that -+ # works. -+ # -+ python_config = None -+ for pc in ( -+ f'python3-config', -+ f'{sys.executable} {sysconfig.get_config_var("srcdir")}/python-config.py', -+ f'{python_exe}-config', -+ ): -+ e = subprocess.run( -+ f'{pc} --includes', -+ shell=1, -+ stdout=subprocess.DEVNULL, -+ stderr=subprocess.DEVNULL, -+ check=0, -+ ).returncode -+ log1(f'{e=} from {pc!r}.') -+ if e == 0: -+ python_config = pc -+ assert python_config, f'Cannot find python-config' -+ else: -+ python_config = f'{python_exe}-config' - log1(f'Using {python_config=}.') - try: - self.includes = run( f'{python_config} --includes', capture=1).strip() -diff --git a/setup.py b/setup.py -index 23a5c78..4b3b5c7 100755 ---- a/setup.py -+++ b/setup.py -@@ -36,6 +36,9 @@ Environmental variables: - PYMUPDF_MUPDF_LIB - Directory containing MuPDF libraries, (libmupdf.so, - libmupdfcpp.so). -+ -+ PYMUPDF_PYTHON_CONFIG -+ Optional path to python-config. - - PYMUPDF_SETUP_IMPLEMENTATIONS - Must be one of 'a', 'b', 'ab'. If unset we use 'ab'. --- -2.41.0 - diff --git a/package/python-pymupdf/0001-src-extra-i-fix-for-swig-4-5.patch b/package/python-pymupdf/0001-src-extra-i-fix-for-swig-4-5.patch new file mode 100644 index 0000000000..1979bf9486 --- /dev/null +++ b/package/python-pymupdf/0001-src-extra-i-fix-for-swig-4-5.patch @@ -0,0 +1,25 @@ +From d2ddf9032d61f8344cd06ab2c4bb077771047e22 Mon Sep 17 00:00:00 2001 +From: Julian Smith <julian.smith@artifex.com> +Date: Sat, 22 Aug 2026 08:11:57 +0100 +Subject: [PATCH] src/extra.i: fix for swig-4.5. + +Python 2's PyString_FromString() is no longer provided by swig code. +Upstream: https://github.com/pymupdf/PyMuPDF/commit/d2ddf9032d61f8344cd06ab2c4bb077771047e22 +Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> +--- + src/extra.i | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/extra.i b/src/extra.i +index f62cdf83c..dd1670a2e 100644 +--- a/src/extra.i ++++ b/src/extra.i +@@ -225,7 +225,7 @@ static void messagev(const char* format, va_list va) + static PyObject* message_fn = PyObject_GetAttrString(pymupdf_module, "message"); + char* text; + vasprintf(&text, format, va); +- PyObject* text_py = PyString_FromString(text); ++ PyObject* text_py = PyUnicode_FromString(text); + PyObject* args = PyTuple_Pack(1, text_py); + PyObject* ret = PyObject_CallObject(message_fn, args); + Py_XDECREF(ret); diff --git a/package/python-pymupdf/Config.in b/package/python-pymupdf/Config.in index e6e7c38c9e..810d642602 100644 --- a/package/python-pymupdf/Config.in +++ b/package/python-pymupdf/Config.in @@ -3,10 +3,11 @@ config BR2_PACKAGE_PYTHON_PYMUPDF depends on BR2_INSTALL_LIBSTDCPP # mupdf -> harfbuzz depends on BR2_TOOLCHAIN_HAS_SYNC_4 # mupdf -> harfbuzz depends on BR2_TOOLCHAIN_GCC_AT_LEAST_4_9 # mupdf -> harfbuzz - depends on !BR2_STATIC_LIBS # runtime failure + depends on !BR2_STATIC_LIBS # mupdf python bindings select BR2_PACKAGE_HOST_SWIG select BR2_PACKAGE_FREETYPE select BR2_PACKAGE_MUPDF + select BR2_PACKAGE_MUPDF_PYTHON_BINDINGS select BR2_PACKAGE_PYTHON3_ZLIB # runtime help Python bindings for the PDF rendering library MuPDF. diff --git a/package/python-pymupdf/python-pymupdf.hash b/package/python-pymupdf/python-pymupdf.hash index 341366d46f..01f68da74e 100644 --- a/package/python-pymupdf/python-pymupdf.hash +++ b/package/python-pymupdf/python-pymupdf.hash @@ -1,5 +1,5 @@ # md5, sha256 from https://pypi.org/pypi/pymupdf/json -md5 5c219a0c4cb3d57b60e39cc901ebd220 PyMuPDF-1.23.22.tar.gz -sha256 c41cd91d83696cea67a4b6c65cc1951c2019ac0a561c5a3f543318ede30d3cd0 PyMuPDF-1.23.22.tar.gz +md5 ffd24ff2579b94e30151cf0e6ed95bcc pymupdf-1.28.2.tar.gz +sha256 5e0be7908a715aa20333caddd73f1d6f01e4cd0c26e869fa2dd0b7f344da2249 pymupdf-1.28.2.tar.gz # Locally computed sha256 checksums sha256 57c8ff33c9c0cfc3ef00e650a1cc910d7ee479a8bc509f6c9209a7c2a11399d6 COPYING diff --git a/package/python-pymupdf/python-pymupdf.mk b/package/python-pymupdf/python-pymupdf.mk index 1d6ad78bce..a14bad557d 100644 --- a/package/python-pymupdf/python-pymupdf.mk +++ b/package/python-pymupdf/python-pymupdf.mk @@ -5,21 +5,23 @@ ################################################################################ # python-pymupdf's version must be compatible with mupdf's version -PYTHON_PYMUPDF_VERSION = 1.23.22 -PYTHON_PYMUPDF_SOURCE = PyMuPDF-$(PYTHON_PYMUPDF_VERSION).tar.gz -PYTHON_PYMUPDF_SITE = https://files.pythonhosted.org/packages/05/20/a0d1221d8f379afcc12b4d1687a8f4adb69eef659e835d781c3fa331ff46 -PYTHON_PYMUPDF_SETUP_TYPE = setuptools +PYTHON_PYMUPDF_VERSION = 1.28.2 +PYTHON_PYMUPDF_SOURCE = pymupdf-$(PYTHON_PYMUPDF_VERSION).tar.gz +PYTHON_PYMUPDF_SITE = https://files.pythonhosted.org/packages/a3/fb/b6761fa2d5266f2cdb24c3b91f4023070ab7848381417678e7a289a1d52a +PYTHON_PYMUPDF_SETUP_TYPE = pep517 PYTHON_PYMUPDF_LICENSE = AGPL-3.0+ PYTHON_PYMUPDF_LICENSE_FILES = COPYING # No license file included in pip, but it's present on github -PYTHON_PYMUPDF_DEPENDENCIES = freetype host-swig mupdf +PYTHON_PYMUPDF_DEPENDENCIES = freetype host-python-pipcl host-swig mupdf PYTHON_PYMUPDF_BUILD_OPTS = --skip-dependency-check +# LD needs to be overriden because pipcl expects it to be a linker +# driver (e.g. gcc) and not an actual linker. PYTHON_PYMUPDF_ENV = \ + LD=$(TARGET_CC) \ PYMUPDF_INCLUDES="$(STAGING_DIR)/usr/include/freetype2:$(STAGING_DIR)/usr/include" \ PYMUPDF_MUPDF_LIB="$(STAGING_DIR)/usr/lib" \ - PYMUPDF_PYTHON_CONFIG="$(STAGING_DIR)/usr/bin/python3-config" \ - PYMUPDF_SETUP_IMPLEMENTATIONS=a \ + PIPCL_PYTHON_CONFIG="$(STAGING_DIR)/usr/bin/python3-config" \ PYMUPDF_SETUP_MUPDF_BUILD= $(eval $(python-package)) diff --git a/support/testing/tests/package/sample_python_pymupdf.py b/support/testing/tests/package/sample_python_pymupdf.py index ffcbfa1140..574bd27965 100644 --- a/support/testing/tests/package/sample_python_pymupdf.py +++ b/support/testing/tests/package/sample_python_pymupdf.py @@ -1,4 +1,4 @@ -import fitz_old as fitz +import fitz # Write a test PDF file outfile = "python-pymupdf.pdf" diff --git a/support/testing/tests/package/test_python_pymupdf.py b/support/testing/tests/package/test_python_pymupdf.py index 1af3efc8af..ac826f74ab 100644 --- a/support/testing/tests/package/test_python_pymupdf.py +++ b/support/testing/tests/package/test_python_pymupdf.py @@ -9,7 +9,7 @@ class TestPythonPy3PyMuPDF(TestPythonPackageBase): BR2_PACKAGE_PYTHON3=y BR2_PACKAGE_PYTHON_PYMUPDF=y BR2_TARGET_ROOTFS_EXT2=y - BR2_TARGET_ROOTFS_EXT2_SIZE="120M" + BR2_TARGET_ROOTFS_EXT2_SIZE="240M" """ sample_scripts = ["tests/package/sample_python_pymupdf.py"] timeout = 30 -- 2.54.0 _______________________________________________ buildroot mailing list buildroot@buildroot.org https://lists.buildroot.org/mailman/listinfo/buildroot ^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-10-07 11:02 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-30 12:00 [Buildroot] [PATCH 1/2] package/python-pipcl: new host package Raphaël Mélotte via buildroot 2026-09-30 12:00 ` [Buildroot] [PATCH 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 Raphaël Mélotte via buildroot 2026-10-01 5:52 ` Waldemar Brodkorb 2026-10-04 15:41 ` Thomas Petazzoni via buildroot 2026-10-05 12:47 ` Raphaël Mélotte via buildroot 2026-10-05 15:50 ` Thomas Petazzoni via buildroot 2026-10-07 10:46 ` Raphaël Mélotte via buildroot 2026-10-04 15:38 ` [Buildroot] [PATCH 1/2] package/python-pipcl: new host package Thomas Petazzoni via buildroot 2026-10-05 12:39 ` Raphaël Mélotte via buildroot 2026-10-05 15:40 ` [Buildroot] [PATCH v2 " Raphaël Mélotte via buildroot 2026-10-05 15:40 ` [Buildroot] [PATCH v2 2/2] package/mupdf, python-pymupdf: bump to versions 1.28.5 and 1.28.2 Raphaël Mélotte via buildroot
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.