静态编译的Python3程序可以不依赖发行版库文件环境,几乎可以在任何发行版零依赖运行。
构建静态Python3的方法
前提条件
建议在 Alpine Linux 的 Docker 中编译
步骤说明
1. 确定静态编译模块
首先确定要静态编译进Python的模块,比如需要将 asyncio
模块静态编译到 python3,而 asyncio
会依赖其它的底层模块(_socket
,math
,select
,array
,_posixsubprocess
,_contextvars
等),详细的官方库编译项可以在 Modules/Setup
中查找,需要一次次尝试查漏补缺。
2. 恢复源码目录初始状态
make distclean
3. 编写静态编译模块配置文件
将需要静态编译的模块信息写到文件 Modules/Setup.local
中:
vi Modules/Setup.local
内容如下:
*static*
_asyncio _asynciomodule.c
_socket socketmodule.c
math mathmodule.c _math.c -DPy_BUILD_CORE_MODULE
select selectmodule.c
array arraymodule.c
_posixsubprocess _posixsubprocess.c
_contextvars _contextvarsmodule.c
_struct _struct.c
binascii binascii.c
4. 执行 configure 配置
./configure LDFLAGS="-static" --disable-shared
检查环境中是否还缺少编译依赖。
5. 检查 Modules/Setup.local 文件
再次检查 Modules/Setup.local
文件,确保执行 configure
后没有被覆盖或者置空:
- 如果被修改覆盖了,需要重新写入
Modules/Setup.local
,再执行第四步./configure LDFLAGS="-static" --disable-shared
。 - 如果还是被覆盖了,检查
configure
过程中的报错。 - 还是不行的,删除当前源码,重新解压出原始源码,再次尝试。
6. 执行编译
根据实际情况进行多线程编译(-j
后面接线程数):
make -j10 LDFLAGS="-static" LINKFORSHARED=" "
LDFLAGS="-static"
代表是将静态编译的参数传进编译器LINKFORSHARED=" "
是置空LINKFORSHARED
变量,避免编译出共享库so
7. 测试运行
当前目录直接测试运行是否正常,是否报缺失模块:
ldd ./python # 查看执行文件是否静态
./python xxxx.py
8. 打包 Python3 程序
程序运行正常就可以打包 python3 程序了(bin
文件 + lib
PY
类型的依赖库):
pwd
/root/0616/Python-3.9.23
将程序临时安装在目录下的 1
路径:
make install LDFLAGS="-static" LINKFORSHARED=" " DESTDIR=/root/0616/Python-3.9.23/1
将 /root/0616/Python-3.9.23/2
目录下的文件打包到目标环境上的机器即可运行:
ls /root/0616/Python-3.9.23/2/usr/local/lib/
libpython3.9.a pkgconfig python3.9
执行以下命令复制文件到目标环境:
rsync -avP /root/0616/Python-3.9.23/2/usr/local/ root@new:/usr/local/
ln -sv /usr/local/bin/python3 /usr/bin/python3-static
更简单的:只用复制静态 python
文件和 usr/local/lib/python3.9
到目标环境中即可。
官方文档(Building Python Statically): https://wiki.python.org/moin/BuildStatically