OpenWrt MT7621使用pyinstaller打包失败解决办法

时间:2021-12-19 23:24:17

前段时间移植一个python项目到OpenWrt,掉了不少坑,总结一下希望帮到有需要的人,来看打包问题:

0x01

在OpenWrt 使用pip直接安装了pyinstaller,打包过程中出现文件缺失、文件错误的问题:

从githut/pyinstaller得知linux环境下使用pyinstaller需要ldd、objcopy、objdump支持,openwrt安装gcc即可自动安装binutils:

opkg update  opkg install gcc

github pyinstaller:https://github.com/pyinstaller/pyinstaller


0x02

继续打包,继续报错,错误信息如下:

root@mux:~/huanyun_daemon# pyinstaller hy_daemon.py
2230 INFO: PyInstaller: 3.2.1
2232 INFO: Python: 2.7.9
2240 INFO: Platform: Linux-3.18.29-mips-with-glibc2.0
2244 INFO: wrote /root/huanyun_daemon/hy_daemon.spec
2278 INFO: UPX is not available.
2294 INFO: Extending PYTHONPATH with paths
['/root/huanyun_daemon', '/root/huanyun_daemon']
2296 INFO: checking Analysis
2454 INFO: checking PYZ
2542 INFO: checking PKG
2556 INFO: Building because toc changed
2558 INFO: Building PKG (CArchive) out00-PKG.pkg
ldd: can't open cache '/etc/ld.so.cache'
2713 INFO: Building PKG (CArchive) out00-PKG.pkg completed successfully.
2785 INFO: Bootloader /usr/lib/python2.7/site-packages/PyInstaller/bootloader/Linux-32bit/run
2788 INFO: checking EXE
2790 INFO: Building EXE because out00-EXE.toc is non existent
2791 INFO: Building EXE from out00-EXE.toc
2795 INFO: Appending archive to ELF section in EXE /root/huanyun_daemon/build/hy_daemon/hy_daemon
Traceback (most recent call last):
  File "/usr/bin/pyinstaller", line 9, in <module>
    load_entry_point('PyInstaller==3.2.1', 'console_scripts', 'pyinstaller')()
  File "/usr/lib/python2.7/site-packages/PyInstaller/__main__.py", line 90, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "/usr/lib/python2.7/site-packages/PyInstaller/__main__.py", line 46, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "/usr/lib/python2.7/site-packages/PyInstaller/building/build_main.py", line 788, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "/usr/lib/python2.7/site-packages/PyInstaller/building/build_main.py", line 734, in build
    exec(text, spec_namespace)
  File "<string>", line 26, in <module>
  File "/usr/lib/python2.7/site-packages/PyInstaller/building/api.py", line 411, in __init__
    self.__postinit__()
  File "/usr/lib/python2.7/site-packages/PyInstaller/building/datastruct.py", line 161, in __postinit__
    self.assemble()
  File "/usr/lib/python2.7/site-packages/PyInstaller/building/api.py", line 563, in assemble
    self.name)
  File "/usr/lib/python2.7/site-packages/PyInstaller/compat.py", line 486, in exec_command_all
    stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

继续填坑,根据github用户提示,打包出错原因是:使用pip安装的pyinstaller,已经预编译过bootloader。需要在Openwrt平台手动重新编译,再手动安装:

1, git clone https://github.com/pyinstaller/pyinstaller.git
2, cd pyinstaller && git checkout v3.1
3, cd bootloader
4, python ./waf distclean all --no-lsb
5, python waf configure --no-lsb build install

https://github.com/pyinstaller/pyinstaller/issues/2050#issuecomment-248525988


0x03

以为柳暗花明,猝不及防又一坑:

重编译bootloader过程中出现:无法识别gcc -m32

在源码wscript文件找到这个-m32,看注释描述:

        # This ensures proper compilation with 64bit gcc and 32bit Python
        # or vice versa or with manually choosen --target-arch.
        # Option -m32/-m64 has to be passed to cflags and linkflages.
        elif ctx.env.PYI_ARCH == '32bit':
            # It was reported that flag '-m32' does not work with gcc
            # on 32-bit arm Linux. So skip the -m32 flag.
            if not (machine() == 'arm' and is_linux):
                ctx.check_cc(ccflags='-m32', msg='Checking for flags -m32')
                ctx.env.append_value('CFLAGS', '-m32')
                ctx.env.append_value('LINKFLAGS', '-m32')
            # Set LARGE_ADDRESS_AWARE_FLAG to True.
            # On Windows this allows 32bit apps to use 4GB of memory and
            # not only 2GB.
            # TODO verify if this option being as default might cause any side effects.
            if is_win:
                ctx.env.append_value('LINKFLAGS', '-Wl,--large-address-aware')
        elif ctx.env.PYI_ARCH == '64bit':
            ctx.check_cc(ccflags='-m64', msg='Checking for flags -m64')
            ctx.env.append_value('CFLAGS', '-m64')
            ctx.env.append_value('LINKFLAGS', '-m64')

elif ctx.env.PYI_ARCH == '32bit':
pass掉就好了:
        # This ensures proper compilation with 64bit gcc and 32bit Python
        # or vice versa or with manually choosen --target-arch.
        # Option -m32/-m64 has to be passed to cflags and linkflages.
        elif ctx.env.PYI_ARCH == '32bit':
	    pass
            # It was reported that flag '-m32' does not work with gcc
            # on 32-bit arm Linux. So skip the -m32 flag.
	   # if not (machine() == None and machine() == 'arm' and is_linux):
            #    ctx.check_cc(ccflags='-m32', msg='Checking for flags -m32')
            #    ctx.env.append_value('CFLAGS', '-m32')
            #    ctx.env.append_value('LINKFLAGS', '-m32')
            # Set LARGE_ADDRESS_AWARE_FLAG to True.
            # On Windows this allows 32bit apps to use 4GB of memory and
            # not only 2GB.
            # TODO verify if this option being as default might cause any side effects.
           # if is_win:
            #    ctx.env.append_value('LINKFLAGS', '-Wl,--large-address-aware')
        elif ctx.env.PYI_ARCH == '64bit':
            ctx.check_cc(ccflags='-m64', msg='Checking for flags -m64')
            ctx.env.append_value('CFLAGS', '-m64')
            ctx.env.append_value('LINKFLAGS', '-m64')

修改完毕,继续编译bootloader,根据提示增加需要的头文件,即可通过编译


0x04

最后一步,回到顶层目录,手动安装pyinstaller:

python setup.py install
搞定,附上一个打包成功的截图:

OpenWrt MT7621使用pyinstaller打包失败解决办法

总结:安装gcc-->修改bootloader的wscript文件-->编译-->安装

第一次写博客,希望能帮助到有需要的人OpenWrt MT7621使用pyinstaller打包失败解决办法