[Python-checkins] bpo-45188: Windows now regenerates frozen modules at the start of build instead of late (GH-28322)

zooba webhook-mailer at python.org
Wed Sep 15 13:11:20 EDT 2021


https://github.com/python/cpython/commit/09b4ad11f323f8702cde795e345b75e0fbb1a9a5
commit: 09b4ad11f323f8702cde795e345b75e0fbb1a9a5
branch: main
author: Steve Dower <steve.dower at python.org>
committer: zooba <steve.dower at microsoft.com>
date: 2021-09-15T18:11:12+01:00
summary:

bpo-45188: Windows now regenerates frozen modules at the start of build instead of late (GH-28322)

This will enable us to drop the frozen module header files from the repository.

It does currently cause many source files to be built twice, which just takes more time. For whoever comes to fix this in the future, the files shared between freeze_module and pythoncore should be put into a static library that is consumed by both.

files:
A Misc/NEWS.d/next/Build/2021-09-14-00-47-57.bpo-45188.MNbo_T.rst
A PC/config_minimal.c
M PCbuild/_freeze_module.vcxproj
M PCbuild/pcbuild.proj
M PCbuild/pcbuild.sln
M Programs/_freeze_module.c
M Tools/scripts/freeze_modules.py

diff --git a/Misc/NEWS.d/next/Build/2021-09-14-00-47-57.bpo-45188.MNbo_T.rst b/Misc/NEWS.d/next/Build/2021-09-14-00-47-57.bpo-45188.MNbo_T.rst
new file mode 100644
index 0000000000000..df470e8eeb30c
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2021-09-14-00-47-57.bpo-45188.MNbo_T.rst
@@ -0,0 +1,3 @@
+Windows builds now regenerate frozen modules as the first part of the build.
+Previously the regeneration was later in the build, which would require it
+to be restarted if any modules had changed.
diff --git a/PC/config_minimal.c b/PC/config_minimal.c
new file mode 100644
index 0000000000000..adb1c44a7242e
--- /dev/null
+++ b/PC/config_minimal.c
@@ -0,0 +1,53 @@
+/* Module configuration */
+
+/* This file contains the table of built-in modules.
+    See create_builtin() in import.c. */
+
+#include "Python.h"
+
+extern PyObject* PyInit_faulthandler(void);
+extern PyObject* PyInit__tracemalloc(void);
+extern PyObject* PyInit_gc(void);
+extern PyObject* PyInit_nt(void);
+extern PyObject* PyInit__signal(void);
+extern PyObject* PyInit_winreg(void);
+
+extern PyObject* PyInit__ast(void);
+extern PyObject* PyInit__io(void);
+extern PyObject* PyInit_atexit(void);
+extern PyObject* _PyWarnings_Init(void);
+extern PyObject* PyInit__string(void);
+extern PyObject* PyInit__tokenize(void);
+
+extern PyObject* PyMarshal_Init(void);
+extern PyObject* PyInit__imp(void);
+
+struct _inittab _PyImport_Inittab[] = {
+    {"_ast", PyInit__ast},
+    {"faulthandler", PyInit_faulthandler},
+    {"gc", PyInit_gc},
+    {"nt", PyInit_nt}, /* Use the NT os functions, not posix */
+    {"_signal", PyInit__signal},
+    {"_tokenize", PyInit__tokenize},
+    {"_tracemalloc", PyInit__tracemalloc},
+
+    {"winreg", PyInit_winreg},
+
+    /* This module "lives in" with marshal.c */
+    {"marshal", PyMarshal_Init},
+
+    /* This lives it with import.c */
+    {"_imp", PyInit__imp},
+
+    /* These entries are here for sys.builtin_module_names */
+    {"builtins", NULL},
+    {"sys", NULL},
+    {"_warnings", _PyWarnings_Init},
+    {"_string", PyInit__string},
+
+    {"_io", PyInit__io},
+    {"atexit", PyInit_atexit},
+
+    /* Sentinel */
+    {0, 0}
+};
diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj
index a0bedf49e6990..a87dca75c34fa 100644
--- a/PCbuild/_freeze_module.vcxproj
+++ b/PCbuild/_freeze_module.vcxproj
@@ -88,24 +88,145 @@
   <PropertyGroup Label="UserMacros" />
   <ItemDefinitionGroup>
     <ClCompile>
