Skip to content

Commit d28a8a9

Browse files
committed
Moves Windows installer externals onto SVN and updates the build process to grab them automatically.
1 parent de6e800 commit d28a8a9

File tree

8 files changed

+100
-70
lines changed

8 files changed

+100
-70
lines changed

Tools/msi/README.txt

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,14 @@ the initial download size by separating them into their own MSIs.
6262
Building the Installer
6363
======================
6464

65+
Before building the installer, download extra build dependencies using
66+
Tools\msi\get_externals.bat. (Note that this is in addition to the
67+
similarly named file in PCBuild.)
68+
6569
For testing, the installer should be built with the Tools/msi/build.bat
6670
script:
6771

68-
build.bat [-x86] [-x64] [--doc]
72+
build.bat [-x86] [-x64] [--doc] [--test-marker] [--pack]
6973

7074
This script will build the required configurations of Python and
7175
generate an installer layout in PCBuild/(win32|amd64)/en-us.
@@ -80,8 +84,13 @@ available, it will simply be excluded from the installer. Ensure
8084
also set %HTMLHELP% to the Html Help Compiler (hhc.exe), or put HHC on
8185
your PATH or in externals/.
8286

83-
If WiX is not found on your system, it will be automatically downloaded
84-
and extracted to the externals/ directory.
87+
Specify --test-marker to build an installer that works side-by-side with
88+
an official Python release. All registry keys and install locations will
89+
include an extra marker to avoid overwriting files. This marker is
90+
currently an 'x' prefix, but may change at any time.
91+
92+
Specify --pack to build an installer that does not require all MSIs to
93+
be available alongside. This takes longer, but is easier to share.
8594

8695

8796
For an official release, the installer should be built with the
@@ -175,6 +184,38 @@ The following properties may be passed when building these projects.
175184
When true, rebuilds all of the MSIs making up the layout. Defaults to
176185
true.
177186

187+
Uploading the Installer
188+
=======================
189+
190+
For official releases, the uploadrelease.bat script should be used.
191+
192+
You will require PuTTY so that plink.exe and pscp.exe can be used, and your
193+
SSH key can be activated in pageant.exe. PuTTY should be either on your path
194+
or in %ProgramFiles(x86)%\PuTTY.
195+
196+
To include signatures for each uploaded file, you will need gpg2.exe on your
197+
path or have run get_externals.bat. You may also need to "gpg2.exe --import"
198+
your key before running the upload script.
199+
200+
uploadrelease.bat --host <host> --user <username> [--dry-run] [--no-gpg]
201+
202+
The host is the URL to the server. This can be provided by the Release
203+
Manager. You should be able to SSH to this address.
204+
205+
The username is your own username, which you have permission to SSH into
206+
the server containing downloads.
207+
208+
Use --dry-run to display the generated upload commands without executing
209+
them. Signatures for each file will be generated but not uploaded unless
210+
--no-gpg is also passed.
211+
212+
Use --no-gpg to suppress signature generation and upload.
213+
214+
The default target directory (which appears in uploadrelease.proj) is
215+
correct for official Python releases, but may be overridden with
216+
--target <path> for other purposes. This path should generally not include
217+
any version specifier, as that will be added automatically.
218+
178219
Modifying the Installer
179220
=======================
180221

@@ -298,9 +339,9 @@ based on whether the install is for all users of the machine or just for
298339
the user performing the installation.
299340

