• Pyinstaller打包详解---生成windows、linux下的整包可执行文件


    1、原理及作用:

    pyinstaller自身打包的流程:读取编写好的python脚本,分析其中调用的模块和库,然后收集这些文件的副本(包括Python的解释器)。最后把副本与脚本,可执行文件等放在一个文件夹中,或者可选的封装在一个可执行文件中。我们可以将自己的python代码打包成一个可执行文件。起到代码保护和封装的作用。

    2、打包流程:

    2-1、安装pyinstaller
    pip install pyinstaller
    2-2、拷贝main.spec文件

    我们用main.spec文件记录打包需要的文件依赖等,pyinstaller参数的本质可认为是 .spec文件中的配置属性。main.spec文件可按照类型直接在internet中拷贝模板即可,之后进行修改。(下文有模板示例)

    camera_stress_test_tool_main工具为例:

    将下面模板的camera_stress_test_tool_main.spec文件拷贝至和 main.py同目录下

    亦可用pyi-makespec  main.py生成 .spec文件,需注意按需使用参数

    -F, –onefile打包一个单个文件
    -D, –onedir 打包多个文件,在dist中生成很多依赖文件,适合以框架形式编写工具代码,我个人比较推荐这样,代码易于维护
    -K, –tk 在部署时包含 TCL/TK
    -a, –ascii 不包含编码.在支持Unicode的python版本上默认包含所有的编码.
    -d, –debug 产生debug版本的可执行文件
    -w,–windowed,–noconsole 使用Windows子系统执行.当程序启动的时候不会打开命令行(只对Windows有效)
    -c,–nowindowed,–console 使用控制台子系统执行(默认)(只对Windows有效)pyinstaller -c xxxx.pypyinstaller xxxx.py –console
    -s,–strip 可执行文件和共享库将run through strip.注意Cygwin的strip往往使普通的win32 Dll无法使用.
    -X, –upx 如果有UPX安装(执行Configure.py时检测),会压缩执行文件(Windows系统中的DLL也会)(参见note)
    -o DIR, –out=DIR 指定spec文件的生成目录,如果没有指定,而且当前目录是PyInstaller的根目录,会自动创建一个用于输出(spec和生成的可执行文件)的目录.如果没有指定,而当前目录不是PyInstaller的根目录,则会输出到当前的目录下.
    -p DIR, –path=DIR 设置导入路径(和使用PYTHONPATH效果相似).可以用路径分割符(Windows使用分号,Linux使用冒号)分割,指定多个目录.也可以使用多个-p参数来设置多个导入路径,让pyinstaller自己去找程序需要的资源
    –icon=<FILE.ICO> 将file.ico添加为可执行文件的资源(只对Windows系统有效),改变程序的图标 pyinstaller -i ico路径 xxxxx.py
    –icon=<FILE.EXE,N> 将file.exe的第n个图标添加为可执行文件的资源(只对Windows系统有效)
    -v FILE, –version=FILE 将verfile作为可执行文件的版本资源(只对Windows系统有效)
    -n NAME, –name=NAME 可选的项目(产生的spec的)名字.如果省略,第一个脚本的主文件名将作为spec的名字

    camera_stress_test_tool_main.spec文件模板示例:(模板为单文件示范)

    # -*- mode: python ; coding: utf-8 -*-
    
    block_cipher = None
    
    
    a = Analysis(['main.py',
                './cfg/__init__.py',
                './cfg/setting.py',
                './comm/__init__.py',
                './comm/logger.py',
                './comm/utils.py',
                './handler/__init__.py',
                './handler/invite_handler.py',
                './handler/sip_parse_handler.py',
                './handler/subscribe_handler.py',
                './my_thread/__init__.py',
                './my_thread/alarm.py',
                './my_thread/audio_media.py',
                './my_thread/audio_media_rtp.py',
                './my_thread/broadcast.py',
                './my_thread/my_sip_epoll.py',
                './my_thread/timer.py',
                './my_thread/video_media.py',
                './redis_utils/__init__.py',
                './redis_utils/redis_keys.py',
                './redis_utils/redis_work.py',
                './__init__.py',
                './device.py',
                './std/ietf/__init__.py',
                './std/ietf/rfc1035.py',
                './std/ietf/rfc2198.py',
                './std/ietf/rfc2396.py',
                './std/ietf/rfc2617.py',
                './std/ietf/rfc2833.py',
                './std/ietf/rfc3261.py',
                './std/ietf/rfc3489.py',
                './std/ietf/rfc5658.py',
                './std/ietf/rfc6455.py',
                './std/ietf/rfc7064.py',
                './std/ietf/rfc7065.py',
                './std/itu_t/__init__.py',
                './std/w3c/__init__.py',
                './std/w3c/simplexml.py',
                './std/__init__.py'],
                 pathex=['./'],
                 binaries=[],
                 datas=[],
                 hiddenimports=[],
                 hookspath=[],
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    exe = EXE(pyz,
              a.scripts,
              a.binaries,
              a.zipfiles,
              a.datas,
              [],
              name='main',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              upx_exclude=[],
              runtime_tmpdir=None,
              console=True )
    2-3、修改main.spec文件

    一般来说,我们需要在“Analysis”这个item中,加入打包的代码的路径,(此处需注意路径相关依赖,与创建spec的路径相对应,一般在main.py文件基础上找,可写绝对及相对路径)。另外:是否加入图标路径icon,是否需要console等可按需配置。

    为了便于理解掌握命令配置参数

    下面附上main.spec文件的配置详情:

    2-4、执行打包命令
    pyinstaller  main.spec
     
    2-5、删除源代码和中间产物

    打包完成后可删除生成的build文件夹,.spec文件等,亦可将代码删除,之后我们可直接运行打包成品的可执行文件。

     
    2-6、运行检查打包后的可执行文件

    修改配置文件相关配置后

    (注意是配置文件不是代码,修改代码则需要重新打包)

    可直接进入dist文件夹中,找到可执行文件,linux下直接使用下述命令执行。如:

      ./main

    若有路径报错,根据运行情况自行解决相关依赖等。

    常见问题有路径依赖包依赖,一般需解决代码内部引用路径(目前可执行文件的执行路径,与代码入口路径不同)来更改代码,缺省的依赖需加入到.spec文件中等。

    3、简略描述:

    简单点描述Pyinstall的打包流程:
    1、下载好Pyinstaller之后,
    2、拷贝上述spec文件并增删自己的工程代码路径(或使用pyi-makespec main.py命令生成.spec文件)

    3、执行 pyinstaller main.spec

    4、在dist中,检验生成的  main可执行文件

  • 相关阅读:
    dockerfile 详解
    kubectl简介
    关于高级事件的使用
    关于拖拽延伸出来的一些效果
    照片墙的制作过程及其出现的问题
    关于360度全景照片的问题总结
    实战演练-记账本App (五)
    人月神话阅读笔记02
    实战演练-记账本App(四)
    实战演练-记账本App(三)
  • 原文地址:https://www.cnblogs.com/zhangxingcomeon/p/14523893.html
Copyright © 2020-2023  润新知