-      <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>Py_NO_ENABLE_SHARED;Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
+      <AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\Programs\_freeze_module.c" />
+    <ClCompile Include="..\PC\config_minimal.c" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="pythoncore.vcxproj">
-      <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project>
-      <Private>true</Private>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
-      <LinkLibraryDependencies>true</LinkLibraryDependencies>
-      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
-    </ProjectReference>
+    <ClCompile Include="..\Modules\atexitmodule.c" />
+    <ClCompile Include="..\Modules\faulthandler.c" />
+    <ClCompile Include="..\Modules\gcmodule.c" />
+    <ClCompile Include="..\Modules\getbuildinfo.c" />
+    <ClCompile Include="..\Modules\posixmodule.c" />
+    <ClCompile Include="..\Modules\signalmodule.c" />
+    <ClCompile Include="..\Modules\_tracemalloc.c" />
+    <ClCompile Include="..\Modules\_io\_iomodule.c" />
+    <ClCompile Include="..\Modules\_io\bufferedio.c" />
+    <ClCompile Include="..\Modules\_io\bytesio.c" />
+    <ClCompile Include="..\Modules\_io\fileio.c" />
+    <ClCompile Include="..\Modules\_io\iobase.c" />
+    <ClCompile Include="..\Modules\_io\stringio.c" />
+    <ClCompile Include="..\Modules\_io\textio.c" />
+    <ClCompile Include="..\Modules\_io\winconsoleio.c" />
+    <ClCompile Include="..\Objects\abstract.c" />
+    <ClCompile Include="..\Objects\accu.c" />
+    <ClCompile Include="..\Objects\boolobject.c" />
+    <ClCompile Include="..\Objects\bytearrayobject.c" />
+    <ClCompile Include="..\Objects\bytes_methods.c" />
+    <ClCompile Include="..\Objects\bytesobject.c" />
+    <ClCompile Include="..\Objects\call.c" />
+    <ClCompile Include="..\Objects\capsule.c" />
+    <ClCompile Include="..\Objects\cellobject.c" />
+    <ClCompile Include="..\Objects\classobject.c" />
+    <ClCompile Include="..\Objects\codeobject.c" />
+    <ClCompile Include="..\Objects\complexobject.c" />
+    <ClCompile Include="..\Objects\descrobject.c" />
+    <ClCompile Include="..\Objects\dictobject.c" />
+    <ClCompile Include="..\Objects\enumobject.c" />
+    <ClCompile Include="..\Objects\exceptions.c" />
+    <ClCompile Include="..\Objects\fileobject.c" />
+    <ClCompile Include="..\Objects\floatobject.c" />
+    <ClCompile Include="..\Objects\frameobject.c" />
+    <ClCompile Include="..\Objects\funcobject.c" />
+    <ClCompile Include="..\Objects\genericaliasobject.c" />
+    <ClCompile Include="..\Objects\genobject.c" />
+    <ClCompile Include="..\Objects\interpreteridobject.c" />
+    <ClCompile Include="..\Objects\iterobject.c" />
+    <ClCompile Include="..\Objects\listobject.c" />
+    <ClCompile Include="..\Objects\longobject.c" />
+    <ClCompile Include="..\Objects\memoryobject.c" />
+    <ClCompile Include="..\Objects\methodobject.c" />
+    <ClCompile Include="..\Objects\moduleobject.c" />
+    <ClCompile Include="..\Objects\namespaceobject.c" />
+    <ClCompile Include="..\Objects\object.c" />
+    <ClCompile Include="..\Objects\obmalloc.c" />
+    <ClCompile Include="..\Objects\odictobject.c" />
+    <ClCompile Include="..\Objects\picklebufobject.c" />
+    <ClCompile Include="..\Objects\rangeobject.c" />
+    <ClCompile Include="..\Objects\setobject.c" />
+    <ClCompile Include="..\Objects\sliceobject.c" />
+    <ClCompile Include="..\Objects\structseq.c" />
+    <ClCompile Include="..\Objects\tupleobject.c" />
+    <ClCompile Include="..\Objects\typeobject.c" />
+    <ClCompile Include="..\Objects\unicodectype.c" />
+    <ClCompile Include="..\Objects\unicodeobject.c" />
+    <ClCompile Include="..\Objects\unionobject.c" />
+    <ClCompile Include="..\Objects\weakrefobject.c" />
+    <ClCompile Include="..\Parser\myreadline.c" />
+    <ClCompile Include="..\Parser\parser.c" />
+    <ClCompile Include="..\Parser\peg_api.c" />
+    <ClCompile Include="..\Parser\pegen.c" />
+    <ClCompile Include="..\Parser\string_parser.c" />
+    <ClCompile Include="..\Parser\token.c" />
+    <ClCompile Include="..\Parser\tokenizer.c" />
+    <ClCompile Include="..\PC\getpathp.c" />
+    <ClCompile Include="..\PC\invalid_parameter_handler.c" />
+    <ClCompile Include="..\PC\msvcrtmodule.c" />
+    <ClCompile Include="..\PC\winreg.c" />
+    <ClCompile Include="..\Python\_warnings.c" />
+    <ClCompile Include="..\Python\asdl.c" />
+    <ClCompile Include="..\Python\ast.c" />
+    <ClCompile Include="..\Python\ast_opt.c" />
+    <ClCompile Include="..\Python\ast_unparse.c" />
+    <ClCompile Include="..\Python\bltinmodule.c" />
+    <ClCompile Include="..\Python\bootstrap_hash.c" />
+    <ClCompile Include="..\Python\ceval.c" />
+    <ClCompile Include="..\Python\codecs.c" />
+    <ClCompile Include="..\Python\compile.c" />
+    <ClCompile Include="..\Python\context.c" />
+    <ClCompile Include="..\Python\dtoa.c" />
+    <ClCompile Include="..\Python\dynamic_annotations.c" />
+    <ClCompile Include="..\Python\dynload_win.c" />
+    <ClCompile Include="..\Python\errors.c" />
+    <ClCompile Include="..\Python\fileutils.c" />
+    <ClCompile Include="..\Python\formatter_unicode.c" />
+    <ClCompile Include="..\Python\frame.c" />
+    <ClCompile Include="..\Python\future.c" />
+    <ClCompile Include="..\Python\getargs.c" />
+    <ClCompile Include="..\Python\getcompiler.c" />
+    <ClCompile Include="..\Python\getcopyright.c" />
+    <ClCompile Include="..\Python\getopt.c" />
+    <ClCompile Include="..\Python\getplatform.c" />
+    <ClCompile Include="..\Python\getversion.c" />
+    <ClCompile Include="..\Python\hamt.c" />
+    <ClCompile Include="..\Python\hashtable.c" />
+    <ClCompile Include="..\Python\import.c" />
+    <ClCompile Include="..\Python\importdl.c" />
+    <ClCompile Include="..\Python\initconfig.c" />
+    <ClCompile Include="..\Python\marshal.c" />
+    <ClCompile Include="..\Python\modsupport.c" />
+    <ClCompile Include="..\Python\mysnprintf.c" />
+    <ClCompile Include="..\Python\mystrtoul.c" />
+    <ClCompile Include="..\Python\pathconfig.c" />
+    <ClCompile Include="..\Python\preconfig.c" />
+    <ClCompile Include="..\Python\pyarena.c" />
+    <ClCompile Include="..\Python\pyctype.c" />
+    <ClCompile Include="..\Python\pyfpe.c" />
+    <ClCompile Include="..\Python\pyhash.c" />
+    <ClCompile Include="..\Python\pylifecycle.c" />
+    <ClCompile Include="..\Python\pymath.c" />
+    <ClCompile Include="..\Python\pystate.c" />
+    <ClCompile Include="..\Python\pystrcmp.c" />
+    <ClCompile Include="..\Python\pystrhex.c" />
+    <ClCompile Include="..\Python\pystrtod.c" />
+    <ClCompile Include="..\Python\Python-ast.c" />
+    <ClCompile Include="..\Python\pythonrun.c" />
+    <ClCompile Include="..\Python\Python-tokenize.c" />
+    <ClCompile Include="..\Python\pytime.c" />
+    <ClCompile Include="..\Python\specialize.c" />
+    <ClCompile Include="..\Python\structmember.c" />
+    <ClCompile Include="..\Python\suggestions.c" />
+    <ClCompile Include="..\Python\symtable.c" />
+    <ClCompile Include="..\Python\sysmodule.c" />
+    <ClCompile Include="..\Python\thread.c" />
+    <ClCompile Include="..\Python\traceback.c" />
   </ItemGroup>
   <ItemGroup>
     <!-- BEGIN frozen modules -->