300341
The default installation location when installing for all users is
301-
"%ProgramFiles%\Python 3.X" for the 64-bit interpreter and
302-
"%ProgramFiles(x86)%\Python 3.X" for the 32-bit interpreter. (Note that
303-
the latter path is equivalent to "%ProgramFiles%\Python 3.X" when
342+
"%ProgramFiles%\Python3X" for the 64-bit interpreter and
343+
"%ProgramFiles(x86)%\Python3X-32" for the 32-bit interpreter. (Note that
344+
the latter path is equivalent to "%ProgramFiles%\Python3X-32" when
304345
running a 32-bit version of Windows.) This location requires
305346
administrative privileges to install or later modify the installation.
306347

@@ -311,6 +352,8 @@ interpreter. Only the current user can access this location. This
311352
provides a suitable level of protection against malicious modification
312353
of Python's files.
313354

355+
(Default installation locations are set in Tools\msi\bundle\bundle.wxs.)
356+
314357
Within this install directory is the following approximate layout:
315358

316359
.\python[w].exe The core executable files
@@ -487,6 +530,6 @@ Removing Python will clean up all the files and registry keys that were
487530
created by the installer, as well as __pycache__ folders that are
488531
explicitly handled by the installer. Python packages installed later
489532
using a tool like pip will not be removed. Some components may be
490-
installed by other installers (such as the MSVCRT) and these will not be
491-
removed if another product has a dependency on them.
533+
installed by other installers and these will not be removed if another
534+
product has a dependency on them.
492535

Tools/msi/build.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts
1919

2020
if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1)
2121

22+
call "%D%get_externals.bat"
23+
2224
call "%PCBUILD%env.bat" x86
2325

2426
if defined BUILDX86 (
@@ -48,12 +50,10 @@ if defined BUILDPACK (
4850
)
4951

5052
if defined BUILDX86 (
51-
"%PCBUILD%win32\python.exe" "%D%get_wix.py"
5253
msbuild %BUILD_CMD%
5354
if errorlevel 1 goto :eof
5455
)
5556
if defined BUILDX64 (
56-
"%PCBUILD%amd64\python.exe" "%D%get_wix.py"
5757
msbuild /p:Platform=x64 %BUILD_CMD%
5858
if errorlevel 1 goto :eof
5959
)

Tools/msi/buildrelease.bat

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename}
2929

3030
set D=%~dp0
3131
set PCBUILD=%D%..\..\PCBuild\
32+
set EXTERNALS=%D%..\..\externals\windows-installer\
3233

3334
set BUILDX86=
3435
set BUILDX64=
@@ -59,12 +60,15 @@ if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1
5960

6061
if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1)
6162

63+
call "%D%get_externals.bat"
64+
6265
:builddoc
6366
if "%SKIPBUILD%" EQU "1" goto skipdoc
6467
if "%SKIPDOC%" EQU "1" goto skipdoc
6568

6669
if not defined PYTHON where py -q || echo Cannot find py on path and PYTHON is not set. && exit /B 1
6770
if not defined SPHINXBUILD where sphinx-build -q || echo Cannot find sphinx-build on path and SPHINXBUILD is not set. && exit /B 1
71+
6872
call "%D%..\..\doc\make.bat" htmlhelp
6973
if errorlevel 1 goto :eof
7074
:skipdoc
@@ -73,7 +77,7 @@ where hg /q || echo Cannot find Mercurial on PATH && exit /B 1
7377

7478
where dlltool /q && goto skipdlltoolsearch
7579
set _DLLTOOL_PATH=
76-
where /R "%D%..\..\externals" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc"
80+
where /R "%EXTERNALS%\" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc"
7781
if not exist "%_DLLTOOL_PATH%" echo Cannot find binutils on PATH or in external && exit /B 1
7882
for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf
7983
set _DLLTOOL_PATH=
@@ -170,8 +174,6 @@ if not "%SKIPBUILD%" EQU "1" (
170174
@echo off
171175
)
172176

173-
"%BUILD%python.exe" "%D%get_wix.py"
174-
175177
set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI%
176178
if "%PGO%" NEQ "" set BUILDOPTS=%BUILDOPTS% /p:PGOBuildPath=%BUILD%
177179
msbuild "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true

