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

2024-09-30 10:27:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我最近根据Joao Ventura非常有用的两部分系列中概述的方法,使用自制安装的python3.7在Mac OS X中成功地嵌入了一个python发行版和一个应用程序,这里提供了两部分供参考(http://joaoventura.net/blog/2016/embeddable-python-osx/)和(http://joaoventura.net/blog/2016/embeddable-python-osx-from-src/

对我来说,唯一剩下的问题是通过压缩整个标准库减去lib-dynloadconfig-3.7m-darwinsite-packages,来减小应用程序中python发行版的大小

我的目录结构如下:

- python3.7/
  - include/
  - lib/
    - python3.7/
  - libpython3.7.dylib
  - python3.7 <executable>

基本的初始步骤是将lib-dynloadconfig-3.7m-darwinlib/python3.7移动,这样我就可以将sodlib源文件压缩到lib/python37.zip中,然后将lib-dynloadconfig-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. 选择所有文件和文件夹,并使用OSX的Finder compress压缩以生成python37.zip

  2. 使用python zipfile模块:

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

  1. 使用来自How can you bundle all your python code into a single zip file?zip方法
cd lib/python3.7
zip -r9 ../python37.zip *

在所有情况下,我都是通过将PYTHONPATH设置为压缩库来实现的,如下所示:

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

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

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

提前感谢您提供的任何帮助


Tags: 模块方法config应用程序http标准netlib
1条回答
网友
1楼 · 发布于 2024-09-30 10:27:03

经过漫长的淘汰过程,终于找到了答案

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

下面是一个bash脚本,用于整个过程,它可能有效,也可能无效。它假设您已经从python.org下载了一个python源代码发行版

然后cd进入结果源文件夹,并在根目录中运行此脚本

#!/usr/bin/env bash

# build_python.sh
# NOTE: need os.py to remain in site-packages or it will fail



NAME=xpython
PWD=$(pwd)
PREFIX=${PWD}/${NAME}
VERSION=3.8
VER="${VERSION//./}"
LIB=${PREFIX}/lib/python${VERSION}
MAC_DEP_TARGET=10.13


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-38-darwin.so
}

rm_bin() {
    echo "removing $PREFIX/bin/$1"
    rm -rf $PREFIX/bin/$1
}

./configure MACOSX_DEPLOYMENT_TARGET=${MAC_DEP_TARGET} \
   prefix=$PREFIX \
   enable-shared \
   with-universal-archs=64-bit \
   with-lto \
   enable-optimizations

make altinstall


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 $PREFIX/lib/pkgconfig
remove $PREFIX/share

# remove what you want here...
rm_ext _tkinter


rm_bin 2to3-${VERSION}
rm_bin idle${VERSION}
rm_bin easy_install-${VERSION}
rm_bin pip${VERSION}



mv $LIB/lib-dynload $PREFIX
cp $LIB/os.py $PREFIX
clean $PREFIX
python -m zipfile -c $PREFIX/lib/python${VER}.zip $LIB/*
remove $LIB
mkdir -p $LIB
mv $PREFIX/lib-dynload $LIB
mv $PREFIX/os.py $LIB
mkdir $LIB/site-packages

这是针对mac用户的,可以很容易地适应其他平台。它没有经过很好的测试,所以如果遇到任何问题,请发布反馈

相关问题 更多 >

    热门问题