@@ -126,7 +247,7 @@
     </None>
     <None Include="..\Tools\freeze\flag.py">
       <ModName>hello</ModName>
-      <IntFile>$(IntDir)ello.g.h</IntFile>
+      <IntFile>$(IntDir)hello.g.h</IntFile>
       <OutFile>$(PySourcePath)Python\frozen_modules\hello.h</OutFile>
     </None>
     <!-- END frozen modules -->
@@ -134,9 +255,9 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-  <Target Name="_RebuildFrozen">
+  <Target Name="_RebuildFrozen" AfterTargets="AfterBuild" Condition="$(Configuration) != 'PGUpdate'">
     <Exec Command='"$(TargetPath)" "%(None.ModName)" "%(None.FullPath)" "%(None.IntFile)"' />
-    
+
     <Copy SourceFiles="%(None.IntFile)"
           DestinationFiles="%(None.OutFile)"
           Condition="!Exists(%(None.OutFile)) or (Exists(%(None.IntFile)) and '$([System.IO.File]::ReadAllText(%(None.OutFile)).Replace(`&#x0D;&#x0A;`, `&#x0A;`))' != '$([System.IO.File]::ReadAllText(%(None.IntFile)).Replace(`&#x0D;&#x0A;`, `&#x0A;`))')">
