Skip to content

Commit a8a256f

Browse files
authored
Update 3.12 support branch (#257)
* Update patch to include back ports of recent changes in the 3.13 branch * Incorporate changes to main workflow * Automate generation of modulemap.
1 parent d5b0f34 commit a8a256f

16 files changed

+640
-556
lines changed

.github/workflows/ci.yaml

+5-6
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:
@@ -109,19 +105,22 @@ jobs:
109105
- uses: actions/[email protected]
110106

111107
- name: Set up Python
112-
uses: actions/setup-python@v5.3.0
108+
uses: actions/setup-python@v5.4.0
113109
with:
114110
# Appending -dev ensures that we can always build the dev release.
115111
# It's a no-op for versions that have been published.
116112
python-version: ${{ needs.config.outputs.PYTHON_VER }}-dev
113+
# Ensure that we *always* use the latest build, not a cached version.
114+
# It's an edge case, but when a new alpha is released, we need to use it ASAP.
115+
check-latest: true
117116

118117
- name: Build ${{ matrix.target }}
119118
run: |
120119
# Do the build for the requested target.
121120
make ${{ matrix.target }} BUILD_NUMBER=${{ needs.config.outputs.BUILD_NUMBER }}
122121
123122
- name: Upload build artefacts
124-
uses: actions/upload-artifact@v4.4.3
123+
uses: actions/upload-artifact@v4.6.1
125124
with:
126125
name: Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz
127126
path: dist/Python-${{ needs.config.outputs.PYTHON_VER }}-${{ matrix.target }}-support.${{ needs.config.outputs.BUILD_NUMBER }}.tar.gz

.github/workflows/publish.yaml

+1-1
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

+2-2
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

+62-22
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ 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
30+
LIBFFI_VERSION=3.4.7-1
3131
MPDECIMAL_VERSION=4.0.0-1
32-
OPENSSL_VERSION=3.0.15-1
33-
XZ_VERSION=5.6.2-1
32+
OPENSSL_VERSION=3.0.16-1
33+
XZ_VERSION=5.6.4-1
3434

3535
# Supported OS
3636
OS_LIST=macOS iOS tvOS watchOS
@@ -129,10 +129,10 @@ ARCH-$(target)=$$(subst .,,$$(suffix $(target)))
129129
ifneq ($(os),macOS)
130130
ifeq ($$(findstring simulator,$$(SDK-$(target))),)
131131
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))
132-
IS_SIMULATOR-$(target)="False"
132+
IS_SIMULATOR-$(target)=False
133133
else
134134
TARGET_TRIPLE-$(target)=$$(ARCH-$(target))-apple-$$(OS_LOWER-$(target))$$(VERSION_MIN-$(os))-simulator
135-
IS_SIMULATOR-$(target)="True"
135+
IS_SIMULATOR-$(target)=True
136136
endif
137137
endif
138138

@@ -261,6 +261,9 @@ PYTHON_LIB-$(target)=$$(PYTHON_FRAMEWORK-$(target))/Python
261261
PYTHON_BIN-$(target)=$$(PYTHON_INSTALL-$(target))/bin
262262
PYTHON_INCLUDE-$(target)=$$(PYTHON_FRAMEWORK-$(target))/Headers
263263
PYTHON_STDLIB-$(target)=$$(PYTHON_INSTALL-$(target))/lib/python$(PYTHON_VER)
264+
PYTHON_PLATFORM_CONFIG-$(target)=$$(PYTHON_INSTALL-$(target))/platform-config/$$(ARCH-$(target))-$$(SDK-$(target))
265+
PYTHON_PLATFORM_SITECUSTOMIZE-$(target)=$$(PYTHON_PLATFORM_CONFIG-$(target))/sitecustomize.py
266+
264267

265268
$$(PYTHON_SRCDIR-$(target))/configure: \
266269
downloads/Python-$(PYTHON_VERSION).tar.gz \
@@ -318,23 +321,35 @@ $$(PYTHON_LIB-$(target)): $$(PYTHON_SRCDIR-$(target))/python.exe
318321
# Remove any .orig files produced by the compliance patching process
319322
find $$(PYTHON_INSTALL-$(target)) -name "*.orig" -exec rm {} \;
320323

321-
endif
322-
323-
PYTHON_SITECUSTOMIZE-$(target)=$(PROJECT_DIR)/support/$(PYTHON_VER)/$(os)/platform-site/$(target)/sitecustomize.py
324324

