@@ -845,6 +845,7 @@ def run_msbuild(
845845 platform : str ,
846846 python_version : str ,
847847 windows_sdk_version : str ,
848+ freethreaded : bool ,
848849):
849850 args = [
850851 str (msbuild ),
@@ -867,6 +868,9 @@ def run_msbuild(
867868 f"/property:DefaultWindowsSDKVersion={ windows_sdk_version } " ,
868869 ]
869870
871+ if freethreaded :
872+ args .append ("/property:DisableGil=true" )
873+
870874 exec_and_log (args , str (pcbuild_path ), os .environ )
871875
872876
@@ -1118,6 +1122,7 @@ def collect_python_build_artifacts(
11181122 arch : str ,
11191123 config : str ,
11201124 openssl_entry : str ,
1125+ freethreaded : bool ,
11211126):
11221127 """Collect build artifacts from Python.
11231128
@@ -1243,6 +1248,20 @@ def find_additional_dependencies(project: pathlib.Path):
12431248
12441249 return set ()
12451250
1251+ if arch == "amd64" :
1252+ abi_platform = "win_amd64"
1253+ elif arch == "win32" :
1254+ abi_platform = "win32"
1255+ else :
1256+ raise ValueError ("unhandled arch: %s" % arch )
1257+
1258+ if freethreaded :
1259+ abi_tag = ".cp%st-%s" % (python_majmin , abi_platform )
1260+ lib_suffix = "t"
1261+ else :
1262+ abi_tag = ""
1263+ lib_suffix = ""
1264+
12461265 # Copy object files for core sources into their own directory.
12471266 core_dir = out_dir / "build" / "core"
12481267 core_dir .mkdir (parents = True )
@@ -1263,12 +1282,12 @@ def find_additional_dependencies(project: pathlib.Path):
12631282 exts = ("lib" , "exp" )
12641283
12651284 for ext in exts :
1266- source = outputs_path / ("python%s.%s" % (python_majmin , ext ))
1267- dest = core_dir / ("python%s.%s" % (python_majmin , ext ))
1285+ source = outputs_path / ("python%s%s .%s" % (python_majmin , lib_suffix , ext ))
1286+ dest = core_dir / ("python%s%s .%s" % (python_majmin , lib_suffix , ext ))
12681287 log ("copying %s" % source )
12691288 shutil .copyfile (source , dest )
12701289
1271- res ["core" ]["shared_lib" ] = "install/python%s.dll" % python_majmin
1290+ res ["core" ]["shared_lib" ] = "install/python%s%s .dll" % ( python_majmin , lib_suffix )
12721291
12731292 # We hack up pythoncore.vcxproj and the list in it when this function
12741293 # runs isn't totally accurate. We hardcode the list from the CPython
@@ -1354,12 +1373,15 @@ def find_additional_dependencies(project: pathlib.Path):
13541373 res ["extensions" ][ext ] = [entry ]
13551374
13561375 # Copy the extension static library.
1357- ext_static = outputs_path / ("%s.lib" % ext )
1358- dest = dest_dir / ("%s.lib" % ext )
1376+ ext_static = outputs_path / ("%s%s .lib" % ( ext , abi_tag ) )
1377+ dest = dest_dir / ("%s%s .lib" % ( ext , abi_tag ) )
13591378 log ("copying static extension %s" % ext_static )
13601379 shutil .copyfile (ext_static , dest )
13611380
1362- res ["extensions" ][ext ][0 ]["shared_lib" ] = "install/DLLs/%s.pyd" % ext
1381+ res ["extensions" ][ext ][0 ]["shared_lib" ] = "install/DLLs/%s%s.pyd" % (
1382+ ext ,
1383+ abi_tag ,
1384+ )
13631385
13641386 lib_dir = out_dir / "build" / "lib"
13651387 lib_dir .mkdir ()
@@ -1394,6 +1416,7 @@ def build_cpython(
13941416) -> pathlib .Path :
13951417 parsed_build_options = set (build_options .split ("+" ))
13961418 pgo = "pgo" in parsed_build_options
1419+ freethreaded = "freethreaded" in parsed_build_options
13971420
13981421 msbuild = find_msbuild (msvc_version )
13991422 log ("found MSBuild at %s" % msbuild )
@@ -1425,6 +1448,12 @@ def build_cpython(
14251448 # as we do for Unix builds.
14261449 mpdecimal_archive = None
14271450
1451+ if freethreaded :
1452+ (major , minor , _ ) = python_version .split ("." )
1453+ python_exe = f"python{ major } .{ minor } t.exe"
1454+ else :
1455+ python_exe = "python.exe"
1456+
14281457 if arch == "amd64" :
14291458 build_platform = "x64"
14301459 build_directory = "amd64"
@@ -1507,6 +1536,7 @@ def build_cpython(
15071536 platform = build_platform ,
15081537 python_version = python_version ,
15091538 windows_sdk_version = windows_sdk_version ,
1539+ freethreaded = freethreaded ,
15101540 )
15111541
15121542 # build-windows.py sets some environment variables which cause the
@@ -1526,7 +1556,7 @@ def build_cpython(
15261556 # test execution. We work around this by invoking the test harness
15271557 # separately for each test.
15281558 instrumented_python = (
1529- pcbuild_path / build_directory / "instrumented" / "python.exe"
1559+ pcbuild_path / build_directory / "instrumented" / python_exe
15301560 )
15311561
15321562 tests = subprocess .run (
@@ -1572,6 +1602,7 @@ def build_cpython(
15721602 platform = build_platform ,
15731603 python_version = python_version ,
15741604 windows_sdk_version = windows_sdk_version ,
1605+ freethreaded = freethreaded ,
15751606 )
15761607 artifact_config = "PGUpdate"
15771608
@@ -1583,6 +1614,7 @@ def build_cpython(
15831614 platform = build_platform ,
15841615 python_version = python_version ,
15851616 windows_sdk_version = windows_sdk_version ,
1617+ freethreaded = freethreaded ,
15861618 )
15871619 artifact_config = "Release"
15881620
@@ -1615,6 +1647,9 @@ def build_cpython(
16151647 "--include-venv" ,
16161648 ]
16171649
1650+ if freethreaded :
1651+ args .append ("--include-freethreaded" )
1652+
16181653 # CPython 3.12 removed distutils.
16191654 if not meets_python_minimum_version (python_version , "3.12" ):
16201655 args .append ("--include-distutils" )
@@ -1639,7 +1674,7 @@ def build_cpython(
16391674 # Install pip and setuptools.
16401675 exec_and_log (
16411676 [
1642- str (install_dir / "python.exe" ),
1677+ str (install_dir / python_exe ),
16431678 "-m" ,
16441679 "pip" ,
16451680 "install" ,
@@ -1656,7 +1691,7 @@ def build_cpython(
16561691 if meets_python_maximum_version (python_version , "3.11" ):
16571692 exec_and_log (
16581693 [
1659- str (install_dir / "python.exe" ),
1694+ str (install_dir / python_exe ),
16601695 "-m" ,
16611696 "pip" ,
16621697 "install" ,
@@ -1691,6 +1726,7 @@ def build_cpython(
16911726 build_directory ,
16921727 artifact_config ,
16931728 openssl_entry = openssl_entry ,
1729+ freethreaded = freethreaded ,
16941730 )
16951731
16961732 for ext , init_fn in sorted (builtin_extensions .items ()):
@@ -1775,7 +1811,7 @@ def build_cpython(
17751811 }
17761812
17771813 # Collect information from running Python script.
1778- python_exe = out_dir / "python" / "install" / "python.exe"
1814+ python_exe = out_dir / "python" / "install" / python_exe
17791815 metadata_path = td / "metadata.json"
17801816 env = dict (os .environ )
17811817 env ["ROOT" ] = str (out_dir / "python" )
0 commit comments