]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111650: Ensure pyconfig.h includes Py_GIL_DISABLED on Windows (GH-112778)
authorSteve Dower <steve.dower@python.org>
Wed, 13 Dec 2023 15:38:45 +0000 (15:38 +0000)
committerGitHub <noreply@github.com>
Wed, 13 Dec 2023 15:38:45 +0000 (15:38 +0000)
25 files changed:
.github/workflows/reusable-windows.yml
Lib/sysconfig/__init__.py
Lib/test/test_sysconfig.py
Lib/test/test_venv.py
Misc/NEWS.d/next/Windows/2023-12-05-22-56-30.gh-issue-111650.xlWmvM.rst [new file with mode: 0644]
Modules/_ctypes/_ctypes_test.c
Modules/_scproxy.c
Modules/_stat.c
Modules/_testcapi/heaptype_relative.c
Modules/_testcapi/vectorcall_limited.c
Modules/_testclinic_limited.c
Modules/_testimportmultiple.c
Modules/_uuidmodule.c
Modules/errnomodule.c
Modules/resource.c
Modules/xxlimited.c
Modules/xxlimited_35.c
PC/layout/main.py
PC/pyconfig.h.in [moved from PC/pyconfig.h with 99% similarity]
PC/winsound.c
PCbuild/_freeze_module.vcxproj
PCbuild/pyproject.props
PCbuild/pythoncore.vcxproj
Tools/msi/dev/dev_files.wxs
Tools/peg_generator/pegen/build.py

index 29e0a7e35b54501b288235a0f282684344ada791..47a3c10d2ca4c1e0a6b67b2f4b815dd3abe8050f 100644 (file)
@@ -16,7 +16,7 @@ jobs:
     steps:
     - uses: actions/checkout@v4
     - name: Build CPython
-      run: .\PCbuild\build.bat -e -d -p Win32 ${{ inputs.free-threaded && '--disable-gil' || '' }}
+      run: .\PCbuild\build.bat -e -d -v -p Win32 ${{ inputs.free-threaded && '--disable-gil' || '' }}
     - name: Display build info
       run: .\python.bat -m test.pythoninfo
     - name: Tests
@@ -33,7 +33,7 @@ jobs:
     - name: Register MSVC problem matcher
       run: echo "::add-matcher::.github/problem-matchers/msvc.json"
     - name: Build CPython
-      run: .\PCbuild\build.bat -e -d -p x64 ${{ inputs.free-threaded && '--disable-gil' || '' }}
+      run: .\PCbuild\build.bat -e -d -v -p x64 ${{ inputs.free-threaded && '--disable-gil' || '' }}
     - name: Display build info
       run: .\python.bat -m test.pythoninfo
     - name: Tests
@@ -50,4 +50,4 @@ jobs:
     - name: Register MSVC problem matcher
       run: echo "::add-matcher::.github/problem-matchers/msvc.json"
     - name: Build CPython
-      run: .\PCbuild\build.bat -e -d -p arm64 ${{ inputs.free-threaded && '--disable-gil' || '' }}
+      run: .\PCbuild\build.bat -e -d -v -p arm64 ${{ inputs.free-threaded && '--disable-gil' || '' }}
index 2a7fa45be079de7afe78412a8a95935c579912ff..c60c9f3440615becce1f1f86f8f54db5e84952a1 100644 (file)
@@ -404,7 +404,16 @@ def get_config_h_filename():
     """Return the path of pyconfig.h."""
     if _PYTHON_BUILD:
         if os.name == "nt":
-            inc_dir = os.path.join(_PROJECT_BASE, "PC")
+            # This ought to be as simple as dirname(sys._base_executable), but
+            # if a venv uses symlinks to a build in the source tree, then this
+            # fails. So instead we guess the subdirectory name from sys.winver
+            if sys.winver.endswith('-32'):
+                arch = 'win32'
+            elif sys.winver.endswith('-arm64'):
+                arch = 'arm64'
+            else:
+                arch = 'amd64'
+            inc_dir = os.path.join(_PROJECT_BASE, 'PCbuild', arch)
         else:
             inc_dir = _PROJECT_BASE
     else:
index 2a6813f00bccc65c4920c6a5d9801bb6f52d725a..a19c04b1b2cde552e494d07031b984096efd5f73 100644 (file)
@@ -472,11 +472,15 @@ class TestSysConfig(unittest.TestCase):
             # should be a full source checkout.
             Python_h = os.path.join(srcdir, 'Include', 'Python.h')
             self.assertTrue(os.path.exists(Python_h), Python_h)
-            # <srcdir>/PC/pyconfig.h always exists even if unused on POSIX.
-            pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h')
+            # <srcdir>/PC/pyconfig.h.in always exists even if unused
+            pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h.in')
             self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h)
             pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in')
             self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in)
+            if os.name == 'nt':
+                # <executable dir>/pyconfig.h exists on Windows in a build tree
+                pyconfig_h = os.path.join(sys.executable, '..', 'pyconfig.h')
+                self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h)
         elif os.name == 'posix':
             makefile_dir = os.path.dirname(sysconfig.get_makefile_filename())
             # Issue #19340: srcdir has been realpath'ed already
index 890672c5d27eec47795f1172ce33341db12334ec..617d14dcb9c5fe674a6595c97cb72b3d55d99723 100644 (file)
@@ -46,14 +46,18 @@ if is_emscripten or is_wasi:
 def check_output(cmd, encoding=None):
     p = subprocess.Popen(cmd,
         stdout=subprocess.PIPE,
-        stderr=subprocess.PIPE,
-        encoding=encoding)
+        stderr=subprocess.PIPE)
     out, err = p.communicate()
     if p.returncode:
         if verbose and err:
-            print(err.decode('utf-8', 'backslashreplace'))
+            print(err.decode(encoding or 'utf-8', 'backslashreplace'))
         raise subprocess.CalledProcessError(
             p.returncode, cmd, out, err)
+    if encoding:
+        return (
+            out.decode(encoding, 'backslashreplace'),
+            err.decode(encoding, 'backslashreplace'),
+        )
     return out, err
 
 class BaseTest(unittest.TestCase):
@@ -281,8 +285,8 @@ class BasicTest(BaseTest):
             ('get_config_h_filename()', sysconfig.get_config_h_filename())):
             with self.subTest(call):
                 cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call
-                out, err = check_output(cmd)
-                self.assertEqual(out.strip(), expected.encode(), err)
+                out, err = check_output(cmd, encoding='utf-8')
+                self.assertEqual(out.strip(), expected, err)
 
     @requireVenvCreate
     @unittest.skipUnless(can_symlink(), 'Needs symlinks')
@@ -303,8 +307,8 @@ class BasicTest(BaseTest):
             ('get_config_h_filename()', sysconfig.get_config_h_filename())):
             with self.subTest(call):
                 cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call