325-
$$(PYTHON_SITECUSTOMIZE-$(target)):
326-
@echo ">>> Create cross-platform sitecustomize.py for $(target)"
327-
mkdir -p $$(dir $$(PYTHON_SITECUSTOMIZE-$(target)))
328-
cat $(PROJECT_DIR)/patch/Python/sitecustomize.$(os).py \
325+
$$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target)):
326+
@echo ">>> Create cross-plaform config for $(target)"
327+
mkdir -p $$(PYTHON_PLATFORM_CONFIG-$(target))
328+
# Create the cross-platform site definition
329+
echo "import _cross_$$(ARCH-$(target))_$$(SDK-$(target)); import _cross_venv;" \
330+
> $$(PYTHON_PLATFORM_CONFIG-$(target))/_cross_venv.pth
331+
cp $(PROJECT_DIR)/patch/Python/make_cross_venv.py \
332+
$$(PYTHON_PLATFORM_CONFIG-$(target))/make_cross_venv.py
333+
cp $(PROJECT_DIR)/patch/Python/_cross_venv.py \
334+
$$(PYTHON_PLATFORM_CONFIG-$(target))/_cross_venv.py
335+
cp $$(PYTHON_STDLIB-$(target))/_sysconfig* \
336+
$$(PYTHON_PLATFORM_CONFIG-$(target))
337+
cat $(PROJECT_DIR)/patch/Python/_cross_target.py.tmpl \
329338
| sed -e "s/{{os}}/$(os)/g" \
339+
| sed -e "s/{{platform}}/$$(OS_LOWER-$(target))/g" \
330340
| sed -e "s/{{arch}}/$$(ARCH-$(target))/g" \
341+
| sed -e "s/{{sdk}}/$$(SDK-$(target))/g" \
331342
| sed -e "s/{{version_min}}/$$(VERSION_MIN-$(os))/g" \
332343
| sed -e "s/{{is_simulator}}/$$(IS_SIMULATOR-$(target))/g" \
333-
| sed -e "s/{{multiarch}}/$$(ARCH-$(target))-$$(SDK-$(target))/g" \
334-
| sed -e "s/{{tag}}/$$(OS_LOWER-$(target))-$$(VERSION_MIN-$(os))-$$(ARCH-$(target))-$$(SDK-$(target))/g" \
335-
> $$(PYTHON_SITECUSTOMIZE-$(target))
344+
> $$(PYTHON_PLATFORM_CONFIG-$(target))/_cross_$$(ARCH-$(target))_$$(SDK-$(target)).py
345+
cat $(PROJECT_DIR)/patch/Python/sitecustomize.py.tmpl \
346+
| sed -e "s/{{arch}}/$$(ARCH-$(target))/g" \
347+
| sed -e "s/{{sdk}}/$$(SDK-$(target))/g" \
348+
> $$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target))
349+
350+
endif
336351

337-
$(target): $$(PYTHON_SITECUSTOMIZE-$(target)) $$(PYTHON_LIB-$(target))
352+
$(target): $$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target)) $$(PYTHON_LIB-$(target))
338353

339354
###########################################################################
340355
# Target: Debug
@@ -363,6 +378,8 @@ vars-$(target):
363378
@echo "PYTHON_BIN-$(target): $$(PYTHON_BIN-$(target))"
364379
@echo "PYTHON_INCLUDE-$(target): $$(PYTHON_INCLUDE-$(target))"
365380
@echo "PYTHON_STDLIB-$(target): $$(PYTHON_STDLIB-$(target))"
381+
@echo "PYTHON_PLATFORM_CONFIG-$(target): $$(PYTHON_PLATFORM_CONFIG-$(target))"
382+
@echo "PYTHON_PLATFORM_SITECUSTOMIZE-$(target): $$(PYTHON_PLATFORM_SITECUSTOMIZE-$(target))"
366383
@echo
367384

368385
endef # build-target
@@ -408,6 +425,7 @@ PYTHON_FRAMEWORK-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/Python.framework
408425
PYTHON_INSTALL_VERSION-$(sdk)=$$(PYTHON_FRAMEWORK-$(sdk))/Versions/$(PYTHON_VER)
409426
PYTHON_LIB-$(sdk)=$$(PYTHON_INSTALL_VERSION-$(sdk))/Python
410427
PYTHON_INCLUDE-$(sdk)=$$(PYTHON_INSTALL_VERSION-$(sdk))/include/python$(PYTHON_VER)
428+
PYTHON_MODULEMAP-$(sdk)=$$(PYTHON_INCLUDE-$(sdk))/module.modulemap
411429
PYTHON_STDLIB-$(sdk)=$$(PYTHON_INSTALL_VERSION-$(sdk))/lib/python$(PYTHON_VER)
412430

