Portable的意思是可拔插的,便携式的。Portable 程序在一台计算机上编译好后,移植到其他计算机上就可以直接运行。一般程序运行时都会依赖一些第三方库,只要把对这些库的依赖方式由静态依赖改成动态依赖,再把这些库和主体程序放到一起打包,就成为一个Portable 程序。
当然Portable 也是有限度的,不能跨操作系统移植,毕竟程序对操作系统的依赖关联太多,除非把整个系统也移植了😂。
以Python-3.6.5 为例,讲述一下源码编译一个Portable Pyton 的主要流程。
Windows 平台
winpython 是一个专门编译Windows 平台下Portable Pyton 的项目,可以直接下载WinPython32-3.6.5.0Zero.exe或者WinPython64-3.6.5.0Zero.exe,解压出来就是对应的32位Portable Pyton 或64位Portable Pyton.
macOS 平台
最好在OS X10.9
系统下编译Portable Pyton,对其他更高级的macOS 兼容性会好一些。
python 的一些内置模块会依赖第三方库,主要是:
所以,我们要先安装这些库。
编译lzma
下载xz-5.2.3.tar.gz,解压到/tmp/xz-5.2.3
,然后:
1 | $ cd /tmp |
编译openssl
下载openssl-OpenSSL_1_0_2t.zip,解压到/tmp/openssl-OpenSSL_1_0_2t
,然后:
1 | $ cd /tmp/openssl-OpenSSL_1_0_2t |
编译tcl/tk
下载tcl8519-src.zip,解压到/tmp/tk8519-src
;下载tk8519-src.zip,解压到/tmp/tk8519-src
,然后:
1 | $ cd /tmp/tcl8519-src |
编译python
下载Python-3.6.5,解压到/tmp/Python-3.6.5
, 然后:
1 | $ cd /tmp |
修改依赖路径
以上python 安装在/tmp/python
,把python 依赖的第三方动态库,复制到/tmp/python/lib
:
1 | $ cd /tmp/python/lib |
macOS下,otool
工具可以查看动态库的依赖路径,intall_name_tool
工具可以修改动态库的依赖路径。
我们要把所有的外部依赖(除了系统依赖)都修改为/tmp/python/lib
内部依赖,绝对的依赖路径也改为相对的依赖路径:
修改libssl.1.0.0.dylib
:
1 | $ cd /tmp/python/lib |
修改_lzma.cpython-36m-darwin.so
:
1 | $ cd /tmp/python/lib/python3.6/lib-dynload |
修改_ssl.cpython-36m-darwin.so
:
1 | $ cd /tmp/python/lib/python3.6/lib-dynload |
修改_tkinter.cpython-36m-darwin.so
:
1 | $ cd /tmp/python/lib/python3.6/lib-dynload |
测试
测试修改依赖路径后的python运行情况:
1 | $ cd /tmp/python |
升级pip
1 | $ cd /tmp/python |
最后
我们得到了一个Portable Pyton /tmp/python
,可以内嵌到其他程序中一起打包,分发到各个计算机运行。