Skip to content

Commit 3747f5f

Browse files
authored
Update 3.9 patch with recent changes (#264)
* Adds recent iOS patches from 3.14 development * Adds CI workflow changes from main branch * Adds modulemap generation * Adds new-style platform-site handling
1 parent 9c15787 commit 3747f5f

16 files changed

+652
-543
lines changed

.github/workflows/ci.yaml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
name: CI
22
on:
33
pull_request:
4-
push:
5-
branches:
6-
- main
7-
- 3.*
84
workflow_call:
95
inputs:
106
build-number:
@@ -103,19 +99,22 @@ jobs:
10399
- uses: actions/[email protected]
104100

105101
- name: Set up Python
106-
uses: actions/setup-python@v5.3.0
102+
uses: actions/setup-python@v5.4.0
107103
with:
108104
# Appending -dev ensures that we can always build the dev release.
109105
# It's a no-op for versions that have been published.
110106
python-version: ${{ needs.config.outputs.PYTHON_VER }}-dev
107+
# Ensure that we *always* use the latest build, not a cached version.
108+
# It's an edge case, but when a new alpha is released, we need to use it ASAP.
109+
check-latest: true
111110

112111
- name: Build ${{ matrix.target }}
113112
run: |
114113
# Do the build for the requested target.
115114
make ${{ matrix.target }} BUILD_NUMBER=${{ needs.config.outputs.BUILD_NUMBER }}
116115
117116
- name: Upload build artefacts
118-
uses: actions/upload-artifact@v4.4.3
117+
uses: actions/upload-artifact@v4.6.1
119118
with:
120119
name: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
121120
path: dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz

.github/workflows/publish.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
- uses: actions/checkout@v4
1212

1313
- name: Set up Python environment
14-
uses: actions/setup-python@v5.3.0
14+
uses: actions/setup-python@v5.4.0
1515
with:
1616
python-version: "3.X"
1717

.github/workflows/release.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ jobs:
4040
needs: [ config, ci ]
4141
steps:
4242
- name: Get build artifacts
43-
uses: actions/[email protected].8
43+
uses: actions/[email protected].9
4444
with:
4545
pattern: Python-*
4646
path: dist
4747
merge-multiple: true
4848

4949
- name: Create Release
50-
uses: ncipollo/release-action@v1.14.0
50+
uses: ncipollo/release-action@v1.16.0
5151
with:
5252
name: ${{ needs.ci.outputs.PYTHON_VER }}-${{ needs.config.outputs.BUILD_NUMBER }}
5353
tag: ${{ needs.ci.outputs.PYTHON_VER }}-${{ needs.config.outputs.BUILD_NUMBER }}

Makefile

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ PYTHON_VER=$(basename $(PYTHON_VERSION))
2727
# The binary releases of dependencies, published at:
2828
# https://github.com/beeware/cpython-apple-source-deps/releases
2929
BZIP2_VERSION=1.0.8-1
30-
LIBFFI_VERSION=3.4.6-1
31-
OPENSSL_VERSION=3.0.15-1
32-
XZ_VERSION=5.6.2-1
30+
LIBFFI_VERSION=3.4.7-1
31+
OPENSSL_VERSION=3.0.16-1
32+
XZ_VERSION=5.6.4-1
3333

3434
# Supported OS
3535
OS_LIST=macOS iOS tvOS watchOS
@@ -128,10 +128,10 @@ ARCH-$(target)=$$(subst .,,$$(suffix $(target)))
128128
ifneq ($(os),macOS)
129129
ifeq ($$(findstring simulator,$$(SDK-$(target))),)
130130
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))
131-
IS_SIMULATOR-$(target)="False"
131+
IS_SIMULATOR-$(target)=False
132132
else
133133
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))-simulator
134-
IS_SIMULATOR-$(target)="True"
134+
IS_SIMULATOR-$(target)=True
135135
endif
136136
endif
137137

@@ -240,6 +240,9 @@ PYTHON_LIB-$(target)=$$(PYTHON_FRAMEWORK-$(target))/Python
240240
PYTHON_BIN-$(target)=$$(PYTHON_INSTALL-$(target))/bin
241241
PYTHON_INCLUDE-$(target)=$$(PYTHON_FRAMEWORK-$(target))/Headers
242242
PYTHON_STDLIB-$(target)=$$(PYTHON_INSTALL-$(target))/lib/python$(PYTHON_VER)
243+
PYTHON_PLATFORM_CONFIG-$(target)=$$(PYTHON_INSTALL-$(target))/platform-config/$$(ARCH-$(target))-$$(SDK-$(target))
244+
PYTHON_PLATFORM_SITECUSTOMIZE-$(target)=$$(PYTHON_PLATFORM_CONFIG-$(target))/sitecustomize.py
245+
243246

