我最近使用自制软件安装了 python3.7,成功地将 python 发行版嵌入了 Mac OS X 中的应用程序,按照 Joao Ventura 非常有用的两部分系列中概述的方法,此处提供供参考(http://joaoventura.net/博客/2016/embeddable-python-osx/)和(http://joaoventura.net/blog/2016/embeddable-python-osx-from-src/)。
对我来说唯一剩下的问题是通过 zip 压缩整个标准库减去
lib-dynload
、config-3.7m-darwin
和 site-packages
来减小应用程序中 python 发行版的大小。
我的目录结构如下:
- python3.7/
- include/
- lib/
- python3.7/
- libpython3.7.dylib
- python3.7 <executable>
基本的初始步骤是将
lib-dynload
和config-3.7m-darwin
从lib/python3.7
移动,这样我就可以将sodlib源文件压缩到lib/python37.zip
中,然后将lib-dynload
和config-3.7m-darwin
移回现在空的lib/python3.7
最终得到所需的结构:
- python3.7/
- include/
- lib/
- python3.7/
- lib-dynload/
- config-3.7m-darwin
- python37.zip
- libpython3.7.dylib
- python3.7 <executable>
为了测试它是否有效,我会检查可执行文件中的
sys.path
并尝试导入模块并检查其 __file__
属性以查看它是否来自 zip 存档。
在此基础上,我会
cd
进入lib/python3.7
并尝试以下操作:
选择所有文件和文件夹,并使用 OS X 的 Finder 的
compress
进行压缩以生成 python37.zip
使用Python
zipfile
模块:
python -m zipfile -c python37.zip lib/python3.7/*
如何将所有 Python 代码捆绑到一个 zip 文件中?中的
zip
cd lib/python3.7
zip -r9 ../python37.zip *
在所有情况下,我都通过将 PYTHONPATH 设置为压缩库来使其工作,如下所示:
PYTHONPATH=lib/python37.zip ./python3.7`
这样做后,我能够成功地从 zip 存档导入并验证模块是否来自 zip 存档。但是没有设置PYTHONPATH,它不起作用。
因此,我非常感谢您提供一些帮助来建立正确且最直接的方法来压缩标准库,以便从 sys.path 自动识别它(无需任何额外的步骤,例如指定 PYTHONPATH 环境值,这可能不是可能在用户的机器上)。
预先感谢您提供的任何帮助。
S
经过漫长的排除过程终于弄清楚了。
您必须保留在站点包中的唯一模块是
os.py
。
这是整个过程的 bash 脚本,可能有效也可能无效。它假设您已经从 python.org 下载了 python 源代码发行版
然后
cd
进入生成的源文件夹并在根目录中运行此脚本
#!/usr/bin/env bash
# build_zpython.sh
# builds minimized python with zipped `site-packages`
# NOTE: need os.py to remain in site-packages or just above it or it will fail
# ----------------------------------------------------------------------------
# VARS
NAME=zpython
VERSION=3.11.7
MAC_DEP_TARGET=10.13
# ----------------------------------------------------------------------------
PWD=$(pwd)
PREFIX=${PWD}/${NAME}
VER=${VERSION%.*}
VERN="${VER//./}"
LIB=${PREFIX}/lib/python${VER}
URL=https://www.python.org/ftp/python/${VERSION}/Python-${VERSION}.tar.xz
get_python() {
wget $URL
}
remove() {
echo "removing $1"
rm -rf $1
}
rm_lib() {
echo "removing $1"
rm -rf ${LIB}/$1
}
clean() {
echo "removing __pycache__ .pyc/o from $1"
find $1 | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
}
clean_tests() {
echo "removing 'test' dirs from $1"
find $1 | grep -E "(tests|test)" | xargs rm -rf
}
clean_site_packages() {
echo "removing everything in $LIB/site-packages"
rm -rf $LIB/site-packages/*
}
rm_ext() {
echo "removing $LIB/lib-dynload/$1.cpython-${VER}-darwin.so"
rm -rf $LIB/lib-dynload/$1.cpython-*.so
}
rm_bin() {
echo "removing $PREFIX/bin/$1"
rm -rf $PREFIX/bin/$1
}
# ----------------------------------------------------------------------------
# main
main() {
if ! test -f Python-${VERSION}.tar.xz; then
wget $URL
fi
if test -d Python-${VERSION}; then
rm -rf Python-${VERSION}
fi
tar xvf Python-${VERSION}.tar.xz
cd Python-${VERSION}
./configure MACOSX_DEPLOYMENT_TARGET=${MAC_DEP_TARGET} \
--prefix=$PREFIX \
--enable-shared \
--disable-test-modules \
--with-ensurepip=no \
--without-static-libpython
make install
clean $PREFIX
clean_tests $LIB
clean_site_packages
remove ${LIB}/site-packages
# remove what you want here...
rm_lib config-${VERSION}-darwin
rm_lib idlelib
rm_lib lib2to3
rm_lib tkinter
rm_lib turtledemo
rm_lib turtle.py
rm_lib ensurepip
rm_lib venv
remove $LIB/distutils/command/*.exe
remove $LIB/lib-dynload/_xx*.so
remove $LIB/lib-dynload/xx*.so
remove $PREFIX/lib/pkgconfig
remove $PREFIX/share
# remove what you want here...
rm_ext _tkinter
rm_bin 2to3-${VER}
rm_bin idle${VER}
rm_bin idle3
rm_bin 2to3-${VER}
rm_bin 2to3
mv $LIB/lib-dynload $PREFIX
cp $LIB/os.py $PREFIX
clean $PREFIX
echo "zip site-packages"
python3 -m zipfile -c $PREFIX/lib/python${VERN}.zip $LIB/*
remove $LIB
mkdir -p $LIB
mv $PREFIX/lib-dynload $LIB
mv $PREFIX/os.py $LIB
mkdir $LIB/site-packages
echo "cleanup"
rm -rf Python-${VERSION}
}
test_zpython() {
./python/bin/python3 -c "import string; print(string.__file__)"
./python/bin/python3 -c "import string; assert string.digits=='0123456789'"
}
# run it
time main
# test it
test_zpython
这是针对 Mac 用户的,可以轻松适应其他平台。它尚未经过充分测试,因此如果您遇到任何问题,请发布反馈。