17
17
# - XZ-iOS - build XZ for iOS
18
18
# - XZ-tvOS - build XZ for tvOS
19
19
# - 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
20
23
# - Python-macOS - build Python for macOS
21
24
# - Python-iOS - build Python for iOS
22
25
# - Python-tvOS - build Python for tvOS
@@ -30,7 +33,11 @@ BUILD_NUMBER=custom
30
33
MACOSX_DEPLOYMENT_TARGET =10.8
31
34
32
35
# 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+")
34
41
PYTHON_VER =$(basename $(PYTHON_VERSION ) )
35
42
36
43
OPENSSL_VERSION_NUMBER =1.1.1
@@ -41,11 +48,13 @@ BZIP2_VERSION=1.0.8
41
48
42
49
XZ_VERSION =5.2.5
43
50
51
+ LIBFFI_VERSION =3.3
52
+
44
53
# Supported OS
45
54
OS =macOS iOS tvOS watchOS
46
55
47
56
# macOS targets
48
- TARGETS-macOS =macosx.x86_64
57
+ TARGETS-macOS =macosx.x86_64 macosx.arm64
49
58
PYTHON_TARGETS-macOS =macOS
50
59
CFLAGS-macOS=-mmacosx-version-min =$(MACOSX_DEPLOYMENT_TARGET )
51
60
83
92
distclean : clean
84
93
rm -rf downloads
85
94
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
87
96
88
97
update-patch :
89
98
# Generate a diff from the clone of the python/cpython Github repository
@@ -141,6 +150,20 @@ downloads/xz-$(XZ_VERSION).tgz:
141
150
mkdir -p downloads
142
151
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
143
152
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
+
144
167
# ##########################################################################
145
168
# Python
146
169
# ##########################################################################
@@ -156,7 +179,7 @@ clean-Python:
156
179
# Download original Python source code archive.
157
180
downloads/Python-$(PYTHON_VERSION ) .tgz :
158
181
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
160
183
161
184
# Some Python targets needed to identify the host build
162
185
PYTHON_DIR-macOS =build/macOS/Python-$(PYTHON_VERSION ) -macOS
@@ -191,6 +214,7 @@ LDFLAGS-$1=-arch $$(ARCH-$1) -isysroot=$$(SDK_ROOT-$1)
191
214
OPENSSL_DIR-$1=build/$2/openssl-$(OPENSSL_VERSION ) -$1
192
215
BZIP2_DIR-$1=build/$2/bzip2-$(BZIP2_VERSION ) -$1
193
216
XZ_DIR-$1=build/$2/xz-$(XZ_VERSION ) -$1
217
+ LIBFFI_DIR-$1=build/$2/libffi-$(LIBFFI_VERSION )
194
218
195
219
# Unpack OpenSSL
196
220
$$(OPENSSL_DIR-$1 ) /Makefile: downloads/openssl-$(OPENSSL_VERSION ) .tgz
@@ -262,24 +286,32 @@ $$(XZ_DIR-$1)/Makefile: downloads/xz-$(XZ_VERSION).tgz
262
286
$$(XZ_DIR-$1 ) /src/liblzma/.libs/liblzma.a: $$(XZ_DIR-$1 ) /Makefile
263
287
cd $$(XZ_DIR-$1 ) && make && make install
264
288
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.
267
292
ifneq ($2,macOS)
293
+ LIBFFI_BUILD_DIR-$1 =build_$$(SDK-$1 ) -$$(ARCH-$1 )
268
294
PYTHON_DIR-$1 =build/$2/Python-$(PYTHON_VERSION ) -$1
269
295
pyconfig.h-$1 =pyconfig-$$(ARCH-$1 ) .h
270
296
PYTHON_HOST-$1 =$(PYTHON_HOST )
271
297
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
+
272
306
# Unpack Python
273
307
$$(PYTHON_DIR-$1 ) /Makefile : downloads/Python-$(PYTHON_VERSION ) .tgz $$(PYTHON_HOST-$1 )
274
308
# Unpack target Python
275
309
mkdir -p $$(PYTHON_DIR-$1 )
276
310
tar zxf downloads/Python-$(PYTHON_VERSION ) .tgz --strip-components 1 -C $$(PYTHON_DIR-$1 )
277
311
# Apply target Python patches
278
312
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
283
315
# Configure target Python
284
316
cd $$(PYTHON_DIR-$1 ) && PATH=$(PROJECT_DIR ) /$(PYTHON_DIR-macOS ) /dist/bin:$(PATH ) ./configure \
285
317
CC=" $$ (CC-$1 )" LD=" $$ (CC-$1 )" \
@@ -291,7 +323,7 @@ $$(PYTHON_DIR-$1)/Makefile: downloads/Python-$(PYTHON_VERSION).tgz $$(PYTHON_HOS
291
323
$$(PYTHON_CONFIGURE-$2 )
292
324
293
325
# 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
295
327
# Build target Python
296
328
cd $$(PYTHON_DIR-$1 ) && PATH=" $( PROJECT_DIR) /$( PYTHON_DIR-macOS) /dist/bin:$( PATH) " make all install
297
329
@@ -307,9 +339,11 @@ vars-$1:
307
339
@echo "SDK-$1: $$(SDK-$1 ) "
308
340
@echo "SDK_ROOT-$1: $$(SDK_ROOT-$1 ) "
309
341
@echo "CC-$1: $$(CC-$1 ) "
342
+ @echo "LIBFFI_BUILD_DIR-$1: $$(LIBFFI_BUILD_DIR-$1 ) "
310
343
@echo "OPENSSL_DIR-$1: $$(OPENSSL_DIR-$1 ) "
311
344
@echo "BZIP2_DIR-$1: $$(BZIP2_DIR-$1 ) "
312
345
@echo "XZ_DIR-$1: $$(XZ_DIR-$1 ) "
346
+ @echo "LIBFFI_DIR-$1: $$(LIBFFI_DIR-$1 ) "
313
347
@echo "PYTHON_DIR-$1: $$(PYTHON_DIR-$1 ) "
314
348
@echo "pyconfig.h-$1: $$(pyconfig.h-$1 ) "
315
349
@@ -325,6 +359,7 @@ $$(foreach target,$$(TARGETS-$1),$$(eval $$(call build-target,$$(target),$1)))
325
359
OPENSSL_FRAMEWORK-$1=build/$1/Support/OpenSSL
326
360
BZIP2_FRAMEWORK-$1=build/$1/Support/BZip2
327
361
XZ_FRAMEWORK-$1=build/$1/Support/XZ
362
+ LIBFFI_FRAMEWORK-$1=build/$1/Support/libFFI
328
363
PYTHON_FRAMEWORK-$1=build/$1/Support/Python
329
364
PYTHON_RESOURCES-$1=$$(PYTHON_FRAMEWORK-$1 ) /Resources
330
365
@@ -333,11 +368,16 @@ $1: dist/Python-$(PYTHON_VER)-$1-support.$(BUILD_NUMBER).tar.gz
333
368
clean-$1:
334
369
rm -rf build/$1
335
370
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 )
337
372
mkdir -p dist
338
373
echo "Python version: $(PYTHON_VERSION ) " > build/$1/Support/VERSIONS
339
374
echo "Build: $(BUILD_NUMBER ) " >> build/$1/Support/VERSIONS
340
375
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
341
381
echo "BZip2: $(BZIP2_VERSION ) " >> build/$1/Support/VERSIONS
342
382
echo "OpenSSL: $(OPENSSL_VERSION ) " >> build/$1/Support/VERSIONS
343
383
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)
407
447
mkdir -p build/$1
408
448
xcrun lipo -create -o $$@ $$^
409
449
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
411
454
# 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.
412
457
ifeq ($1,macOS)
413
458
# Some targets that are needed for consistency between macOS and other builds,
414
459
# but are no-ops on macOS.
460
+ $$(LIBFFI_FRAMEWORK-$1 ) :
461
+
415
462
build/$1/$$(pyconfig.h-$1 ) :
416
463
417
464
# Unpack Python
@@ -421,25 +468,54 @@ $$(PYTHON_DIR-$1)/Makefile: downloads/Python-$(PYTHON_VERSION).tgz
421
468
tar zxf downloads/Python-$(PYTHON_VERSION ) .tgz --strip-components 1 -C $$(PYTHON_DIR-$1 )
422
469
# Apply target Python patches
423
470
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
428
473
# Configure target Python
429
474
cd $$(PYTHON_DIR-$1 ) && MACOSX_DEPLOYMENT_TARGET=$$(MACOSX_DEPLOYMENT_TARGET ) ./configure \
430
475
--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 \
432
477
$$(PYTHON_CONFIGURE-$1 )
433
478
434
479
# 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
436
481
# Build target Python
437
482
cd $$(PYTHON_DIR-$1 ) && PATH=" $( PROJECT_DIR) /$( PYTHON_DIR-$1 ) /dist/bin:$( PATH) " make all install
438
483
439
484
else
485
+ # The LibFFI folder is shared between all architectures for the OS
486
+ LIBFFI_DIR-$1 =build/$1/libffi-$(LIBFFI_VERSION )
440
487
# The Python targets are the same as they are for every other library
441
488
PYTHON_TARGETS-$1 =$$(TARGETS-$1 )
442
489
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
+
443
519
endif
444
520
445
521
$1: Python-$1
@@ -479,7 +555,9 @@ vars-$1: $$(foreach target,$$(TARGETS-$1),vars-$$(target))
479
555
@echo "OPENSSL_FRAMEWORK-$1: $$(OPENSSL_FRAMEWORK-$1 ) "
480
556
@echo "BZIP2_FRAMEWORK-$1: $$(BZIP2_FRAMEWORK-$1 ) "
481
557
@echo "XZ_FRAMEWORK-$1: $$(XZ_FRAMEWORK-$1 ) "
558
+ @echo "LIBFFI_FRAMEWORK-$1: $$(LIBFFI_FRAMEWORK-$1 ) "
482
559
@echo "PYTHON_FRAMEWORK-$1: $$(PYTHON_FRAMEWORK-$1 ) "
560
+ @echo "LIBFFI_DIR-$1: $$(LIBFFI_DIR-$1 ) "
483
561
@echo "PYTHON_RESOURCES-$1: $$(PYTHON_RESOURCES-$1 ) "
484
562
@echo "PYTHON_TARGETS-$1: $$(PYTHON_TARGETS-$1 ) "
485
563
0 commit comments