4141CONVERT_TO_BUILTIN_EXTENSIONS = {
4242 "_asyncio" : {
4343 # _asynciomodule.c is included in pythoncore for some reason.
44+ # This was fixed in Python 3.9. See hacky code for
45+ # `honor_allow_missing_preprocessor`.
4446 "allow_missing_preprocessor" : True
4547 },
4648 "_bz2" : {},
@@ -407,7 +409,12 @@ def make_project_static_library(source_path: pathlib.Path, project: str):
407409 fh .write ("\n " .join (lines ))
408410
409411
410- def convert_to_static_library (source_path : pathlib .Path , extension : str , entry : dict ):
412+ def convert_to_static_library (
413+ source_path : pathlib .Path ,
414+ extension : str ,
415+ entry : dict ,
416+ honor_allow_missing_preprocessor : bool ,
417+ ):
411418 """Converts an extension to a static library."""
412419
413420 proj_path = source_path / "PCbuild" / ("%s.vcxproj" % extension )
@@ -460,7 +467,7 @@ def convert_to_static_library(source_path: pathlib.Path, extension: str, entry:
460467 lines .append (line )
461468
462469 if not found_preprocessor :
463- if entry .get ("allow_missing_preprocessor" ):
470+ if honor_allow_missing_preprocessor and entry .get ("allow_missing_preprocessor" ):
464471 log ("not adjusting preprocessor definitions for %s" % extension )
465472 else :
466473 log ("introducing <PreprocessorDefinitions> to %s" % extension )
@@ -817,6 +824,7 @@ def hack_project_files(
817824 build_directory : str ,
818825 static : bool ,
819826 building_libffi : bool ,
827+ honor_allow_missing_preprocessor : bool ,
820828):
821829 """Hacks Visual Studio project files to work with our build."""
822830
@@ -900,13 +908,23 @@ def hack_project_files(
900908 # do here.
901909 if static and building_libffi :
902910 libffi_path = td / "libffi" / "libffi.lib"
903- static_replace_in_file (
904- pythoncore_proj ,
905- b"<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>" ,
906- b"<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;"
907- + bytes (libffi_path )
908- + b";%(AdditionalDependencies)</AdditionalDependencies>" ,
909- )
911+ try :
912+ # Python 3.9 version
913+ static_replace_in_file (
914+ pythoncore_proj ,
915+ b"<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies>" ,
916+ b"<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;pathcch.lib;"
917+ + bytes (libffi_path )
918+ + b";%(AdditionalDependencies)</AdditionalDependencies>" ,
919+ )
920+ except NoSearchStringError :
921+ static_replace_in_file (
922+ pythoncore_proj ,
923+ b"<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>" ,
924+ b"<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;"
925+ + bytes (libffi_path )
926+ + b";%(AdditionalDependencies)</AdditionalDependencies>" ,
927+ )
910928
911929 if static :
912930 for extension , entry in sorted (CONVERT_TO_BUILTIN_EXTENSIONS .items ()):
@@ -916,7 +934,9 @@ def hack_project_files(
916934
917935 init_fn = entry .get ("init" , "PyInit_%s" % extension )
918936
919- if convert_to_static_library (cpython_source_path , extension , entry ):
937+ if convert_to_static_library (
938+ cpython_source_path , extension , entry , honor_allow_missing_preprocessor
939+ ):
920940 add_to_config_c (cpython_source_path , extension , init_fn )
921941
922942 # pythoncore.vcxproj produces libpython. Typically pythonXY.dll. We change
@@ -1013,7 +1033,63 @@ def hack_project_files(
10131033 )
10141034
10151035
1016- PYPORT_EXPORT_SEARCH_NEW = b"""
1036+ PYPORT_EXPORT_SEARCH_39 = b"""
1037+ #if defined(__CYGWIN__)
1038+ # define HAVE_DECLSPEC_DLL
1039+ #endif
1040+
1041+ #include "exports.h"
1042+
1043+ /* only get special linkage if built as shared or platform is Cygwin */
1044+ #if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
1045+ # if defined(HAVE_DECLSPEC_DLL)
1046+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
1047+ # define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
1048+ # define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
1049+ /* module init functions inside the core need no external linkage */
1050+ /* except for Cygwin to handle embedding */
1051+ # if defined(__CYGWIN__)
1052+ # define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
1053+ # else /* __CYGWIN__ */
1054+ # define PyMODINIT_FUNC PyObject*
1055+ # endif /* __CYGWIN__ */
1056+ # else /* Py_BUILD_CORE */
1057+ /* Building an extension module, or an embedded situation */
1058+ /* public Python functions and data are imported */
1059+ /* Under Cygwin, auto-import functions to prevent compilation */
1060+ /* failures similar to those described at the bottom of 4.1: */
1061+ /* http://docs.python.org/extending/windows.html#a-cookbook-approach */
1062+ # if !defined(__CYGWIN__)
1063+ # define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE
1064+ # endif /* !__CYGWIN__ */
1065+ # define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE
1066+ /* module init functions outside the core must be exported */
1067+ # if defined(__cplusplus)
1068+ # define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
1069+ # else /* __cplusplus */
1070+ # define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
1071+ # endif /* __cplusplus */
1072+ # endif /* Py_BUILD_CORE */
1073+ # endif /* HAVE_DECLSPEC_DLL */
1074+ #endif /* Py_ENABLE_SHARED */
1075+
1076+ /* If no external linkage macros defined by now, create defaults */
1077+ #ifndef PyAPI_FUNC
1078+ # define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
1079+ #endif
1080+ #ifndef PyAPI_DATA
1081+ # define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
1082+ #endif
1083+ #ifndef PyMODINIT_FUNC
1084+ # if defined(__cplusplus)
1085+ # define PyMODINIT_FUNC extern "C" Py_EXPORTED_SYMBOL PyObject*
1086+ # else /* __cplusplus */
1087+ # define PyMODINIT_FUNC Py_EXPORTED_SYMBOL PyObject*
1088+ # endif /* __cplusplus */
1089+ #endif
1090+ """
1091+
1092+ PYPORT_EXPORT_SEARCH_38 = b"""
10171093#if defined(__CYGWIN__)
10181094# define HAVE_DECLSPEC_DLL
10191095#endif
@@ -1067,7 +1143,7 @@ def hack_project_files(
10671143#endif
10681144"""
10691145
1070- PYPORT_EXPORT_SEARCH_OLD = b"""
1146+ PYPORT_EXPORT_SEARCH_37 = b"""
10711147#if defined(__CYGWIN__)
10721148# define HAVE_DECLSPEC_DLL
10731149#endif
@@ -1121,7 +1197,14 @@ def hack_project_files(
11211197#endif
11221198"""
11231199
1124- PYPORT_EXPORT_REPLACE = b"""
1200+ PYPORT_EXPORT_REPLACE_NEW = b"""
1201+ #include "exports.h"
1202+ #define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE
1203+ #define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
1204+ #define PyMODINIT_FUNC __declspec(dllexport) PyObject*
1205+ """
1206+
1207+ PYPORT_EXPORT_REPLACE_OLD = b"""
11251208#define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE
11261209#define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
11271210#define PyMODINIT_FUNC __declspec(dllexport) PyObject*
@@ -1157,12 +1240,17 @@ def hack_source_files(source_path: pathlib.Path, static: bool):
11571240 pyport_h = source_path / "Include" / "pyport.h"
11581241 try :
11591242 static_replace_in_file (
1160- pyport_h , PYPORT_EXPORT_SEARCH_NEW , PYPORT_EXPORT_REPLACE
1243+ pyport_h , PYPORT_EXPORT_SEARCH_39 , PYPORT_EXPORT_REPLACE_NEW
11611244 )
11621245 except NoSearchStringError :
1163- static_replace_in_file (
1164- pyport_h , PYPORT_EXPORT_SEARCH_OLD , PYPORT_EXPORT_REPLACE
1165- )
1246+ try :
1247+ static_replace_in_file (
1248+ pyport_h , PYPORT_EXPORT_SEARCH_38 , PYPORT_EXPORT_REPLACE_OLD
1249+ )
1250+ except NoSearchStringError :
1251+ static_replace_in_file (
1252+ pyport_h , PYPORT_EXPORT_SEARCH_37 , PYPORT_EXPORT_REPLACE_OLD
1253+ )
11661254
11671255 # Modules/_winapi.c and Modules/overlapped.c both define an
11681256 # ``OverlappedType`` symbol. We rename one to make the symbol conflict
@@ -1928,6 +2016,8 @@ def build_cpython(
19282016 build_directory ,
19292017 static = static ,
19302018 building_libffi = libffi_archive is not None ,
2019+ honor_allow_missing_preprocessor = python_entry_name
2020+ in ("cpython-3.7" , "cpython-3.8" ),
19312021 )
19322022 hack_source_files (cpython_source_path , static = static )
19332023
0 commit comments