1@setlocal
2@echo off
3
4rem This script is intended for building official releases of Python.
5rem To use it to build alternative releases, you should clone this file
6rem and modify the following three URIs.
7
8rem These two will ensure that your release can be installed
9rem alongside an official Python release, by modifying the GUIDs used
10rem for all components.
11rem
12rem The following substitutions will be applied to the release URI:
13rem     Variable        Description         Example
14rem     {arch}          architecture        amd64, win32
15set RELEASE_URI=https://www.python.org/{arch}
16
17rem This is the URL that will be used to download installation files.
18rem The files available from the default URL *will* conflict with your
19rem installer. Trust me, you don't want them, even if it seems like a
20rem good idea.
21rem
22rem The following substitutions will be applied to the download URL:
23rem     Variable        Description         Example
24rem     {version}       version number      3.5.0
25rem     {arch}          architecture        amd64, win32
26rem     {releasename}   release name        a1, b2, rc3 (or blank for final)
27rem     {msi}           MSI filename        core.msi
28set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi}
29
30set D=%~dp0
31set PCBUILD=%D%..\..\PCbuild\
32if NOT DEFINED Py_OutDir set Py_OutDir=%PCBUILD%
33set EXTERNALS=%D%..\..\externals\windows-installer\
34
35set BUILDX86=
36set BUILDX64=
37set TARGET=Rebuild
38set TESTTARGETDIR=
39set PGO=-m test -q --pgo
40set BUILDMSI=1
41set BUILDNUGET=1
42set BUILDZIP=1
43
44
45:CheckOpts
46if "%1" EQU "-h" goto Help
47if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts
48if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts
49if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts
50if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts
51if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts
52if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts
53if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts
54if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts
55if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts
56if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts
57if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts
58if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts
59if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts
60if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts
61if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts
62if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts
63if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts
64if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts
65if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts
66
67if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1
68
69if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1)
70
71if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc"
72if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1
73
74call "%D%get_externals.bat"
75call "%PCBUILD%find_msbuild.bat" %MSBUILD%
76if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
77
78:builddoc
79if "%SKIPBUILD%" EQU "1" goto skipdoc
80if "%SKIPDOC%" EQU "1" goto skipdoc
81
82call "%D%..\..\doc\make.bat" htmlhelp
83if errorlevel 1 goto :eof
84:skipdoc
85
86where dlltool /q && goto skipdlltoolsearch
87set _DLLTOOL_PATH=
88where /R "%EXTERNALS%\" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc"
89if not exist "%_DLLTOOL_PATH%" echo Cannot find binutils on PATH or in external && exit /B 1
90for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf
91set _DLLTOOL_PATH=
92:skipdlltoolsearch
93
94if defined BUILDX86 (
95    call :build x86
96    if errorlevel 1 exit /B
97)
98
99if defined BUILDX64 (
100    call :build x64 "%PGO%"
101    if errorlevel 1 exit /B
102)
103
104if defined TESTTARGETDIR (
105    call "%D%testrelease.bat" -t "%TESTTARGETDIR%"
106)
107
108exit /B 0
109
110:build
111@setlocal
112@echo off
113
114if "%1" EQU "x86" (
115    set PGO=
116    set BUILD=%Py_OutDir%win32\
117    set BUILD_PLAT=Win32
118    set OUTDIR_PLAT=win32
119    set OBJDIR_PLAT=x86
120) else (
121    set BUILD=%Py_OutDir%amd64\
122    set PGO=%~2
123    set BUILD_PLAT=x64
124    set OUTDIR_PLAT=amd64
125    set OBJDIR_PLAT=x64
126)
127
128if exist "%BUILD%en-us" (
129    echo Deleting %BUILD%en-us
130    rmdir /q/s "%BUILD%en-us"
131    if errorlevel 1 exit /B
132)
133
134if exist "%D%obj\Debug_%OBJDIR_PLAT%" (
135    echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%"
136    rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%"
137    if errorlevel 1 exit /B
138)
139
140if exist "%D%obj\Release_%OBJDIR_PLAT%" (
141    echo Deleting "%D%obj\Release_%OBJDIR_PLAT%"
142    rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%"
143    if errorlevel 1 exit /B
144)
145
146if not "%CERTNAME%" EQU "" (
147    set CERTOPTS="/p:SigningCertificate=%CERTNAME%"
148) else (
149    set CERTOPTS=
150)
151if not "%PGO%" EQU "" (
152    set PGOOPTS=--pgo-job "%PGO%"
153) else (
154    set PGOOPTS=
155)
156if not "%SKIPBUILD%" EQU "1" (
157    @echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS%
158    @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS%
159    @if errorlevel 1 exit /B
160    @rem build.bat turns echo back on, so we disable it again
161    @echo off
162
163    @echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET%
164    @call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET%
165    @if errorlevel 1 exit /B
166    @rem build.bat turns echo back on, so we disable it again
167    @echo off
168)
169
170if "%OUTDIR_PLAT%" EQU "win32" (
171    %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI%
172    if errorlevel 1 exit /B
173) else if not exist "%Py_OutDir%win32\en-us\launcher.msi" (
174    %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI%
175    if errorlevel 1 exit /B
176)
177
178set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI%
179if defined BUILDMSI (
180    %MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true
181    if errorlevel 1 exit /B
182    %MSBUILD% "%D%bundle\releaseweb.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false
183    if errorlevel 1 exit /B
184)
185
186if defined BUILDZIP (
187    %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us"
188    if errorlevel 1 exit /B
189)
190
191if defined BUILDNUGET (
192    %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us"
193    if errorlevel 1 exit /B
194)
195
196if not "%OUTDIR%" EQU "" (
197    mkdir "%OUTDIR%\%OUTDIR_PLAT%"
198    mkdir "%OUTDIR%\%OUTDIR_PLAT%\binaries"
199    mkdir "%OUTDIR%\%OUTDIR_PLAT%\symbols"
200    robocopy "%BUILD%en-us" "%OUTDIR%\%OUTDIR_PLAT%" /XF "*.wixpdb"
201    robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\binaries" *.exe *.dll *.pyd /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*"
202    robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\symbols" *.pdb              /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*"
203)
204
205exit /B 0
206
207:Help
208echo buildrelease.bat [--out DIR] [-x86] [-x64] [--certificate CERTNAME] [--build] [--pgo COMMAND]
209echo                  [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] [--skip-pgo]
210echo                  [--download DOWNLOAD URL] [--test TARGETDIR]
211echo                  [-h]
212echo.
213echo    --out (-o)          Specify an additional output directory for installers
214echo    -x86                Build x86 installers
215echo    -x64                Build x64 installers
216echo    --build (-b)        Incrementally build Python rather than rebuilding
217echo    --skip-build (-B)   Do not build Python (just do the installers)
218echo    --skip-doc (-D)     Do not build documentation
219echo    --pgo               Specify PGO command for x64 installers
220echo    --skip-pgo          Build x64 installers without using PGO
221echo    --skip-msi          Do not build executable/MSI packages
222echo    --skip-nuget        Do not build Nuget packages
223echo    --skip-zip          Do not build embeddable package
224echo    --download          Specify the full download URL for MSIs
225echo    --test              Specify the test directory to run the installer tests
226echo    -h                  Display this help information
227echo.
228echo If no architecture is specified, all architectures will be built.
229echo If --test is not specified, the installer tests are not run.
230echo.
231echo For the --pgo option, any Python command line can be used, or 'default' to
232echo use the default task (-m test --pgo).
233echo.
234echo The following substitutions will be applied to the download URL:
235echo     Variable        Description         Example
236echo     {version}       version number      3.5.0
237echo     {arch}          architecture        amd64, win32
238echo     {releasename}   release name        a1, b2, rc3 (or blank for final)
239echo     {msi}           MSI filename        core.msi
240