@@ -145,18 +266,8 @@
 
     <Message Text="Updated files: @(_Updated->'%(Filename)%(Extension)',', ')"
              Condition="'@(_Updated)' != ''" Importance="high" />
-    <Warning Text="Frozen modules (e.g. importlib) were updated. Please rebuild to pick up the changes.%0D%0A%0D%0AIf you are not developing on Windows but you see this error on a continuous integration build, please run 'make regen-all' and commit anything that changes."
-             Condition="'@(_Updated)' != '' and $(Configuration) == 'Debug'" />
-    <Error Text="Frozen (e.g. importlib) files were updated. Please rebuild to pick up the changes.%0D%0A%0D%0AIf you are not developing on Windows but you see this error on a continuous integration build, please run 'make regen-all' and commit anything that changes."
-           Condition="'@(_Updated)' != '' and $(Configuration) == 'Release'" />
-  </Target>
-  <Target Name="RebuildFrozen" AfterTargets="AfterBuild" Condition="$(Configuration) == 'Debug' or $(Configuration) == 'Release'"
-          DependsOnTargets="_RebuildFrozen">
-  </Target>
-  <Target Name="RebuildImportLib" AfterTargets="AfterBuild" Condition="$(Configuration) == 'Debug' or $(Configuration) == 'Release'"
-          DependsOnTargets="_RebuildFrozen">
   </Target>
