From 10ceec5e1ab95b59a52ee66a9b3a57ab19cbd5a0 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Thu, 16 Nov 2023 20:07:00 +0000 Subject: [PATCH] gh-111650: Generate pyconfig.h on Windows Prior to this change, the Py_NOGIL macro was not defined when building C API extensions with the `--disable-gil` build on Windows. `Py_NOGIL` was only defined as a pre-processor definition in pyproject.props, but that is not used by C-API extensions. This instead generates the `pyconfig.h` header on Windows as part of the build process. For now, `Py_NOGIL` is the only macro that may be conditionally defined in the generated file. --- .gitignore | 1 + PC/{pyconfig.h => pyconfig.h.in} | 5 +++- PCbuild/generate_pyconfig.ps1 | 50 ++++++++++++++++++++++++++++++++ PCbuild/pcbuild.proj | 7 +++++ PCbuild/pyproject.props | 1 - 5 files changed, 62 insertions(+), 2 deletions(-) rename PC/{pyconfig.h => pyconfig.h.in} (99%) create mode 100644 PCbuild/generate_pyconfig.ps1 diff --git a/.gitignore b/.gitignore index 8c8273fc7a3aa38..f568cd9fa82208d 100644 --- a/.gitignore +++ b/.gitignore @@ -92,6 +92,7 @@ Programs/_testembed PC/python_nt*.h PC/pythonnt_rc*.h Modules/python.exp +PC/pyconfig.h PC/*/*.exp PC/*/*.lib PC/*/*.bsc diff --git a/PC/pyconfig.h b/PC/pyconfig.h.in similarity index 99% rename from PC/pyconfig.h rename to PC/pyconfig.h.in index e6b368caffe2801..1fe2295920f00fa 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h.in @@ -1,7 +1,7 @@ #ifndef Py_CONFIG_H #define Py_CONFIG_H -/* pyconfig.h. NOT Generated automatically by configure. +/* pyconfig.h.in. This is a manually maintained version used for the Watcom, Borland and Microsoft Visual C++ compilers. It is a @@ -710,6 +710,9 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define to 1 if you have the `erfc' function. */ #define HAVE_ERFC 1 +/* Define if you want to disable the GIL */ +#undef Py_NOGIL + // netdb.h functions (provided by winsock.h) #define HAVE_GETHOSTNAME 1 #define HAVE_GETHOSTBYADDR 1 diff --git a/PCbuild/generate_pyconfig.ps1 b/PCbuild/generate_pyconfig.ps1 new file mode 100644 index 000000000000000..525a3582e12f658 --- /dev/null +++ b/PCbuild/generate_pyconfig.ps1 @@ -0,0 +1,50 @@ +# +# Generates pyconfig.h from PC\pyconfig.h.in +# + +param ( + [string[]]$define, + [string]$File +) + +$definedValues = @{} + +foreach ($arg in $define) { + $parts = $arg -split '=' + + if ($parts.Count -eq 1) { + $key = $parts[0] + $definedValues[$key] = "" + } elseif ($parts.Count -eq 2) { + $key = $parts[0] + $value = $parts[1] + $definedValues[$key] = $value + } else { + Write-Host "Invalid argument: $arg" + exit 1 + } +} + +$cpythonRoot = Split-Path $PSScriptRoot -Parent +$pyconfigPath = Join-Path $cpythonRoot "PC\pyconfig.h.in" + +$header = "/* pyconfig.h. Generated from PC\pyconfig.h.in by generate_pyconfig.ps1. */" + +$lines = Get-Content -Path $pyconfigPath +$lines = @($header) + $lines + +foreach ($i in 0..($lines.Length - 1)) { + if ($lines[$i] -match "^#undef (\w+)$") { + $key = $Matches[1] + if ($definedValues.ContainsKey($key)) { + $value = $definedValues[$key] + $lines[$i] = "#define $key $value".TrimEnd() + } else { + $lines[$i] = "/* #undef $key */" + } + } +} + +$ParentDir = Split-Path -Path $File -Parent +New-Item -ItemType Directory -Force -Path $ParentDir | Out-Null +Set-Content -Path $File -Value $lines diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj index b7b78be768d7ecf..76c794bbdec5547 100644 --- a/PCbuild/pcbuild.proj +++ b/PCbuild/pcbuild.proj @@ -3,6 +3,7 @@ + {CC9B93A2-439D-4058-9D29-6DCF43774405} Win32 @@ -14,6 +15,7 @@ true true false + Py_NOGIL=1,$(PyConfigArgs) @@ -94,6 +96,11 @@ + + + + + $(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)Include\internal\mimalloc;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories) WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions) - Py_NOGIL=1;%(PreprocessorDefinitions) MaxSpeed true