Skip to content

Commit ebdfb65

Browse files
committed
Bump Python version to v3.8.11.
This incorporates macOS 11 compatibility for Apple Silicon.
1 parent 94ca5cd commit ebdfb65

File tree

7 files changed

+483
-18412
lines changed

7 files changed

+483
-18412
lines changed

Makefile

+97-19
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
# - XZ-iOS - build XZ for iOS
1818
# - XZ-tvOS - build XZ for tvOS
1919
# - XZ-watchOS - build XZ for watchOS
20+
# - libFFI-iOS - build libFFI for iOS
21+
# - libFFI-tvOS - build libFFI for tvOS
22+
# - libFFI-watchOS - build libFFI for watchOS
2023
# - Python-macOS - build Python for macOS
2124
# - Python-iOS - build Python for iOS
2225
# - Python-tvOS - build Python for tvOS
@@ -30,7 +33,11 @@ BUILD_NUMBER=custom
3033
MACOSX_DEPLOYMENT_TARGET=10.8
3134

3235
# Version of packages that will be compiled by this meta-package
33-
PYTHON_VERSION=3.8.9
36+
# PYTHON_VERSION is the full version number (e.g., 3.10.0b3)
37+
# PYTHON_MICRO_VERSION is the full version number, without any alpha/beta/rc suffix. (e.g., 3.10.0)
38+
# PYTHON_VER is the major/minor version (e.g., 3.10)
39+
PYTHON_VERSION=3.8.11
40+
PYTHON_MICRO_VERSION=$(shell echo $(PYTHON_VERSION) | grep -Eo "\d+\.\d+\.\d+")
3441
PYTHON_VER=$(basename $(PYTHON_VERSION))
3542

3643
OPENSSL_VERSION_NUMBER=1.1.1
@@ -41,11 +48,13 @@ BZIP2_VERSION=1.0.8
4148

4249
XZ_VERSION=5.2.5
4350

51+
LIBFFI_VERSION=3.3
52+
4453
# Supported OS
4554
OS=macOS iOS tvOS watchOS
4655

4756
# macOS targets
48-
TARGETS-macOS=macosx.x86_64
57+
TARGETS-macOS=macosx.x86_64 macosx.arm64
4958
PYTHON_TARGETS-macOS=macOS
5059
CFLAGS-macOS=-mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET)
5160

@@ -83,7 +92,7 @@ clean:
8392
distclean: clean
8493
rm -rf downloads
8594

86-
downloads: downloads/openssl-$(OPENSSL_VERSION).tgz downloads/bzip2-$(BZIP2_VERSION).tgz downloads/xz-$(XZ_VERSION).tgz downloads/Python-$(PYTHON_VERSION).tgz
95+
downloads: downloads/openssl-$(OPENSSL_VERSION).tgz downloads/bzip2-$(BZIP2_VERSION).tgz downloads/xz-$(XZ_VERSION).tgz downloads/libffi-$(LIBFFI_VERSION).tgz downloads/Python-$(PYTHON_VERSION).tgz
8796

8897
update-patch:
8998
# Generate a diff from the clone of the python/cpython Github repository
@@ -141,6 +150,20 @@ downloads/xz-$(XZ_VERSION).tgz:
141150
mkdir -p downloads
142151
if [ ! -e downloads/xz-$(XZ_VERSION).tgz ]; then curl --fail -L http://tukaani.org/xz/xz-$(XZ_VERSION).tar.gz -o downloads/xz-$(XZ_VERSION).tgz; fi
143152

