Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
3221836
Improve build script for cibuildwheel
mara004 Aug 7, 2025
2d53122
build_native: rework control flow to avoid globals
mara004 Aug 8, 2025
62739f9
Add RedHat patches for big-endian CPUs
mara004 Aug 8, 2025
981baac
build_native: factor out --vendor option
mara004 Aug 8, 2025
30ed5d7
build_native: drop default ICU vendoring w/ cibuildwheel
mara004 Aug 8, 2025
31d99cc
Add comments
mara004 Aug 8, 2025
5d9471f
Fix copy/paste blunder in bigendian.patch
mara004 Aug 9, 2025
3a0ccff
base.py: update a comment
mara004 Aug 9, 2025
cda3478
Merge remote-tracking branch 'origin/main' into cibuildwheel
mara004 Aug 10, 2025
c64a883
Merge remote-tracking branch 'origin/main' into cibuildwheel
mara004 Aug 12, 2025
02ab319
Experimental: draft cibuildwheel workflow
mara004 Aug 12, 2025
c6412f7
continue on workflow
mara004 Aug 12, 2025
f59d102
continue
mara004 Aug 12, 2025
8e7e985
continue
mara004 Aug 12, 2025
0c34dc4
fix CIBW_TEST_COMMAND
mara004 Aug 12, 2025
b973d89
Use `>` rather than `|` with `\`
mara004 Aug 12, 2025
bc94169
don't bother with test suite for now
mara004 Aug 12, 2025
e39c64e
add trailing newline
mara004 Aug 12, 2025
6e3c99a
comment out risc and loongarch
mara004 Aug 12, 2025
c23b765
comments
mara004 Aug 12, 2025
2a03b1b
Attempt to use dynamic matrix
mara004 Aug 15, 2025
65b8ac1
XXX debug matrix
mara004 Aug 15, 2025
ff7e0dd
add missing needs: prepare_matrix
mara004 Aug 15, 2025
4da0fe9
shorter names
mara004 Aug 15, 2025
b15b3a0
IS_CI: recognize cibuildwheel
mara004 Aug 15, 2025
d0c12e0
q&d fix
mara004 Aug 15, 2025
2281415
continue
mara004 Aug 15, 2025
f31561c
continue on docs
mara004 Aug 15, 2025
e398de2
fix missing `&&`
mara004 Aug 15, 2025
dab2dec
take pytest from pypi after all
mara004 Aug 15, 2025
3e8fb55
update docs
mara004 Aug 15, 2025
941b53a
add {project} placeholder
mara004 Aug 15, 2025
f7effae
switch back to `|` after all
mara004 Aug 15, 2025
8c02292
Make matrix generator script nicer
mara004 Aug 15, 2025
797d203
take out test suite after all
mara004 Aug 15, 2025
99fecf6
take out spdx snippet info after all
mara004 Aug 15, 2025
6d4ad89
readme nit
mara004 Aug 15, 2025
76d7e60
cibuildwheel: use oldest possible version of python
mara004 Aug 15, 2025
1173980
comment out riscv64
mara004 Aug 15, 2025
e633929
single-line import
mara004 Aug 15, 2025
735e34d
experimental: move config to pyproject.toml and extend
mara004 Aug 16, 2025
000c397
experimental: enable musllinux
mara004 Aug 16, 2025
f2bfd31
update docs
mara004 Aug 16, 2025
ad8ed7a
experimental: expose musl in workflow
mara004 Aug 16, 2025
5dae578
update doc line
mara004 Aug 16, 2025
820cdb5
symlinks only on manylinux
mara004 Aug 16, 2025
0121463
continue
mara004 Aug 16, 2025
d5de1e0
fix artifact name
mara004 Aug 16, 2025
191ed60
attempt to fix symlinks
mara004 Aug 16, 2025
5efa9bd
add comment
mara004 Aug 16, 2025
ee83b60
symlinks for musllinux
mara004 Aug 16, 2025
e9165a3
unlock riscv64 on musl
mara004 Aug 16, 2025
94d70e3
Fix symlinks for loongarch64
mara004 Aug 16, 2025
581132a
enable symlinks for riscv64
mara004 Aug 16, 2025
5f17127
test commit
mara004 Aug 16, 2025
27427c2
see if installing gcc helps
mara004 Aug 16, 2025
de85d51
debug
mara004 Aug 16, 2025
2c87f76
fix
mara004 Aug 16, 2025
e81a5fc
move
mara004 Aug 16, 2025
9ef117c
reinstall loongarch64
mara004 Aug 16, 2025
6ed6146
move after all
mara004 Aug 16, 2025
ab913ca
continue on cibuildwheel config
mara004 Aug 18, 2025
e21cf25
run test suite on manylinux only
mara004 Aug 18, 2025
09fc9c3
continue on readme
mara004 Aug 18, 2025
15a8cd9
Add 'windows-11-arm' to test matrices
mara004 Aug 19, 2025
2f2b909
add musl armv7l to cibuildwheel workflow
mara004 Aug 19, 2025
f586901
Try to enable manylinux riscv64, add draft macos config (commented out)
mara004 Aug 19, 2025
2aedfd3
continue
mara004 Aug 19, 2025
cadc9e3
use curl instead of wget
mara004 Aug 19, 2025
a014684
Attempt to fix symlinks for armv7l musl
mara004 Aug 19, 2025
484b892
attempt to fix curl usage
mara004 Aug 19, 2025
573f709
attempt to fix risc symlinks
mara004 Aug 19, 2025
a7733d6
Remove outdated note
mara004 Aug 19, 2025
bce5a95
Experiment with macOS
mara004 Aug 20, 2025
b981b59
fix image name
mara004 Aug 20, 2025
ad6e8fc
attempt to set clang path
mara004 Aug 20, 2025
2cf6f8e
cast compiler from string
mara004 Aug 20, 2025
19bf0e5
also cast clang_path to Path
mara004 Aug 20, 2025
b2b1969
Get clang version in a (hopefully) more portable way
mara004 Aug 20, 2025
8a2949a
try different preamble for apple
mara004 Aug 20, 2025
eeda583
another attempt at clang version
mara004 Aug 20, 2025
d882f24
Set Fixme
mara004 Aug 20, 2025
31b8520
try setting long clang path
mara004 Aug 20, 2025
9de9b97
pass through mac deployment target from env
mara004 Aug 20, 2025
214749f
Change clang path back to /usr
mara004 Aug 20, 2025
9c3d6a6
Cleanup
mara004 Aug 21, 2025
808f5d1
continue
mara004 Aug 21, 2025
fc05f03
continue 2
mara004 Aug 21, 2025
853c652
codespell: fix typo
mara004 Aug 21, 2025
feb0c84
workflows: setup-just does not work on windows 11 arm
mara004 Aug 21, 2025
41e4763
Exclude unsupported windows arm python versions
mara004 Aug 21, 2025
7b6b9a2
conda: take out windows arm after all
mara004 Aug 21, 2025
092da23
readme
mara004 Aug 21, 2025
3295996
document gcc symlinks
mara004 Aug 21, 2025
9c61cf5
changelog nits
mara004 Aug 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .github/workflows/cibuildwheel.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# SPDX-FileCopyrightText: 2025 wojiushixiaobai <[email protected]>
# SPDX-FileCopyrightText: 2025 geisserml <[email protected]>
# SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause

name: Build with cibuildwheel
on:
workflow_dispatch:
inputs:
cibw_py_ver:
default: 'cp312'
type: string
existing:
default: true
type: boolean
ibm:
default: true
type: boolean
# emulated:
# default: false
# type: boolean

permissions: {}

jobs:

build_wheels:
name: Build wheel for ${{ matrix.arch }} ${{ matrix.image }} (runs on ${{ matrix.os }})
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
# GitHub doesn't seem to have a proper way to make conditional matrix entries,
# so we have to use an `enabled` property and check it on each step (nasty).
include:
- os: ubuntu-24.04
arch: x86_64
image: manylinux
enabled: ${{ inputs.existing }}
needs_emulator: false
- os: ubuntu-24.04-arm
arch: aarch64
image: manylinux
enabled: ${{ inputs.existing }}
needs_emulator: false
# ppc64le and s390x will become native as soon as we get access to IBM's self-hosted runners
- os: ubuntu-24.04
arch: ppc64le
image: manylinux
enabled: ${{ inputs.ibm }}
needs_emulator: true # false
- os: ubuntu-24.04
arch: s390x
image: manylinux
enabled: ${{ inputs.ibm }}
needs_emulator: true # false
# XXX riscv64 container does not have gn dependency, failing. TODO see if we can procure a pre-build somewhere else.
# - os: ubuntu-24.04
# arch: riscv64
# image: manylinux
# enabled: ${{ inputs.emulated }}
# needs_emulator: true
# XXX loongarch64 needs patched fork of cibuildwheel, but GH Actions don't support conditional `uses:` expressions. Could use the fork for all, but would prefer not to do that. Could duplicate the cibuildwheel step, or the entire workflow, but neither is nice.
# NOTE the loongarch64 container probably won't have gn either, but we can pull it from https://github.com/loong64/gn/releases/latest/download/gn-linux-loong64.tar.gz
# - os: ubuntu-24.04
# arch: loongarch64
# image: manylinux
# enabled: ${{ inputs.emulated }}
# needs_emulator: true

steps:

- name: Check out the repo
if: ${{ matrix.enabled }}
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up QEMU
if: ${{ matrix.enabled && matrix.needs_emulator }}
uses: docker/setup-qemu-action@v3

- name: Build wheels
if: ${{ matrix.enabled }}
uses: pypa/[email protected] # loong64/[email protected]
env:
CIBW_ARCHS: ${{ matrix.arch }}
# Will be tagged as not python specific by our setup.py. inputs.cibw_py_ver only controls the version used at build time. Could also use `*`, then cibuildwheel would build with the oldest supported version, and walk through the others but skip because a compatible wheel is around already.
CIBW_BUILD: "${{ inputs.cibw_py_ver }}-${{ matrix.image }}_${{ matrix.arch }}"
# the symlinks are required on aarch64 and loongarch64
CIBW_BEFORE_ALL_LINUX: >
dnf -y install gn ninja-build freetype-devel glib2-devel lcms2-devel libjpeg-devel libpng-devel libtiff-devel openjpeg2-devel zlib-devel &&
ln -s /opt/rh/gcc-toolset-14/root/bin/gcc /opt/rh/gcc-toolset-14/root/bin/${{ matrix.arch }}-linux-gnu-gcc &&
ln -s /opt/rh/gcc-toolset-14/root/bin/g++ /opt/rh/gcc-toolset-14/root/bin/${{ matrix.arch }}-linux-gnu-g++ &&
ln -s /opt/rh/gcc-toolset-14/root/bin/readelf /opt/rh/gcc-toolset-14/root/bin/${{ matrix.arch }}-linux-gnu-readelf &&
ln -s /opt/rh/gcc-toolset-14/root/bin/nm /opt/rh/gcc-toolset-14/root/bin/${{ matrix.arch }}-linux-gnu-nm
CIBW_BEFORE_BUILD: python setupsrc/pypdfium2_setup/build_native.py --vendor icu
CIBW_ENVIRONMENT: PDFIUM_PLATFORM=sourcebuild
# TODO would like to run the test suite too, but not sure how to get the dependencies: CIBW_TEST_REQUIRES assumably takes them from PyPI, which won't work with the exotic architectures. And if we take them from the system with CIBW_BEFORE_TEST, they're not recognized because cibuildwheel sets up a venv or something.
CIBW_TEST_COMMAND: python -m pypdfium2 --version
with:
output-dir: wheelhouse

- uses: actions/upload-artifact@v4
if: ${{ matrix.enabled }}
with:
path: ./wheelhouse/*.whl
name: pypdfium2-wheel-${{ matrix.arch }}
2 changes: 1 addition & 1 deletion .github/workflows/conda.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:
default: 'latest'
type: string
new_only:
# only with package == "raw", ignored otherwise (actually the default should be false in that case, but I don't know if GH supports dynamic defaults depending on other inputs)
# only with package == "raw", ignored otherwise (actually the default should be false in that case, but don't know if GH supports dynamic defaults depending on other inputs)
default: true
type: boolean
test:
Expand Down
25 changes: 25 additions & 0 deletions REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,31 @@ SPDX-FileCopyrightText = [
]
SPDX-License-Identifier = "BSD-3-Clause OR Apache-2.0"

[[annotations]]
path = "pdfium_patches/cibuildwheel.patch"
precedence = "aggregate"
SPDX-FileCopyrightText = [
"2025 wojiushixiaobai <[email protected]>",
"2025 geisserml <[email protected]>",
]
SPDX-License-Identifier = "BSD-3-Clause OR Apache-2.0"

[[annotations]]
path = [
"pdfium_patches/bigendian.patch",
"pdfium_patches/bigendian_test.patch",
]
precedence = "aggregate"
SPDX-FileCopyrightText = [
"2025 Christian Heimes <[email protected]>",
"2025 geisserml <[email protected]>",
]
SPDX-License-Identifier = "LicenseRef-Ignore"
SPDX-FileComment = '''
Derived from RedHat packaging repository: https://github.com/tiran/libpdfium/blob/d99370b3ac7f0c9cd7222be2dfab2c7b648f2e9e/0001-bigendian.patch
Repo does not have an own license file, but assumably the patches are being made available under pdfium's license, or leastways an open-source license.
'''

[[annotations]]
path = [
"docs/build/.gitkeep",
Expand Down
40 changes: 40 additions & 0 deletions pdfium_patches/bigendian.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
diff --git a/core/fxcrt/cfx_seekablestreamproxy.cpp b/core/fxcrt/cfx_seekablestreamproxy.cpp
index 33cc528..95dc752 100644
--- a/core/fxcrt/cfx_seekablestreamproxy.cpp
+++ b/core/fxcrt/cfx_seekablestreamproxy.cpp
@@ -89,11 +89,19 @@ void SwapByteOrder(pdfium::span<uint16_t> str) {

} // namespace

+#if defined(ARCH_CPU_LITTLE_ENDIAN)
#define BOM_UTF8_MASK 0x00FFFFFF
#define BOM_UTF8 0x00BFBBEF
#define BOM_UTF16_MASK 0x0000FFFF
#define BOM_UTF16_BE 0x0000FFFE
#define BOM_UTF16_LE 0x0000FEFF
+#else
+#define BOM_UTF8_MASK 0xFFFFFF00
+#define BOM_UTF8 0xEFBBBF00
+#define BOM_UTF16_MASK 0xFFFF0000
+#define BOM_UTF16_BE 0xFEFF0000
+#define BOM_UTF16_LE 0xFFFE0000
+#endif

CFX_SeekableStreamProxy::CFX_SeekableStreamProxy(
const RetainPtr<IFX_SeekableReadStream>& stream)
@@ -188,9 +196,15 @@ size_t CFX_SeekableStreamProxy::ReadBlock(pdfium::span<wchar_t> buffer) {
size_t bytes_read =
ReadData(pdfium::as_writable_bytes(buffer).first(bytes_to_read));
size_t elements = bytes_read / sizeof(uint16_t);
+#if defined(ARCH_CPU_LITTLE_ENDIAN)
if (code_page_ == FX_CodePage::kUTF16BE) {
SwapByteOrder(fxcrt::reinterpret_span<uint16_t>(buffer).first(elements));
}
+#else
+ if (code_page_ == FX_CodePage::kUTF16LE) {
+ SwapByteOrder(fxcrt::reinterpret_span<uint16_t>(buffer).first(elements));
+ }
+#endif
UTF16ToWChar(buffer.first(elements));
return elements;
}
29 changes: 29 additions & 0 deletions pdfium_patches/bigendian_test.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--- a/core/fxcrt/binary_buffer_unittest.cpp
+++ b/core/fxcrt/binary_buffer_unittest.cpp
@@ -3,6 +3,7 @@
// found in the LICENSE file.

#include "core/fxcrt/binary_buffer.h"
+#include "core/fxcrt/byteorder.h"

#include <utility>
#include <vector>
@@ -122,7 +123,7 @@
// Assumes little endian.
TEST(BinaryBuffer, AppendUint16) {
BinaryBuffer buffer;
- buffer.AppendUint16(0x4321);
+ buffer.AppendUint16(FromLE16(0x4321));
EXPECT_EQ(2u, buffer.GetSize());
EXPECT_EQ(2u, buffer.GetLength());
EXPECT_EQ(0x21u, buffer.GetSpan()[0]);
@@ -132,7 +133,7 @@
// Assumes little endian.
TEST(BinaryBuffer, AppendUint32) {
BinaryBuffer buffer;
- buffer.AppendUint32(0x87654321);
+ buffer.AppendUint32(FromLE32(0x87654321));
EXPECT_EQ(4u, buffer.GetSize());
EXPECT_EQ(4u, buffer.GetLength());
EXPECT_EQ(0x21u, buffer.GetSpan()[0]);

29 changes: 29 additions & 0 deletions pdfium_patches/cibuildwheel.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
diff --git a/core/fxcodec/jpx/cjpx_decoder.cpp b/core/fxcodec/jpx/cjpx_decoder.cpp
index 4650609..1eadfd5 100644
--- a/core/fxcodec/jpx/cjpx_decoder.cpp
+++ b/core/fxcodec/jpx/cjpx_decoder.cpp
@@ -493,9 +493,11 @@ bool CJPX_Decoder::Init(pdfium::span<const uint8_t> src_data,
}

// For https://crbug.com/42270564
+ /* OpenJPEG 2.5 API
if (!strict_mode) {
CHECK(opj_decoder_set_strict_mode(codec_.get(), false));
}
+ */

opj_image_t* pTempImage = nullptr;
if (!opj_read_header(stream_.get(), codec_.get(), &pTempImage)) {
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp
index fa02d5b..bfa21d3 100644
--- a/core/fxge/cfx_face.cpp
+++ b/core/fxge/cfx_face.cpp
@@ -659,7 +659,7 @@ int CFX_Face::GetCharIndex(uint32_t code) {
}

int CFX_Face::GetNameIndex(const char* name) {
- return FT_Get_Name_Index(GetRec(), name);
+ return FT_Get_Name_Index(GetRec(), const_cast<char*>(name));
}

FX_RECT CFX_Face::GetCharBBox(uint32_t code, int glyph_index) {
3 changes: 1 addition & 2 deletions setupsrc/pypdfium2_setup/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,7 @@ def to_full(self, v_short):

@cached_property
def pinned(self):
# comments are not permitted in JSON, so the reason for the post_pdfium pin (if set) goes here:
# 7309 is the latest tested version. 6996 is too old because we use FPDFFormObj_RemoveObject() which first arrived in 7191.
# comments are not permitted in JSON, so the reason for the post_pdfium pin (if set) goes here: (currently no post_pdfium pin)
record = read_json(AR_RecordFile)
return record["post_pdfium"] or record["pdfium"]

Expand Down
Loading