diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -17,11 +17,13 @@ platform$ pyconfig.h$ python$ +python.bat$ python.exe$ python-config$ python-config.py$ reflog.txt$ tags$ +win-config.dat$ Lib/plat-mac/errors.rsrc.df.rsrc Doc/tools/sphinx/ Doc/tools/docutils/ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -19,6 +19,13 @@ you are going to create an optimized build you want to select "Release" as configuration. +Python can also be built from the command line, using the supplied +"configure.bat" and "make.bat" scripts. The most common usage is: + + configure --with-pydebug && make + +See "Using make.bat" below for more details. + The PCbuild directory is compatible with all versions of Visual Studio from VS C++ Express Edition over the standard edition up to the professional edition. However the express edition does not support features like solution @@ -117,8 +124,8 @@ svn export http://svn.python.org/projects/external/bzip2-1.0.6 - ** NOTE: if you use the Tools\buildbot\external(-amd64).bat approach for - obtaining external sources then you don't need to manually get the source + ** NOTE: if you use the `make external` approach for obtaining + external sources then you don't need to manually get the source above via subversion. ** A custom pre-link step in the bz2 project settings should manage to @@ -137,6 +144,10 @@ extract to ..\xz-5.0.3. If you are using a more recent version of liblzma, it will be necessary to rename the directory from xz- to xz-5.0.3. + ** NOTE: if you use the `make external` approach for obtaining + external sources then you don't need to manually get the source + for liblzma. ** + _ssl Python wrapper for the secure sockets library. @@ -144,8 +155,8 @@ svn export http://svn.python.org/projects/external/openssl-1.0.1e - ** NOTE: if you use the Tools\buildbot\external(-amd64).bat approach for - obtaining external sources then you don't need to manually get the source + ** NOTE: if you use the `make external` approach for obtaining + external sources then you don't need to manually get the source above via subversion. ** Alternatively, get the latest version from http://www.openssl.org. @@ -187,29 +198,17 @@ The subprojects above wrap external projects Python doesn't control, and as such, a little more work is required in order to download the relevant source -files for each project before they can be built. The buildbots do this each -time they're built, so the easiest approach is to run either external.bat or -external-amd64.bat in the ..\Tools\buildbot directory from ..\, i.e.: +files for each project before they can be built. The simple method is to use +the make.bat script's "external" target, which requires "svn.exe" to be on your +PATH. It extracts all the external subprojects from +http://svn.python.org/external and places them in ..\.. (relative to this +directory). - C:\..\svn.python.org\projects\python\trunk\PCbuild>cd .. - C:\..\svn.python.org\projects\python\trunk>Tools\buildbot\external.bat +The "tcltk" target is also available to build Tcl/Tk, which +requires "configure.bat" to have been run. The "build" target ensures that all +externals are present and Tcl/Tk is built before building Python. -This extracts all the external subprojects from http://svn.python.org/external -via Subversion (so you'll need an svn.exe on your PATH) and places them in -..\.. (relative to this directory). The external(-amd64).bat scripts will -also build a debug build of Tcl/Tk; there aren't any equivalent batch files -for building release versions of Tcl/Tk lying around in the Tools\buildbot -directory. If you need to build a release version of Tcl/Tk it isn't hard -though, take a look at the relevant external(-amd64).bat file and find the -two nmake lines, then call each one without the 'DEBUG=1' parameter, i.e.: - -The external-amd64.bat file contains this for tcl: - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install - -So for a release build, you'd call it as: - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install - - XXX Should we compile with OPTS=threads? + XXX Should we compile Tcl/Tk with OPTS=threads? XXX Our installer copies a lot of stuff out of the Tcl/Tk install XXX directory. Is all of that really needed for Python use of Tcl/Tk? @@ -303,6 +302,83 @@ change the "Runtime Library" from "Multi-threaded DLL (/MD)" to "Multi-threaded (/MT)". +Using make.bat +-------------- + +Using make.bat is intended to be the easiest way to quickly build Python, +emulating the use of the Unix make utility. Before running make.bat, you +must run configure.bat with any options you like; the available configure +options can be found by running `configure --help`. Once configured, +make.bat offers several "targets" which can be found by running `make help`. +Each target will perform a different operation, as described in make.bat's +usage message. + +The most common command for the two scripts is as follows: + + configure --with-pydebug && make build test + +This command configures the environment for building a Debug build of Python +(defaulting to 32 bit, unless on a 64 bit machine capable of building 64 bit +Python), builds Python, and then runs the Python test suite if the build +succeeded. It will also leave behind a simple "python.bat" script which will +pass all given commands to the newly built interpreter and a "win-config.dat" +file which holds values for all variables set by configure.bat so that it need +not be run again unless you wish to change certain options. In most cases, the +defaults used by this command will be sufficient. In those cases where you do +want to affect how building is done, you can set environment variables either +before running the script, or on the command line of the script. The variables +available to change are listed below: + + PY_CONFIGURATION -- Which configuration of Python to build, Debug or + Release. This var is best set by configure.bat. + (default: Release) + PY_PLATFORM -- Which platform to build Python for, Win32 or x64. This + var is best set by configure.bat. (default: Win32, + except on 64-bit machines with 64-bit compilers + configured) + PY_NO_EXTERNALS -- If defined (with any value), make.bat will not attempt + to fetch or build external libraries, but they will be + built if they are already where pcbuild.sln expects them + to be. This var is best set by configure.bat. + (default: undefined) + PY_INTERACTIVE -- If defined (with any value), make.bat will ask for user + input in some situations. This var is best set by + configure.bat. (default: undefined) + PYTHON2 -- The command make.bat should use when it needs a Python 2 + interpreter. (default: `py -2`) + PYTHON3 -- The command make.bat should use when it needs a Python 3 + interpreter. (default: python.bat, any Python + interpreter in this source tree, `py -3`, or `python`) + TCLTARGETS -- Targets to pass to Tcl and Tk's build scripts, see + Tcl/Tk documentation for valid options. + (default: clean all install) + TESTPYTHON -- The Python interpreter to run the test suite on. + (default: python.bat or the value of %PYTHON3%) + TESTRUNNER -- The Python command to pass to TESTPYTHON to run the test + suite. (default: Tools\scripts\run_tests.py) + TESTOPTS -- Options to pass to the test runner. (no default setting) + +The options below can only be overridden by specifying them on the command line, +and only affect the way external libraries are fetched. + + BZ2VERSION -- (default: bzip2-1.0.6) + OPENSSLVERSION -- (default: openssl-1.0.1e) + TCLVERSION -- (default: tcl-8.5.11.0) + TKVERSION -- (default: tk-8.5.11.0) + SQLITEVERSION -- (default: sqlite-3.7.12) + LZMAVERSION -- (default: xz-5.0.3) + Set the version of the external library to fetch, and + the name of the folder to fetch it into. Note that to + actually build a version other than the default, other + changes will need to be made in various places + (dependent on the library). + SVNROOT -- The root address from which to fetch external libraries. + (default: http://svn.python.org/projects/external/) + EXTERNALS_DIR -- The directory to fetch external libraries into. Note + that changing this var will require a change to + pyproject.props to actually build the external + libraries. (default: ..\..) + Visual Studio properties ------------------------ diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py --- a/Tools/scripts/run_tests.py +++ b/Tools/scripts/run_tests.py @@ -44,7 +44,11 @@ args.extend(['-u', 'all,-largefile,-audio,-gui']) args.extend(regrtest_args) print(' '.join(args)) - os.execv(sys.executable, args) + if sys.platform == 'win32': + from subprocess import call + call(args) + else: + os.execv(sys.executable, args) if __name__ == '__main__': diff --git a/configure.bat b/configure.bat new file mode 100644 --- /dev/null +++ b/configure.bat @@ -0,0 +1,83 @@ +@echo off +rem Copyright (c) 2013 by Zachary Ware +rem Licensed to PSF under a Contributor Agreement. + +if "%VS100COMNTOOLS%" EQU "" ( + echo Visual Studio not found! + echo Please install at least Microsoft Visual C++ 2010 Express Edition. + goto :eof +) + +setlocal +setlocal enabledelayedexpansion +pushd %~dp0 + + +rem Set defaults + +if "%PY_CONFIGURATION%" EQU "" set PY_CONFIGURATION=Release + +if "%PY_PLATFORM%" EQU "" ( + if DEFINED ProgramFiles(x86^) ( + if EXIST "%VS100COMNTOOLS%..\..\VC\bin\x86_amd64\vcvarsx86_amd64.bat" ( + set PY_PLATFORM=x64 + ) else ( + set PY_PLATFORM=Win32 + ) + ) else ( + set PY_PLATFORM=Win32 + ) +) + +set PY_NO_EXTERNALS= + +set PY_INTERACTIVE= + +rem Set specified vars +for %%o in (%*) do ( + if "%%o" EQU "-h" goto help + if "%%o" EQU "--help" goto help + if "%%o" EQU "--with-pydebug" set PY_CONFIGURATION=Debug + if "%%o" EQU "--with-64-bit" set PY_PLATFORM=x64 + if "%%o" EQU "--without-64-bit" set PY_PLATFORM=Win32 + if "%%o" EQU "--no-externals" set PY_NO_EXTERNALS=defined + if "%%o" EQU "--interactive" set PY_INTERACTIVE=defined +) + +rem Write settings to disk +echo # Configuration settings for building Python > win-config.dat +echo # These values are set by configure.bat and read by make.bat >> win-config.dat +echo. >> win-config.dat + +for %%x in ( + PY_CONFIGURATION, PY_PLATFORM, PY_NO_EXTERNALS, PY_INTERACTIVE +) do ( + echo %%x=!%%x! >> win-config.dat + echo %%x set to "!%%x!" +) + +echo. +echo Saved in %~dp0win-config.dat + +goto end + + + +:help +echo Available options: +echo -h, --help Display this help message +echo. +echo --with-pydebug Build with debug configuration +echo --with(out)-64-bit Enable/disable 64 bit support +echo. +echo --no-externals Don't pull in external libraries +echo Note: This option will cause (expected) build errors^^! +echo --interactive There's a user available to answer questions +echo. +echo All other options are ignored. +goto end + + + +:end +popd diff --git a/make.bat b/make.bat new file mode 100644 --- /dev/null +++ b/make.bat @@ -0,0 +1,770 @@ +@echo off +rem This is a simple emulation of a very limited subset of the functionality of +rem the UNIX make utility, specific to the CPython project. + +rem Copyright (c) 2013 by Zachary Ware +rem Licensed to PSF under a Contributor Agreement. + +rem Exit codes used by this script are as follows: +rem 0 - Success +rem 1 - Generic failure, check output +rem 2 - Bad options given, usage message shown +rem 3 - Third party program not available (NASM, svn, etc.) +rem 4 - Python build failed +rem 5 - Tcl build failed (not returned if Tcl build failed in `build` target) +rem 6 - Configure options not set +rem Any other non-zero code was returned by an external source called by this script + +setlocal +setlocal enabledelayedexpansion + +if [%1] EQU [-C] goto -C + +pushd "%~dp0" + +set _this=%~n0 + + +rem Set default versions (and folder names) for externals. This should be the +rem only place in this file these need to be changed when updated. + +set BZ2VERSION=bzip2-1.0.6 +set OPENSSLVERSION=openssl-1.0.1e +set TCLVERSION=tcl-8.5.11.0 +set TKVERSION=tk-8.5.11.0 +set SQLITEVERSION=sqlite-3.7.12 +set LZMAVERSION=xz-5.0.3 + +set SVNROOT=http://svn.python.org/projects/external/ + +rem Change this var if "externalsDir" has been changed in +rem PCbuild\pyproject.props; this should match it (meaning this path should be +rem relative to the PCbuild dir). +set EXTERNALS_DIR=..\.. + +rem Don't change it here +set EXTERNALS_DIR=%~dp0PCbuild\%EXTERNALS_DIR% + + +rem Try to set configure vars. They can also be set from the command line, so +rem don't worry too much if they're not available here. +if EXIST win-config.dat for /F "eol=#" %%x in (win-config.dat) do set %%x + + +rem ###################### +echo %_this%: Parsing the command line... +echo. + +rem Any variable set above this point can be overridden by command line +rem arguments. Nearly all others should be "private" (start with _). + +set _args=%* + +if NOT DEFINED _args set _args=build + +set _args=%_args:"=[d-quote]% +set _argterm=___ENDOFARGS___ +set _args=%_args% %_argterm% + +set _targets= +set _string= +set _var= +set _value= +set _name= +set _quotes=0 + +:loop + +set _char=%_args:~0,1% + +set _args=%_args:~1% + +if DEFINED _var ( + if "%_char%" EQU "[" ( + if "%_args:~0,8%" EQU "d-quote]" ( + set _args=!_args:~8! + if NOT DEFINED _string ( + set /a _quotes+=1 + ) else ( + set /a _quotes-=1 + ) + set _char=!_args:~0,1! + set _args=!_args:~1! + ) + ) +) + +if "%_char%" EQU "\" ( + if "%_args:~0,9%" EQU "[d-quote]" ( + set _args=%_args:~9% + set _char=\[d-quote] + ) +) + +if %_quotes% LSS 1 ( + if "%_char%" EQU " " ( + if NOT DEFINED _var ( + set _name=!_string! + set _string= + ) else ( + if NOT DEFINED _string ( + set _value=[unset] + ) else ( + set _value=!_string! + set _string= + ) + ) + ) else ( + if "%_char%" EQU "=" ( + if NOT DEFINED _var ( + set _var=!_string:\[d-quote]="! + set _string= + ) + ) else ( + set _string=!_string!!_char! + ) + ) +) else ( + set _string=!_string!!_char! +) + +if DEFINED _name ( + set _target=%_name:[d-quote]="% + set _target=!_target:\"="! + set _targets=%_targets% !_target! + set _name= +) else ( + if DEFINED _var ( + if DEFINED _value ( + if "%_value%" EQU "[unset]" ( + set %_var%= + echo %_this%: %_var% unset + ) else ( + set _value=!_value:\[d-quote]="! + set %_var%=!_value! + echo %_this%: %_var% set to '!_value!' + ) + set _var= + set _value= + ) + ) +) + +if "%_args%" NEQ "%_argterm%" goto loop + +if %_quotes% GTR 0 ( + echo %_this%: Unmatched " in command line, aborting. + popd + exit /B 1 +) + +if "%_targets%" EQU "" ( + set _targets=build +) + +rem End argument parsing magic +rem ########################## + +rem Find an interpreter to use, if one isn't provided. Prefer python.bat (the +rem interpreter most recently built by this script), followed by any other +rem interpreter found in this source tree, followed by an installed Python. In +rem places where it matters, python.bat will be tried explicitly first since it +rem might not exist right now, but could later in the life of this script run. + +if "%PYTHON3%" EQU "" ( + if EXIST python.bat ( + set PYTHON3=python.bat + ) else ( + for /F "usebackq" %%p in (`where /R PCbuild python*.exe 2^>nul`) do ( + set PYTHON3=%%p + ) + if "!PYTHON3!" EQU "" ( + where /Q py.exe + if !ERRORLEVEL! EQU 0 ( + set PYTHON3=py -3 + ) else ( + set PYTHON3=python + ) + ) + ) +) + + +rem Set some internal vars + +if "%PY_PLATFORM%" EQU "x64" ( + set _vcvarsarg=x86_amd64 + set _pybuilddir=%~dp0PCbuild\amd64 + set _tclmachine=AMD64 + set _tclinstalldir=%EXTERNALS_DIR%\tcltk64 +) else ( + set _vcvarsarg=x86 + set _pybuilddir=%~dp0PCbuild + set _tclmachine=IX86 + set _tclinstalldir=%EXTERNALS_DIR%\tcltk +) + + +rem Get the Tcl major.minor version, which will have the . removed below +set _tclbuildextension=!TCLVERSION:~4,3! + +if "%PY_CONFIGURATION%" EQU "Debug" ( + set _pybuildextension=_d.exe + set _tclbuildextension=!_tclbuildextension:.=!g.dll + set _tcldebugsetting=1 +) else ( + set _pybuildextension=.exe + set _tclbuildextension=!_tclbuildextension:.=!.dll + set _tcldebugsetting=0 +) + +rem Call each target, or show a usage message + +rem This variable should hold all valid targets (except -C). + +set _all_targets=all, build, buildbottest, clean, clobber, external, ^ + importlib, msi, patchcheck, tcltk, test + +for %%x in (%_targets%) do ( + for %%y in (%_all_targets%) do ( + if "%%x" EQU "%%y" ( + set _good=True + ) + ) + if NOT DEFINED _good ( + echo %_this%: Unknown target '%%x' + goto usage + ) + set _good= +) + +for %%x in (%_targets%) do ( + echo. + echo %_this%: executing %%x target + echo. + + call :%%x + if !ERRORLEVEL! NEQ 0 ( + echo. + echo %_this%: %%x target failed, aborting. + popd + exit /B !ERRORLEVEL! + ) +) + +popd +exit /B 0 + +echo %_this%: This line should never be printed; all top-level execution should +echo be done above here and everything below should be labelled "subroutines". + +:usage +echo. +echo The Python Make Script for Windows +echo ---------------------------------- +echo Please note that this script is only intended to emulate a very small +echo portion of the UNIX make utility, and only for the CPython project. +echo. +echo Usage: +echo %_this% [all ^| build] -- Build CPython +echo %_this% clean -- Clean out build artifacts for current configuration +echo %_this% clobber -- Clean out all build artifacts and remove externals +echo %_this% patchcheck -- Run Tools\scripts\patchcheck.py +echo %_this% external -- Fetch external libraries in preparation for building +echo %_this% importlib -- Build and run the _freeze_importlib project +echo %_this% msi -- Build a Python .msi +echo %_this% tcltk -- Build Tcl/Tk and install .dlls +echo %_this% test -- Test Python +echo %_this% buildbottest -- Test Python with default options for buildbots +echo %_this% -C DIR [args] -- Change dir to DIR and call another make.bat in that +echo dir with 'args'. E.g. ``make -C Doc html`` +echo. +echo You can also set environment variables for the duration of the script by +echo including them in the command line, e.g.: +echo. +echo make test TESTOPTS="-j 4" TESTPYTHON=PCbuild\python_d.exe + +popd +exit /B 2 + + +:all +:build +rem Builds Python. If requested, first pulls in all external projects and +rem builds Tcl/Tk. Also creates python.bat for convenient calling of the +rem newly built interpreter. + +if "%PY_PLATFORM%" EQU "" goto no-configure +if "%PY_CONFIGURATION%" EQU "" goto no-configure + +echo %_this%: Configured for %PY_CONFIGURATION% %PY_PLATFORM% build. +echo. + +if DEFINED PY_NO_EXTERNALS ( + echo %_this%: Not checking for externals. + echo They will be built if available, ignored if not. + echo. +) else ( + where /Q nasm + if !ERRORLEVEL! NEQ 0 ( + echo %_this%: NASM (version 2.10.01 or greater^) is required to build + echo OpenSSL and was not found on your PATH. It can be + echo downloaded from http://www.nasm.us/ + echo. + if DEFINED PY_INTERACTIVE ( + set /P _continue=Continue without NASM? (y/n^) + ) else ( + set _continue=y + ) + echo. + if /I "!_continue:~,1!" EQU "y" ( + echo %_this%: Continuing... + ) else ( + echo %_this%: Aborting. + exit /B 3 + ) + echo. + ) + + call :external + + if !ERRORLEVEL! NEQ 0 ( + echo %_this%: external target failed (exit code !ERRORLEVEL!^) + exit /B 1 + ) + + if NOT EXIST "%_pybuilddir%\tcl%_tclbuildextension%" set _NeedTclTk=1 + if NOT EXIST "%_pybuilddir%\tk%_tclbuildextension%" set _NeedTclTk=1 + if NOT EXIST "%_tclinstalldir%\include\tcl.h" set _NeedTclTk=1 + + if DEFINED _NeedTclTk ( + set _NeedTclTk= + echo %_this%: Building Tcl/Tk... + call :tcltk + ) else echo %_this%: Necessary Tcl/Tk bits found, no need to build. +) +echo. + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" %_vcvarsarg% + +set _builtpython=%_pybuilddir%\python%_pybuildextension% + +@echo on + +@echo %_this%: Building kill_python... +msbuild PCbuild\kill_python.vcxproj /p:Configuration=Debug /p:PlatformTarget=%PY_PLATFORM% + +@echo. +@echo %_this%: Killing all Pythons running from this checkout... +cmd /C "%_pybuilddir%\kill_python_d.exe" + +@if !ERRORLEVEL! NEQ 0 ( + @echo. + @echo %_this%: kill_python ended with errors, aborting... + @exit /B !ERRORLEVEL! +) + +@echo. +@echo %_this%: Deleting the executable, just to make sure it's fresh +del "%_builtpython%" >nul 2>&1 + +@echo. +@echo %_this%: Building Python... +msbuild PCbuild\pcbuild.sln /p:Configuration=%PY_CONFIGURATION% /p:Platform=%PY_PLATFORM% + +@echo off +echo. + +if EXIST "%_builtpython%" ( + if !ERRORLEVEL! NEQ 0 ( + if DEFINED PY_NO_EXTERNALS ( + echo %_this%: Build errors were expected due to lack of optional external libraries. + echo. + echo %_this%: The newly built Python should still work as expected, though without + echo certain extension modules. + ) else ( + echo %_this%: Build errors were not expected, but Python built anyway. + echo %_this%: Run the test suite (`make test`^) to determine whether the freshly + echo built interpreter is usable. + ) + ) else echo %_this%: Python built successfully^^! + + echo. + echo %_this%: Creating convenience batch script python.bat... + echo @"%_builtpython%" %%* > python.bat + echo %_this%: Testing python.bat... + set _command=python.bat -c "import sys;print(sys.version, '\n\nBuild complete.')" + echo !_command! + echo. + call !_command! + exit /B !ERRORLEVEL! +) else ( + echo %_this%: Python build failed. Check the output above for clues. + exit /B 4 +) + +echo %_this%: This line should not have been reached, please report a bug. +exit /B 1 + + + +:clean +rem Cleans up the environment a bit. Builds the "clean" target of pcbuild.sln +rem in both Release and Debug configurations. + +if "%PY_PLATFORM%" EQU "" goto no-configure + +echo %_this%: Configured for %PY_PLATFORM% platform. + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" %_vcvarsarg% + +@echo on +@echo %_this%: Deleting .pyc/.pyo files ... +del /s Lib\*.pyc Lib\*.pyo + +@echo %_this%: Deleting test leftovers ... +rmdir /s /q build + +msbuild /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=%PY_PLATFORM% + +@if !ERRORLEVEL! NEQ 0 set _warn=1 + +msbuild /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=%PY_PLATFORM% + +@if !ERRORLEVEL! NEQ 0 set _warn=1 + +@echo %_this%: Removing python.bat... +del python.bat + +@echo off + +if DEFINED _warn ( + echo. + echo %_this%: Building the clean targets produced errors, check above output for details. +) + +exit /B 0 + + + +:clobber +rem A deeper clean than the "clean" target; cleans both possible platforms. +rem Also removes all externals dirs, removes Tcl/Tk .dlls, and removes the +rem configuration file created by configure.bat. + +echo %_this%: Cleaning 32-bit build... +echo. +set PY_PLATFORM=Win32 +set _vcvarsarg=x86 +call :clean +echo. + +if EXIST "%VS100COMNTOOLS%..\..\VC\bin\x86_amd64\vcvarsx86_amd64.bat" ( + echo %_this%: Cleaning 64-bit build... + echo. + set PY_PLATFORM=x64 + set _vcvarsarg=x86_amd64 + call :clean + echo. +) + +echo %_this%: Removing Tcl/Tk .dlls... +echo on +del /S PCbuild\tcl*.dll +del /S PCbuild\tk*.dll + +@echo. +@echo %_this%: Removing configuration file... +del win-config.dat + +pushd "%EXTERNALS_DIR%" + +@echo. +@echo %_this%: Clearing externals... +if EXIST %BZ2VERSION% rmdir /S /Q %BZ2VERSION% +if EXIST %OPENSSLVERSION% rmdir /S /Q %OPENSSLVERSION% +if EXIST %TCLVERSION% rmdir /S /Q %TCLVERSION% +if EXIST %TKVERSION% rmdir /S /Q %TKVERSION% +if EXIST tcltk rmdir /S /Q tcltk +if EXIST tcltk64 rmdir /S /Q tcltk64 +if EXIST %SQLITEVERSION% rmdir /S /Q %SQLITEVERSION% +if EXIST %LZMAVERSION% rmdir /S /Q %LZMAVERSION% + +popd + +@echo off +echo %_this%: Done^^! + +exit /B !ERRORLEVEL! + + + +:-C +rem Changes directory to the specified dir, then calls any make.bat found there +rem with the remaining arguments. + +shift +pushd %1 + +:concat-args-loop +shift +if [%1] EQU [] goto after-concat-loop +set ARGS=%ARGS% %1 +goto concat-args-loop +:after-concat-loop + +call make.bat %ARGS% + +popd +exit /B !ERRORLEVEL! + + + +:external +rem Gets the external libraries required for certain optional extension modules. + +pushd "%EXTERNALS_DIR%" + +where /Q svn + +if !ERRORLEVEL! NEQ 0 ( + echo. + echo %_this%: Subversion not available^^! If you want to build with external library + echo support, you'll need to either install Subversion and add it to your + echo PATH, or get the external libraries yourself. See PCbuild\readme.txt. + echo. + + popd + exit /B 3 +) + +echo. +echo %_this%: Fetching sources from %SVNROOT%... + +set _warning_msg= + +for %%v in ("%BZ2VERSION%", "%OPENSSLVERSION%", "%TCLVERSION%", "%TKVERSION%", + "%SQLITEVERSION%", "%LZMAVERSION%") do ( + if NOT EXIST %%v ( + echo. + echo %_this%: Fetching %%v sources... + cmd /C svn export %SVNROOT%%%v + + if !ERRORLEVEL! NEQ 0 ( + set _warning_msg=1 + ) + ) else ( + echo. + echo %_this%: %%v sources already present. + ) +) + +if DEFINED _warning_msg ( + echo. + echo %_this%: Warning^^! Not all libraries could be fetched, see output above. +) else ( + echo. + echo %_this%: External libraries ready for building. +) + +popd +exit /B 0 + + + +:importlib +rem Builds the _freeze_importlib VC project to update Python\importlib.h after +rem changes to Lib\importlib\_bootstrap.py. May leave around build artifacts +rem of a 32 bit Release build. + +set _vcvarsarg=x86 + +if NOT EXIST PCbuild\python.exe ( + if NOT EXIST PCbuild\python_d.exe ( + set _cleanup=True + ) +) + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" %_vcvarsarg% +@echo on +msbuild PCbuild\_freeze_importlib.vcxproj /p:Configuration=Release /p:PlatformTarget=Win32 +@echo off + +if !ERRORLEVEL! NEQ 0 ( + if DEFINED _cleanup ( + echo. + echo %_this%: Build failed, skipping cleanup. + exit /B !ERRORLEVEL! + ) +) + +if DEFINED _cleanup ( + echo %_this%: Cleaning up... + set PY_PLATFORM=Win32 + call :clean +) + +exit /B !ERRORLEVEL! + + + +:msi +rem Creates an MSI installer for Python. + +@echo on +@rem build a release version of everything + +call make PY_CONFIGURATION=Release PY_NO_EXTERNALS= + +if !ERRORLEVEL! NEQ 0 ( + echo %_this%: Python build failed, aborting + exit /B !ERRORLEVEL! +) + +@rem build the documentation +call make -C Doc checkout +call make -C Doc htmlhelp + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" %_vcvarsarg% +@echo on +@rem build the MSI file +pushd PC +nmake /f icons.mak +popd + +pushd Tools\msi +del *.msi +nmake /f msisupport.mak + +@if "%PYTHON2%" EQU "" set PYTHON2=py -2 +cmd /C "%PYTHON2% msi.py" + +@echo off +popd +exit /B !ERRORLEVEL! + + + +:patchcheck +rem Runs the patchcheck script. + +if EXIST python.bat ( + set _python=python.bat +) else set _python=%PYTHON3% + +cmd /C %_python% Tools\scripts\patchcheck.py + +exit /B !ERRORLEVEL! + + + +:tcltk +rem Builds Tcl/Tk. + +if NOT EXIST "%EXTERNALS_DIR%\%TCLVERSION%" call :external +if NOT EXIST "%EXTERNALS_DIR%\%TKVERSION%" call :external + +pushd "%EXTERNALS_DIR%\%TCLVERSION%\win" + +if "%PY_PLATFORM%" EQU "" goto no-configure +if "%PY_CONFIGURATION%" EQU "" goto no-configure + +if EXIST "%_tclinstalldir%" ( + echo %_this%: Clearing previous build... + rmdir /S /Q "%_tclinstalldir%" + del "%_pybuilddir%\tcl*.dll" + del "%_pybuilddir%\tk*.dll" +) + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" %_vcvarsarg% + +rem all and install need to be separate invocations, otherwise nmakehlp is not found on install + +set _command=nmake -f makefile.vc DEBUG=%_tcldebugsetting% MACHINE=%_tclmachine% INSTALLDIR="%_tclinstalldir%" + +if "%TCLTARGETS%" EQU "" ( + set TCLTARGETS=clean all install +) + +for %%t in (%TCLTARGETS%) do ( + set _full_command=%_command% %%t + echo. + echo !_full_command! + cmd /C !_full_command! + + if !ERRORLEVEL! NEQ 0 ( + echo. + echo %_this%: Tcl build failed on %%t step (exit code !ERRORLEVEL!^), aborting. + popd + exit /B 5 + ) +) + +popd + +pushd "%EXTERNALS_DIR%\%TKVERSION%\win" + +set _command=nmake -f makefile.vc OPTS=noxp DEBUG=%_tcldebugsetting% MACHINE=%_tclmachine% INSTALLDIR="%_tclinstalldir%" TCLDIR=..\..\%TCLVERSION% + +for %%t in (%TCLTARGETS%) do ( + set _full_command=%_command% %%t + echo. + echo !_full_command! + cmd /C !_full_command! + + if !ERRORLEVEL! NEQ 0 ( + echo. + echo %_this%: Tk build failed on %%t step (exit code !ERRORLEVEL!^), aborting. + popd + exit /B 5 + ) +) + +popd + +echo on +xcopy /Y "%_tclinstalldir%\bin\tcl%_tclbuildextension%" "%_pybuilddir%" +xcopy /Y "%_tclinstalldir%\bin\tk%_tclbuildextension%" "%_pybuilddir%" + +@echo off +exit /B !ERRORLEVEL! + + + +:test +rem Runs the test suite. The interpreter to test can be changed by setting the +rem TESTPYTHON variable, the command used to run the tests can be changed by +rem setting the TESTRUNNER variable, and options can be changed by TESTOPTS. + +if "%TESTPYTHON%" EQU "" ( + if EXIST python.bat ( + set TESTPYTHON=python.bat + ) else ( + set TESTPYTHON=%PYTHON3% + ) +) + +if "%TESTRUNNER%" EQU "" ( + set TESTRUNNER=Tools\scripts\run_tests.py +) + +cmd /C %TESTPYTHON% %TESTRUNNER% %TESTOPTS% + +exit /B !ERRORLEVEL! + + + +:buildbottest +rem Runs the test suite with default options used by the CPython buildbots. + +if "%TESTTIMEOUT%" EQU "" set TESTTIMEOUT=3600 +set TESTOPTS=-j 1 -u all -W --timeout=%TESTTIMEOUT% %TESTOPTS% +call :test + +exit /B !ERRORLEVEL! + + + +:no-configure +echo %_this%: Please run configure.bat with any desired options first. +exit /B 6