Building CPython: Prerequisites
Compiling CPython from source requires the following environment specifications:
- A C11-compatible compiler. Optional C11 features are not mandatory.
- IEEE 754 floating-point support, including Not-a-Number (NaN) handling.
- Threading capabilities.
- OpenSSL 1.1.1 or newer for the
sslandhashlibmodules. - Microsoft Visual Studio 2017 or later on Windows systems.
Notable historical requirement shifts: C11, IEEE 754, NaN, and VS2017+ became mandatory in 3.11. OpenSSL 1.1.1 was required starting in 3.10. Thread support and OpenSSL 1.0.2 were introduced in 3.7. Selected C99 features like <stdint.h> and static inline were mandated in 3.6. VS2015+ became the Windows baseline in 3.5. Refer to PEP 7 (C Code Style Guide) and PEP 11 (Platform Support) for further details.
Source Tree Regeneration
The CPython repository includes pre-generated artifacts to minimize build dependencies. To recreate these files from scratch, execute:
make regen-all
make regen-stdlib-module-names
make regen-limited-abi
make regen-configure
The Makefile.pre.in file catalogs these generated outputs, their source dependencies, and the tooling used. Search for regen-* targets within it.
Configure Script Regeneration
Running make regen-configure triggers Tools/build/regen-configure.sh, which produces aclocal.m4 and the configure script. By default, it utilizes an Ubuntu container to guarantee consistent tool versions and reproducible outputs. If you prefer local execution without containerization, run:
autoreconf -ivf -Werror
Beware that local generation might yield differing results based on the installed versions of autoconf-archive, aclocal, and pkg-config.
Configure Script Parameters
Display all available configuration options via:
./configure --help
Additional context is available in Misc/SpecialBuilds.txt within the source tree.
General Configuration
--enable-loadable-sqlite-extensions: Permits dynamic extension loading within the_sqlitemodule (disabled by default). Relates tosqlite3.Connection.enable_load_extension().--disable-ipv6: Turns off IPv6 networking support (enabled by default).--enable-big-digits=[15|30]: Configures the bit-width for Python integer digits (defaults to 30). SetsPYLONG_BITS_IN_DIGITaccordingly. Seesys.int_info.bits_per_digit.--with-suffix=SUFFIX: Appends a custom suffix to the Python executable. Defaults to.exeon Windows/macOS,.js/.html/.wasmon WASM targets, and an empty string on standard Unix.--with-tzpath=<pathlist>: Defines the default timezone search path forzoneinfo.TZPATH. Defaults to/usr/share/zoneinfo:/usr/lib/zoneinfo:/usr/share/lib/zoneinfo:/etc/zoneinfo. Paths are separated byos.pathsep.--without-decimal-contextvar: Builds_decimalusing thread-local contexts instead of coroutine-local contexts (default). Seedecimal.HAVE_CONTEXTVAR.--with-dbmliborder=<backendlist>: Overrides the database backend detection order fordbm. Accepts a colon-separated string of backends:ndbm,gdbm,bdb.--without-c-locale-coercion: Disables automatic C locale coercion to UTF-8 (enabled by default). UnsetsPY_COERCE_C_LOCALE. See PEP 538.--without-freelists: Disables all freelists except the empty tuple singleton.--with-platlibdir=DIRNAME: Sets the platform-specific library directory name (defaults tolib, frequentlylib64on Fedora/SuSE). Seesys.platlibdir.--with-wheel-pkg-dir=PATH: Specifies the wheel package directory forensurepip. Useful for distributions that avoid bundled dependencies (e.g., Fedora uses/usr/share/python-wheels/).--with-pkg-config=[check|yes|no]: Controls dependency detection viapkg-config.check(default) makes it optional,yesmandates it,noexplicitly skips it.--enable-pystats: Activates internal statistics gathering. Data is dumped to/tmp/py_stats/(orC:\temp\py_stats\on Windows). Parse results usingTools/scripts/summarize_stats.py.
WebAssembly Targets
--with-emscripten-target=[browser|node]: Sets the build profile forwasm32-emscripten.browser(default) minimizes stdlib and relies on MEMFS.nodeenables NODERAWFS and pthreads.--enable-wasm-dynamic-linking: Activates dynamic linking for WASM, enablingdlopen. Increases binary size due to limited dead code elimination.--enable-wasm-pthreads: Enables pthreads support for WASM builds.
Installation Directories
--prefix=PREFIX: Installs architecture-independent files intoPREFIX(defaults to/usr/local). Accessible viasys.prefix.--exec-prefix=EPREFIX: Installs architecture-dependent files intoEPREFIX(defaults toPREFIX). Accessible viasys.exec_prefix.--disable-test-modules: Skips compilation and installation of test packages and extensions like_testcapi.--with-ensurepip=[upgrade|install|no]: Configures theensurepipexecution during installation.upgrade(default) runs--altinstall --upgrade,installruns--altinstall,noskips it entirely.
Performance Tuning
For maximum runtime efficiency, configure with --enable-optimizations --with-lto (PGO + LTO). The experimental --enable-bolt flag offers additional post-link optimizations.
--enable-optimizations: Enables Profile-Guided Optimization (PGO) usingPROFILE_TASK. Clang requiresllvm-profdata. When paired with--enable-sharedand GCC,-fno-semantic-interpositionis appended to compiler/linker flags.PROFILE_TASK: Environment variable defining the Python command executed for PGO data collection. Defaults to-m test --pgo --timeout=$(TESTTIMEOUT).--with-lto=[full|thin|no|yes]: Activates Link-Time Optimization. Clang requiresllvm-arand an LTO-capable linker (ld.goldorlld). ThinLTO can be explicitly requested viathinon Clang. Since 3.12, ThinLTO is the default Clang strategy if supported.--enable-bolt: Activates the BOLT binary optimizer (requiresllvm-boltandmerge-fdata). Considered experimental; success relies heavily on the specific environment and CPU architecture. LLVM 16+ is strongly recommended.BOLT_INSTRUMENT_FLAGSandBOLT_APPLY_FLAGScan override default BOLT parameters.--with-computed-gotos: Enables computed gotos in the evaluation loop (enabled by default on supported compilers).--without-pymalloc: Disables the specialized Python memory allocator (enabled by default). SeePYTHONMALLOC.--without-doc-strings: Omits static documentation strings to reduce memory footprint. Does not affect Python-defined docstrings. Relates to thePyDoc_STRVAR()macro.--enable-profiling: Enables C-level profiling viagprof.--with-strict-overflow: Appends-fstrict-overflowto C compiler flags (replacing the default-fno-strict-overflow).
Debug Builds
A Python debug build is activated via --with-pydebug. It introduces the following behaviors:
- Default warning filters are emptied, displaying all warnings.
dis appended tosys.abiflags.sys.gettotalrefcount()becomes available.- The
-X showrefcountCLI argument is supported. -dargument andPYTHONDEBUGenvironment variable enable parser debugging.- Defining
__lltrace__enables low-level bytecode tracing. - Memory allocation debug hooks are installed to detect overflows and memory errors.
- Macros
Py_DEBUGandPy_REF_DEBUGare defined. - Runtime checks inside
#ifdef Py_DEBUGblocks are activated, includingassert()and_PyObject_ASSERT(). Checks cover: function argument sanity, pattern-filled memory for Unicode/int objects to detect uninitialized use, exception state consistency during replacements, memory deallocator exception preservation, garbage collector object consistency, and integer overflow checks viaPy_SAFE_DOWNCAST().
Since 3.8, debug and release builds are ABI compatible; defining Py_DEBUG no longer forces Py_TRACE_REFS.
Debugging and Sanitizers
--with-pydebug: Compiles in debug mode, definingPy_DEBUG.--with-trace-refs: Enables reference tracing for debugging. DefinesPy_TRACE_REFS, addssys.getobjects(), and introducesPYTHONDUMPREFS. ABI incompatible with release and standard debug builds.--with-assertions: Enables C assertions (unsetsNDEBUGin OPT). Similar to debug mode assertions but without the full debug build overhead.--with-valgrind: Enables Valgrind support.--with-dtrace: Enables DTrace profiling.--with-address-sanitizer: Enables ASan (AddressSanitizer).--with-memory-sanitizer: Enables MSan (MemorySanitizer).--with-undefined-behavior-sanitizer: Enables UBSan (UndefinedBehaviorSanitizer).
Linker Configuration
--enable-shared: Compiles the sharedlibpythonlibrary.--without-static-libpython: Skips buildinglibpythonMAJOR.MINOR.aand installingpython.o.
External Libraries
--with-libs='lib1 ...': Links additional external libraries.--with-system-expat: Buildspyexpatusing the system's installedexpatlibrary.--with-system-libmpdec: Builds_decimalusing the system's installedmpdeclibrary.--with-readline=editline: Useseditlineas the backend for thereadlinemodule. DefinesWITH_EDITLINE.--without-readline: Skips building thereadlinemodule entirely. UnsetsHAVE_LIBREADLINE.--with-libm=STRING: Overrides the default math library (libm).--with-libc=STRING: Overrides the default C library (libc).--with-openssl=DIR: Specifies the root directory for OpenSSL.--with-openssl-rpath=[no|auto|DIR]: Configures OpenSSL runtime library paths (rpath).no(default) sets no rpath,autodetects based on--with-opensslandpkg-config,DIRsets an explicit path.
Security Algorithms
--with-hash-algorithm=[fnv|siphash13|siphash24]: Selects the hashing algorithm forPython/pyhash.c. Defaults tosiphash13.--with-builtin-hashlib-hashes=md5,sha1,sha256,sha512,sha3,blake2: Specifies which hash modules are built-in.--with-ssl-default-suites=[python|openssl|STRING]: Overrides OpenSSL default cipher suites.python(default) uses Python recommendations,opensslpreserves upstream defaults,STRINGapplies a custom string. Choosingpythonor a custom string also sets TLS 1.2 as the minimum protocol version.
macOS Specifics
--enable-universalsdk[=SDKDIR]: Creates a universal binary. Optionally specifies the macOS SDK directory.--enable-framework[=INSTALLDIR]: Creates aPython.frameworkinstead of a standard Unix install. Optionally specifies the installation path.--with-universal-archs=ARCH: Defines the universal binary architecture (e.g.,universal2,32-bit,64-bit,3-way,intel,intel-32,intel-64,all). Requires--enable-universalsdk.--with-framework-name=FRAMEWORK: Specifies the framework name (defaults toPython). Requires--enable-framework.
Cross-Compilation
Cross-compiling builds Python for a target architecture different from the build host. It requires a build-platform Python interpreter matching the target version.
--build=BUILD: Specifies the build platform (auto-detected byconfig.guess).--host=HOST: Specifies the target platform.--with-build-python=path/to/python: Points to the build-platform Python binary.CONFIG_SITE=file: Environment variable pointing to a configuration overrides file.
Example config.site for an ARM64 target:
# config.site-arm64
ac_cv_func_getaddrinfo=yes
ac_cv_file__dev_ptmx=yes
ac_cv_have_decl_printf=yes
Example cross-compilation invocation:
CONFIG_SITE=config.site-arm64 ../configure \
--build=x86_64-linux-gnu \
--host=aarch64-linux-gnu \
--with-build-python=../x86_64/python
Build System Architecture
Key Source Files
configure.acgeneratesconfigure.Makefile.pre.ingeneratesMakefile(viaconfigure).pyconfig.his generated byconfigure.Modules/Setupdictates C extension builds, processed byModule/makesetup.
Build Pipeline
- C source files (
.c) compile into object files (.o). - Object files are archived into the static
libpython(.a). python.oandlibpythonare linked into the finalpythonexecutable.- C extensions are built by the
Makefileaccording toModules/Setup.
Makefile Targets
make: Builds Python alongside the standard library.make platform: Builds thepythonexecutable without standard library extensions.make profile-opt: Constructs Python using Profile-Guided Optimization. Automatically invoked by default if--enable-optimizationswas configured.make buildbottest: Compiles Python and runs the test suite mimicking buildbot behavior. Timeout defaults to 1200 seconds, adjustable viaTESTTIMEOUT.make install: Compiles and installs Python.make regen-all: Regenerates most derived files.make regen-stdlib-module-namesandautoconfmust run separately for remaining artifacts.make clean: Removes build artifacts.make distclean: Removes build artifacts and files generated byconfigure.
C Extension Variants
Built-in modules (e.g., sys) are compiled with the Py_BUILD_CORE_BUILTIN macro. They lack a __file__ attribute:
>> import sys
>>> print(sys)
<module 'sys' (built-in)>
>>> print(sys.__file__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'sys' has no attribute '__file__'
Dynamic modules (e.g., _json) are compiled with the Py_BUILD_CORE_MODULE macro. They possess a __spec__.origin (and historically __file__) pointing to their shared object:
>> import _json
>>> print(_json)
<module '_json' from '/usr/lib64/python3.11/lib-dynload/_json.cpython-311-x86_64-linux-gnu.so'>
>>> print(_json.__spec__.origin)
'/usr/lib64/python3.11/lib-dynload/_json.cpython-311-x86_64-linux-gnu.so'
Within Modules/Setup, extensions defined before the *shared* marker become built-ins, while those after it become dynamic libraries.
The macros PyAPI_FUNC(), PyAPI_DATA(), and PyMODINIT_FUNC (defined in Include/exports.h) resolve to Py_EXPORTED_SYMBOL if Py_BUILD_CORE_MODULE is set, otherwise Py_IMPORTED_SYMBOL. Misapplying Py_BUILD_CORE_BUILTIN on a shared extension will hide its PyInit_xxx() function, resulting in an ImportError.
Compiler and Linker Flags
Flags are initially set by ./configure and environment variables, then consumed by the Makefile.
Preprocessor Flags
CONFIGURE_CPPFLAGS: Passed directly to./configure.CPPFLAGS: C/C++ preprocessor flags (e.g.,-Iinclude_dir). Must contain shell values so extension modules can locate directories specified in environment variables.BASECPPFLAGS: Base preprocessor flags.PY_CPPFLAGS: Additional preprocessor flags for interpreter object files. Defaults to$(BASECPPFLAGS) -I. -I$(srcdir)/Include $(CONFIGURE_CPPFLAGS) $(CPPFLAGS).
Compiler Flags
CC: C compiler command (e.g.,gcc -pthread).CXX: C++ compiler command (e.g.,g++ -pthread).CFLAGS: General C compiler flags.CFLAGS_NODIST: Used strictly for interpreter and stdlib C extension builds. Prevents flags from leaking into the installedCFLAGS, which would otherwise override user/package-Ipaths or impose unmanageable strictness like-Werroron third-party modules.COMPILEALL_OPTS: Arguments forcompileallduringmake installPYC generation. Defaults to-j0.EXTRA_CFLAGS: Additional C compiler directives.CONFIGURE_CFLAGS: Passed to./configure.CONFIGURE_CFLAGS_NODIST: Passed to./configure.BASECFLAGS: Base compiler flags.OPT: Optimization flags.CFLAGS_ALIASING: Aliasing strictness flags for compilingPython/dtoa.c.CCSHARED: Flags for shared library compilation (e.g.,-fPICon Linux/BSD).CFLAGSFORSHARED: Extra C flags for interpreter object files. Defaults to$(CCSHARED), or empty if--enable-sharedis active.PY_CFLAGS: Defaults to$(BASECFLAGS) $(OPT) $(CONFIGURE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS).PY_CFLAGS_NODIST: Defaults to$(CONFIGURE_CFLAGS_NODIST) $(CFLAGS_NODIST) -I$(srcdir)/Include/internal.PY_STDMODULE_CFLAGS: Flags for interpreter object files. Defaults to$(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARED).PY_CORE_CFLAGS: Defaults to$(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE.PY_BUILTIN_MODULE_CFLAGS: Flags for stdlib built-ins. Defaults to$(PY_STDMODULE_CFLAGS) -DPy_BUILD_CORE_BUILTIN.PURIFY: Purify memory debugger command. Defaults to empty.
Linker Flags
LINKCC: Linker command for executables likepythonand_testembed. Defaults to$(PURIFY) $(CC).CONFIGURE_LDFLAGS: Passed to./configure. Avoid setting directly so users can append values via command line without overriding presets.LDFLAGS_NODIST: Used similar toCFLAGS_NODIST. Prevents installedLDFLAGSfrom overriding user/package-Llibrary paths.CONFIGURE_LDFLAGS_NODIST: Passed to./configure.LDFLAGS: Linker flags (e.g.,-Llib_dir). Must contain shell values to support extension module builds using environment-specified directories.LIBS: Linker flags passing libraries to the linker (e.g.,-lrt).LDSHARED: Command to build a shared library. Defaults to@LDSHARED@ $(PY_LDFLAGS).BLDSHARED: Command to build the sharedlibpython. Defaults to@BLDSHARED@ $(PY_CORE_LDFLAGS).PY_LDFLAGS: Defaults to$(CONFIGURE_LDFLAGS) $(LDFLAGS).PY_LDFLAGS_NODIST: Defaults to$(CONFIGURE_LDFLAGS_NODIST) $(LDFLAGS_NODIST).PY_CORE_LDFLAGS: Linker flags specifically for interpreter object files.