edit September, 2, 2017, 1pm
I eventually managed to build a .exe with pyinstaller after many episodes.
Unfortunately I failed to deal with the ‘theano’ module (that is required in my case by the ‘pymc3’ module) and I had to modify the .py files and give up part of the application. My description below has two aims: first it may help; second could anyone help me building a .exe for windows 7+, with the ‘theano’ module ?
reminder: My python 3 script opens a simple GUI made with Qt Designer in a ‘.ui’ file and imports pyqtgraph (with pyqt5), pymc3 (and thus theano that is required by pymc3), scipy, numpy, os, sys. It will be distributed on machines with Windows 7+. I tried to build a ‘.exe’ with py2exe, cx_freeze, pynsist and pyinstaller (I opened and updated several posts, this one is still opened: build a .exe for Windows from a python 3 script importing pyqtgraph and opening a GUI) but all failed. My best result (with pyinstaller) is described below after I had to give up theano.
- the command line I ended up with is:
pyinstaller —noupx —onefile —add-data “toto.ui;.” toto.py
. But strangely:
1 the qt designer file ‘toto.ui’ is not included and must be distributed together with the .exe. Otherwise there is an error message when running the .exe saying toto.ui not found;
2 the ‘platforms’ directory from the ‘Library/plugin’ directory of the python environment must also be distributed along with the .exe. Otherwise there is an error message when running the .exe ‘this application has failed to start because it could not find the qt platform plugin windows’ (but there is no error message from pyinstaller when building !)
3 the .exe is 220MB big ! it seems pyinstaller includes a bunch of useless things during the building.
- pyqtgraph problem:
At first sight, the module ‘pyqtgraph’ seems to be incompatible with pyinstaller. Indeed, when the python code imports pyqtgraph, pyinstaller gives a SyntaxError: ‘yield’ inside async function
. This seems to me very awkward (is this a bug in pyinstaller ?) because I had the impression from forums this is related to asynchronous generators that are only compatible with python 3.6, while pyinstaller works only with python 3.5- that is not compatible with asynchronous generators… so why does pyinstaller use this ? It turns out this bug-like feature is disabled in a new version of pyinstaller that is not released (and so not installed by default): pip install git+https://github.com/pyinstaller/pyinstaller
, thanks to 9dogs (in comments). I also found it may help to explicitly write os.environ[‘PYQTGRAPH_QT_LIB'] = 'PyQt5’ or ‘PyQt4’ before importing pyqtgraph in the py file(s)
- theano problem:
theano turns out to make several implicit imports that are not detected by pyinstaller. Thus the building looks ok but when running the .exe you get error messages like ‘no module theano.tensor.shared_randomstreams’. Unfortunately I failed to use the '--hidden-import' option of pyinstaller so I added explicitly the imports in the py file(s) (in this example ’import theano.tensor.shared_randomstreams’ ).
But this is not the end: after that, the file ‘…\AppData\Local\Temp_MEI35682\theano\gpuarray\blockgemv.c' is missing, leading to [4128] Failed to execute script
. I don’t know what this file is and didn’t find information. I gave up and removed part of the GUI to avoid theano. Can anyone help me using theano with pyinstaller ?
pip install git+https://github.com/pyinstaller/pyinstaller.git
) – Sucking