Skip to content

Commit ebe5589

Browse files
scripts/gh_release.py: Support building with Py_LIMITED_API.
When enabled, we build generic wheel with python-3.8, then use it for build+test of all python versions using a second invocation of cibuildwheel.
1 parent 88a47a7 commit ebe5589

File tree

1 file changed

+57
-7
lines changed

1 file changed

+57
-7
lines changed

scripts/gh_release.py

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@
5252
Used to directly set PYMUPDF_SETUP_MUPDF_BUILD.
5353
E.g. 'git:--recursive --depth 1 --shallow-submodules --branch master https://github.com/ArtifexSoftware/mupdf.git'
5454
inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE
55-
Used to directly set PYMUPDF_SETUP_MUPDF_BUILD_TYPE.
55+
Used to directly set PYMUPDF_SETUP_MUPDF_BUILD_TYPE. Note that as of
56+
2024-09-10 .github/workflows/build_wheels.yml does not set this.
57+
Py_LIMITED_API
58+
If specified we build a single wheel for all python versions using the Python Limited API.
5659
5760
Building for Pyodide
5861
@@ -65,6 +68,11 @@
6568
with CC etc set up to create Pyodide binaries in a wheel called, for
6669
example, `PyMuPDF-1.23.2-cp311-none-emscripten_3_1_32_wasm32.whl`.
6770
71+
Set up for use outside Github
72+
73+
sudo apt install docker.io
74+
sudo usermod -aG docker $USER
75+
6876
Example usage:
6977
7078
PYMUPDF_SETUP_MUPDF_BUILD=../mupdf py -3.9-32 PyMuPDF/scripts/gh_release.py venv build-devel
@@ -192,6 +200,8 @@ def get_bool(name, default=0):
192200
inputs_PYMUPDF_SETUP_MUPDF_BUILD = os.environ.get('inputs_PYMUPDF_SETUP_MUPDF_BUILD')
193201
inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE = os.environ.get('inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE')
194202

203+
PYMUPDF_SETUP_Py_LIMITED_API = os.environ.get('PYMUPDF_SETUP_Py_LIMITED_API')
204+
195205
log( f'{inputs_flavours=}')
196206
log( f'{inputs_sdist=}')
197207
log( f'{inputs_skeleton=}')
@@ -205,6 +215,7 @@ def get_bool(name, default=0):
205215
log( f'{inputs_wheels_cps=}')
206216
log( f'{inputs_PYMUPDF_SETUP_MUPDF_BUILD=}')
207217
log( f'{inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE=}')
218+
log( f'{PYMUPDF_SETUP_Py_LIMITED_API=}')
208219

209220
# Build Pyodide wheel if specified.
210221
#
@@ -254,7 +265,7 @@ def set_if_unset(name, value):
254265
env_extra[ name] = value
255266
else:
256267
log( f'Not changing {name}={v!r} to {value!r}')
257-
set_if_unset( 'CIBW_BUILD_VERBOSITY', '3')
268+
set_if_unset( 'CIBW_BUILD_VERBOSITY', '1')
258269
# We exclude pp* because of `fitz_wrap.obj : error LNK2001: unresolved
259270
# external symbol PyUnicode_DecodeRawUnicodeEscape`.
260271
# 2024-06-05: musllinux on aarch64 fails because libclang cannot find
@@ -337,7 +348,7 @@ def env_pass(name):
337348
def env_set(name, value, pass_=False):
338349
assert isinstance( value, str)
339350
if not name.startswith('CIBW'):
340-
assert pass_, f'{name=} {value=}'
351+
assert pass_, f'Non-CIBW* name requires `pass_` to be true. {name=} {value=}.'
341352
env_extra[ name] = value
342353
if pass_:
343354
env_pass(name)
@@ -373,7 +384,44 @@ def set_cibuild_test():
373384
# We include MuPDF build-time files.
374385
flavour_d = True
375386

376-
if inputs_flavours:
387+
if PYMUPDF_SETUP_Py_LIMITED_API:
388+
# Build one wheel with oldest python, then fake build with other python
389+
# versions so we test everything.
390+
log(f'{PYMUPDF_SETUP_Py_LIMITED_API=}')
391+
env_pass('PYMUPDF_SETUP_Py_LIMITED_API')
392+
# This isn't actually necessary - PYMUPDF_SETUP_Py_LIMITED_API is
393+
# already in the environment - but we set it anyway for clarity.
394+
env_set('PYMUPDF_SETUP_Py_LIMITED_API', PYMUPDF_SETUP_Py_LIMITED_API, pass_=1)
395+
CIBW_BUILD_old = env_extra.get('CIBW_BUILD')
396+
assert CIBW_BUILD_old is not None
397+
env_set('CIBW_BUILD', 'cp38*')
398+
log(f'Building single wheel.')
399+
run( f'cibuildwheel{platform_arg}', env_extra=env_extra)
400+
401+
# Fake-build with all python versions, using the wheel we have
402+
# just created. This works by setting PYMUPDF_SETUP_URL_WHEEL
403+
# which makes PyMuPDF's setup.py copy an existing wheel instead
404+
# of building a wheel itself; it also copes with existing
405+
# wheels having extra platform tags (from cibuildwheel's use of
406+
# auditwheel).
407+
#
408+
env_set('PYMUPDF_SETUP_URL_WHEEL', f'file://wheelhouse/', pass_=True)
409+
410+
set_cibuild_test()
411+
env_set('CIBW_BUILD', CIBW_BUILD_old)
412+
413+
# Disable cibuildwheels use of auditwheel. The wheel was repaired
414+
# when it was created above so we don't need to do so again. This
415+
# also avoids problems with musl wheels on a Linux glibc host where
416+
# auditwheel fails with: `ValueError: Cannot repair wheel, because
417+
# required library "libgcc_s-a3a07607.so.1" could not be located`.
418+
#
419+
env_set('CIBW_REPAIR_WHEEL_COMMAND', '')
420+
421+
log(f'Testing on all python versions using wheels in wheelhouse/.')
422+
run( f'cibuildwheel{platform_arg}', env_extra=env_extra)
423+
424+
elif inputs_flavours:
377425
# Build and test PyMuPDF and PyMuPDFb wheels.
378426
#
379427

@@ -734,13 +782,15 @@ def run(command, env_extra=None, check=1, timeout=None):
734782
leave processes running if timeout expires.
735783
'''
736784
env = None
737-
message = 'Running:'
785+
message = 'Running: '
738786
if env_extra:
739787
env = os.environ.copy()
740788
env.update(env_extra)
789+
message += '\n[environment:\n'
741790
for n, v in env_extra.items():
742-
message += f' {n}={v}'
743-
message += f' {command}'
791+
message += f' {n}={shlex.quote(v)}\n'
792+
message += ']\n'
793+
message += f'{command}'
744794
log(message, caller=1)
745795
return subprocess.run(command, check=check, shell=1, env=env, timeout=timeout)
746796

0 commit comments

Comments
 (0)