如何正确压缩整个Python标准库?

问题描述 投票:0回答:1

我最近使用自制软件安装了 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
并尝试以下操作:

  1. 选择所有文件和文件夹,并使用 OS X 的 Finder 的

    compress
    进行压缩以生成
    python37.zip

  2. 使用Python

    zipfile
    模块:

python -m zipfile -c python37.zip lib/python3.7/*

  1. 使用
    如何将所有 Python 代码捆绑到一个 zip 文件中?
    中的 zip
  2. 方法
cd lib/python3.7
zip -r9 ../python37.zip *

在所有情况下,我都通过将 PYTHONPATH 设置为压缩库来使其工作,如下所示:

PYTHONPATH=lib/python37.zip ./python3.7`

这样做后,我能够成功地从 zip 存档导入并验证模块是否来自 zip 存档。但是没有设置PYTHONPATH,它不起作用。

因此,我非常感谢您提供一些帮助来建立正确且最直接的方法来压缩标准库,以便从 sys.path 自动识别它(无需任何额外的步骤,例如指定 PYTHONPATH 环境值,这可能不是可能在用户的机器上)。

预先感谢您提供的任何帮助。

S

python zip
1个回答
1
投票

经过漫长的排除过程终于弄清楚了。

您必须保留在站点包中的唯一模块是

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 用户的,可以轻松适应其他平台。它尚未经过充分测试,因此如果您遇到任何问题,请发布反馈。

© www.soinside.com 2019 - 2024. All rights reserved.