静态编译Python解释器?
我正在构建一个专用的嵌入式Python解释器,想要避免依赖动态库,所以我想用静态库来编译这个解释器,比如用libc.a
而不是libc.so
。
我还想把Python标准库中所有的动态库都静态链接起来。我知道可以使用Freeze.py
来实现这个,但有没有其他的方法可以一步到位完成呢?
4 个回答
使用 freeze 并不能让你一次性完成所有工作(无论你用什么方法,你都需要多个构建步骤,比如多次调用编译器)。首先,你需要编辑 Modules/Setup
文件,把你想要的所有扩展模块都加进去。接下来,你构建 Python,这样就会得到一个叫 libpythonxy.a 的文件。然后,你运行 freeze,这样会生成一些 C 文件和一个 config.c 文件。你还需要把这些文件编译一下,然后把它们整合到 libpythonxy.a 中(或者创建一个单独的库)。
这些步骤你只需要做一次,针对你想要集成的每种架构和 Python 版本。当你构建你的应用程序时,只需要链接 libpythonxy.a 和 freeze 生成的库就可以了。
CPython CMake Buildsystem 提供了一种替代的方法来构建 Python,使用的是 CMake 工具。
它可以静态地构建 Python 库,并且可以把你想要的所有模块都包含在这个库里。只需要设置 CMake 的选项
BUILD_SHARED OFF
BUILD_STATIC ON
然后把你想要的 BUILTIN_<扩展名>
设置为 ON
。
我发现了这个(主要是关于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'
这将显示所有由于静态链接而无法编译的模块。