cx_Freeze-防止包含不需要的软件包 [英] cx_Freeze - Preventing including unneeded packages

查看:184
本文介绍了cx_Freeze-防止包含不需要的软件包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用PyQt4编写了一个微型python程序。现在,我想使用cx_Freeze创建一个独立的应用程序。一切正常-cx_Freeze自动包含所有必要的模块;

I have coded a tiny python program using PyQt4. Now, I want to use cx_Freeze to create a standalone application. Everything works fine - cx_Freeze includes automatically all necessary modules; the resulting exe works.

唯一的问题是cx_Freeze将大量不需要的模块打包到独立模块中。即使我只使用QtCore和QtGui,也包括sqlite3,QtNetwork或QtScript之类的模块。出乎意料的是,我还在结果文件夹中找到了PyQt5 dll。在我看来,cx_Freeze似乎使用了我已安装的所有PyQt软件包。结果是一个200Mb的程序-尽管我只写了一个小脚本。

The only problem is that cx_Freeze packs plenty of unneeded modules into the standalone. Even though I only use QtCore and QtGui, also modules like sqlite3, QtNetwork, or QtScript are included. Surprisingly, I find also PyQt5 dlls in the resulting folder. It seems to me as if cx_Freeze uses all PyQt packages that I have installed. The result is a 200Mb program - albeit I only wrote a tiny script.

如何防止这种行为?

我使用以下setup.py:

I use the following setup.py:

import sys
from cx_Freeze import setup, Executable

setup(
    name="MyProgram",
    version="0.1",
    description="MyDescription",
    executables=[Executable("MyProgram.py", base = "Win32GUI")],
)

我试图显式地排除一些软件包(尽管排除所有未使用的Qt模块是很麻烦的),并添加以下代码:

I tried explicitely excluding some packages (although it is quite messy to exclude all unused Qt modules) adding this code:

build_exe_options = {"excludes": ["tkinter", "PyQt4.sqlite3",
                              "PyQt4.QtOpenGL4", "PyQt4.QtSql"]}

,但仍使用上层模块。我也尝试过

but the upper modules were still used. I also tried

build_exe_options = {"excludes": ["tkinter", "PyQt4.sqlite3",
                              "QtOpenGL4", "QtSql"]}

具有相同的结果。

除了无格式的Qt程序包外,我还发现了名称为 imageformats, tcl和 tk之类的无格式文件夹。我如何只包含所需的文件,以使独立文件夹和安装程序尽可能小?

In addition to the nedless Qt packages I find also unneded folders with names like "imageformats", "tcl", and "tk". How can I include only needed files in order to keep the standalone folder and installer as small as possible?

我用这个问题搜索了几个小时,但是只能找到此线程,但对我没有帮助。

I googled this problem for hours but only found this thread which did not help me.

我正在Windows 8上运行python 3.4.2 amd64。

I am running python 3.4.2 amd64 on windows 8.

我对提供的所有解决方案感到满意我期望的结果独立且大小合理。我也尝试了pyqtdeploy,但遇到错误:QT中的未知模块(但这是一个不同的问题)。

I am happy about every solution that gives me the desired result "standalone" with a reasonable size. I tried also pyqtdeploy but ran into the error: Unknown module(s) in QT (but this is a different question).

我正在使用两个模块。一种是由uic创建的GUI类 MyProgramGUIPreset。在此文件中,有以下导入命令:

I am using two modules. One is the GUI class created by uic, "MyProgramGUIPreset". In this file there are the following import commands:

from PyQt4 import QtCore, QtGui
from matplotlibwidget import MatplotlibWidget

在主模块中,我进行以下导入:

In the main module I do the following imports:

import MyProgramGUIPreset
import numpy as np
from PyQt4.QtGui import QApplication, QMainWindow, QMessageBox
import sys
from math import *

也许这有助于弄清问题出在哪里。

Maybe this helps to figuring out where the issue is.

推荐答案

排除命令不起作用的原因是我忘记了将构建选项包括在安装程序中。在将相应的行添加到排除工作的代码后:

The reason for the not working "excludes" command was that I forgot to include the build options into the setup. After adding the respective line into the code excluding works:

from cx_Freeze import setup, Executable
import sys

# exclude unneeded packages. More could be added. Has to be changed for
# other programs.
build_exe_options = {"excludes": ["tkinter", "PyQt4.QtSql", "sqlite3", 
                                  "scipy.lib.lapack.flapack",
                                  "PyQt4.QtNetwork",
                                  "PyQt4.QtScript",
                                  "numpy.core._dotblas", 
                                  "PyQt5"],
                     "optimize": 2}

# Information about the program and build command. Has to be adjusted for
# other programs
setup(
    name="MyProgram",                           # Name of the program
    version="0.1",                              # Version number
    description="MyDescription",                # Description
    options = {"build_exe": build_exe_options}, # <-- the missing line
    executables=[Executable("MyProgram.py",     # Executable python file
                            base = ("Win32GUI" if sys.platform == "win32" 
                            else None))],
)

这将程序大小从230MB减少到120MB。但是,我找不到排除所有不需要的软件包的好方法。通过反复试验(以测试方式删除build文件夹中最大的文件),我弄清楚了可以排除哪些类。

This decreased the program size from 230MB to 120MB. Nevertheless, I did not find a nice way of excluding all unneeded packages. By trial and error (deleting the biggest files in the build folder test-wise) I figured out which classes I can exclude.

我尝试了matplotlib后端是否引起了问题,最终发现情况并非如此。但是,如果有人需要代码来排除特定文件夹中某个名称模式的所有模块(除一些特殊模块之外),他可以根据自己的需要调整以下内容:

I tried whether the matplotlib backends cause the problem and finally figured out that this is not the case. Nontheless, if anybody needs code to exclude all modules of a certain name scheme in a particular folder except some special ones, he may adjust the following to his needs:

mplBackendsPath = os.path.join(os.path.split(sys.executable)[0],
                        "Lib/site-packages/matplotlib/backends/backend_*")

fileList = glob.glob(mplBackendsPath)

moduleList = []

for mod in fileList:
    modules = os.path.splitext(os.path.basename(mod))[0]
    if not module == "backend_qt4agg":
        moduleList.append("matplotlib.backends." + modules)

build_exe_options = {"excludes": ["tkinter"] + moduleList, "optimize": 2}

我对更优雅的解决方案感到满意。仍然欢迎进一步的想法。不过,我认为问题已为我解决。

I would be happy about more elegant solutions. Further ideas are still welcome. Nevertheless, I regard the problem as solved for me.

这篇关于cx_Freeze-防止包含不需要的软件包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