244247
$$(PYTHON_SRCDIR-$(target))/configure: \
245248
downloads/Python-$(PYTHON_VERSION).tar.gz \
@@ -292,23 +295,35 @@ $$(PYTHON_LIB-$(target)): $$(PYTHON_SRCDIR-$(target))/python.exe
292295
# Remove any .orig files produced by the compliance patching process
293296
find $$(PYTHON_INSTALL-$(target)) -name "*.orig" -exec rm {} \;
294297

295-
endif
296-
297-
PYTHON_SITECUSTOMIZE-$(target)=$(PROJECT_DIR)/support/$(PYTHON_VER)/$(os)/platform-site/$(target)/sitecustomize.py
298298

299-
$$(PYTHON_SITECUSTOMIZE-$(target)):
300-
@echo ">>> Create cross-platform sitecustomize.py for $(target)"
301-
mkdir -p $$(dir $$(PYTHON_SITECUSTOMIZE-$(target)))
302-
cat $(PROJECT_DIR)/patch/Python/sitecustomize.$(os).py \
299+
$$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target)):
300+
@echo ">>> Create cross-plaform config for $(target)"
301+
mkdir -p $$(PYTHON_PLATFORM_CONFIG-$(target))
302+
# Create the cross-platform site definition
303+
echo "import _cross_$$(ARCH-$(target))_$$(SDK-$(target)); import _cross_venv;" \
304+
> $$(PYTHON_PLATFORM_CONFIG-$(target))/_cross_venv.pth
305+
cp $(PROJECT_DIR)/patch/Python/make_cross_venv.py \
306+
$$(PYTHON_PLATFORM_CONFIG-$(target))/make_cross_venv.py
307+
cp $(PROJECT_DIR)/patch/Python/_cross_venv.py \
308+
$$(PYTHON_PLATFORM_CONFIG-$(target))/_cross_venv.py
309+
cp $$(PYTHON_STDLIB-$(target))/_sysconfig* \
310+
$$(PYTHON_PLATFORM_CONFIG-$(target))
311+
cat $(PROJECT_DIR)/patch/Python/_cross_target.py.tmpl \
303312
| sed -e "s/{{os}}/$(os)/g" \
313+
| sed -e "s/{{platform}}/$$(OS_LOWER-$(target))/g" \
304314
| sed -e "s/{{arch}}/$$(ARCH-$(target))/g" \
315+
| sed -e "s/{{sdk}}/$$(SDK-$(target))/g" \
305316
| sed -e "s/{{version_min}}/$$(VERSION_MIN-$(os))/g" \
306317
| sed -e "s/{{is_simulator}}/$$(IS_SIMULATOR-$(target))/g" \
307-
| sed -e "s/{{multiarch}}/$$(ARCH-$(target))-$$(SDK-$(target))/g" \
308-
| sed -e "s/{{tag}}/$$(OS_LOWER-$(target))-$$(VERSION_MIN-$(os))-$$(ARCH-$(target))-$$(SDK-$(target))/g" \
309-
> $$(PYTHON_SITECUSTOMIZE-$(target))
318+
> $$(PYTHON_PLATFORM_CONFIG-$(target))/_cross_$$(ARCH-$(target))_$$(SDK-$(target)).py
319+
cat $(PROJECT_DIR)/patch/Python/sitecustomize.py.tmpl \
320+
| sed -e "s/{{arch}}/$$(ARCH-$(target))/g" \
321+
| sed -e "s/{{sdk}}/$$(SDK-$(target))/g" \
322+
> $$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target))
323+
324+
endif
310325

311-
$(target): $$(PYTHON_SITECUSTOMIZE-$(target)) $$(PYTHON_LIB-$(target))
326+
$(target): $$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target)) $$(PYTHON_LIB-$(target))
312327

