@@ -636,6 +636,7 @@ def hack_props(td: pathlib.Path, pcbuild_path: pathlib.Path, arch: str, static:
636
636
637
637
sqlite_path = td / ("sqlite-autoconf-%s" % sqlite_version )
638
638
bzip2_path = td / ("bzip2-%s" % bzip2_version )
639
+ libffi_path = td / "libffi"
639
640
tcltk_path = td / ("cpython-bin-deps-%s" % tcltk_commit )
640
641
xz_path = td / ("xz-%s" % xz_version )
641
642
zlib_path = td / ("zlib-%s" % zlib_version )
@@ -654,6 +655,9 @@ def hack_props(td: pathlib.Path, pcbuild_path: pathlib.Path, arch: str, static:
654
655
if b"<bz2Dir>" in line :
655
656
line = b"<bz2Dir>%s\\ </bz2Dir>" % bzip2_path
656
657
658
+ elif b"<libffiOutDir>" in line :
659
+ line = b"<libffiOutDir>%s\\ </libffiOutDir>" % libffi_path
660
+
657
661
elif b"<lzmaDir>" in line :
658
662
line = b"<lzmaDir>%s\\ </lzmaDir>" % xz_path
659
663
@@ -1233,47 +1237,76 @@ def build_openssl(perl_path: pathlib.Path, arch: str, profile: str):
1233
1237
1234
1238
1235
1239
def build_libffi (
1236
- build_dir : pathlib . Path , arch : str , prepare_ffi : pathlib .Path , sh_exe : pathlib .Path
1240
+ python : str , arch : str , sh_exe : pathlib .Path , dest_archive : pathlib .Path
1237
1241
):
1238
- ffi_source_path = build_dir / "libffi"
1242
+ with tempfile .TemporaryDirectory (prefix = "libffi-build-" ) as td :
1243
+ td = pathlib .Path (td )
1239
1244
1240
- # As of April 15, 2020, the libffi source release on GitHub doesn't
1241
- # have patches that we need to build. https://bugs.python.org/issue40293
1242
- # tracks getting a proper release. Until then, git clone the repo.
1243
- subprocess .run (
1244
- [
1245
- "git.exe" ,
1246
- "clone" ,
1247
- "--single-branch" ,
1248
- "--branch" ,
1249
- "libffi" ,
1250
- "https://github.com/python/cpython-source-deps.git" ,
1251
- str (ffi_source_path ),
1252
- ],
1253
- check = True ,
1254
- )
1245
+ ffi_source_path = td / "libffi"
1255
1246
1256
- subprocess .run (
1257
- ["git.exe" , "checkout" , "ed22026f39b37f892ded95d7b30e77dfb5126334" ],
1258
- cwd = ffi_source_path ,
1259
- check = True ,
1260
- )
1247
+ # As of April 15, 2020, the libffi source release on GitHub doesn't
1248
+ # have patches that we need to build. https://bugs.python.org/issue40293
1249
+ # tracks getting a proper release. Until then, git clone the repo.
1250
+ subprocess .run (
1251
+ [
1252
+ "git.exe" ,
1253
+ "clone" ,
1254
+ "--single-branch" ,
1255
+ "--branch" ,
1256
+ "libffi" ,
1257
+ "https://github.com/python/cpython-source-deps.git" ,
1258
+ str (ffi_source_path ),
1259
+ ],
1260
+ check = True ,
1261
+ )
1261
1262
1262
- # We build libffi by running the build script that CPython ships.
1263
- env = dict ( os . environ )
1264
- env [ "LIBFFI_SOURCE" ] = str ( ffi_source_path )
1265
- env [ "VCVARSALL" ] = str ( find_vcvarsall_path ())
1266
- env [ "SH" ] = str ( sh_exe )
1263
+ subprocess . run (
1264
+ [ "git.exe" , "checkout" , "ed22026f39b37f892ded95d7b30e77dfb5126334" ],
1265
+ cwd = ffi_source_path ,
1266
+ check = True ,
1267
+ )
1267
1268
1268
- args = [str (prepare_ffi ), "-pdb" ]
1269
- if arch == "x86" :
1270
- args .append ("-x86" )
1271
- else :
1272
- args .append ("-x64" )
1269
+ # We build libffi by running the build script that CPython ships.
1270
+ python_archive = download_entry (python , BUILD )
1271
+ extract_tar_to_directory (python_archive , td )
1273
1272
1274
- # Running the build script from Python will install the files into the
1275
- # appropriate directory.
1276
- subprocess .run (args , env = env , check = True )
1273
+ python_entry = DOWNLOADS [python ]
1274
+ prepare_libffi = (
1275
+ td
1276
+ / ("Python-%s" % python_entry ["version" ])
1277
+ / "PCBuild"
1278
+ / "prepare_libffi.bat"
1279
+ )
1280
+
1281
+ env = dict (os .environ )
1282
+ env ["LIBFFI_SOURCE" ] = str (ffi_source_path )
1283
+ env ["VCVARSALL" ] = str (find_vcvarsall_path ())
1284
+ env ["SH" ] = str (sh_exe )
1285
+
1286
+ args = [str (prepare_libffi ), "-pdb" ]
1287
+ if arch == "x86" :
1288
+ args .append ("-x86" )
1289
+ artifacts_path = ffi_source_path / "i686-pc-cygwin"
1290
+ else :
1291
+ args .append ("-x64" )
1292
+ artifacts_path = ffi_source_path / "x86_64-w64-cygwin"
1293
+
1294
+ subprocess .run (args , env = env , check = True )
1295
+
1296
+ out_dir = td / "out" / "libffi"
1297
+ out_dir .mkdir (parents = True )
1298
+
1299
+ for f in os .listdir (artifacts_path / ".libs" ):
1300
+ if f .endswith ((".lib" , ".exp" , ".dll" , ".pdb" )):
1301
+ shutil .copyfile (artifacts_path / ".libs" / f , out_dir / f )
1302
+
1303
+ shutil .copytree (artifacts_path / "include" , out_dir / "include" )
1304
+ shutil .copyfile (
1305
+ artifacts_path / "fficonfig.h" , out_dir / "include" / "fficonfig.h"
1306
+ )
1307
+
1308
+ with dest_archive .open ("wb" ) as fh :
1309
+ create_tar_from_directory (fh , td / "out" )
1277
1310
1278
1311
1279
1312
RE_ADDITIONAL_DEPENDENCIES = re .compile (
@@ -1564,7 +1597,7 @@ def find_additional_dependencies(project: pathlib.Path):
1564
1597
return res
1565
1598
1566
1599
1567
- def build_cpython (python_entry_name : str , arch : str , sh_exe , profile ):
1600
+ def build_cpython (python_entry_name : str , arch : str , profile , libffi_archive = None ):
1568
1601
static = profile == "static"
1569
1602
pgo = "-pgo" in profile
1570
1603
@@ -1607,7 +1640,7 @@ def build_cpython(python_entry_name: str, arch: str, sh_exe, profile):
1607
1640
with tempfile .TemporaryDirectory (prefix = "python-build-" ) as td :
1608
1641
td = pathlib .Path (td )
1609
1642
1610
- with concurrent .futures .ThreadPoolExecutor (8 ) as e :
1643
+ with concurrent .futures .ThreadPoolExecutor (9 ) as e :
1611
1644
fs = []
1612
1645
for a in (
1613
1646
python_archive ,
@@ -1625,19 +1658,12 @@ def build_cpython(python_entry_name: str, arch: str, sh_exe, profile):
1625
1658
for f in fs :
1626
1659
f .result ()
1627
1660
1661
+ if libffi_archive :
1662
+ extract_tar_to_directory (libffi_archive , td )
1663
+
1628
1664
with zipfile .ZipFile (setuptools_archive ) as zf :
1629
1665
zf .extractall (td )
1630
1666
1631
- cpython_source_path = td / ("Python-%s" % python_version )
1632
- pcbuild_path = cpython_source_path / "PCBuild"
1633
-
1634
- prepare_libffi = pcbuild_path / "prepare_libffi.bat"
1635
-
1636
- if prepare_libffi .exists ():
1637
- assert sh_exe
1638
-
1639
- build_libffi (td , arch , prepare_libffi , sh_exe )
1640
-
1641
1667
# We need all the OpenSSL library files in the same directory to appease
1642
1668
# install rules.
1643
1669
if not static :
@@ -2002,12 +2028,16 @@ def main():
2002
2028
LOG_PREFIX [0 ] = "openssl"
2003
2029
build_openssl (perl_path , arch , profile = args .profile )
2004
2030
2031
+ if "3.7" not in args .python :
2032
+ libffi_archive = BUILD / ("libffi-windows-%s-%s.tar" % (arch , args .profile ))
2033
+ if not libffi_archive .exists ():
2034
+ build_libffi (args .python , arch , pathlib .Path (args .sh ), libffi_archive )
2035
+ else :
2036
+ libffi_archive = None
2037
+
2005
2038
LOG_PREFIX [0 ] = "cpython"
2006
2039
tar_path = build_cpython (
2007
- args .python ,
2008
- arch ,
2009
- sh_exe = pathlib .Path (args .sh ) if args .sh else None ,
2010
- profile = args .profile ,
2040
+ args .python , arch , profile = args .profile , libffi_archive = libffi_archive
2011
2041
)
2012
2042
2013
2043
compress_python_archive (
0 commit comments