Skip to content

Commit

Permalink
pythongh-111650: Generate pyconfig.h on Windows
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
colesbury committed Nov 16, 2023
1 parent f4b5588 commit 10ceec5
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion PC/pyconfig.h → PC/pyconfig.h.in
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
50 changes: 50 additions & 0 deletions PCbuild/generate_pyconfig.ps1
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions PCbuild/pcbuild.proj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<Import Project="python.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{CC9B93A2-439D-4058-9D29-6DCF43774405}</ProjectGuid>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
Expand All @@ -14,6 +15,7 @@
<IncludeSSL Condition="'$(IncludeSSL)' == ''">true</IncludeSSL>
<IncludeTkinter Condition="'$(IncludeTkinter)' == ''">true</IncludeTkinter>
<IncludeUwp Condition="'$(IncludeUwp)' == ''">false</IncludeUwp>
<PyConfigArgs Condition="'$(DisableGil)' == 'true'">Py_NOGIL=1,$(PyConfigArgs)</PyConfigArgs>
</PropertyGroup>

<ItemDefinitionGroup>
Expand Down Expand Up @@ -94,6 +96,11 @@
<Projects2 Include="venvlauncher.vcxproj;venvwlauncher.vcxproj" />
</ItemGroup>

<Target Name="PreBuild" BeforeTargets="Build">
<!-- Stick a _PLACEHOLDER=1 after $(PyConfigArgs) to handle both trailing commas and empty $(PyConfigArgs) -->
<Exec Command="powershell.exe $(PySourcePath)PCbuild\generate_pyconfig.ps1 -File $(PySourcePath)PC\pyconfig.h -define $(PyConfigArgs)_PLACEHOLDER=1" />
</Target>

<Target Name="Build">
<MSBuild Projects="@(FreezeProjects)"
Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)"
Expand Down
1 change: 0 additions & 1 deletion PCbuild/pyproject.props
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
<ClCompile>
<AdditionalIncludeDirectories>$(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)Include\internal\mimalloc;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(DisableGil)' == 'true'">Py_NOGIL=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>

<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
Expand Down

0 comments on commit 10ceec5

Please sign in to comment.