源自半个多月前周报里看到的帖子 https://gregoryszorc.com/blog/2022/05/10/announcing-the-pyoxy-python-runner/
看作者的意思, 有了绿色版 Python 解释器, 打包发布时候对环境要求就更低了, 比如打个 docker 镜像也不用提前安装 Python 了
1
ysc3839 2022-05-30 04:27:31 +08:00 via Android
CPython 本身就可以实现真单文件,C/C++部分静态链接,Python 部分代码打包成 zip 然后塞进可执行文件里。
不能单文件的是 native module ,因为用的是系统级的 DLL/so/dylib 机制进行加载,目前似乎没有哪个系统支持从内存中加载 DLL 的。 Node.js 的 Electron 和 pkg 也会把 native module 解压出来的。 |
2
codehz 2022-05-30 06:25:20 +08:00
|
3
ysc3839 2022-05-30 06:40:39 +08:00 via Android
@codehz 不可移植,意味着不会有官方支持这种做法,意味着所有功能、问题都要自己实现、修复。那既然要自己实现,还不如研究如何把第三方 native module 直接静态链接进可执行文件中。自解压 native module 本来就是为了能直接利用现有的 native module binaries 所做的妥协。
|
4
bybyte 2022-05-30 08:38:57 +08:00
@ysc3839 从系统中加载 DLL 是可以的,这种方法经常用来躲过反作弊系统的检测 https://bbs.pediy.com/thread-230147.htm
|
5
weyou 2022-05-30 09:03:18 +08:00 via Android
@ysc3839 Tcl/Tk 语言的 starkit 打包工具就是利用 VFS ( virtual file system )的内存文件系统做到了只从内存加载动态库( dll 或者 so 都可以)。而且这项技术已经有二三十年了,一直很奇怪 Python 的打包工具为什么没有实现
|
6
ysc3839 2022-05-30 09:22:21 +08:00 via Android
|
7
dant 2022-05-30 09:52:55 +08:00 1
@ysc3839 Linux 可以用 memfd 然后 dlopen("/proc/self/fd/x"),或者 Android linker 直接支持 fd+offset 从 apk 里载入 未压缩的 so 。
但是 Python 的问题是总有一些库会用 __file__ 拼文件系统路径加载资源,PyInstaller 因此写了不少 hook 。 |
8
ysc3839 2022-05-30 09:56:16 +08:00 via Android
@dant 访问文件反而不是最主要的问题,通过 Python 本身的接口访问的话,总有办法拦截下来的。通过 native module 访问的话,上述几个方案似乎也是不进行处理。
|
9
ClericPy OP @weyou 是这个原因导致 zipapp 不能支持 .so/.pyd 这类导入的么, 所以 shiv 每次都得解压缩了才能用(虽然兼容性更好, 如果能解压缩到内存就好了). 这部分知识不太了解
至于楼下提到的 __file__ 那是那几个库自己的问题, 正常情况不是 web 那边静态文件靠 pkgutil.get_data 够用 本来以为就是想问问单文件解释器可用情况, 以及解决不解压的单文件运行方式, 没想到知道了这么多新知识, 活到老学到老 |
10
ClericPy OP 更新
https://github.com/indygreg/python-build-standalone/releases 这个当绿色版解释器很稳了, rye 用的就是它, 貌似就是 pyoxy 相关的. 试了下不错 sqlite 还得琢磨怎么带进去 |