313328
###########################################################################
314329
# Target: Debug
@@ -335,6 +350,8 @@ vars-$(target):
335350
@echo "PYTHON_BIN-$(target): $$(PYTHON_BIN-$(target))"
336351
@echo "PYTHON_INCLUDE-$(target): $$(PYTHON_INCLUDE-$(target))"
337352
@echo "PYTHON_STDLIB-$(target): $$(PYTHON_STDLIB-$(target))"
353+
@echo "PYTHON_PLATFORM_CONFIG-$(target): $$(PYTHON_PLATFORM_CONFIG-$(target))"
354+
@echo "PYTHON_PLATFORM_SITECUSTOMIZE-$(target): $$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target))"
338355
@echo
339356

340357
endef # build-target
@@ -380,6 +397,7 @@ PYTHON_FRAMEWORK-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/Python.framework
380397
PYTHON_INSTALL_VERSION-$(sdk)=$$(PYTHON_FRAMEWORK-$(sdk))/Versions/$(PYTHON_VER)
381398
PYTHON_LIB-$(sdk)=$$(PYTHON_INSTALL_VERSION-$(sdk))/Python
382399
PYTHON_INCLUDE-$(sdk)=$$(PYTHON_INSTALL_VERSION-$(sdk))/include/python$(PYTHON_VER)
400+
PYTHON_MODULEMAP-$(sdk)=$$(PYTHON_INCLUDE-$(sdk))/module.modulemap
383401
PYTHON_STDLIB-$(sdk)=$$(PYTHON_INSTALL_VERSION-$(sdk))/lib/python$(PYTHON_VER)
384402

385403
else
@@ -390,11 +408,13 @@ else
390408
# The non-macOS frameworks don't use the versioning structure.
391409

392410
PYTHON_INSTALL-$(sdk)=$(PROJECT_DIR)/install/$(os)/$(sdk)/python-$(PYTHON_VERSION)
411+
PYTHON_MODULEMAP-$(sdk)=$$(PYTHON_INCLUDE-$(sdk))/module.modulemap
393412
PYTHON_FRAMEWORK-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/Python.framework
394413
PYTHON_LIB-$(sdk)=$$(PYTHON_FRAMEWORK-$(sdk))/Python
395414
PYTHON_BIN-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/bin
396415
PYTHON_INCLUDE-$(sdk)=$$(PYTHON_FRAMEWORK-$(sdk))/Headers
397416
PYTHON_STDLIB-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/lib/python$(PYTHON_VER)
417+
PYTHON_PLATFORM_CONFIG-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/platform-config
398418

399419
$$(PYTHON_LIB-$(sdk)): $$(foreach target,$$(SDK_TARGETS-$(sdk)),$$(PYTHON_LIB-$$(target)))
400420
@echo ">>> Build Python fat library for the $(sdk) SDK"
@@ -419,6 +439,15 @@ $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h: $$(PYTHON_LIB-$(sdk))
419439
# Copy headers as-is from the first target in the $(sdk) SDK
420440
cp -r $$(PYTHON_INCLUDE-$$(firstword $$(SDK_TARGETS-$(sdk)))) $$(PYTHON_INCLUDE-$(sdk))
421441

442+
# Create the modulemap file
443+
cp -r patch/Python/module.modulemap.prefix $$(PYTHON_MODULEMAP-$(sdk))
444+
echo "" >> $$(PYTHON_MODULEMAP-$(sdk))
445+
cd $$(PYTHON_SRCDIR-$$(firstword $$(SDK_TARGETS-$(sdk))))/Include && \
446+
find cpython -name "*.h" | sort | sed -e 's/^/ exclude header "/' | sed 's/$$$$/"/' >> $$(PYTHON_MODULEMAP-$(sdk)) && \
447+
echo "" >> $$(PYTHON_MODULEMAP-$(sdk)) && \
448+
find internal -name "*.h" | sort | sed -e 's/^/ exclude header "/' | sed 's/$$$$/"/' >> $$(PYTHON_MODULEMAP-$(sdk))
449+
echo "\n}" >> $$(PYTHON_MODULEMAP-$(sdk))
450+
422451
# Link the PYTHONHOME version of the headers
423452
mkdir -p $$(PYTHON_INSTALL-$(sdk))/include
424453
ln -si ../Python.framework/Headers $$(PYTHON_INSTALL-$(sdk))/include/python$(PYTHON_VER)
@@ -430,7 +459,7 @@ $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h: $$(PYTHON_LIB-$(sdk))
430459
cp $$(PYTHON_SRCDIR-$$(firstword $$(SDK_TARGETS-$(sdk))))/$(os)/Resources/pyconfig.h $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h
431460

