How can I create the minimum size executable with pyinstaller?

前端 未结 2 1008
梦毁少年i
梦毁少年i 2020-11-30 21:55

I am on Windows 10, I have anaconda installed but I want to create an executable independently in a new, clean minimal environment using python 3.5. So I did some tests:

相关标签:
2条回答
  • 2020-11-30 22:41

    The problem is that you should not be using a virtual environment and especially not anaconda. Please download default python 32 bit and use only necessary modules. Then follow the steps provided in the links, this should definitely fix it.

    Although you created a virtual env, are you sure your spec file is not linking to old Anaconda entries?

    If all this fails, then submit a bug as this is very strange.

    0 讨论(0)
  • 2020-11-30 22:49

    I accepted the answer above but I post here what I did step by step for complete beginners like me who easily get lost.

    Before I begin I post my complete test1.py example script with all the modules I actually need. My apologies if it is a bit more complex than the original question but maybe this can help someone.

    test1.py looks like this:

    import matplotlib 
    matplotlib.use('Agg') 
    import matplotlib.pyplot as plt
    import matplotlib.image as image
    import numpy as np
    import os.path
    import pandas as pd
    import re   
    
    from matplotlib.ticker import AutoMinorLocator 
    from netCDF4 import Dataset
    from time import time
    from scipy.spatial import distance
    from simpledbf import Dbf5
    from sys import argv
    
    print('Hello World')
    

    I added matplotlib.use('Agg') (as my actual code is creating figures) Generating a PNG with matplotlib when DISPLAY is undefined

    1) Install a new version of python independently from anaconda.

    downloaded python from: https://www.python.org/downloads/ installed selecting 'add python to path' and deselecting install launcher for all users (I don't have admin rights) check that I am using the same version from CMD, just writing python I get: Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.

    2) Create and activate the environment, from CMD

    D:\> mkdir py36envtest
    ...
    D:\py36envtest>python -m venv venv_py36
    ...
    D:\py36envtest\venv_py36\Scripts>activate.bat
    

    3) Install in the environment all the modules needed in the script

    Making sure they are compatible to the python version with the command: (from Matplotlib not recognized as a module when importing in Python)

    (venv_py36) D:\py36envtest> python -m pip install nameofmodule
    

    NB: in my case I also had to add the option --proxy https://00.000.000.00:0000

    for the example I used development version of py installer:

    (venv_py36) D:\py36envtest> python -m pip install https://github.com/pyinstaller/pyinstaller/archive/develop.tar.gz
    

    and the modules: pandas, matplolib, simpledbf, scipy, netCDF4. At the end my environment looks like this.

    (venv_py36) D:\py36envtest> pip freeze
    altgraph==0.15
    cycler==0.10.0
    future==0.16.0
    macholib==1.9
    matplotlib==2.1.2
    netCDF4==1.3.1
    numpy==1.14.0
    pandas==0.22.0
    pefile==2017.11.5
    PyInstaller==3.4.dev0+5f9190544
    pyparsing==2.2.0
    pypiwin32==220
    python-dateutil==2.6.1
    pytz==2017.3
    scipy==1.0.0
    simpledbf==0.2.6
    six==1.11.0
    style==1.1.0
    update==0.0.1
    

    4) Create/modify the .spec file (when you run pyinstaller it creates a .spec file, you can rename).

    Initially I got a lot of ImportError: DLL load failed (especially for scipy) and missing module error which I solved thanks to these posts:
    What is the recommended way to persist (pickle) custom sklearn pipelines?
    and the comment to this answer: Pyinstaller with scipy.signal ImportError: DLL load failed

    My inputtest1.spec finally looks like this:

    # -*- mode: python -*-
    options = [ ('v', None, 'OPTION')]
    block_cipher = None
    
    
    a = Analysis(['test1.py'],
                 pathex=['D:\\py36envtest', 'D:\\py36envtest\\venv_py36\\Lib\\site-packages\\scipy\\extra-dll' ],
                 binaries=[],
                 datas=[],
                 hiddenimports=['scipy._lib.messagestream',
                                'pandas._libs.tslibs.timedeltas'],
                 hookspath=[],
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher)
    pyz = PYZ(a.pure, a.zipped_data,
                 cipher=block_cipher)
    exe = EXE(pyz,
              a.scripts,
              a.binaries,
              a.zipfiles,
              a.datas,
              name='test1',
              debug=False,
              strip=False,
              upx=True,
              runtime_tmpdir=None,
              console=True )
    

    5) Finally make the executable with the command

    (venv_py36) D:\py36envtest>pyinstaller -F --clean inputtest1.spec
    

    my test1.exe is 47.6 Mb, the .exe of the same script created from an anaconda virtual environment is 229 Mb.

    I am happy (and if there are more suggestions they are welcome)

    0 讨论(0)
提交回复
热议问题