Skip to content

Commit 2c899cc

Browse files
authored
bpo-30687: Fixes build scripts to find msbuild.exe and stop relying on vcvarsall.bat (#2252) (#2281)
* Fixes build scripts to find msbuild.exe and stop relying on vcvarsall.bat Also fixes bdist_wininst.vcxproj to use correct version in generated name.
1 parent a601fcc commit 2c899cc

File tree

10 files changed

+135
-95
lines changed

10 files changed

+135
-95
lines changed

Misc/NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ Library
252252
Windows
253253
-------
254254

255+
- bpo-30687: Locate msbuild.exe on Windows when building rather than
256+
vcvarsall.bat
257+
255258
- Issue #29392: Prevent crash when passing invalid arguments into msvcrt module.
256259

257260
C API

PC/bdist_wininst/bdist_wininst.vcxproj

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
<OutDir>$(PySourcePath)lib\distutils\command\</OutDir>
5959
<LinkIncremental>false</LinkIncremental>
6060
<TargetName>wininst-$(VisualStudioVersion)</TargetName>
61+
<TargetName Condition="$(PlatformToolset) == 'v140'">wininst-14.0</TargetName>
62+
<TargetName Condition="$(PlatformToolset) == 'v120'">wininst-12.0</TargetName>
63+
<TargetName Condition="$(PlatformToolset) == 'v110'">wininst-11.0</TargetName>
64+
<TargetName Condition="$(PlatformToolset) == 'v100'">wininst-10.0</TargetName>
6165
<TargetName Condition="$(Platform) == 'x64'">$(TargetName)-amd64</TargetName>
6266
<TargetExt>.exe</TargetExt>
6367
</PropertyGroup>

PC/bdist_wininst/build.bat

+4-7
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@ set PCBUILD=%~dp0..\..\PCBuild\
77

88
echo Building Lib\distutils\command\wininst-xx.0.exe
99

10-
call "%PCBUILD%env.bat" x86
11-
if errorlevel 1 goto :eof
10+
call "%PCBUILD%find_msbuild.bat" %MSBUILD%
11+
if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
1212

13-
msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=Win32
13+
%MSBUILD% "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=Win32
1414
if errorlevel 1 goto :eof
1515

1616

1717
echo Building Lib\distutils\command\wininst-xx.0-amd64.exe
1818

19-
call "%PCBUILD%env.bat" x86_amd64
20-
if errorlevel 1 goto :eof
21-
22-
msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=x64
19+
%MSBUILD% "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=x64

PCbuild/build.bat

+11-21
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ exit /b 127
4848
:Run
4949
setlocal
5050
set platf=Win32
51-
set vs_platf=x86
5251
set conf=Release
5352
set target=Build
5453
set dir=%~dp0
@@ -57,10 +56,6 @@ set verbose=/nologo /v:m
5756
set kill=
5857
set do_pgo=
5958
set pgo_job=-m test --pgo
60-
set on_64_bit=true
61-
62-
rem This may not be 100% accurate, but close enough.
63-
if "%ProgramFiles(x86)%"=="" (set on_64_bit=false)
6459

6560
:CheckOpts
6661
if "%~1"=="-h" goto Usage
@@ -90,18 +85,12 @@ if "%IncludeTkinter%"=="" set IncludeTkinter=true
9085

9186
if "%IncludeExternals%"=="true" call "%dir%get_externals.bat"
9287

93-
if "%platf%"=="x64" (
94-
if "%on_64_bit%"=="true" (
95-
rem This ought to always be correct these days...
96-
set vs_platf=amd64
97-
) else (
98-
if "%do_pgo%"=="true" (
99-
echo.ERROR: Cannot cross-compile with PGO
100-
echo. 32bit operating system detected, if this is incorrect,
101-
echo. make sure the ProgramFiles(x86^) environment variable is set
102-
exit /b 1
103-
)
104-
set vs_platf=x86_amd64
88+
if "%do_pgo%" EQU "true" if "%platf%" EQU "x64" (
89+
if "%PROCESSOR_ARCHITEW6432%" NEQ "AMD64" if "%PROCESSOR_ARCHITECTURE%" NEQ "AMD64" (
90+
echo.ERROR: Cannot cross-compile with PGO
91+
echo. 32bit operating system detected. Ensure your PROCESSOR_ARCHITECTURE
92+
echo. and PROCESSOR_ARCHITEW6432 environment variables are correct.
93+
exit /b 1
10594
)
10695
)
10796

@@ -110,7 +99,8 @@ if exist "%GIT%" set GITProperty=/p:GIT="%GIT%"
11099
if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty=
111100

112101
rem Setup the environment
113-
call "%dir%env.bat" %vs_platf% >nul
102+
call "%dir%find_msbuild.bat" %MSBUILD%
103+
if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
114104

115105
if "%kill%"=="true" call :Kill
116106

@@ -129,7 +119,7 @@ goto Build
129119

130120
:Kill
131121
echo on
132-
msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^
122+
%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^
133123
/p:Configuration=%conf% /p:Platform=%platf%^
134124
/p:KillPython=true
135125

@@ -141,7 +131,7 @@ rem Call on MSBuild to do the work, echo the command.
141131
rem Passing %1-9 is not the preferred option, but argument parsing in
142132
rem batch is, shall we say, "lackluster"
143133
echo on
144-
msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^
134+
%MSBUILD% "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^
145135
/p:Configuration=%conf% /p:Platform=%platf%^
146136
/p:IncludeExternals=%IncludeExternals%^
147137
/p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^
@@ -153,4 +143,4 @@ goto :eof
153143

154144
:Version
155145
rem Display the current build version information
156-
msbuild "%dir%python.props" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9
146+
%MSBUILD% "%dir%python.props" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9

PCbuild/find_msbuild.bat

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
@rem
2+
@rem Searches for MSBuild.exe. This is the only tool we need to initiate
3+
@rem a build, so we no longer search for the full VC toolset.
4+
@rem
5+
@rem This file is supposed to modify the state of the caller (specifically
6+
@rem the MSBUILD variable), so we do not use setlocal or echo, and avoid
7+
@rem changing any other persistent state.
8+
@rem
9+
10+
@rem No arguments provided means do full search
11+
@if '%1' EQU '' goto :begin_search
12+
13+
@rem One argument may be the full path. Use a goto so we don't try to
14+
@rem parse the next if statement - incorrect quoting in the multi-arg
15+
@rem case can cause us to break immediately.
16+
@if '%2' EQU '' goto :one_arg
17+
18+
@rem Entire command line may represent the full path if quoting failed.
19+
@if exist "%*" (set MSBUILD="%*") & (set _Py_MSBuild_Source=environment) & goto :found
20+
@goto :begin_search
21+
22+
:one_arg
23+
@if exist "%~1" (set MSBUILD="%~1") & (set _Py_MSBuild_Source=environment) & goto :found
24+
25+
:begin_search
26+
@set MSBUILD=
27+
28+
@rem If msbuild.exe is on the PATH, assume that the user wants that one.
29+
@where msbuild > "%TEMP%\msbuild.loc" 2> nul && set /P MSBUILD= < "%TEMP%\msbuild.loc" & del "%TEMP%\msbuild.loc"
30+
@if exist "%MSBUILD%" set MSBUILD="%MSBUILD%" & (set _Py_MSBuild_Source=PATH) & goto :found
31+
32+
@rem VS 2017 sets exactly one install as the "main" install, so we may find MSBuild in there.
33+
@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32 >nul 2>nul
34+
@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32') DO @(
35+
@if "%%i"=="15.0" @if exist "%%k\MSBuild\15.0\Bin\msbuild.exe" @(set MSBUILD="%%k\MSBuild\15.0\Bin\msbuild.exe")
36+
)
37+
@if exist %MSBUILD% (set _Py_MSBuild_Source=Visual Studio 2017 registry) & goto :found
38+
39+
@rem VS 2015 and earlier register MSBuild separately, so we can find it.
40+
@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32 >nul 2>nul
41+
@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32') DO @(
42+
@if "%%i"=="MSBuildToolsPath" @if exist "%%k\msbuild.exe" @(set MSBUILD="%%k\msbuild.exe")
43+
)
44+
@if exist %MSBUILD% (set _Py_MSBuild_Source=registry) & goto :found
45+
46+
47+
@exit /b 1
48+
49+
:found
50+
@echo Using %MSBUILD% (found in the %_Py_MSBuild_Source%)
51+
@set _Py_MSBuild_Source=

PCbuild/python.vcxproj

+4-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
8484
<ImportGroup Label="ExtensionTargets">
8585
</ImportGroup>
86-
<Target Name="ValidateUcrtbase" AfterTargets="AfterBuild">
86+
<Target Name="ValidateUcrtbase" AfterTargets="AfterBuild" Condition="$(Configuration) != 'PGInstrument'">
8787
<PropertyGroup>
8888
<UcrtName>ucrtbase</UcrtName>
8989
<UcrtName Condition="'$(Configuration)' == 'Debug'">ucrtbased</UcrtName>
@@ -94,6 +94,8 @@ set PYTHONPATH=$(PySourcePath)Lib
9494
</Target>
9595
<Target Name="GeneratePythonBat" AfterTargets="AfterBuild">
9696
<PropertyGroup>
97+
<_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(Platform) == 'Win32'">@set PATH=%PATH%%3B$(VCInstallDir)bin</_PGOPath>
98+
<_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(Platform) == 'x64'">@set PATH=%PATH%%3B$(VCInstallDir)bin\amd64</_PGOPath>
9799
<_Content>@rem This script invokes the most recently built Python with all arguments
98100
@rem passed through to the interpreter. This file is generated by the
99101
@rem build process and any changes *will* be thrown away by the next
@@ -103,6 +105,7 @@ set PYTHONPATH=$(PySourcePath)Lib
103105
@echo Running $(Configuration)^|$(Platform) interpreter...
104106
@setlocal
105107
@set PYTHONHOME=$(PySourcePath)
108+
$(_PGOPath)
106109
@"$(OutDir)python$(PyDebugExt).exe" %*
107110
</_Content>
108111
<_ExistingContent Condition="Exists('$(PySourcePath)python.bat')">$([System.IO.File]::ReadAllText('$(PySourcePath)python.bat'))</_ExistingContent>

Tools/msi/build.bat

+5-5
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts
2222
if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1)
2323

2424
call "%D%get_externals.bat"
25-
26-
call "%PCBUILD%env.bat" x86
25+
call "%PCBUILD%find_msbuild.bat" %MSBUILD%
26+
if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
2727

2828
if defined BUILDX86 (
2929
call "%PCBUILD%build.bat" -d -e %REBUILD% %BUILDTEST%
@@ -44,7 +44,7 @@ if defined BUILDDOC (
4444
)
4545

4646
rem Build the launcher MSI separately
47-
msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86
47+
%MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86
4848

4949
set BUILD_CMD="%D%bundle\snapshot.wixproj"
5050
if defined BUILDTEST (
@@ -58,11 +58,11 @@ if defined REBUILD (
5858
)
5959

6060
if defined BUILDX86 (
61-
msbuild %BUILD_CMD%
61+
%MSBUILD% %BUILD_CMD%
6262
if errorlevel 1 goto :eof
6363
)
6464
if defined BUILDX64 (
65-
msbuild /p:Platform=x64 %BUILD_CMD%
65+
%MSBUILD% /p:Platform=x64 %BUILD_CMD%
6666
if errorlevel 1 goto :eof
6767
)
6868

0 commit comments

Comments
 (0)