1@echo off
2goto Run
3:Usage
4echo.%~nx0 [flags and arguments] [quoted MSBuild options]
5echo.
6echo.Build CPython from the command line.  Requires the appropriate
7echo.version(s) of Microsoft Visual Studio to be installed (see readme.txt).
8echo.
9echo.After the flags recognized by this script, up to 9 arguments to be passed
10echo.directly to MSBuild may be passed.  If the argument contains an '=', the
11echo.entire argument must be quoted (e.g. `%~nx0 "/p:PlatformToolset=v100"`).
12echo.Alternatively you can put extra flags for MSBuild in a file named
13echo.`msbuild.rsp` in the `PCbuild` directory, one flag per line. This file
14echo.will be picked automatically by MSBuild. Flags put in this file does not
15echo.need to be quoted. You can still use environment variables inside the
16echo.response file.
17echo.
18echo.Available flags:
19echo.  -h  Display this help message
20echo.  -V  Display version information for the current build
21echo.  -r  Target Rebuild instead of Build
22echo.  -d  Set the configuration to Debug
23echo.  -E  Don't fetch or build external libraries.  Extension modules that
24echo.      depend on external libraries will not attempt to build if this flag
25echo.      is present; -e is also accepted to explicitly enable fetching and
26echo.      building externals.
27echo.  -m  Enable parallel build (enabled by default)
28echo.  -M  Disable parallel build
29echo.  -v  Increased output messages
30echo.  -vv Verbose output messages
31echo.  -q  Quiet output messages (errors and warnings only)
32echo.  -k  Attempt to kill any running Pythons before building (usually done
33echo.      automatically by the pythoncore project)
34echo.  --pgo          Build with Profile-Guided Optimization.  This flag
35echo.                 overrides -c and -d
36echo.  --test-marker  Enable the test marker within the build.
37echo.
38echo.Available flags to avoid building certain modules.
39echo.These flags have no effect if '-e' is not given:
40echo.  --no-ctypes   Do not attempt to build _ctypes
41echo.  --no-ssl      Do not attempt to build _ssl
42echo.  --no-tkinter  Do not attempt to build Tkinter
43echo.
44echo.Available arguments:
45echo.  -c Release ^| Debug ^| PGInstrument ^| PGUpdate
46echo.     Set the configuration (default: Release)
47echo.  -p x64 ^| Win32 ^| ARM ^| ARM64
48echo.     Set the platform (default: Win32)
49echo.  -t Build ^| Rebuild ^| Clean ^| CleanAll
50echo.     Set the target manually
51echo.  --pgo-job  The job to use for PGO training; implies --pgo
52echo.             (default: "-m test --pgo")
53exit /b 127
54
55:Run
56setlocal
57set platf=Win32
58set conf=Release
59set target=Build
60set dir=%~dp0
61set parallel=/m
62set verbose=/nologo /v:m /clp:summary
63set kill=
64set do_pgo=
65set pgo_job=-m test --pgo
66
67:CheckOpts
68if "%~1"=="-h" goto Usage
69if "%~1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts
70if "%~1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts
71if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts
72if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts
73if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts
74if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts
75if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts
76if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts
77if "%~1"=="-vv" (set verbose=/v:d /ds) & shift & goto CheckOpts
78if "%~1"=="-q" (set verbose=/v:q /nologo /clp:summary) & shift & goto CheckOpts
79if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts
80if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts
81if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts
82if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts
83if "%~1"=="-V" shift & goto :Version
84rem These use the actual property names used by MSBuild.  We could just let
85rem them in through the environment, but we specify them on the command line
86rem anyway for visibility so set defaults after this
87if "%~1"=="-e" (set IncludeExternals=true) & shift & goto CheckOpts
88if "%~1"=="-E" (set IncludeExternals=false) & shift & goto CheckOpts
89if "%~1"=="--no-ctypes" (set IncludeCTypes=false) & shift & goto CheckOpts
90if "%~1"=="--no-ssl" (set IncludeSSL=false) & shift & goto CheckOpts
91if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts
92
93if "%IncludeExternals%"=="" set IncludeExternals=true
94if "%IncludeCTypes%"=="" set IncludeCTypes=true
95if "%IncludeSSL%"=="" set IncludeSSL=true
96if "%IncludeTkinter%"=="" set IncludeTkinter=true
97
98if "%IncludeExternals%"=="true" call "%dir%get_externals.bat"
99
100if "%do_pgo%" EQU "true" if "%platf%" EQU "x64" (
101    if "%PROCESSOR_ARCHITEW6432%" NEQ "AMD64" if "%PROCESSOR_ARCHITECTURE%" NEQ "AMD64" (
102        echo.ERROR: Cannot cross-compile with PGO
103        echo.       32bit operating system detected. Ensure your PROCESSOR_ARCHITECTURE
104        echo.       and PROCESSOR_ARCHITEW6432 environment variables are correct.
105        exit /b 1
106    )
107)
108
109if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc"
110if exist "%GIT%" set GITProperty=/p:GIT="%GIT%"
111if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty=
112
113rem Setup the environment
114call "%dir%find_msbuild.bat" %MSBUILD%
115if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
116
117if "%kill%"=="true" call :Kill
118if ERRORLEVEL 1 exit /B 3
119
120if "%do_pgo%"=="true" (
121    set conf=PGInstrument
122    call :Build %1 %2 %3 %4 %5 %6 %7 %8 %9
123)
124rem %VARS% are evaluated eagerly, which would lose the ERRORLEVEL
125rem value if we didn't split it out here.
126if "%do_pgo%"=="true" if ERRORLEVEL 1 exit /B %ERRORLEVEL%
127if "%do_pgo%"=="true" (
128    del /s "%dir%\*.pgc"
129    del /s "%dir%\..\Lib\*.pyc"
130    echo on
131    call "%dir%\..\python.bat" %pgo_job%
132    @echo off
133    call :Kill
134    set conf=PGUpdate
135    set target=Build
136)
137goto :Build
138
139:Kill
140echo on
141%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^
142 /p:Configuration=%conf% /p:Platform=%platf%^
143 /p:KillPython=true
144
145@echo off
146exit /B %ERRORLEVEL%
147
148:Build
149rem Call on MSBuild to do the work, echo the command.
150rem Passing %1-9 is not the preferred option, but argument parsing in
151rem batch is, shall we say, "lackluster"
152echo on
153%MSBUILD% "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^
154 /p:Configuration=%conf% /p:Platform=%platf%^
155 /p:IncludeExternals=%IncludeExternals%^
156 /p:IncludeCTypes=%IncludeCTypes%^
157 /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^
158 /p:UseTestMarker=%UseTestMarker% %GITProperty%^
159 %1 %2 %3 %4 %5 %6 %7 %8 %9
160
161@echo off
162exit /b %ERRORLEVEL%
163
164:Version
165rem Display the current build version information
166call "%dir%find_msbuild.bat" %MSBUILD%
167if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
168%MSBUILD% "%dir%pythoncore.vcxproj" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9
169if ERRORLEVEL 1 exit /b 3