413431
else
@@ -418,11 +436,13 @@ else
418436
# The non-macOS frameworks don't use the versioning structure.
419437

420438
PYTHON_INSTALL-$(sdk)=$(PROJECT_DIR)/install/$(os)/$(sdk)/python-$(PYTHON_VERSION)
439+
PYTHON_MODULEMAP-$(sdk)=$$(PYTHON_INCLUDE-$(sdk))/module.modulemap
421440
PYTHON_FRAMEWORK-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/Python.framework
422441
PYTHON_LIB-$(sdk)=$$(PYTHON_FRAMEWORK-$(sdk))/Python
423442
PYTHON_BIN-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/bin
424443
PYTHON_INCLUDE-$(sdk)=$$(PYTHON_FRAMEWORK-$(sdk))/Headers
425444
PYTHON_STDLIB-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/lib/python$(PYTHON_VER)
445+
PYTHON_PLATFORM_CONFIG-$(sdk)=$$(PYTHON_INSTALL-$(sdk))/platform-config
426446

427447
$$(PYTHON_LIB-$(sdk)): $$(foreach target,$$(SDK_TARGETS-$(sdk)),$$(PYTHON_LIB-$$(target)))
428448
@echo ">>> Build Python fat library for the $(sdk) SDK"
@@ -447,6 +467,15 @@ $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h: $$(PYTHON_LIB-$(sdk))
447467
# Copy headers as-is from the first target in the $(sdk) SDK
448468
cp -r $$(PYTHON_INCLUDE-$$(firstword $$(SDK_TARGETS-$(sdk)))) $$(PYTHON_INCLUDE-$(sdk))
449469

470+
# Create the modulemap file
471+
cp -r patch/Python/module.modulemap.prefix $$(PYTHON_MODULEMAP-$(sdk))
472+
echo "" >> $$(PYTHON_MODULEMAP-$(sdk))
473+
cd $$(PYTHON_SRCDIR-$$(firstword $$(SDK_TARGETS-$(sdk))))/Include && \
474+
find cpython -name "*.h" | sort | sed -e 's/^/ exclude header "/' | sed 's/$$$$/"/' >> $$(PYTHON_MODULEMAP-$(sdk)) && \
475+
echo "" >> $$(PYTHON_MODULEMAP-$(sdk)) && \
476+
find internal -name "*.h" | sort | sed -e 's/^/ exclude header "/' | sed 's/$$$$/"/' >> $$(PYTHON_MODULEMAP-$(sdk))
477+
echo "\n}" >> $$(PYTHON_MODULEMAP-$(sdk))
478+
450479
# Link the PYTHONHOME version of the headers
451480
mkdir -p $$(PYTHON_INSTALL-$(sdk))/include
452481
ln -si ../Python.framework/Headers $$(PYTHON_INSTALL-$(sdk))/include/python$(PYTHON_VER)
@@ -458,7 +487,7 @@ $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h: $$(PYTHON_LIB-$(sdk))
458487
cp $$(PYTHON_SRCDIR-$$(firstword $$(SDK_TARGETS-$(sdk))))/$(os)/Resources/pyconfig.h $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h
459488

460489

461-
$$(PYTHON_STDLIB-$(sdk))/LICENSE.TXT: $$(PYTHON_LIB-$(sdk)) $$(PYTHON_FRAMEWORK-$(sdk))/Info.plist $$(PYTHON_INCLUDE-$(sdk))/pyconfig.h
490+
$$(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)))
462491
@echo ">>> Build Python stdlib for the $(sdk) SDK"
463492
mkdir -p $$(PYTHON_STDLIB-$(sdk))/lib-dynload
464493
# Copy stdlib from the first target associated with the $(sdk) SDK
@@ -473,6 +502,10 @@ $$(PYTHON_STDLIB-$(sdk))/LICENSE.TXT: $$(PYTHON_LIB-$(sdk)) $$(PYTHON_FRAMEWORK-
473502
# Copy the individual _sysconfigdata modules into names that include the architecture
474503
$$(foreach target,$$(SDK_TARGETS-$(sdk)),cp $$(PYTHON_STDLIB-$$(target))/_sysconfigdata_* $$(PYTHON_STDLIB-$(sdk))/; )
475504

505+
# Copy the platform site folders for each architecture
506+
mkdir -p $$(PYTHON_PLATFORM_CONFIG-$(sdk))
507+
$$(foreach target,$$(SDK_TARGETS-$(sdk)),cp -r $$(PYTHON_PLATFORM_CONFIG-$$(target)) $$(PYTHON_PLATFORM_CONFIG-$(sdk)); )
508+
476509
# Merge the binary modules from each target in the $(sdk) SDK into a single binary
477510
$$(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))); )
478511

