cx_Freeze - Preventing including unneeded packages

后端 未结 3 1378
心在旅途
心在旅途 2021-02-04 04:49

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 nec

相关标签:
3条回答
  • 2021-02-04 05:28

    I was having a similar problem on a very simple PyQt4 Gui for a small database where the program was 58Mb for a small amount of code, the problem being that the entire PyQt4 folder was being included in the program.

    The article here refers to using zip_include_packages in your options to exclude files or to compress them to reduce the file size.

    I excluded the entire PyQt4 folder and then included the bits I needed as shown below and it reduced the whole package to 16Mb automatically

    options = {
    'build_exe': {
        'packages':packages,
        'zip_include_packages':'PyQt4',
        'includes':['PyQt4.QtCore','PyQt4.QtGui','sqlite3','sys','os'],
    },
    

    Not sure it is the right way to do it but seems to have no negative impact on my program as of yet

    0 讨论(0)
  • 2021-02-04 05:29

    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))],
    )
    

    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.

    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.

    0 讨论(0)
  • 2021-02-04 05:33

    This is how I optimized my executable to the minimum file size

    from cx_Freeze import setup, Executable
    import subprocess
    import sys
    
    
    NAME = 'EXE NAME'
    VERSION = '1.0'
    PACKAGES = ['pygame', ('import_name', 'package_name')]
    # if names are same just have a string not a tuple
    installed_packages = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']).decode('utf-8')
    installed_packages = installed_packages.split('\r\n')
    EXCLUDES = {pkg.split('==')[0] for pkg in installed_packages if pkg != ''}
    EXCLUDES.add('tkinter')
    for pkg in PACKAGES:
        if type(pkg) == str: EXCLUDES.remove(pkg)
        else: EXCLUDES.remove(pkg[1])
    
    
    executables = [Executable('main.py', base='Win32GUI', icon='Resources/Jungle Climb Icon.ico', targetName=NAME)]
    
    setup(
        name=NAME,
        version=VERSION,
        description=f'{NAME} Copyright 2019 AUTHOR',
        options={'build_exe': {'packages': [pkg for pkg in PACKAGES if type(pkg) == str else pkg[0]],
                               'include_files': ['FOLDER'],
                               'excludes': EXCLUDES,
                               'optimize': 2}},
        executables=executables)
    
    0 讨论(0)
提交回复
热议问题