zoukankan      html  css  js  c++  java
  • compile mycli by pyinstaller

    背景 

    在服务器没有安装mycli,安装的python版本不一致的情况下,想到通过pyinstaller编译出mycli的二进制文件直接运行。

    pyinstaller -F /usr/bin/python3.6/bin/mycli --onefile 编译成功,然后悲剧的情况来了

    Traceback (most recent call last):
      File "mycli", line 11, in <module>
      File "site-packages/click/core.py", line 829, in __call__
      File "site-packages/click/core.py", line 782, in main
      File "site-packages/click/core.py", line 1066, in invoke
      File "site-packages/click/core.py", line 610, in invoke
      File "site-packages/mycli/main.py", line 1053, in cli
      File "site-packages/mycli/main.py", line 118, in __init__
      File "site-packages/configobj.py", line 554, in __getitem__
    KeyError: 'main'
    [277772] Failed to execute script mycli

    问题解决

    阅读mycli源码,发现问题出在配置读取部分

    site-packages/mycli/main.py文件中

    PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))
    default_config_file = os.path.join(PACKAGE_ROOT, 'myclirc')

    问题就出现在了__file__的使用上,mycli会读取site-packages/mycli/main.py同级目录下的myclirc, AUTHORS, SPONSORS三个文件,但是pyinstaller编译时,并不会打包这三个文件,导致运行出错。

    接下来就是打包,让我们看看pyinstaller --add-data参数的使用方法

    format: {source}{os_separator}{destination}

    destination file or files: desination folder which will contain your source files

    NOTENOT destination file name, desination folder path, which is RELATIVE path of distination root, NOT absolute path

    这里相对路径的含义比较有意思,上面的报错信息路径为:site-packages/mycli/main.py,但是mycli/main.py中打印出的path确是/tmp/_MEItHovkQ/mycl

    基于以上信息,我们可以这样编译mycli

    #!/bin/sh
    
    pyinstaller -F /usr/local/tencent/python3.6/bin/mycli --onefile 
    --add-data "/usr/local/tencent/python3.6/lib/python3.6/site-packages/mycli/myclirc:mycli" 
    --add-data "/usr/local/tencent/python3.6/lib/python3.6/site-packages/mycli/AUTHORS:mycli" 
    --add-data "/usr/local/tencent/python3.6/lib/python3.6/site-packages/mycli/SPONSORS:mycli" 

    pyinstaller与__file__ 

    #测试代码
    #
    main.py #!/usr/bin/python3 import aaa import os print(os.path.abspath(os.path.dirname(__file__))) # aaa/__init__.py import os print(os.path.abspath(os.path.dirname(__file__)))
    #直接执行脚本

    root@b1f294ad4d44 ~# python3 main.py
    /root/aaa
    /root

    #pyinstaller编译后执行

    root@b1f294ad4d44 ~# ./dist/main
    /tmp/_MEIqn3ZG5/aaa
    /root

    可见,入口python文件其实就是编译出来的二进制文件,所有引用的lib根目录是 /tmp/xxx/<lib-name>

  • 相关阅读:
    php7.4 降级 php7.1 的坑
    python 记录网页 生成pdf
    Mac 安装常用软件环境
    python 2.7 操作 excel
    007整数反转
    006Z字形变换
    005最长回文子串
    004寻找两个正序数组的中位数
    003无重复字符的最长子串
    002两数相加
  • 原文地址:https://www.cnblogs.com/redstar9451/p/12496958.html
Copyright © 2011-2022 走看看