-                out, err = check_output(cmd)
-                self.assertEqual(out.strip(), expected.encode(), err)
+                out, err = check_output(cmd, encoding='utf-8')
+                self.assertEqual(out.strip(), expected, err)
 
     if sys.platform == 'win32':
         ENV_SUBDIRS = (
diff --git a/Misc/NEWS.d/next/Windows/2023-12-05-22-56-30.gh-issue-111650.xlWmvM.rst b/Misc/NEWS.d/next/Windows/2023-12-05-22-56-30.gh-issue-111650.xlWmvM.rst
new file mode 100644 (file)
index 0000000..5a34933
--- /dev/null
@@ -0,0 +1,3 @@
+Ensures the ``Py_GIL_DISABLED`` preprocessor variable is defined in
+:file:`pyconfig.h` so that extension modules written in C are able to use
+it.
index fc9fc131f6249a6022369e90a2ddc82eecafdd3d..2681b9c58ecb9da74a2a832fc207e4d06dd90d73 100644 (file)
@@ -1,6 +1,4 @@
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 // Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
index 7920d2c2b8739dd4f56d5e0cd8602ac93da26aa8..fe82e918677f9a386ee1bdc127a63ff63bc7ba92 100644 (file)
@@ -3,9 +3,7 @@
  * using the SystemConfiguration framework.
  */
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 // Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
index 1ef1e97f4b7dcaec9a3a7929f8712bc3f20e7f4d..80f8a92668976b776be114ff81989d9f682e1248 100644 (file)
@@ -11,9 +11,7 @@
  *
  */
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 // Need limited C API version 3.13 for PyModule_Add() on Windows
index 52286f05f7154ce125b5fc7a9eb81675f45468bf..52bda75736b31679c758453a95442adc76387d2b 100644 (file)
@@ -1,6 +1,4 @@
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 #define Py_LIMITED_API 0x030c0000 // 3.12
index 0a650f1b351d2ddb6535725824e8b807c994e54c..d7b8d33b7f716203190bc0a9974c5274ccd09615 100644 (file)
@@ -1,8 +1,6 @@
 /* Test Vectorcall in the limited API */
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 #define Py_LIMITED_API 0x030c0000 // 3.12
index 61bc84134458dabbce1a9c92e927789889c692c0..ef595be0b626db8fd45f0181a5396da495fb1d04 100644 (file)
@@ -4,9 +4,7 @@
 #undef Py_BUILD_CORE_MODULE
 #undef Py_BUILD_CORE_BUILTIN
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 // For now, only limited C API 3.13 is supported
index 245e81b2dce7f8fdf4f5f399afcf1e7470ba8ae5..7e6556ad400cdeccd249b560e740710bfb3154e3 100644 (file)
@@ -4,9 +4,7 @@
  * foo, bar), only the first one is called the same as the compiled file.
  */
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 #define Py_LIMITED_API 0x03020000
index d8b211c632eef16f4f7573698476cd2ecef3921a..4b6852c0d0ec73d432f843d796b754b92c4d3e48 100644 (file)
@@ -3,9 +3,7 @@
  * DCE compatible Universally Unique Identifier library.
  */
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 // Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
index 8287edbfb47f6c819957b5a1406e8d9a7d091038..1100e9f6094352bee6434afdaac023224099b92d 100644 (file)
@@ -1,8 +1,6 @@
 /* Errno module */
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 // Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
index a4b8f648c329e3238ed28b944d1a2e22018a1da5..19020b8cc1b6db2fba1960a7fd763bfac1ac5c71 100644 (file)
@@ -1,6 +1,4 @@
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 // Need limited C API version 3.13 for PySys_Audit()
index 19f61216255cfa1839fe46d805ead9b07a32cb1f..0bb5e12d7c3dd985c5c85719c34316f0f664d144 100644 (file)
@@ -62,9 +62,7 @@
           pass
    */
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 // Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
index 867820a6cb93fae14cfdd4763d92acec128f5c8d..754a368f77e940132f87f0ba1c64c1f1d4eadbeb 100644 (file)
@@ -5,9 +5,7 @@
  * See the xxlimited module for an extension module template.
  */
 
-#ifndef _MSC_VER
 #include "pyconfig.h"   // Py_GIL_DISABLED
-#endif
 
 #ifndef Py_GIL_DISABLED
 #define Py_LIMITED_API 0x03050000
index cb2e4878da26b10ce9850e972758702586113c93..accfd51dd978fb95e59b305943733732c06e912f 100644 (file)
@@ -73,7 +73,10 @@ def copy_if_modified(src, dest):
         )
 
     if do_copy:
-        shutil.copy2(src, dest)
+        try:
+            shutil.copy2(src, dest)
+        except FileNotFoundError:
+            raise FileNotFoundError(src) from None
 
 
 def get_lib_layout(ns):
