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-ssl      Do not attempt to build _ssl
41echo.  --no-tkinter  Do not attempt to build Tkinter
42echo.
43echo.Available arguments:
44echo.  -c Release ^| Debug ^| PGInstrument ^| PGUpdate
45echo.     Set the configuration (default: Release)
46echo.  -p x64 ^| Win32
47echo.     Set the platform (default: Win32)
48echo.  -t Build ^| Rebuild ^| Clean ^| CleanAll
49echo.     Set the target manually
50echo.  --pgo-job  The job to use for PGO training; implies --pgo
51echo.             (default: "-m test --pgo")
52exit /b 127
53
54:Run
55setlocal
56set platf=Win32
57set conf=Release
58set target=Build
59set dir=%~dp0
60set parallel=/m
61set verbose=/nologo /v:m
62set kill=
63set do_pgo=
64set pgo_job=-m test --pgo
65
66:CheckOpts
67if "%~1"=="-h" goto Usage
68if "%~1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts
69if "%~1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts
70if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts
71if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts
72if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts
73if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts
74if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts
75if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts
76if "%~1"=="-vv" (set verbose=/v:d /ds) & shift & goto CheckOpts
77if "%~1"=="-q" (set verbose=/v:q /nologo /clp:summary) & shift & goto CheckOpts
78if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts
79if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts
80if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts
81if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts
82if "%~1"=="-V" shift & goto Version
83rem These use the actual property names used by MSBuild.  We could just let
84rem them in through the environment, but we specify them on the command line
85rem anyway for visibility so set defaults after this
86if "%~1"=="-e" (set IncludeExternals=true) & shift & goto CheckOpts
87if "%~1"=="-E" (set IncludeExternals=false) & shift & goto CheckOpts
88if "%~1"=="--no-ssl" (set IncludeSSL=false) & shift & goto CheckOpts
89if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts
90
91if "%IncludeExternals%"=="" set IncludeExternals=true
92if "%IncludeSSL%"=="" set IncludeSSL=true
93if "%IncludeTkinter%"=="" set IncludeTkinter=true
94
95if "%IncludeExternals%"=="true" call "%dir%get_externals.bat"
96
97if "%do_pgo%" EQU "true" if "%platf%" EQU "x64" (
98    if "%PROCESSOR_ARCHITEW6432%" NEQ "AMD64" if "%PROCESSOR_ARCHITECTURE%" NEQ "AMD64" (
99        echo.ERROR: Cannot cross-compile with PGO
100        echo.       32bit operating system detected. Ensure your PROCESSOR_ARCHITECTURE
101        echo.       and PROCESSOR_ARCHITEW6432 environment variables are correct.
102        exit /b 1
103    )
104)
105
106if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc"
107if exist "%GIT%" set GITProperty=/p:GIT="%GIT%"
108if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty=
109
110rem Setup the environment
111call "%dir%find_msbuild.bat" %MSBUILD%
112if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2)
113
114if "%kill%"=="true" call :Kill
115
116if "%do_pgo%"=="true" (
117    set conf=PGInstrument
118    call :Build %1 %2 %3 %4 %5 %6 %7 %8 %9
119    del /s "%dir%\*.pgc"
120    del /s "%dir%\..\Lib\*.pyc"
121    echo on
122    call "%dir%\..\python.bat" %pgo_job%
123    @echo off
124    call :Kill
125    set conf=PGUpdate
126    set target=Build
127)
128goto Build
129:Kill
130echo on
131%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^
132 /p:Configuration=%conf% /p:Platform=%platf%^
133 /p:KillPython=true
134
135@echo off
136goto :eof
137
138:Build
139rem Call on MSBuild to do the work, echo the command.
140rem Passing %1-9 is not the preferred option, but argument parsing in
141rem batch is, shall we say, "lackluster"
142echo on
143%MSBUILD% "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^
144 /p:Configuration=%conf% /p:Platform=%platf%^
145 /p:IncludeExternals=%IncludeExternals%^
146 /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^
147 /p:UseTestMarker=%UseTestMarker% %GITProperty%^
148 %1 %2 %3 %4 %5 %6 %7 %8 %9
149
150@echo off
151goto :eof
152
153:Version
154rem Display the current build version information
155call "%dir%find_msbuild.bat" %MSBUILD%
156if not ERRORLEVEL 1 %MSBUILD% "%dir%pythoncore.vcxproj" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9
157