pyinstaller打包Orange3

首先加入3个库的钩子 hook

hook-Orange

from PyInstaller.utils.hooks import copy_metadata
from PyInstaller.utils.hooks import collect_data_files
from PyInstaller.utils.hooks import collect_submodules
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all("Orange")
datas += copy_metadata('Orange3')
# datas += collect_data_files("Orange")
# hiddenimports = collect_submodules('Orange')

hook-orangecanvas

from PyInstaller.utils.hooks import copy_metadata
from PyInstaller.utils.hooks import collect_data_files
from PyInstaller.utils.hooks import collect_submodules
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all("orangecanvas")
datas += copy_metadata('orange_canvas_core')
# datas += collect_data_files("orangecanvas")
# hiddenimports = collect_submodules('orangecanvas')

hook-orangewidget

from PyInstaller.utils.hooks import copy_metadata
from PyInstaller.utils.hooks import collect_data_files
from PyInstaller.utils.hooks import collect_submodules
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all("orangewidget")
datas += copy_metadata('orange_widget_base')
# datas += collect_data_files("orangewidget")
# hiddenimports = collect_submodules('orangewidget')

保证不缺文件

改动入口文件 Orange3/canvas/__main__

def resource_path(relative_path):
    if getattr(sys, 'frozen', False):  # 是否Bundle Resource
        base_path = sys._MEIPASS
    else:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

解决临时temp位置读取问题

539行

if pkg_resources.resource_exists(pkg_name, resource):

开始,打包后pkg_resources功能使用有错误,需要修改为手动读取

with open(resource_path(pkg_name + '/' + resource)) as f:
        stylesheet_string = f.read()
    base = resource_path(os.getcwd() + '\\' + pkg_name + '\\' + "styles")
    pattern = re.compile(
        r"^\s@([a-zA-Z0-9_]+?)\s*:\s*([a-zA-Z0-9_/]+?);\s*$",
        flags=re.MULTILINE
    )
    matches = pattern.findall(stylesheet_string)
    for prefix, search_path in matches:
        QDir.addSearchPath(prefix, os.path.join(base, search_path))
        log.info("Adding search path %r for prefix, %r",
                 search_path, prefix)
    stylesheet_string = pattern.sub("", stylesheet_string)
dirpath = resource_path(os.getcwd() + '\\' + pkg_name)
QDir.addSearchPath("canvas_icons", os.path.join(dirpath, "icons"))

然后spec打包配置文件需要修改,解决剩余问题

# -*- mode: python ; coding: utf-8 -*-


block_cipher = None
import pkg_resources
import os

hook_ep_packages = dict()
hiddenimports = set()

# List of packages that should have there Distutils entrypoints included.
ep_packages = ["orange.widgets"]

if ep_packages:
    for ep_package in ep_packages:
        for ep in pkg_resources.iter_entry_points(ep_package):
            if ep_package in hook_ep_packages:
                package_entry_point = hook_ep_packages[ep_package]
            else:
                package_entry_point = []
                hook_ep_packages[ep_package] = package_entry_point
            package_entry_point.append("{} = {}".format(ep.name, ep.module_name))
            hiddenimports.add(ep.module_name)

    try:
        os.mkdir('./generated')
    except FileExistsError:
        pass
解决pkg_resources.iter_entry_points问题,生成在线运行钩子文件
    with open("./generated/pkg_resources_hook.py", "w") as f:
        f.write("""# Runtime hook generated from spec file to support pkg_resources entrypoints.
ep_packages = {}

if ep_packages:
    import pkg_resources
    default_iter_entry_points = pkg_resources.iter_entry_points

    def hook_iter_entry_points(group, name=None):
        if group in ep_packages and ep_packages[group]:
            eps = ep_packages[group]
            for ep in eps:
                parsedEp = pkg_resources.EntryPoint.parse(ep)
                parsedEp.dist = pkg_resources.Distribution(project_name='Orange3',version='3.27.1')
                yield parsedEp
        else:
            return default_iter_entry_points(group, name)

    pkg_resources.iter_entry_points = hook_iter_entry_points
""".format(hook_ep_packages))

a = Analysis(['run.py'],
             pathex=['C:\\Users\\Lenovo\\PycharmProjects\\pythonProject'],
             binaries=[],
             datas=[],
             hiddenimports=list(hiddenimports)+['sklearn.utils._weight_vector','openTSNE._matrix_mul.matrix_mul'],解决部分组件缺失包问题
             hookspath=[],
             runtime_hooks=["./generated/pkg_resources_hook.py"],在线运行钩子文件
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
remove = ["_simple_tree", "_tree_scorers", "_contingency", "_io", "_valuecount", "_variable", "_distance", "_discretize", "_relieff", "_som", "_grid_density"]
temp=a.binaries[:]
for t in temp:
    if any(r+'.cp37-win_amd64.pyd' in t[1] for r in remove):
        print('Removing'+ t[1])
        a.binaries.remove(t)移除无效pyd文件,解决运行前warning提示对话框问题
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='run',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False , icon='favicon.ico')加入打包程序图标

 

上一篇:egg 打包


下一篇:Go语言连接Oracle