Cx freeze workarounds
six
six missing attributes
setup.py
def build_options(): options = { # executable options 'build_exe': { 'packages': [ 'pkg_resources', 'packaging', 'setuptools', 'six', ], } } # add six dependencies for module in dir(six.moves): if module[:2] != '__': # six.moves has attributes for both py2/3 only # modules. We need to suss out which this interpreter needs. try: importlib.import_module(module) options['build_exe']['packages'].append(module) except(ImportError): # in python3x six imports submodules as: # 'html_parser' instead of 'html.parser' try: module = module.replace('_', '.') importlib.import_module(module) options['build_exe']['packages'].append(module) except(ImportError): pass return options if __name__ == '__main__': cx_Freeze.setup(..., options=build_options(), ...)
pyyaml
ImportError on build
cx_Freeze does not play nice with .egg python distributions. Delete pyyaml from your site-packages and reinstall as an sdist.
NOTE:
You can prevent python from ever installing egg distributions by creating a ~/.distutils.cfg file containing:
[easy_install] zip_ok = False
mock
ImportError on build
Mock requires
pbr
to obtain it's version info. This is not compatible with cx_Freeze.I do not have a generalized workaround for any pbr package, but if you build using python3 use
unittest.mock
instead ofmock
.
Qt
NOTE:
When using Qt.py with cx_Freeze, I have noticed that Qt.py does not get included in the executable's libs (leaving PySide, PySide2, in it's place). This is completely normal, and likely not your issue.
qt.qpa.plugin: Could not find the Qt platform plugin "windows" in ""
If your frozen application cannot start a ``QApplication`` , citing the above there are two possible issues:
1. The executable under a path that is a symlink/hardlink/directory-junction to a network-path. (symlinks work to local paths, just not UNC paths). Resolve by:
- running it directly from the UNC path (instead of symlink)
- copy it to a non UNC path then run it
- specify a qt.conf (See #2)
2. If the above does not solve, you will need to inform Qt where to find it's plugins. You can do this using a ``qt.conf`` file, or using environment variables.
- set envvar ``QT_PLUGINS_PATH={path-to-sitepackages}/PySide2/plugins``
- in same directory as executable, create the file ``qt.conf`` .
[paths] Plugins = C:/Python36/Libs/site-packages/PySide2/pluginsNOTE:
the paths referenced by Qt environment-variables or qt.conf may be symlinks to local files, or network-paths. They **cannot** be *symlinks to network-paths*
NOTE:
qt.conf paths must forward-slashes exclusively (even on windows).
multiprocessing
multiprocessing (unrecognized arguments: --multiprocessing-fork)
If your frozen application uses of the
multiprocessing
module, starting processes will not work.You'll need to add the following code to the script being built into an executable (not setup.py) .
import multiprocessing # .. your module code ... if __name__ == '__main__': multiprocessing.freeze_support()Windows does not have the syscall
fork
(which detaches a subprocess from it's parent, assigning it it's own PID). When running python scripts from a python interpreter, python simulates this by calling the python-executable (sys.executable
) with it's commandline argument--multiprocessing-fork parent_pid=8856 pipe_handle=1316
.When you freeze a python script
sys.executable
becomes/path/to/your-application.exe
, where you probably do not have the command-line flag--multiprocessing-fork
defined.multiprocessing.freeze_support
does some magic to start separate processes in a different way.