@@ -208,8 +211,7 @@ def get_layout(ns):
 
         for dest, src in rglob(ns.source / "Include", "**/*.h"):
             yield "include/{}".format(dest), src
-        src = ns.source / "PC" / "pyconfig.h"
-        yield "include/pyconfig.h", src
+        yield "include/pyconfig.h", ns.build / "pyconfig.h"
 
     for dest, src in get_tcltk_lib(ns):
         yield dest, src
similarity index 99%
rename from PC/pyconfig.h
rename to PC/pyconfig.h.in
index e6b368caffe2801c83232e125bc064cf0b1846e9..d8f0a6be69c21a6d9b18cbfb6a520fabc995fb7c 100644 (file)
@@ -739,4 +739,7 @@ Py_NO_ENABLE_SHARED to find out.  Also support MS_NO_COREDLL for b/w compat */
 /* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */
 #define HAVE_X509_VERIFY_PARAM_SET1_HOST 1
 
+/* Define if you want to disable the GIL */
+#undef Py_GIL_DISABLED
+
 #endif /* !Py_CONFIG_H */
index b0e416cfec4699686be4b7da627c3fb174330e50..7e4ebd90f50c2e404f3e8d6d1fe6697a52fa0658 100644 (file)
@@ -35,6 +35,8 @@
    winsound.PlaySound(None, 0)
 */
 
+#include "pyconfig.h"  // Py_GIL_DISABLED
+
 #ifndef Py_GIL_DISABLED
 // Need limited C API version 3.12 for Py_MOD_PER_INTERPRETER_GIL_SUPPORTED
 #define Py_LIMITED_API 0x030c0000
index a1c37e183f21c7f112592816f04f31eea2270355..f8c5fafa561efa54cd664ca997da4e43214240e8 100644 (file)
@@ -89,6 +89,7 @@
   <ItemDefinitionGroup>
     <ClCompile>
       <PreprocessorDefinitions>Py_NO_ENABLE_SHARED;Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <Optimization>Disabled</Optimization>
       <WholeProgramOptimization>false</WholeProgramOptimization>
     </ClCompile>
     <ClCompile Include="..\Python\traceback.c" />
     <ClCompile Include="..\Python\tracemalloc.c" />
   </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\PC\pyconfig.h.in" />
+  </ItemGroup>
   <ItemGroup>
     <!-- BEGIN frozen modules -->
     <None Include="..\Lib\importlib\_bootstrap.py">
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
+
+  <!-- Direct copy from pythoncore.vcxproj, but this one is only used for our
+       own build. All other extension modules will use the copy that pythoncore
+       generates. -->
+  <Target Name="_UpdatePyconfig" BeforeTargets="PrepareForBuild">
+    <MakeDir Directories="$(IntDir)" Condition="!Exists($(IntDir))" />
+    <ItemGroup>
+      <PyConfigH Remove="@(PyConfigH)" />
+      <PyConfigH Include="@(ClInclude)" Condition="'%(Filename)%(Extension)' == 'pyconfig.h.in'" />
+    </ItemGroup>
+    <Error Text="Did not find pyconfig.h" Condition="@(ClInclude) == ''" />
+    <PropertyGroup>
+      <PyConfigH>@(PyConfigH->'%(FullPath)', ';')</PyConfigH>
+      <PyConfigHText>$([System.IO.File]::ReadAllText($(PyConfigH)))</PyConfigHText>
+      <OldPyConfigH Condition="Exists('$(IntDir)pyconfig.h')">$([System.IO.File]::ReadAllText('$(IntDir)pyconfig.h'))</OldPyConfigH>
+    </PropertyGroup>
+    <PropertyGroup Condition="$(DisableGil) == 'true'">
+      <PyConfigHText>$(PyConfigHText.Replace('#undef Py_GIL_DISABLED', '#define Py_GIL_DISABLED 1'))</PyConfigHText>
+    </PropertyGroup>
+    <Message Text="Updating pyconfig.h" Condition="$(PyConfigHText.TrimEnd()) != $(OldPyConfigH.TrimEnd())" />
+    <WriteLinesToFile File="$(IntDir)pyconfig.h"
+                      Lines="$(PyConfigHText)"
+                      Overwrite="true"
+                      Condition="$(PyConfigHText.TrimEnd()) != $(OldPyConfigH.TrimEnd())" />
+  </Target>
+
   <Target Name="_RebuildGetPath" AfterTargets="_RebuildFrozen" Condition="$(Configuration) != 'PGUpdate'">
     <Exec Command='"$(TargetPath)" "%(GetPath.ModName)" "%(GetPath.FullPath)" "%(GetPath.IntFile)"' />
 