-  <Target Name="_CleanFrozen" BeforeTargets="CoreClean">
+  <Target Name="_CleanFrozen" BeforeTargets="CoreClean" Condition="$(Configuration) != 'PGUpdate'">
     <ItemGroup>
       <Clean Include="%(None.IntFile)" />
     </ItemGroup>
diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj
index f464ad3b18e44..b3cbd471c66ac 100644
--- a/PCbuild/pcbuild.proj
+++ b/PCbuild/pcbuild.proj
@@ -14,6 +14,18 @@
   </PropertyGroup>
 
   <ItemDefinitionGroup>
+    <FreezeProjects>
+      <Platform>$(Platform)</Platform>
+      <Platform Condition="$(Platform) == 'ARM'">Win32</Platform>
+      <Platform Condition="$(Platform) == 'ARM64'">x64</Platform>
+      <Configuration>$(Configuration)</Configuration>
+      <Configuration Condition="$(Configuration) == 'PGInstrument'">Release</Configuration>
+      <Properties></Properties>
+      <BuildTarget>Build</BuildTarget>
+      <CleanTarget>Clean</CleanTarget>
+      <CleanAllTarget>CleanAll</CleanAllTarget>
+      <BuildInParallel>false</BuildInParallel>
+    </FreezeProjects>
     <Projects>
       <Platform>$(Platform)</Platform>
       <Configuration>$(Configuration)</Configuration>
@@ -73,7 +85,7 @@
     </Projects>
 
     <!-- _freeze_module -->
-    <Projects2 Condition="$(Platform) != 'ARM' and $(Platform) != 'ARM64'" Include="_freeze_module.vcxproj" />
+    <FreezeProjects Include="_freeze_module.vcxproj" />
     <!-- python[w].exe -->
     <Projects2 Include="python.vcxproj;pythonw.vcxproj" />
     <Projects2 Include="python_uwp.vcxproj;pythonw_uwp.vcxproj" Condition="$(IncludeUwp)" />
@@ -82,6 +94,11 @@
   </ItemGroup>
 
   <Target Name="Build">
+    <MSBuild Projects="@(FreezeProjects)"
+             Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)"
+             BuildInParallel="%(BuildInParallel)"
+             StopOnFirstFailure="true"
+             Targets="%(BuildTarget)" />
     <MSBuild Projects="@(Projects)"
              Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)"
              BuildInParallel="%(BuildInParallel)"
diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln
index c774e04971735..3629a8508a3a6 100644
--- a/PCbuild/pcbuild.sln
+++ b/PCbuild/pcbuild.sln
@@ -14,6 +14,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj",
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+	ProjectSection(ProjectDependencies) = postProject
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC} = {19C0C13F-47CA-4432-AFF3-799A296A4DDC}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}"
 EndProject
