设置和构建¶
本说明介绍如何获取源代码的工作副本和 CPython 解释器的编译版本(CPython 是 Python 的版本,可从 https://pythonlang.cn/ 中获取)。它还概述了 CPython 源代码的目录结构。
或者,如果您已安装 Docker,您可能希望使用 我们的官方镜像。这些镜像包含多个 Python 版本的最新版本以及 Git 头,仅用于开发和测试目的。
另请参阅
快速参考 简要总结了从安装 Git 到提交拉取请求的过程。
安装 Git¶
CPython 使用 Git 进行版本控制。Git 命令行程序名为 git
;这也用于指代 Git 本身。Git 适用于所有常见操作系统。
安装
由于 CPython 仓库托管在 GitHub 上,因此请参阅 GitHub 设置说明 或 Git 项目说明 以获取分步安装说明。您可能还想考虑使用图形客户端,例如 TortoiseGit 或 GitHub Desktop。
配置
配置 您的姓名和电子邮件 并创建 SSH 密钥,因为这将允许您与 GitHub 交互,而无需每次执行命令(例如
git pull
、git push
或git fetch
)时输入用户名和密码。在 Windows 上,您还应该 启用 autocrlf。
获取源代码¶
CPython 仓库托管在 GitHub 上。要获取源代码副本,您应该 在 GitHub 上分叉 Python 仓库、创建个人分叉的本地克隆,并配置远程。
您只需在每台机器上执行这些步骤一次
按右上角的 Fork。
当询问在哪里分叉仓库时,选择将其分叉到您的用户名。
您的分叉将在
https://github.com/<username>/cpython
中创建。克隆您的 GitHub 分叉(用您的用户名替换
<username>
)$ git clone git@github.com:<username>/cpython.git
(您可以同时使用基于 SSH 或基于 HTTPS 的 URL。)
添加
upstream
远程,然后配置git
从upstream
拉取main
并始终推送到origin
$ cd cpython $ git remote add upstream https://github.com/python/cpython $ git config --local branch.main.remote upstream $ git remote set-url --push upstream git@github.com:<your-username>/cpython.git
验证您的设置是否正确
$ git remote -v origin git@github.com:<your-username>/cpython.git (fetch) origin git@github.com:<your-username>/cpython.git (push) upstream https://github.com/python/cpython (fetch) upstream git@github.com:<your-username>/cpython.git (push) $ git config branch.main.remote upstream
有关这些命令的更多信息,请参阅 Git Bootcamp 和备忘单。
如果您一切操作正确,您现在应该在 cpython
目录中有一个代码副本,以及两个指向您自己的 GitHub 分叉(origin
)和官方 CPython 仓库(upstream
)的远程。
如果您想要已发布的 Python 版本(即 维护模式 中的版本)的工作副本,您可以签出发行分支。例如,要签出 Python 3.8 的工作副本,请执行 git switch 3.8
。
执行此类更新时,您需要重新编译 CPython。
请注意,CPython 会注意到它正在从工作副本中运行。这意味着,如果您在工作副本中编辑 CPython 的源代码,Python 代码的更改将被解释器拾取,以便立即使用和测试。(如果您更改 C 代码,您需要按照以下说明重新编译受影响的文件。)
可以从同一个存储库中对文档进行修补;请参阅 开始。
将 pre-commit 安装为 Git 钩子¶
为了确保您的代码正确地进行 linted,我们建议将 pre-commit 设置为 Git 钩子
$ pre-commit install --allow-missing-config
pre-commit installed at .git/hooks/pre-commit
现在 pre-commit 将在 git commit
上自动运行。
编译和构建¶
CPython 提供了几个编译标志,有助于调试各种内容。虽然所有已知的标志都可以在 Misc/SpecialBuilds.txt
文件中找到,但最关键的是 Py_DEBUG
标志,它创建了所谓的“pydebug”构建。此标志开启了各种额外的健全性检查,有助于发现常见问题。此标志的使用非常普遍,以至于开启此标志是基本编译选项。
您应该始终在 CPython 的 pydebug 构建下进行开发(唯一不应该这样做的情况是您正在进行性能测量)。即使仅处理纯 Python 代码,pydebug 构建也提供了一些有用的检查,您不应该跳过这些检查。
另请参阅
各种配置和构建标志的效果记录在 Python 配置文档 中。
Unix¶
核心 CPython 解释器仅需要 C 编译器才能构建,但是,某些扩展模块将需要其他库的开发头文件(例如用于压缩的 zlib
库)。根据您打算处理的内容,您可能需要安装这些其他要求,以便已编译的解释器支持所需的功能。
如果您想安装这些可选依赖项,请参阅下面的 安装依赖项 部分。
如果您不需要安装它们,那么为开发构建 Python 的基本步骤是配置它,然后编译它。
配置通常是
$ ./configure --with-pydebug
更多标志可用于 configure
,但这是您应该做的最低限度,以获得 CPython 的 pydebug 构建。
注意
您可能需要在特定构建目录中重新运行 configure
之前或之后运行 make clean
。
完成 configure
后,您可以使用以下命令编译 CPython:
$ make -s -j2
这将构建 CPython,仅将警告和错误打印到 stderr,并使用最多 2 个 CPU 核心。如果您使用的是具有 2 个以上内核的多核机器(或单核机器),您可以调整传递给 -j
标志的数字,以匹配您拥有的内核数(或者,如果您的 Make 版本支持,您可以使用 -j
而无需数字,Make 将不会限制可以同时运行的步骤数)。
在构建结束时,您应该会看到一条成功消息,后面是尚未构建的扩展模块列表,因为它们缺少依赖项
The necessary bits to build these optional modules were not found:
_gdbm
To find the necessary bits, look in configure.ac and config.log.
Checked 106 modules (31 built-in, 74 shared, 0 n/a on macosx-13.4-arm64, 0 disabled, 1 missing, 0 failed on import)
如果构建失败,并且您使用的是符合 C89 或 C99 的编译器,请在 问题跟踪器 上打开一个错误报告。
如果您决定 安装依赖项,您需要重新运行 configure
和 make
。
CPython 构建完成后,你将获得一个可就地运行的工作版本;在大多数机器上(以及所有示例中使用),运行 ./python
(避免与 Python
目录发生冲突),在使用不区分大小写的文件系统(例如 macOS 默认情况下)的任何地方,运行 ./python.exe
。通常无需安装构建的 Python 副本!解释器将意识到它从何处运行,从而使用工作副本中找到的文件。如果你担心可能会意外安装工作副本版本,则可以在配置步骤中添加 --prefix=/tmp/python
。从工作目录运行时,最好避免对 configure
使用 --enable-shared
标志;除非你非常小心,否则你可能会意外地使用较旧的已安装共享 Python 库中的代码,而不是你刚刚构建的解释器运行。
Clang¶
如果你使用 clang 构建 CPython,你可能希望设置一些标志来消除一些对 CPython 来说特别多余的标准警告,这些标志是 -Wno-unused-value -Wno-empty-body -Qunused-arguments
。在运行 configure
时,可以将 CFLAGS
环境变量设置为这些标志。
如果你将 clang 与 ccache 一起使用,请使用 -Wno-parentheses-equality
标志关闭嘈杂的 parentheses-equality
警告。这些警告是由 clang 无法获得足够的信息来检测扩展宏中的无关括号是否有效而引起的,因为预处理是由 ccache 单独完成的。
如果你使用 LLVM 2.8,还需要使用 -no-integrated-as
标志来构建 ctypes
模块(如果没有该标志,CPython 的其余部分仍将正确构建)。
优化¶
如果你尝试提高 CPython 的性能,你可能希望使用 CPython 的优化版本。使用启用了优化的 CPython 构建可能需要更长的时间,而且通常没有必要这样做。但是,如果你想要针对建议的性能优化获得准确的基准测试结果,这是必不可少的。
对于 Python 的优化版本,请使用 configure --enable-optimizations --with-lto
。这将设置默认的 make 目标,以启用 Profile Guided Optimization (PGO),并且可以在某些平台上自动启用 Link Time Optimization (LTO)。请参阅 --enable-optimizations
和 --with-lto
以了解有关这些选项的更多信息。
$ ./configure --enable-optimizations --with-lto
Windows¶
注意
如果你使用 Windows Subsystem for Linux (WSL),请从本机 Windows shell 程序(如 PowerShell 或 cmd.exe
命令提示符)克隆存储库,并使用面向 Windows 的 Git 版本,例如 从 Git 官方网站下载的 Git for Windows。否则,Visual Studio 将无法找到项目的所有文件,并且构建将失败。
有关在 Windows 上构建 Python 的简洁分步摘要,你可以阅读 Victor Stinner 的指南。
可以使用 Microsoft Visual Studio 2017 或更高版本构建所有受支持的 Python 版本。你可以下载并使用任何免费或付费版本的 Visual Studio。
在安装它时,选择 Python 开发 工作负载和可选的 Python 本机开发工具 组件以获取所有必要的构建工具。如果你尚未安装 Git for Windows,可以在 单个组件 选项卡中找到它。
注意
如果你想构建 MSI 安装程序,请注意它们的构建工具链依赖于 Microsoft .NET Framework 版本 3.5(可能不包含在 Windows 的最新版本中,例如 Windows 10)。如果你正在较新的 Windows 版本上构建,请使用控制面板(.NET Framework 3.5(包括 .NET 2.0 和 3.0) 项。
)并确保已启用你的第一次构建应使用命令行,以确保下载任何外部依赖项
PCbuild\build.bat -c Debug
上述命令行构建使用 -c Debug
参数在 Debug
配置中构建,这启用了对开发 Python 有帮助的检查和断言。默认情况下,它在 Release
配置中构建,并针对 64 位 x64
平台,而不是 32 位 Win32
;分别使用 -c
和 -p
来控制构建配置和平台。
此构建成功后,如果你愿意,可以在 Visual Studio IDE 中打开 PCbuild\pcbuild.sln
解决方案以继续开发。在 Visual Studio 中构建时,请确保从工具栏中的下拉菜单中选择与脚本所用设置相匹配的构建设置(调试 配置和 x64 平台)。
注意
如果你需要更改构建配置或平台,请先使用 build.bat
脚本将这些选项设置为构建一次,然后再在 VS 中使用这些选项进行构建,以确保所有文件都已正确重建,否则在加载未重建的模块时可能会遇到错误。
避免选择 PGInstrument
和 PGUpdate
配置,因为它们适用于 PGO 构建,不适用于常规开发。
你可以使用已编译的 Python 运行构建
PCbuild\amd64\python_d.exe
请参阅 PCBuild 自述文件,了解有关其他必要软件和构建方法的更多详细信息。
WASI¶
WASI 是 WebAssembly 的系统接口标准。通过 C 编译器(可以针对 WebAssembly)和 wasi-libc(为 WASI 提供与 POSIX 兼容的垫片)的组合,CPython 可以作为来宾在 WASI 主机/运行时上运行。
注意
由于 CPython 的交叉编译专为 ./configure
/ make
而设计,因此以下说明假定使用基于 Unix 的操作系统。
要为 WASI 构建,你需要交叉编译 CPython。这需要一个 C 编译器,就像为 Unix 构建一样,还需要
所有这些都在 devcontainer 中提供。你还可以将容器中安装的内容用作这些工具的哪些版本已知可以工作的参考。
注意
CPython 仅针对 WASI 验证了上述工具。使用其他编译器、主机或 WASI 版本应该可以工作,但容器中指定的上述工具及其版本已通过 构建机器人 进行了测试。
为 WASI 构建需要进行交叉构建,其中有一个构建 Python 来帮助生成 CPython 的 WASI 构建(从技术上讲,这是一个“主机 x 主机”交叉构建,因为构建 Python 也是目标 Python,而主机构建是 WASI 构建)。这意味着你实际上构建了 CPython 两次:一次是为了让构建系统使用 Python 版本,另一次是你最终关心的构建(即构建 Python 不适合你直接使用,只适合构建系统)。
获取 CPython 的 WASI 调试构建的最简单方法是使用 Tools/wasm/wasi.py build
命令(应该使用你在计算机上安装的最新版本的 Python 运行)
$ python3 Tools/wasm/wasi.py build --quiet -- --config-cache --with-pydebug
该单个命令将在 cross-build/build
和 cross-build/wasm32-wasi
中分别配置和构建构建 Python 和 WASI 构建。
你还可以分别执行每个配置和构建步骤;上述命令是以下命令的便捷包装
$ python Tools/wasm/wasi.py configure-build-python --quiet -- --config-cache --with-pydebug
$ python Tools/wasm/wasi.py make-build-python --quiet
$ python Tools/wasm/wasi.py configure-host --quiet -- --config-cache
$ python Tools/wasm/wasi.py make-host --quiet
注意
configure-host
命令从构建 Python 推断使用 --with-pydebug
。
在 wasi.py build
之后运行单独的命令很有用,例如,如果你只想在进行代码更改后运行 make-host
步骤。
一旦一切完成,将会有一个 cross-build/wasm32-wasi/python.sh
帮助文件,你可以使用它来运行 python.wasm
文件(请参阅 configure-host
子命令的输出)
$ cross-build/wasm32-wasi/python.sh --version
你还可以使用 Makefile
目标,由于 HOSTRUNNER
环境变量已被设置为与 python.sh
中使用的类似值,因此它们将按预期工作
$ make -C cross-build/wasm32-wasi test
注意
WASI 使用基于功能的安全模型。这意味着除非你告诉 WASI 主机,否则它不会授予你机器的完全访问权限。这也意味着诸如文件之类的内容最终可能会映射到 WASI 主机内的不同路径。因此,如果你尝试将文件路径传递给 python.wasm
/ python.sh
,它需要匹配 WASI 主机内部的路径,而不是你机器上的路径(很像使用容器)。
iOS¶
为 iOS 编译 Python 需要一台 macOS 机器,在较新版本的 macOS 上运行较新版本的 Xcode。Apple 希望开发者保持其操作系统和工具的最新状态;如果你的 macOS 版本比主要版本落后一个以上版本,或者你的 Xcode 版本比次要版本落后几个版本,你可能会遇到困难。不可能使用 Windows 或 Linux 作为构建机器来编译 iOS。
在 iOS 上为 Python 进行完整构建需要编译 CPython 四次:一次用于 macOS;然后分别用于 iOS 使用的三个底层平台
ARM64 设备(iPhone 或 iPad);
在较新的 macOS 机器上运行的 ARM64 模拟器;以及
在较旧的 macOS 机器上运行的 x86_64 模拟器。
需要 macOS 构建,因为构建 Python 涉及运行一些 Python 代码。在 Python 的普通桌面构建中,你可以编译 Python 解释器,然后使用该解释器运行 Python 代码。但是,为 iOS 生成的二进制文件无法在 macOS 上运行,因此你需要提供一个外部 Python 解释器。从 CPython 代码签出的根目录运行以下命令
$ ./configure --prefix=$(pwd)/cross-build/macOS
$ make -j4 all
$ make install
这将在 cross-build/macOS
目录中为 macOS 构建并安装 Python。
CPython 构建系统一次只能编译一个平台。一次可以测试一个平台;但是,出于分发目的,你必须编译所有三个平台,并合并结果。有关此合并过程的详细信息,请参阅 iOS 自述文件。
以下说明将为 iOS 构建 CPython,并启用所有扩展,前提是你已在 cross-build
文件夹的子文件夹中安装了构建依赖项 XZ、BZip2、OpenSSL 和 libFFI。有关如何获取这些依赖项的详细信息,请参阅 iOS 部分关于安装构建依赖项。然而,这些依赖项都是严格可选的,包括 libFFI 是强烈推荐的,因为 ctypes
模块需要它,该模块用于 iOS 以支持访问本机系统 API。
$ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"
$ ./configure \
LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/xz/include" \
LIBLZMA_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/xz/lib -llzma" \
BZIP2_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/bzip2/include" \
BZIP2_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/bzip2/lib -lbz2" \
LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/libffi/include" \
LIBFFI_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/libffi/lib -lffi" \
--with-openssl="$(pwd)/cross-build/iphoneos.arm64/openssl" \
--host=arm64-apple-ios12.0 \
--build=arm64-apple-darwin \
--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \
--enable-framework
$ make -j4 all
$ make install
$ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"
$ ./configure \
LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/xz/include" \
LIBLZMA_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/xz/lib -llzma" \
BZIP2_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/bzip2/include" \
BZIP2_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/bzip2/lib -lbz2" \
LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/libffi/include" \
LIBFFI_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/libffi/lib -lffi" \
--with-openssl="$(pwd)/cross-build/iphonesimulator.arm64/openssl" \
--host=arm64-apple-ios12.0-simulator \
--build=arm64-apple-darwin \
--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \
--enable-framework
$ make -j4 all
$ make install
$ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"
$ ./configure \
LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/xz/include" \
LIBLZMA_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/xz/lib -llzma" \
BZIP2_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/bzip2/include" \
BZIP2_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/bzip2/lib -lbz2" \
LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/libffi/include" \
LIBFFI_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/libffi/lib -lffi" \
--with-openssl="$(pwd)/cross-build/iphonesimulator.x86_64/openssl" \
--host=x86_64-apple-ios12.0-simulator \
--build=arm64-apple-darwin \
--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \
--enable-framework
$ make -j4 all
$ make install
这些说明会在构建之前修改你的 PATH
。由于 iOS 和 macOS 共享一个硬件架构 (ARM64),因此 macOS ARM64 二进制文件很容易意外链接到你的 iOS 构建中。当构建系统上存在 Homebrew 时,这种情况尤其常见。避免此问题的最可靠方法是从 PATH
中删除任何其他库的潜在来源。
但是,PATH
并不是完全空白的——它包含 iOS/Resources/bin
文件夹。此文件夹包含一系列脚本,用于包装 Xcode xcrun 工具的调用,从 sysconfig
模块中编码的值中删除用户和版本特定的路径。这些脚本的副本包含在最终构建产品中。
此构建完成后,iOS/Frameworks
文件夹将包含一个 Python.framework
,可用于测试。
要在 iOS 上运行测试套件,请为模拟器平台完成构建,确保构建中的路径修改仍然有效,然后运行
$ make testios
在 2022 M1 MacBook Pro 上运行完整测试套件大约需要 12 分钟,另外还需要几分钟来构建测试平台应用程序并启动模拟器。在 Xcode 测试项目编译期间,会有大量的控制台输出;但是,在测试套件运行期间,没有控制台输出或进度。这是 Xcode 在命令行执行时的副作用。您应该会在测试过程中看到 iOS 模拟器出现;模拟器将启动到 iOS 登陆屏幕,将安装测试平台应用程序,然后启动。在测试套件运行期间,模拟器的屏幕将变黑。测试套件完成后,将在命令行报告成功或失败。如果失败,您将看到 CPython 测试套件输出的完整日志。
您还可以在 Xcode 本身中运行测试套件。如果您想在物理设备上运行,这是必需的;如果您需要运行单个测试或部分测试,这也是最简单的方法。有关详细信息,请参阅 iOS 自述文件。
安装依赖项¶
本节说明如何在 Linux、macOS 和 iOS 上安装其他扩展(例如 zlib
)。
对于基于 Unix 的系统,我们尝试在可能的情况下使用系统库。这意味着只有在相关系统头文件可用时,可选组件才会构建。获取适当头文件的最佳方式因发行版而异,但下面列出了一些流行发行版的相应命令。
在 Fedora、RHEL、CentOS 和其他基于 dnf
的系统上
$ sudo dnf install dnf-plugins-core # install this to use 'dnf builddep'
$ sudo dnf builddep python3
在 Debian、Ubuntu 和其他基于 apt
的系统上,尝试使用 apt
命令获取您正在处理的 Python 的依赖项。
首先,确保您已启用源列表中的源软件包。您可以通过将源软件包的位置(包括 URL、发行版名称和组件名称)添加到 /etc/apt/sources.list
来执行此操作。以 Ubuntu 22.04 LTS(Jammy Jellyfish)为例
$ deb-src http://archive.ubuntu.com/ubuntu/ jammy main
或者,使用编辑器取消注释包含 deb-src
的行,例如
$ sudo nano /etc/apt/sources.list
对于其他发行版,如 Debian,请更改 URL 和名称以对应于特定发行版。
然后您应该更新软件包索引
$ sudo apt-get update
现在,您可以通过 apt
安装构建依赖项
$ sudo apt-get build-dep python3
$ sudo apt-get install pkg-config
如果您想构建所有可选模块,请安装以下软件包及其依赖项
$ sudo apt-get install build-essential gdb lcov pkg-config \
libbz2-dev libffi-dev libgdbm-dev libgdbm-compat-dev liblzma-dev \
libncurses5-dev libreadline6-dev libsqlite3-dev libssl-dev \
lzma lzma-dev tk-dev uuid-dev zlib1g-dev libmpdec-dev
对于 macOS 系统(版本 10.9+),可以自动下载并安装开发者工具;您无需下载完整的 Xcode 应用程序。
如有必要,请运行以下命令
$ xcode-select --install
这也将确保系统头文件安装到 /usr/include
中。
另请注意,macOS 不包括 Python 标准库使用的几个库,包括 libzma
,因此,除非安装它们的本地副本,否则可能会看到一些扩展模块构建失败。从 OS X 10.11 开始,Apple 不再为 OpenSSL 的弃用系统版本提供头文件,这意味着您将无法构建 _ssl
扩展。一种解决方案是从第三方包管理器(如 Homebrew 或 MacPorts)安装这些库,然后将头文件和库文件的相应路径添加到您的 configure
命令中。
对于 Homebrew,使用 brew
安装依赖项
$ brew install pkg-config openssl@3.0 xz gdbm tcl-tk mpdecimal
对于 Python 3.13 及更高版本
$ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \
GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \
./configure --with-pydebug \
--with-system-libmpdec \
--with-openssl="$(brew --prefix openssl@3.0)"
对于 Python 3.11 和 3.12
$ GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \
GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \
./configure --with-pydebug \
--with-openssl="$(brew --prefix openssl@3.0)"
对于 Python 3.8、3.9 和 3.10
$ CPPFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \
LDFLAGS="-L$(brew --prefix gdbm)/lib -L$(brew --prefix xz)/lib" \
./configure --with-pydebug \
--with-openssl="$(brew --prefix openssl@3.0)" \
--with-tcltk-libs="$(pkg-config --libs tcl tk)" \
--with-tcltk-includes="$(pkg-config --cflags tcl tk)"
对于 MacPorts,使用 port
安装依赖项
$ sudo port install pkgconfig openssl xz gdbm tcl tk +quartz mpdecimal
对于 Python 3.13 及更高版本
$ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \
GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \
./configure --with-pydebug \
--with-system-libmpdec
对于 Python 3.11 和 3.12
$ GDBM_CFLAGS="-I$(dirname $(dirname $(which port)))/include" \
GDBM_LIBS="-L$(dirname $(dirname $(which port)))/lib -lgdbm" \
./configure --with-pydebug
最后,运行 make
$ make -s -j2
有时会为新版本添加可选模块,这些模块尚未在操作系统级别的构建依赖项中识别。在这些情况下,只需在 Discourse 上的核心开发类别中寻求帮助即可。
解释如何在没有 root 访问权限的情况下在基于 Unix 的系统上构建可选依赖项超出了本指南的范围。
有关构建的各种选项和注意事项的更多详细信息,请参阅 macOS README。
注意
虽然您需要一个 C 编译器来构建 CPython,但您不需要任何 C 语言知识即可做出贡献!CPython 的大部分区域完全用 Python 编写:截至撰写本文时,CPython 包含的 Python 代码略多于 C。
在 Windows 上,扩展已经包含在内并自动构建。
与 CPython 本身一样,CPython 的依赖项必须针对 iOS 支持的每种硬件架构进行编译。查阅 XZ、bzip2、OpenSSL 和 libffi 的文档,了解有关如何配置项目以进行跨平台 iOS 构建的详细信息。
或者,BeeWare 项目维护了一个 用于构建 iOS 依赖项的项目,并为每个依赖项分发 预编译二进制文件。如果您使用此项目自己构建依赖项,则 install
文件夹的子文件夹可用于配置 CPython。如果您使用预编译二进制文件,则应将每个 tarball 解压到单独的文件夹中,并使用该文件夹作为配置目标。
重新生成 configure
¶
如果对 Python 做出了依赖于某些 POSIX 系统特定功能(例如使用新的系统调用)的更改,则有必要更新 configure
脚本以测试该功能的可用性。Python 的 configure
脚本是从 configure.ac
使用 GNU Autoconf 生成的。
编辑 configure.ac
后,运行 make regen-configure
以生成 configure
、pyconfig.h.in
和 aclocal.m4
。在提交包含对 configure.ac
所做更改的 Pull 请求时,请确保也提交已生成文件中的更改。
Python 的 configure.ac
脚本需要特定版本的 GNU Autoconf。对于 Python 3.12 及更高版本,需要 GNU Autoconf v2.71。对于 Python 3.11 及更低版本,需要 GNU Autoconf v2.69。
重新生成 configure
的推荐方法(也是迄今为止最简单的方法)是
$ make regen-configure
这将使用 Podman 或 Docker 使用 GNU Autoconf 的正确版本进行重新生成。
如果你无法(或不想)使用 make regen-configure
,请安装 autoconf-archive 和 pkg-config 实用程序,并确保 pkg.m4
宏文件位于适当的 aclocal 位置
$ ls $(aclocal --print-ac-dir) | grep pkg.m4
注意
运行 autoreconf 与运行 autoconf 不同。例如,单独运行 autoconf 不会重新生成 pyconfig.h.in
。 autoreconf 会根据需要反复运行 autoconf 和许多其他工具。
重新生成 ABI 转储¶
维护分支(非 main
)在 Doc/data/pythonX.Y.abi
中有一个特殊文件,使我们能够知道给定的 Pull 请求是否影响公共 ABI。此文件由 GitHub CI 在名为 Check if the ABI has changed
的检查中使用,如果给定的 Pull 请求对 ABI 有所更改且 ABI 文件未更新,则该检查将失败。
此检查充当故障保护,并且并不一定意味着无法合并 Pull 请求。当此检查失败时,你应将相关的发布经理添加到 PR 中,以便他们了解更改并验证是否可以进行更改。
重要
在第一个候选版本之前允许进行 ABI 更改。在第一个候选版本之后,所有进一步的版本都必须具有相同的 ABI,以确保与本机扩展和其他与 Python 解释器交互的工具的兼容性。请参阅有关候选版本阶段的文档。
当 PR 检查失败时,关联的运行将把更新的 ABI 文件作为工件附加。在发布经理批准后,你可以下载此文件并将其添加到 PR 中以通过检查。
你可以通过调用 regen abidump
Make 目标自行重新生成 ABI 文件。请注意,为此,你需要在 GitHub CI 用于检查 ABI 的相同环境中重新生成 ABI 文件。这是因为不同的平台可能包含一些平台特定的详细信息,即使 Python ABI 相同,也会导致检查失败。使用与 CI 使用的平台相同的平台重新生成 ABI 文件的最简单方法是使用 Docker
# In the CPython root:
$ docker run -v$(pwd):/src:Z -w /src --rm -it ubuntu:22.04 \
bash /src/.github/workflows/regen-abidump.sh
请注意,用于执行脚本的 ubuntu
版本很重要,并且必须与 CI 用于检查 ABI 的版本匹配。有关更多信息,请参阅 .github/workflows/build.yml
文件。
对构建进行故障排除¶
本节列出 Python 编译期间可能出现的一些常见问题,并提出了解决方案。
避免重新创建自动生成的文件¶
在某些情况下,你可能会在运行 make
时在 Parser/asdl_c.py
或 Python/makeopcodetargets.py
等脚本中遇到 Python 错误。Python 会自动生成它自己的部分代码,从头开始进行完整构建需要运行自动生成脚本。但是,这使得 Python 构建需要一个已安装的 Python 解释器;当尝试使用已安装的新 (3.x) Python 构建旧 (2.x) Python 或反之亦然时,这也可能导致版本不匹配。
为了解决这个问题,自动生成的文件也签入 Git 存储库。因此,如果您不接触自动生成脚本,则无需自动生成任何内容。
编辑器和工具¶
Python 的使用非常广泛,以至于几乎所有代码编辑器都以某种形式支持编写 Python 代码。各种编码工具还包括 Python 支持。
对于核心开发人员认为需要针对Python 中的编码进行一些特殊注释的编辑器和工具,请参阅 其他资源。
目录结构¶
CPython 源代码树中有几个顶级目录。了解每个目录的用途将帮助您找到某个功能实现的位置。不过,请意识到每条规则总有例外。
Doc
官方文档。这是 https://docs.pythonlang.cn/ 使用的内容。另请参阅 构建文档。
Grammar
包含 Python 的 EBNF 语法文件。
Include
包含所有解释器范围的标头文件。
Lib
用纯 Python 实现的标准库部分。
Mac
特定于 Mac 的代码(例如,将 IDLE 用作 macOS 应用程序)。
Misc
不属于其他地方的内容。通常是各种类型的特定于开发人员的文档。
Modules
用 C 实现的标准库部分(以及一些其他代码)。
Objects
所有内置类型的代码。
PC
特定于 Windows 的代码。
PCbuild
用于 python.org 上提供的 Windows 安装程序当前使用的 MSVC 版本的构建文件。
Parser
与解析器相关的代码。AST 节点的定义也保存在这里。
Programs
C 可执行文件的源代码,包括 CPython 解释器的 main 函数。
Python
构成 CPython 运行时核心的代码。这包括编译器、eval 循环和各种内置模块。
Tools
用于(或曾经用于)维护 Python 的各种工具。
使用 GitHub Codespaces 做出贡献¶
什么是 GitHub Codespaces?¶
如果您想开始为 CPython 做出贡献,而无需设置本地开发环境,则可以使用 GitHub Codespaces。Codespaces 是 GitHub 提供的基于云的开发环境,允许开发人员直接在他们的 Web 浏览器或 Visual Studio Code(VS Code)中编写、构建、测试和调试代码。
为了帮助您入门,CPython 包含一个 devcontainer 文件夹,其中包含一个 JSON 配置文件,为项目的全体用户提供一致且经过版本控制的 codespace 配置。它还包含一个 Dockerfile,如果您愿意直接使用它,则允许您在 Docker 容器中设置相同的环境,但本地使用。
创建 CPython codespace¶
以下是使用 Codespaces 提交补丁所需的基本步骤。您首先需要导航到托管在 GitHub 上的 CPython 存储库。
然后您需要
按
,
键启动当前分支的 codespace 设置屏幕(或者,单击绿色 代码 按钮并选择codespaces
选项卡,然后按绿色 在 main 上创建 codespace 按钮)。应该会出现一个屏幕,让您知道您的 codespace 正在设置中。(注意:由于提供了 CPython devcontainer,codespaces 将使用它指定的配置。)
一个 VS Code 的网络版本 将在您的 Web 浏览器中打开,它已经与您的代码和一个终端链接到远程 codespace,其中 CPython 及其文档已经构建完成。
使用终端和常规 Git 命令创建新分支,在准备就绪后提交并推送您的更改!
如果您关闭存储库并稍后回来,您可以随时通过导航到 CPython 存储库、选择 Codespaces 选项卡并选择您最近的 Codespaces 会话来恢复您的 Codespace。然后您应该能够从您离开的地方继续!
本地使用 Codespaces¶
在 Codespace 屏幕的左下角,您将看到一个绿色或灰色方块,上面写着 Codespaces。您可以单击此按钮以获得其他选项。如果您更喜欢在本地安装的 VS Code 副本中工作,则可以选择选项 在 VS Code 中 打开
。您仍将在远程 Codespace 实例上工作,从而使用远程实例的计算能力。计算能力可能比您的本地机器高出很多规格,这可能会有所帮助。