153+
###########################################################################
154+
# LIBFFI
155+
###########################################################################
156+
157+
# Clean the LibFFI project
158+
clean-libFFI:
159+
rm -rf build/*/libffi-$(LIBFFI_VERSION) \
160+
build/*/Support/libFFI
161+
162+
# Download original XZ source code archive.
163+
downloads/libffi-$(LIBFFI_VERSION).tgz:
164+
mkdir -p downloads
165+
if [ ! -e downloads/libffi-$(LIBFFI_VERSION).tgz ]; then curl --fail -L http://github.com/libffi/libffi/releases/download/v$(LIBFFI_VERSION)/libffi-$(LIBFFI_VERSION).tar.gz -o downloads/libffi-$(LIBFFI_VERSION).tgz; fi
166+
144167
###########################################################################
145168
# Python
146169
###########################################################################
@@ -156,7 +179,7 @@ clean-Python:
156179
# Download original Python source code archive.
157180
downloads/Python-$(PYTHON_VERSION).tgz:
158181
mkdir -p downloads
159-
if [ ! -e downloads/Python-$(PYTHON_VERSION).tgz ]; then curl -L https://www.python.org/ftp/python/$(PYTHON_VERSION)/Python-$(PYTHON_VERSION).tgz > downloads/Python-$(PYTHON_VERSION).tgz; fi
182+
if [ ! -e downloads/Python-$(PYTHON_VERSION).tgz ]; then curl -L https://www.python.org/ftp/python/$(PYTHON_MICRO_VERSION)/Python-$(PYTHON_VERSION).tgz > downloads/Python-$(PYTHON_VERSION).tgz; fi
160183

161184
# Some Python targets needed to identify the host build
162185
PYTHON_DIR-macOS=build/macOS/Python-$(PYTHON_VERSION)-macOS
@@ -191,6 +214,7 @@ LDFLAGS-$1=-arch $$(ARCH-$1) -isysroot=$$(SDK_ROOT-$1)
191214
OPENSSL_DIR-$1=build/$2/openssl-$(OPENSSL_VERSION)-$1
192215
BZIP2_DIR-$1=build/$2/bzip2-$(BZIP2_VERSION)-$1
193216
XZ_DIR-$1=build/$2/xz-$(XZ_VERSION)-$1
217+
LIBFFI_DIR-$1=build/$2/libffi-$(LIBFFI_VERSION)
194218

195219
# Unpack OpenSSL
196220
$$(OPENSSL_DIR-$1)/Makefile: downloads/openssl-$(OPENSSL_VERSION).tgz
@@ -262,24 +286,32 @@ $$(XZ_DIR-$1)/Makefile: downloads/xz-$(XZ_VERSION).tgz
262286
$$(XZ_DIR-$1)/src/liblzma/.libs/liblzma.a: $$(XZ_DIR-$1)/Makefile
263287
cd $$(XZ_DIR-$1) && make && make install
264288

265-
# macOS builds are compiled as a single build. As a result, the macOS Python
266-
# build is configured in the `build` macro, rather than the `build-target` macro.
289+
# macOS builds use their own libFFI, and are compiled as a single
290+
# universal2 build. As a result, the macOS Python build is configured
291+
# in the `build` macro, rather than the `build-target` macro.
267292
ifneq ($2,macOS)
293+
LIBFFI_BUILD_DIR-$1=build_$$(SDK-$1)-$$(ARCH-$1)
268294
PYTHON_DIR-$1=build/$2/Python-$(PYTHON_VERSION)-$1
269295
pyconfig.h-$1=pyconfig-$$(ARCH-$1).h
270296
PYTHON_HOST-$1=$(PYTHON_HOST)
271297

