- 作者:
- 分类:知识&开发->语言->Python
- 阅读:812
- 点赞:3
- 版权:CC BY-SA 4.0
- 创建:2023-09-05
- 更新:2023-09-06
原文链接(持续更新):https://neucrack.com/p/504
下载源码
https://www.python.org/downloads/source/
编译给 HOST(PC)用的 python
cd Python-3.6.9/
./configure --prefix=$PWD/../_install_host --enable-shared
make -j`nproc`
make install
配置参数
https://docs.python.org/3/using/configure.html#configure-options
export PATH=_install_host的bin 路径
export LD_LIBRARY_PATH=_install_host的lib路径
python3 --version
编译 target
清除之前的
make distclean
这里是 armA7 为例
./configure --host=arm-openwrt-linux --build=armv7l --prefix=`pwd`/../python_target --enable-shared --with-build-python --enable-ipv6 ac_cv_file__dev_ptmx="yes" ac_cv_file__dev_ptc="no"
make -j`nproc`
make install
如果最后遇到了subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1.
用 root 用户编辑 /usr/bin/lsb_release
, #!/usr/bin/python3
改为 python3
即可,这是因为 python3 命令才能调用到我们编译出来的 python3。
交叉编译遇到 The necessary bits to build these optional modules were not found
Python build finished successfully!
The necessary bits to build these optional modules were not found:
_bz2 _curses _curses_panel
_dbm _gdbm _hashlib
_lzma _sqlite3 _ssl
_tkinter nis readline
zlib
To find the necessary bits, look in setup.py in detect_modules() for the module's name.
The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:
_abc atexit pwd
time
Failed to build these modules:
_ctypes _uuid
Could not build the ssl module!
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_PARAM_set1_host().
LibreSSL 2.6.4 and earlier do not provide the necessary APIs, https://github.com/libressl-portable/portable/issues/381
编译好了使用python3 -m ensurepip
来安装 pip,也会出现找不到zlib
模块的问题。
如果是本机编译比较好解决,比如Ubuntu
直接apt
安装对应的包就好了。
交叉编译则比较麻烦:
在Python 源码 setup.py 中有detect_modules
函数来找依赖的源码,其中detect_compress_exts
函数就是找zlib
,可以看到它去zlib_inc = find_file('zlib.h', [], self.inc_dirs)
include
的路径找zlib.h
头文件了,以及self.lib_dirs
找库文件,所以理论上我们交叉编译好 zlib
,并且编译 Python 时往./configure
命令传入CFLAGS="-I***/include CPPFLAGS="-I***/include" LDFLAGS="-L***/lib
环境变量就好了,其它模块同理去看对应的detect_*****()
函数里面在检测什么变量,编译时传入环境变量即可。
可以参考这里: https://gist.github.com/j-c-cook/2a291dc0bfaa2f6639272e344ff66e62
$ tar -xvf v1.2.11.tar.gz && cd cd zlib-1.2.11/
$ CHOST="${cross}" CC="${cross}-gcc" CXX="${cross}-g++" AR="${cross}-ar" LD="${cross}-ld" RANLIB="${cross}-ranlib"
$ ./configure --prefix=$HOME/zlibArm
$ make -j`nproc`
$ make install
pip 也需要 ssl, openssl 有专门的参数--with-openssl=DIR
, 设置了这个参数,configure 会自动去这个目录下找include``lib
,所以不用我们自己设置变量了。这个 DIR 就是交叉编译后的 openssl install 路径
$ tar -xvf OpenSSL_1_1_1o.tar.gz && cd openssl-OpenSSL_1_1_1o
$ ./Configure linux-generic32 shared -DL_ENDIAN --prefix=$HOME/opensslArm --openssldir=$HOME/opensslArm
$ make CC="${cross}"-gcc RANLIB="${cross}"-ranlib LD="${cross}"-ld MAKEDEPPROG="${cross}"-gcc PROCESSOR=ARM
$ make install
$ cd cpython-3.7.13/
$ CHOST="${cross}" CC="${cross}"-gcc CXX="${cross}"-g++ AR="${cross}"-ar LD="${cross}"-ld RANLIB="${cross}"-ranlib CFLAGS="-I$HOME/zlibArm/include -I$HOME/sqliteArm/include -I$HOME/libffiArm/include" LDFLAGS="-L$HOME/zlibArm/lib -L$HOME/sqliteArm/lib -L$HOME/libffiArm/lib" CPPFLAGS="-I$HOME/zlibArm/include -I$HOME/sqliteArm/include -I$HOME/libffiArm/include" ./configure --prefix=$HOME/pythonArm --host="${cross}" --target=arm --build=x86_64-linux-gnu --with-openssl="$HOME/opensslArm" --disable-ipv6 ac_cv_file__dev_ptmx=no ac_cv_file__dev_ptc=no --with-ensurepip=install --enable-loadable-sqlite-extensions --enable-optimizations
$ make -j 8