432461

433-
$$(PYTHON_STDLIB-$(sdk))/LICENSE.TXT: $$(PYTHON_LIB-$(sdk)) $$(PYTHON_FRAMEWORK-$(sdk))/Info.plist $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h
462+
$$(PYTHON_STDLIB-$(sdk))/LICENSE.TXT: $$(PYTHON_LIB-$(sdk)) $$(PYTHON_FRAMEWORK-$(sdk))/Info.plist $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h $$(foreach target,$$(SDK_TARGETS-$(sdk)),$$(PYTHON_PLATFORM_SITECUSTOMIZE-$$(target)))
434463
@echo ">>> Build Python stdlib for the $(sdk) SDK"
435464
mkdir -p $$(PYTHON_STDLIB-$(sdk))/lib-dynload
436465
# Copy stdlib from the first target associated with the $(sdk) SDK
@@ -445,6 +474,10 @@ $$(PYTHON_STDLIB-$(sdk))/LICENSE.TXT: $$(PYTHON_LIB-$(sdk)) $$(PYTHON_FRAMEWORK-
445474
# Copy the individual _sysconfigdata modules into names that include the architecture
446475
$$(foreach target,$$(SDK_TARGETS-$(sdk)),cp $$(PYTHON_STDLIB-$$(target))/_sysconfigdata_* $$(PYTHON_STDLIB-$(sdk))/; )
447476

477+
# Copy the platform site folders for each architecture
478+
mkdir -p $$(PYTHON_PLATFORM_CONFIG-$(sdk))
479+
$$(foreach target,$$(SDK_TARGETS-$(sdk)),cp -r $$(PYTHON_PLATFORM_CONFIG-$$(target)) $$(PYTHON_PLATFORM_CONFIG-$(sdk)); )
480+
448481
# Merge the binary modules from each target in the $(sdk) SDK into a single binary
449482
$$(foreach module,$$(wildcard $$(PYTHON_STDLIB-$$(firstword $$(SDK_TARGETS-$(sdk))))/lib-dynload/*),lipo -create -output $$(PYTHON_STDLIB-$(sdk))/lib-dynload/$$(notdir $$(module)) $$(foreach target,$$(SDK_TARGETS-$(sdk)),$$(PYTHON_STDLIB-$$(target))/lib-dynload/$$(notdir $$(module))); )
450483

@@ -529,6 +562,15 @@ $$(PYTHON_XCFRAMEWORK-$(os))/Info.plist: \
529562
# Rewrite the framework to make it standalone
530563
patch/make-relocatable.sh $$(PYTHON_INSTALL_VERSION-macosx) 2>&1 > /dev/null
531564

565+
# Create the modulemap file
566+
cp -r patch/Python/module.modulemap.prefix $$(PYTHON_MODULEMAP-macosx)
567+
echo "" >> $$(PYTHON_MODULEMAP-macosx)
568+
cd $$(PYTHON_INCLUDE-macosx) && \
569+
find cpython -name "*.h" | sort | sed -e 's/^/ exclude header "/' | sed 's/$$$$/"/' >> $$(PYTHON_MODULEMAP-macosx) && \
570+
echo "" >> $$(PYTHON_MODULEMAP-macosx) && \
571+
find internal -name "*.h" | sort | sed -e 's/^/ exclude header "/' | sed 's/$$$$/"/' >> $$(PYTHON_MODULEMAP-macosx)
572+
echo "\n}" >> $$(PYTHON_MODULEMAP-macosx)
573+
532574
# Re-apply the signature on the binaries.
533575
codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f $$(PYTHON_LIB-macosx) \
534576
2>&1 | tee $$(PYTHON_INSTALL-macosx)/python-$(os).codesign.log
@@ -552,7 +594,7 @@ support/$(PYTHON_VER)/macOS/VERSIONS:
552594
dist/Python-$(PYTHON_VER)-macOS-support.$(BUILD_NUMBER).tar.gz: \
553595
$$(PYTHON_XCFRAMEWORK-macOS)/Info.plist \
554596
support/$(PYTHON_VER)/macOS/VERSIONS \
555-
$$(foreach target,$$(TARGETS-macOS), $$(PYTHON_SITECUSTOMIZE-$$(target)))
597+
$$(foreach target,$$(TARGETS-macOS), $$(PYTHON_PLATFORM_SITECUSTOMIZE-$$(target)))
556598

557599
@echo ">>> Create final distribution artefact for macOS"
558600
mkdir -p dist
@@ -575,9 +617,7 @@ $$(PYTHON_XCFRAMEWORK-$(os))/Info.plist: \
575617
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/include $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
576618
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/bin $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
577619
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/lib $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
578-
579-
@echo ">>> Create helper links in XCframework for $(os)"
580-
$$(foreach sdk,$$(SDKS-$(os)),ln -si $$(SDK_SLICE-$$(sdk)) $$(PYTHON_XCFRAMEWORK-$(os))/$$(sdk); )
620+
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/platform-config $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
581621

582622
ifeq ($(os),iOS)
583623
@echo ">>> Clone testbed project for $(os)"
@@ -596,7 +636,7 @@ endif
596636

597637
dist/Python-$(PYTHON_VER)-$(os)-support.$(BUILD_NUMBER).tar.gz: \
598638
$$(PYTHON_XCFRAMEWORK-$(os))/Info.plist \
599-
$$(foreach target,$$(TARGETS-$(os)), $$(PYTHON_SITECUSTOMIZE-$$(target)))
639+
$$(foreach target,$$(TARGETS-$(os)), $$(PYTHON_PLATFORM_SITECUSTOMIZE-$$(target)))
600640

601641
@echo ">>> Create final distribution artefact for $(os)"
602642
mkdir -p dist

README.rst

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,6 @@ Each support package contains:
8383

8484
* ``VERSIONS``, a text file describing the specific versions of code used to build the
8585
support package;
86-
* ``platform-site``, a folder that contains site customization scripts that can be used
87-
to make your local Python install look like it is an on-device install for each of the
88-
underlying target architectures supported by the platform. This is needed because when
89-
you run ``pip`` you'll be on a macOS machine with a specific architecture; if ``pip``
90-
tries to install a binary package, it will install a macOS binary wheel (which won't
91-
work on iOS/tvOS/watchOS). However, if you add the ``platform-site`` folder to your
92-
``PYTHONPATH`` when invoking pip, the site customization will make your Python install
93-
return ``platform`` and ``sysconfig`` responses consistent with on-device behavior,
94-
which will cause ``pip`` to install platform-appropriate packages.
9586
* ``Python.xcframework``, a multi-architecture build of the Python runtime library
9687

9788
On iOS/tvOS/watchOS, the ``Python.xcframework`` contains a
@@ -105,6 +96,32 @@ needed to build packages. This is required because Xcode uses the ``xcrun``
10596
alias to dynamically generate the name of binaries, but a lot of C tooling
10697
expects that ``CC`` will not contain spaces.
10798

99+
Each slice of an iOS/tvOS/watchOS XCframework also contains a
100+
``platform-config`` folder with a subfolder for each supported architecture in
101+
that slice. These subfolders can be used to make a macOS Python environment
102+
behave as if it were on an iOS/tvOS/watchOS device. This works in one of two
103+
ways:
104+
105+
1. **A sitecustomize.py script**. If the ``platform-config`` subfolder is on
106+
your ``PYTHONPATH`` when a Python interpreter is started, a site
107+
customization will be applied that patches methods in ``sys``, ``sysconfig``
108+
and ``platform`` that are used to identify the system.
109+
110+
2. **A make_cross_venv.py script**. If you call ``make_cross_venv.py``,
111+
providing the location of a virtual environment, the script will add some
112+
files to the ``site-packages`` folder of that environment that will
113+
automatically apply the same set of patches as the ``sitecustomize.py``
114+
script whenever the environment is activated, without any need to modify
115+
``PYTHONPATH``. If you use ``build`` to create an isolated PEP 517
116+
environment to build a wheel, these patches will also be applied to the
117+
isolated build environment that is created.
118+
119+
iOS distributions also contain a copy of the iOS ``testbed`` project - an Xcode
120+
project that can be used to run test suites of Python code. See the `CPython
121+
documentation on testing packages
122+
<https://docs.python.org/3/using/ios.html#testing-a-python-package>`__ for
123+
details on how to use this testbed.
124+
108125
For a detailed instructions on using the support package in your own project,
109126
see the `usage guide <./USAGE.md>`__
110127

0 commit comments

Comments
 (0)