@@ -557,6 +590,15 @@ $$(PYTHON_XCFRAMEWORK-$(os))/Info.plist: \
557590
# Rewrite the framework to make it standalone
558591
patch/make-relocatable.sh $$(PYTHON_INSTALL_VERSION-macosx) 2>&1 > /dev/null
559592

593+
# Create the modulemap file
594+
cp -r patch/Python/module.modulemap.prefix $$(PYTHON_MODULEMAP-macosx)
595+
echo "" >> $$(PYTHON_MODULEMAP-macosx)
596+
cd $$(PYTHON_INCLUDE-macosx) && \
597+
find cpython -name "*.h" | sort | sed -e 's/^/ exclude header "/' | sed 's/$$$$/"/' >> $$(PYTHON_MODULEMAP-macosx) && \
598+
echo "" >> $$(PYTHON_MODULEMAP-macosx) && \
599+
find internal -name "*.h" | sort | sed -e 's/^/ exclude header "/' | sed 's/$$$$/"/' >> $$(PYTHON_MODULEMAP-macosx)
600+
echo "\n}" >> $$(PYTHON_MODULEMAP-macosx)
601+
560602
# Re-apply the signature on the binaries.
561603
codesign -s - --preserve-metadata=identifier,entitlements,flags,runtime -f $$(PYTHON_LIB-macosx) \
562604
2>&1 | tee $$(PYTHON_INSTALL-macosx)/python-$(os).codesign.log
@@ -580,7 +622,7 @@ support/$(PYTHON_VER)/macOS/VERSIONS:
580622
dist/Python-$(PYTHON_VER)-macOS-support.$(BUILD_NUMBER).tar.gz: \
581623
$$(PYTHON_XCFRAMEWORK-macOS)/Info.plist \
582624
support/$(PYTHON_VER)/macOS/VERSIONS \
583-
$$(foreach target,$$(TARGETS-macOS), $$(PYTHON_SITECUSTOMIZE-$$(target)))
625+
$$(foreach target,$$(TARGETS-macOS), $$(PYTHON_PLATFORM_SITECUSTOMIZE-$$(target)))
584626

585627
@echo ">>> Create final distribution artefact for macOS"
586628
mkdir -p dist
@@ -603,9 +645,7 @@ $$(PYTHON_XCFRAMEWORK-$(os))/Info.plist: \
603645
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/include $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
604646
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/bin $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
605647
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/lib $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
606-
607-
@echo ">>> Create helper links in XCframework for $(os)"
608-
$$(foreach sdk,$$(SDKS-$(os)),ln -si $$(SDK_SLICE-$$(sdk)) $$(PYTHON_XCFRAMEWORK-$(os))/$$(sdk); )
648+
$$(foreach sdk,$$(SDKS-$(os)),cp -r $$(PYTHON_INSTALL-$$(sdk))/platform-config $$(PYTHON_XCFRAMEWORK-$(os))/$$(SDK_SLICE-$$(sdk)); )
609649

610650
ifeq ($(os),iOS)
611651
@echo ">>> Clone testbed project for $(os)"
@@ -625,7 +665,7 @@ endif
625665

626666
dist/Python-$(PYTHON_VER)-$(os)-support.$(BUILD_NUMBER).tar.gz: \
627667
$$(PYTHON_XCFRAMEWORK-$(os))/Info.plist \
628-
$$(foreach target,$$(TARGETS-$(os)), $$(PYTHON_SITECUSTOMIZE-$$(target)))
668+
$$(foreach target,$$(TARGETS-$(os)), $$(PYTHON_PLATFORM_SITECUSTOMIZE-$$(target)))
629669

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

README.rst

+26-9
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)