静态编译Python解释器?

52 投票
4 回答
33944 浏览
提问于 2025-04-15 13:00

我正在构建一个专用的嵌入式Python解释器,想要避免依赖动态库,所以我想用静态库来编译这个解释器,比如用libc.a而不是libc.so

我还想把Python标准库中所有的动态库都静态链接起来。我知道可以使用Freeze.py来实现这个,但有没有其他的方法可以一步到位完成呢?

4 个回答

6

使用 freeze 并不能让你一次性完成所有工作(无论你用什么方法,你都需要多个构建步骤,比如多次调用编译器)。首先,你需要编辑 Modules/Setup 文件,把你想要的所有扩展模块都加进去。接下来,你构建 Python,这样就会得到一个叫 libpythonxy.a 的文件。然后,你运行 freeze,这样会生成一些 C 文件和一个 config.c 文件。你还需要把这些文件编译一下,然后把它们整合到 libpythonxy.a 中(或者创建一个单独的库)。

这些步骤你只需要做一次,针对你想要集成的每种架构和 Python 版本。当你构建你的应用程序时,只需要链接 libpythonxy.a 和 freeze 生成的库就可以了。

10

CPython CMake Buildsystem 提供了一种替代的方法来构建 Python,使用的是 CMake 工具。

它可以静态地构建 Python 库,并且可以把你想要的所有模块都包含在这个库里。只需要设置 CMake 的选项

BUILD_SHARED                     OFF
BUILD_STATIC                     ON

然后把你想要的 BUILTIN_<扩展名> 设置为 ON

36

我发现了这个(主要是关于Python模块的静态编译):

这里描述了一个配置文件的位置:

<Python_Source>/Modules/Setup

如果这个文件不存在,可以通过复制来创建:

<Python_Source>/Modules/Setup.dist

Setup文件里面有很多文档,而源代码中附带的README也提供了很多有用的编译信息。

我还没有尝试编译,但我觉得有了这些资源,我应该能成功。我会在这里以评论的形式分享我的结果。

更新

要获得一个纯静态的Python可执行文件,你还需要这样配置:

./configure LDFLAGS="-static -static-libgcc" CPPFLAGS="-static"

一旦你使用这些标志进行构建,你可能会收到很多关于“重命名因为库不存在”的警告。这意味着你没有正确配置Modules/Setup,需要:

a) 在文件顶部添加一行,像这样:

*static*

(就是在“static”这个词前后加上星号,没有空格)

b) 取消注释你想要静态可用的所有模块(比如math、array等等...)

你可能还需要添加特定的链接器标志(就像我上面提到的链接中说的)。到目前为止,我的经验是这些库在没有修改的情况下也能正常工作。

运行make时,使用以下命令可能也会有帮助:

make 2>&1 | grep 'renaming'

这将显示所有由于静态链接而无法编译的模块。

撰写回答