298+
# Build LibFFI
299+
$$(LIBFFI_DIR-$1)/libffi.$1.a: $$(LIBFFI_DIR-$1)/darwin_common
300+
cd $$(LIBFFI_DIR-$1)/$$(LIBFFI_BUILD_DIR-$1) && make
301+
302+
# Copy in the lib to a non-BUILD_DIR dependent location;
303+
# include the target in the final filename for disambiguation
304+
cp $$(LIBFFI_DIR-$1)/$$(LIBFFI_BUILD_DIR-$1)/.libs/libffi.a $$(LIBFFI_DIR-$1)/libffi.$1.a
305+
272306
# Unpack Python
273307
$$(PYTHON_DIR-$1)/Makefile: downloads/Python-$(PYTHON_VERSION).tgz $$(PYTHON_HOST-$1)
274308
# Unpack target Python
275309
mkdir -p $$(PYTHON_DIR-$1)
276310
tar zxf downloads/Python-$(PYTHON_VERSION).tgz --strip-components 1 -C $$(PYTHON_DIR-$1)
277311
# Apply target Python patches
278312
cd $$(PYTHON_DIR-$1) && patch -p1 < $(PROJECT_DIR)/patch/Python/Python.patch
279-
# Copy in the embedded and platform/arch configuration
280-
cp -f $(PROJECT_DIR)/patch/Python/Setup.embedded $$(PYTHON_DIR-$1)/Modules/Setup.embedded
281-
if [ -e "$(PROJECT_DIR)/patch/Python/Setup.$2-$$(ARCH-$1)" ]; then \
282-
cp -f $(PROJECT_DIR)/patch/Python/Setup.$2-$$(ARCH-$1) $$(PYTHON_DIR-$1)/Modules/Setup.$2-$$(ARCH-$1); fi
313+
# Copy in the embedded module configuration
314+
cat $(PROJECT_DIR)/patch/Python/Setup.embedded $(PROJECT_DIR)/patch/Python/Setup.$2 > $$(PYTHON_DIR-$1)/Modules/Setup.local
283315
# Configure target Python
284316
cd $$(PYTHON_DIR-$1) && PATH=$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH) ./configure \
285317
CC="$$(CC-$1)" LD="$$(CC-$1)" \
@@ -291,7 +323,7 @@ $$(PYTHON_DIR-$1)/Makefile: downloads/Python-$(PYTHON_VERSION).tgz $$(PYTHON_HOS
291323
$$(PYTHON_CONFIGURE-$2)
292324

293325
# Build Python
294-
$$(PYTHON_DIR-$1)/dist/lib/libpython$(PYTHON_VER).a: build/$2/Support/OpenSSL build/$2/Support/BZip2 build/$2/Support/XZ $$(PYTHON_DIR-$1)/Makefile
326+
$$(PYTHON_DIR-$1)/dist/lib/libpython$(PYTHON_VER).a: build/$2/Support/OpenSSL build/$2/Support/BZip2 build/$2/Support/XZ build/$2/Support/libFFI $$(PYTHON_DIR-$1)/Makefile
295327
# Build target Python
296328
cd $$(PYTHON_DIR-$1) && PATH="$(PROJECT_DIR)/$(PYTHON_DIR-macOS)/dist/bin:$(PATH)" make all install
297329

@@ -307,9 +339,11 @@ vars-$1:
307339
@echo "SDK-$1: $$(SDK-$1)"
308340
@echo "SDK_ROOT-$1: $$(SDK_ROOT-$1)"
309341
@echo "CC-$1: $$(CC-$1)"
342+
@echo "LIBFFI_BUILD_DIR-$1: $$(LIBFFI_BUILD_DIR-$1)"
310343
@echo "OPENSSL_DIR-$1: $$(OPENSSL_DIR-$1)"
311344
@echo "BZIP2_DIR-$1: $$(BZIP2_DIR-$1)"
312345
@echo "XZ_DIR-$1: $$(XZ_DIR-$1)"
346+
@echo "LIBFFI_DIR-$1: $$(LIBFFI_DIR-$1)"
313347
@echo "PYTHON_DIR-$1: $$(PYTHON_DIR-$1)"
314348
@echo "pyconfig.h-$1: $$(pyconfig.h-$1)"
315349

@@ -325,6 +359,7 @@ $$(foreach target,$$(TARGETS-$1),$$(eval $$(call build-target,$$(target),$1)))
325359
OPENSSL_FRAMEWORK-$1=build/$1/Support/OpenSSL
326360
BZIP2_FRAMEWORK-$1=build/$1/Support/BZip2
327361
XZ_FRAMEWORK-$1=build/$1/Support/XZ
362+
LIBFFI_FRAMEWORK-$1=build/$1/Support/libFFI
328363
PYTHON_FRAMEWORK-$1=build/$1/Support/Python
329364
PYTHON_RESOURCES-$1=$$(PYTHON_FRAMEWORK-$1)/Resources
330365

@@ -333,11 +368,16 @@ $1: dist/Python-$(PYTHON_VER)-$1-support.$(BUILD_NUMBER).tar.gz
333368
clean-$1:
334369
rm -rf build/$1
335370

336-
dist/Python-$(PYTHON_VER)-$1-support.$(BUILD_NUMBER).tar.gz: $$(BZIP2_FRAMEWORK-$1) $$(XZ_FRAMEWORK-$1) $$(OPENSSL_FRAMEWORK-$1) $$(PYTHON_FRAMEWORK-$1)
371+
dist/Python-$(PYTHON_VER)-$1-support.$(BUILD_NUMBER).tar.gz: $$(BZIP2_FRAMEWORK-$1) $$(XZ_FRAMEWORK-$1) $$(OPENSSL_FRAMEWORK-$1) $$(LIBFFI_FRAMEWORK-$1) $$(PYTHON_FRAMEWORK-$1)
337372
mkdir -p dist
338373
echo "Python version: $(PYTHON_VERSION) " > build/$1/Support/VERSIONS
339374
echo "Build: $(BUILD_NUMBER)" >> build/$1/Support/VERSIONS
340375
echo "---------------------" >> build/$1/Support/VERSIONS
376+
ifeq ($1,macOS)
377+
echo "libFFI: macOS native" >> build/$1/Support/VERSIONS
378+
else
379+
echo "libFFI: $(LIBFFI_VERSION)" >> build/$1/Support/VERSIONS
380+
endif
341381
echo "BZip2: $(BZIP2_VERSION)" >> build/$1/Support/VERSIONS
342382
echo "OpenSSL: $(OPENSSL_VERSION)" >> build/$1/Support/VERSIONS
343383
echo "XZ: $(XZ_VERSION)" >> build/$1/Support/VERSIONS
@@ -407,11 +447,18 @@ build/$1/xz/lib/liblzma.a: $$(foreach target,$$(TARGETS-$1),$$(XZ_DIR-$$(target)
407447
mkdir -p build/$1
408448
xcrun lipo -create -o $$@ $$^
409449

410-
# macOS builds a single Python target; thus it needs to be
450+
# Build libFFI
451+
libFFI-$1: $$(LIBFFI_FRAMEWORK-$1)
452+
453+
# macOS builds a single Python universal2 target; thus it needs to be
411454
# configured in the `build` macro, not the `build-target` macro.
455+
# macOS also uses the system-provided libFFI, so there's no need to package
456+
# a libFFI framework for macOS.
412457
ifeq ($1,macOS)
413458
# Some targets that are needed for consistency between macOS and other builds,
414459
# but are no-ops on macOS.
460+
$$(LIBFFI_FRAMEWORK-$1):
461+
415462
build/$1/$$(pyconfig.h-$1):
416463

417464
# Unpack Python
@@ -421,25 +468,54 @@ $$(PYTHON_DIR-$1)/Makefile: downloads/Python-$(PYTHON_VERSION).tgz
421468
tar zxf downloads/Python-$(PYTHON_VERSION).tgz --strip-components 1 -C $$(PYTHON_DIR-$1)
422469
# Apply target Python patches
423470
cd $$(PYTHON_DIR-$1) && patch -p1 < $(PROJECT_DIR)/patch/Python/Python.patch
424-
# A locally hosted Python requires a full Setup.local configuration
425-
# because there's no PYTHON_HOST_PLATFORM to cause Setup.local to be
426-
# generated
427-
cat $(PROJECT_DIR)/patch/Python/Setup.embedded $(PROJECT_DIR)/patch/Python/Setup.macOS-x86_64 > $$(PYTHON_DIR-$1)/Modules/Setup.local
471+
# Copy in the embedded module configuration
472+
cat $(PROJECT_DIR)/patch/Python/Setup.embedded $(PROJECT_DIR)/patch/Python/Setup.$1 > $$(PYTHON_DIR-$1)/Modules/Setup.local
428473
# Configure target Python
429474
cd $$(PYTHON_DIR-$1) && MACOSX_DEPLOYMENT_TARGET=$$(MACOSX_DEPLOYMENT_TARGET) ./configure \
430475
--prefix=$(PROJECT_DIR)/$$(PYTHON_DIR-$1)/dist \
431-
--without-doc-strings --enable-ipv6 --without-ensurepip \
476+
--without-doc-strings --enable-ipv6 --without-ensurepip --enable-universalsdk --with-universal-archs=universal2 \
432477
$$(PYTHON_CONFIGURE-$1)
433478

434479
# Build Python
435-
$$(PYTHON_DIR-$1)/dist/lib/libpython$(PYTHON_VER).a: build/$1/Support/OpenSSL build/$1/Support/BZip2 build/$1/Support/XZ $$(PYTHON_DIR-$1)/Makefile
480+
$$(PYTHON_DIR-$1)/dist/lib/libpython$(PYTHON_VER).a: build/$1/Support/OpenSSL build/$1/Support/BZip2 build/$1/Support/XZ build/$1/Support/libFFI $$(PYTHON_DIR-$1)/Makefile
436481
# Build target Python
437482
cd $$(PYTHON_DIR-$1) && PATH="$(PROJECT_DIR)/$(PYTHON_DIR-$1)/dist/bin:$(PATH)" make all install
438483

439484
else
485+
# The LibFFI folder is shared between all architectures for the OS
486+
LIBFFI_DIR-$1=build/$1/libffi-$(LIBFFI_VERSION)
440487
# The Python targets are the same as they are for every other library
441488
PYTHON_TARGETS-$1=$$(TARGETS-$1)
442489

490+
# Unpack LibFFI and generate source & headers
491+
$$(LIBFFI_DIR-$1)/darwin_common: downloads/libffi-$(LIBFFI_VERSION).tgz
492+
# Unpack sources
493+
mkdir -p $$(LIBFFI_DIR-$1)
494+
tar zxf downloads/libffi-$(LIBFFI_VERSION).tgz --strip-components 1 -C $$(LIBFFI_DIR-$1)
495+
# Apply libffi patches. Apple builds of libffi use a utility script; that
496+
# script doesn't work with Python3 using the out-of-the-box version in
497+
# libffi 3.3. This patch adds some changes that will be included in libFFI
498+
# 3.4 (whenever that is released), plus some extra targets to support
499+
# tvOS and watchOS.
500+
cd $$(LIBFFI_DIR-$1) && patch -p1 < $(PROJECT_DIR)/patch/libffi/libffi.patch
501+
# Configure the build
502+
cd $$(LIBFFI_DIR-$1) && python generate-darwin-source-and-headers.py --only-$(shell echo $1 | tr '[:upper:]' '[:lower:]')
503+
504+
$$(LIBFFI_FRAMEWORK-$1): $$(LIBFFI_DIR-$1)/libffi.a
505+
# Create framework directory structure
506+
mkdir -p $$(LIBFFI_FRAMEWORK-$1)
507+
508+
# Copy the headers.
509+
cp -f -r $$(LIBFFI_DIR-$1)/darwin_common/include $$(LIBFFI_FRAMEWORK-$1)/Headers
510+
cp -f -r $$(LIBFFI_DIR-$1)/darwin_$(shell echo $1 | tr '[:upper:]' '[:lower:]')/include/* $$(LIBFFI_FRAMEWORK-$1)/Headers
511+
512+
# Create the fat library
513+
xcrun libtool -no_warning_for_no_symbols -static \
514+
-o $$(LIBFFI_FRAMEWORK-$1)/libFFI.a $$^
515+
516+
$$(LIBFFI_DIR-$1)/libffi.a: $$(foreach target,$$(TARGETS-$1),$$(LIBFFI_DIR-$1)/libffi.$$(target).a)
517+
xcrun lipo -create -o $$@ $$^
518+
443519
endif
444520

445521
$1: Python-$1
@@ -479,7 +555,9 @@ vars-$1: $$(foreach target,$$(TARGETS-$1),vars-$$(target))
479555
@echo "OPENSSL_FRAMEWORK-$1: $$(OPENSSL_FRAMEWORK-$1)"
480556
@echo "BZIP2_FRAMEWORK-$1: $$(BZIP2_FRAMEWORK-$1)"
481557
@echo "XZ_FRAMEWORK-$1: $$(XZ_FRAMEWORK-$1)"
558+
@echo "LIBFFI_FRAMEWORK-$1: $$(LIBFFI_FRAMEWORK-$1)"
482559
@echo "PYTHON_FRAMEWORK-$1: $$(PYTHON_FRAMEWORK-$1)"
560+
@echo "LIBFFI_DIR-$1: $$(LIBFFI_DIR-$1)"
483561
@echo "PYTHON_RESOURCES-$1: $$(PYTHON_RESOURCES-$1)"
484562
@echo "PYTHON_TARGETS-$1: $$(PYTHON_TARGETS-$1)"
485563

0 commit comments

Comments
 (0)