Tools/msi/get_externals.bat

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@echo off
2+
setlocal
3+
rem Simple script to fetch source for external tools
4+
5+
where /Q svn
6+
if ERRORLEVEL 1 (
7+
echo.svn.exe must be on your PATH to get external tools.
8+
echo.Try TortoiseSVN (http://tortoisesvn.net/^) and be sure to check the
9+
echo.command line tools option.
10+
popd
11+
exit /b 1
12+
)
13+
14+
if not exist "%~dp0..\..\externals" mkdir "%~dp0..\..\externals"
15+
pushd "%~dp0..\..\externals"
16+
17+
if "%SVNROOT%"=="" set SVNROOT=http://svn.python.org/projects/external/
18+
19+
if not exist "windows-installer\.svn" (
20+
echo.Checking out installer dependencies to %CD%\windows-installer
21+
svn co %SVNROOT%windows-installer
22+
) else (
23+
echo.Updating installer dependencies in %CD%\windows-installer
24+
svn up windows-installer
25+
)
26+
27+
popd

Tools/msi/get_wix.py

Lines changed: 0 additions & 49 deletions
This file was deleted.

Tools/msi/msi.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
<OutputPath Condition="!HasTrailingSlash($(OutputPath))">$(OutputPath)\</OutputPath>
5454
<OutDir>$(OutputPath)</OutDir>
5555
<ReuseCabinetCache>true</ReuseCabinetCache>
56-
<CRTRedist Condition="'$(CRTRedist)' == ''">$(ExternalsDir)\redist</CRTRedist>
56+
<CRTRedist Condition="'$(CRTRedist)' == ''">$(ExternalsDir)\windows-installer\redist</CRTRedist>
5757
<CRTRedist Condition="!Exists($(CRTRedist))"></CRTRedist>
5858
<DocFilename>python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm</DocFilename>
5959

Tools/msi/uploadrelease.bat

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ set HOST=
88
set USER=
99
set TARGET=
1010
set DRYRUN=false
11+
set NOGPG=
1112

1213
:CheckOpts
1314
if "%1" EQU "-h" goto Help
@@ -18,6 +19,7 @@ if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts
1819
if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts
1920
if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts
2021
if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts
22+
if "%1" EQU "--no-gpg" (set NOGPG=true) && shift && goto CheckOpts
2123

2224
if not defined PLINK where plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc"
2325
if not defined PLINK where /R "%ProgramFiles(x86)%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc"
@@ -31,10 +33,15 @@ if not defined PSCP where /R "%ProgramFiles(x86)%" pscp > "%TEMP%\pscp.loc" 2> n
3133
if not defined PSCP echo Cannot locate pscp.exe & exit /B 1
3234
echo Found pscp.exe at %PSCP%
3335

34-
if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc"
35-
if not defined GPG where /R "%PCBUILD%..\externals" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc"
36-
if not defined GPG echo Cannot locate gpg2.exe. Signatures will not be uploaded & pause
37-
echo Found gpg2.exe at %GPG%
36+
if defined NOGPG (
37+
set GPG=
38+
echo Skipping GPG signature generation because of --no-gpg
39+
) else (
40+
if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc"
41+
if not defined GPG where /R "%PCBUILD%..\externals\windows-installer" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc"
42+
if not defined GPG echo Cannot locate gpg2.exe. Signatures will not be uploaded & pause
43+
echo Found gpg2.exe at %GPG%
44+
)
3845

3946
call "%PCBUILD%env.bat" > nul 2> nul
4047
pushd "%D%"

Tools/msi/wix.props

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
<PropertyGroup>
66
<WixInstallPath Condition="'$(WixInstallPath)' == '' and Exists('$(MSBuildThisFileDirectory)\Wix')">$(MSBuildThisFileDirectory)\Wix\</WixInstallPath>
7-
<WixInstallPath Condition="'$(WixInstallPath)' == '' and Exists('$(ExternalsDir)\Wix')">$(ExternalsDir)\Wix\</WixInstallPath>
8-
<WixInstallPath Condition="'$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.9@InstallRoot)</WixInstallPath>
9-
<WixInstallPath Condition="'$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.9@InstallRoot)</WixInstallPath>
7+
<WixInstallPath Condition="'$(WixInstallPath)' == '' and Exists('$(ExternalsDir)\windows-installer\wix')">$(ExternalsDir)\windows-installer\wix\</WixInstallPath>
8+
<WixInstallPath Condition="'$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.10@InstallRoot)</WixInstallPath>
9+
<WixInstallPath Condition="'$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.10@InstallRoot)</WixInstallPath>
1010
<WixTargetsPath>$(WixInstallPath)\Wix.targets</WixTargetsPath>
1111
</PropertyGroup>
1212
</Project>

0 commit comments

Comments
 (0)