@@ -793,22 +796,6 @@ Global
 		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32
 		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64
 		{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|ARM.ActiveCfg = Debug|ARM
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|ARM64.ActiveCfg = Debug|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|ARM64.ActiveCfg = PGInstrument|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|ARM64.ActiveCfg = PGUpdate|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|ARM.ActiveCfg = Release|ARM
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|ARM64.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32
-		{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64
 		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM.ActiveCfg = Debug|ARM
 		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM.Build.0 = Debug|ARM
 		{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM64.ActiveCfg = Debug|ARM64
@@ -1059,20 +1046,30 @@ Global
 		{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32
 		{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64
 		{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.ActiveCfg = Debug|ARM
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM64.ActiveCfg = Debug|ARM64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.ActiveCfg = Debug|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.Build.0 = Debug|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM64.ActiveCfg = Debug|x64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM64.Build.0 = Debug|x64
 		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.ActiveCfg = Debug|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.Build.0 = Debug|Win32
 		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.ActiveCfg = Debug|x64
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.Build.0 = Debug|x64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM.ActiveCfg = Release|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM.Build.0 = Release|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM64.ActiveCfg = Release|x64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM64.Build.0 = Release|x64
 		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.ActiveCfg = Release|Win32
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.ActiveCfg = Release|Win32
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.Build.0 = Release|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.ActiveCfg = Release|x64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.Build.0 = Release|x64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|ARM.ActiveCfg = Release|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|ARM64.ActiveCfg = Release|x64
 		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|Win32.ActiveCfg = Release|Win32
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|Win32
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM.ActiveCfg = Release|ARM
-		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM64.ActiveCfg = Release|ARM64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|x64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM.ActiveCfg = Release|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM.Build.0 = Release|Win32
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM64.ActiveCfg = Release|x64
+		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM64.Build.0 = Release|x64
 		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.ActiveCfg = Release|Win32
 		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.Build.0 = Release|Win32
 		{19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.ActiveCfg = Release|x64
diff --git a/Programs/_freeze_module.c b/Programs/_freeze_module.c
index 7e9f02aec8a0f..4b0633e7e7a3d 100644
--- a/Programs/_freeze_module.c
+++ b/Programs/_freeze_module.c
@@ -25,12 +25,7 @@ static const struct _frozen _PyImport_FrozenModules[] = {
     {0, 0, 0} /* sentinel */
 };
 
-#ifndef MS_WINDOWS
-/* On Windows, this links with the regular pythonXY.dll, so this variable comes
-   from frozen.obj. In the Makefile, frozen.o is not linked into this executable,
-   so we define the variable here. */
 const struct _frozen *PyImport_FrozenModules;
-#endif
 
 static const char header[] =
     "/* Auto-generated by Programs/_freeze_module.c */";
diff --git a/Tools/scripts/freeze_modules.py b/Tools/scripts/freeze_modules.py
index a9111eca634b1..044ea095fdcd4 100644
--- a/Tools/scripts/freeze_modules.py
+++ b/Tools/scripts/freeze_modules.py
@@ -6,7 +6,8 @@
 from collections import namedtuple
 import hashlib
 import os
-import os.path
+import ntpath
+import posixpath
 import subprocess
 import sys
 import textwrap
@@ -21,7 +22,19 @@
 STDLIB_DIR = os.path.join(ROOT_DIR, 'Lib')
 # If MODULES_DIR is changed then the .gitattributes file needs to be updated.
 MODULES_DIR = os.path.join(ROOT_DIR, 'Python/frozen_modules')
-TOOL = os.path.join(ROOT_DIR, 'Programs', '_freeze_module')
+
+if sys.platform != "win32":
+    TOOL = os.path.join(ROOT_DIR, 'Programs', '_freeze_module')
+else:
+    def find_tool():
+        for arch in ['amd64', 'win32']:
+            for exe in ['_freeze_module.exe', '_freeze_module_d.exe']:
+                tool = os.path.join(ROOT_DIR, 'PCbuild', arch, exe)
+                if os.path.isfile(tool):
+                    return tool
+        sys.exit("ERROR: missing _freeze_module.exe; you need to run PCbuild/build.bat")
+    TOOL = find_tool()
+    del find_tool
 
 MANIFEST = os.path.join(MODULES_DIR, 'MANIFEST')
 FROZEN_FILE = os.path.join(ROOT_DIR, 'Python', 'frozen.c')
@@ -81,6 +94,28 @@
 }
 
 
+#######################################
+# platform-specific helpers
+
+if os.path is posixpath:
+    relpath_for_posix_display = os.path.relpath
+
+    def relpath_for_windows_display(path, base):
+        return ntpath.relpath(
+            ntpath.join(*path.split(os.path.sep)),
+            ntpath.join(*base.split(os.path.sep)),
+        )
+
+else:
+    relpath_for_windows_display = ntpath.relpath
+
+    def relpath_for_posix_display(path, base):
+        return posixpath.relpath(
+            posixpath.join(*path.split(os.path.sep)),
+            posixpath.join(*base.split(os.path.sep)),
+        )
+
+
 #######################################
 # specs
 
@@ -253,7 +288,7 @@ def summarize(self):
         if source:
             source = f'<{source}>'
         else:
-            source = os.path.relpath(self.pyfile, ROOT_DIR)
+            source = relpath_for_posix_display(self.pyfile, ROOT_DIR)
         return {
             'module': self.name,
             'ispkg': self.ispkg,
@@ -397,7 +432,7 @@ def replace_block(lines, start_marker, end_marker, replacements, file):
         raise Exception(f"End marker {end_marker!r} "
                         f"occurs before start marker {start_marker!r} "
                         f"in file {file}")
-    replacements = [line.rstrip() + os.linesep for line in replacements]
+    replacements = [line.rstrip() + '\n' for line in replacements]
     return lines[:start_pos + 1] + replacements + lines[end_pos:]
 
 
@@ -446,7 +481,7 @@ def regen_frozen(modules):
     for src in _iter_sources(modules):
         # Adding a comment to separate sections here doesn't add much,
         # so we don't.
-        header = os.path.relpath(src.frozenfile, parentdir)
+        header = relpath_for_posix_display(src.frozenfile, parentdir)
         headerlines.append(f'#include "{header}"')
 
     deflines = []
@@ -503,11 +538,10 @@ def regen_makefile(modules):
     frozenfiles = []
     rules = ['']
     for src in _iter_sources(modules):
-        header = os.path.relpath(src.frozenfile, ROOT_DIR)
-        relfile = header.replace('\\', '/')
-        frozenfiles.append(f'\t\t$(srcdir)/{relfile} \\')
+        header = relpath_for_posix_display(src.frozenfile, ROOT_DIR)
+        frozenfiles.append(f'\t\t$(srcdir)/{header} \\')
 
-        pyfile = os.path.relpath(src.pyfile, ROOT_DIR)
+        pyfile = relpath_for_posix_display(src.pyfile, ROOT_DIR)
         # Note that we freeze the module to the target .h file
         # instead of going through an intermediate file like we used to.
         rules.append(f'{header}: Programs/_freeze_module {pyfile}')
@@ -546,9 +580,9 @@ def regen_pcbuild(modules):
         # See bpo-45186 and bpo-45188.
         if src.id not in ESSENTIAL and src.id != 'hello':
             continue
-        pyfile = os.path.relpath(src.pyfile, ROOT_DIR).replace('/', '\\')
-        header = os.path.relpath(src.frozenfile, ROOT_DIR).replace('/', '\\')
-        intfile = header.split('\\')[-1].strip('.h') + '.g.h'
+        pyfile = relpath_for_windows_display(src.pyfile, ROOT_DIR)
+        header = relpath_for_windows_display(src.frozenfile, ROOT_DIR)
+        intfile = ntpath.splitext(ntpath.basename(header))[0] + '.g.h'
         projlines.append(f'    <None Include="..\\{pyfile}">')
         projlines.append(f'      <ModName>{src.frozenid}</ModName>')
         projlines.append(f'      <IntFile>$(IntDir){intfile}</IntFile>')
@@ -600,7 +634,7 @@ def _freeze_module(frozenid, pyfile, frozenfile):
     print('#', '  '.join(os.path.relpath(a) for a in argv), flush=True)
     try:
         subprocess.run(argv, check=True)
-    except subprocess.CalledProcessError:
+    except (FileNotFoundError, subprocess.CalledProcessError):
         if not os.path.exists(TOOL):
             sys.exit(f'ERROR: missing {TOOL}; you need to run "make regen-frozen"')
         raise  # re-raise



More information about the Python-checkins mailing list