index 0acc7045c39a269df843889a01ad59f1a097e936..68c0550f7603b7fa51b25c14fb7d4f83916ce478 100644 (file)
@@ -10,6 +10,8 @@
     <Py_IntDir Condition="'$(Py_IntDir)' == ''">$(MSBuildThisFileDirectory)obj\</Py_IntDir>
     <IntDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\$(ProjectName)\</IntDir>
     <IntDir>$(IntDir.Replace(`\\`, `\`))</IntDir>
+    <!-- pyconfig.h is updated by pythoncore.vcxproj, so it's always in pythoncore's IntDir -->
+    <GeneratedPyConfigDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\pythoncore\</GeneratedPyConfigDir>
     <TargetName Condition="'$(TargetName)' == ''">$(ProjectName)</TargetName>
     <TargetName>$(TargetName)$(PyDebugExt)</TargetName>
     <GenerateManifest>false</GenerateManifest>
@@ -38,9 +40,8 @@
   </PropertyGroup>
   <ItemDefinitionGroup>
     <ClCompile>
-      <AdditionalIncludeDirectories>$(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)Include\internal\mimalloc;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)Include\internal\mimalloc;$(GeneratedPyConfigDir);$(PySourcePath)PC;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <PreprocessorDefinitions Condition="'$(DisableGil)' == 'true'">Py_GIL_DISABLED=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions Condition="'$(SupportPGO)' and ($(Configuration) == 'PGInstrument' or $(Configuration) == 'PGUpdate')">_Py_USING_PGO=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 
       <Optimization>MaxSpeed</Optimization>
@@ -60,6 +61,7 @@
       <AdditionalOptions Condition="$(PlatformToolset) == 'ClangCL'">-Wno-deprecated-non-prototype -Wno-unused-label -Wno-pointer-sign -Wno-incompatible-pointer-types-discards-qualifiers -Wno-unused-function %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions Condition="$(Configuration) != 'Debug' and $(PlatformToolset) == 'ClangCL'">-flto %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions Condition="$(MSVCHasBrokenARM64Clamping) == 'true' and $(Platform) == 'ARM64'">-d2pattern-opt-disable:-932189325 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalOptions Condition="$(GenerateSourceDependencies) == 'true'">/sourceDependencies "$(IntDir.Trim(`\`))" %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <ClCompile Condition="$(Configuration) == 'Debug'">
       <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
index 778fc834c0db9c1f88e34cc03165c1004c5c1cef..90aa8cf28f8c5d5a08027b7e558faf100d7c0630 100644 (file)
     <ClInclude Include="..\Parser\string_parser.h" />
     <ClInclude Include="..\Parser\pegen.h" />
     <ClInclude Include="..\PC\errmap.h" />
-    <ClInclude Include="..\PC\pyconfig.h" />
+    <ClInclude Include="..\PC\pyconfig.h.in" />
     <ClInclude Include="..\Python\condvar.h" />
     <ClInclude Include="..\Python\stdlib_module_names.h" />
     <ClInclude Include="..\Python\thread_nt.h" />
     <Import Project="regen.targets" />
   </ImportGroup>
   <Target Name="_TriggerRegen" BeforeTargets="PrepareForBuild" DependsOnTargets="Regen" />
+
+  <Target Name="_UpdatePyconfig" BeforeTargets="PrepareForBuild">
+    <MakeDir Directories="$(IntDir)" Condition="!Exists($(IntDir))" />
+    <ItemGroup>
+      <PyConfigH Remove="@(PyConfigH)" />
+      <PyConfigH Include="@(ClInclude)" Condition="'%(Filename)%(Extension)' == 'pyconfig.h.in'" />
+    </ItemGroup>
+    <Error Text="Did not find pyconfig.h" Condition="@(ClInclude) == ''" />
+    <PropertyGroup>
+      <PyConfigH>@(PyConfigH->'%(FullPath)', ';')</PyConfigH>
+      <PyConfigHText>$([System.IO.File]::ReadAllText($(PyConfigH)))</PyConfigHText>
+      <OldPyConfigH Condition="Exists('$(IntDir)pyconfig.h')">$([System.IO.File]::ReadAllText('$(IntDir)pyconfig.h'))</OldPyConfigH>
+    </PropertyGroup>
+    <PropertyGroup Condition="$(DisableGil) == 'true'">
+      <PyConfigHText>$(PyConfigHText.Replace('#undef Py_GIL_DISABLED', '#define Py_GIL_DISABLED 1'))</PyConfigHText>
+    </PropertyGroup>
+    <Message Text="Updating pyconfig.h" Condition="$(PyConfigHText.TrimEnd()) != $(OldPyConfigH.TrimEnd())" />
+    <WriteLinesToFile File="$(IntDir)pyconfig.h"
+                      Lines="$(PyConfigHText)"
+                      Overwrite="true"
+                      Condition="$(PyConfigHText.TrimEnd()) != $(OldPyConfigH.TrimEnd())" />
+  </Target>
+  <Target Name="_CopyPyconfig" Inputs="$(IntDir)pyconfig.h" Outputs="$(OutDir)pyconfig.h" AfterTargets="Build" DependsOnTargets="_UpdatePyconfig">
+    <Copy SourceFiles="$(IntDir)pyconfig.h" DestinationFolder="$(OutDir)" />
+  </Target>
+  <Target Name="_CleanPyconfig" AfterTargets="Clean">
+    <Delete Files="$(IntDir)pyconfig.h;$(OutDir)pyconfig.h" />
+  </Target>
+
   <Target Name="_GetBuildInfo" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <GIT Condition="$(GIT) == ''">git</GIT>
index 21f9c848cc6be585a9fda3f88429facaf06c161a..4357dc86d9d3564ea4de88b3b0befc8802437b50 100644 (file)
@@ -3,7 +3,7 @@
     <Fragment>
         <ComponentGroup Id="dev_pyconfig">
             <Component Id="include_pyconfig.h" Directory="include" Guid="*">
-                <File Id="include_pyconfig.h" Name="pyconfig.h" Source="!(bindpath.src)PC\pyconfig.h" KeyPath="yes" />
+                <File Id="include_pyconfig.h" Name="pyconfig.h" Source="pyconfig.h" KeyPath="yes" />
             </Component>
         </ComponentGroup>
     </Fragment>
index 30bfb31471c7b26ad5552bf6b13347efe78e1d85..7df39a3b0ae48edc17255888e8389514c61b69e2 100644 (file)
@@ -143,6 +143,10 @@ def compile_c_extension(
         str(MOD_DIR.parent.parent.parent / "Parser" / "lexer"),
         str(MOD_DIR.parent.parent.parent / "Parser" / "tokenizer"),
     ]
+    if sys.platform == "win32":
+        # HACK: The location of pyconfig.h has moved within our build, and
+        # setuptools hasn't updated for it yet. So add the path manually for now
+        include_dirs.append(pathlib.Path(sysconfig.get_config_h_filename()).parent)
     extension = Extension(
         extension_name,
         sources=[generated_source_path],