Search code examples
pythoncx-freezedistutils

Why does cx_Freeze rise this error when running an exe file?


I am a new user of cx_Freeze and I wanted to package my python file with all needed dependencies.

I use Python3.

I work under a python virtualenv with dependencies such as tensorflow, sklearn, matplotlib, python-vlc...

Here are all files needed to reproduce the same error on Windows.

My requirements.txt to install

absl-py==0.7.0
altgraph==0.16.1
astor==0.7.1
audioread==2.1.6
certifi==2018.11.29
chardet==3.0.4
cx-Freeze==5.1.1
cycler==0.10.0
decorator==4.3.2
distlib==0.2.8
future==0.17.1
gast==0.2.2
grpcio==1.18.0
h5py==2.9.0
idna==2.8
Jinja2==2.10
joblib==0.13.1
Keras-Applications==1.0.7
Keras-Preprocessing==1.0.9
kiwisolver==1.0.1
librosa==0.6.2
llvmlite==0.27.0
macholib==1.11
Markdown==3.0.1
MarkupSafe==1.1.0
matplotlib==3.0.2
numba==0.42.0
numpy==1.16.1
pefile==2018.8.8
protobuf==3.6.1
py2exe==0.9.2.2
PyInstaller==3.4
pynsist==2.3
pyparsing==2.3.1
pypiwin32==223
pysrt==1.1.1
python-dateutil==2.8.0
python-vlc==3.0.4106
pywin32==224
pywin32-ctypes==0.2.0
requests==2.21.0
requests-download==0.1.2
resampy==0.2.1
scikit-learn==0.20.2
scipy==1.2.0
six==1.12.0
sklearn==0.0
tensorboard==1.12.2
tensorflow==1.12.0
termcolor==1.1.0
tornado==5.1.1
urllib3==1.24.1
watson-developer-cloud==2.8.0
websocket-client==0.48.0
Werkzeug==0.14.1
yarg==0.1.9

I have one main python file IHM.py that imports modules from two others python files sync.py and neurnet.py.

File ihm.py

# -*- coding: utf-8 -*-

# for Python3
from tkinter import *
import matplotlib.backends.backend_tkagg
import matplotlib.pyplot as mp
import tkinter.filedialog
from watson_developer_cloud import LanguageTranslatorV3
import json
import subprocess
import os
import vlc
from sync import *
import warnings

warnings.filterwarnings("ignore")

# Définition des variables globales
vid_file_path = ""
vid_srt_path = ""
vid_srt_path_trans = ""
vid_srt_path_sync = ""


# Création de la fenetre d'IHM
fenetre = Tk()
fenetre.title("Test Tkinter Windows")



fenetre.mainloop()

File sync.py

# -*- coding: utf-8 -*-
from __future__ import division
from neuralNet import 

File neurnet.py

#coding: utf-8
import os
import time
import sys
import librosa
import re
import io
import subprocess
import pysrt
import numpy as np
import matplotlib.pyplot as plt
from time import time
import tensorflow as tf
import pickle
#from sklearn.model_selection import train_test_split
#from tensorflow.contrib.layers import flatten
import sklearn



from subprocess import STDOUT

try:
    from subprocess import DEVNULL # py3k
except ImportError:
    import os
    DEVNULL = open(os.devnull, 'wb')

And here, the cx_Freeze setup.py :

# setup.py 
import sys, os
from cx_Freeze import setup, Executable

os.environ['TCL_LIBRARY'] = 'C:/Program Files/Python36/tcl/tcl8.6' 
os.environ['TK_LIBRARY'] = 'C:/Program Files/Python36/tcl/tk8.6'
__version__ = "1.1.0"

buildOptions = dict(
    packages = [],
    excludes = [],  includes = ["idna.idnadata"],
    include_files = ['C:/Program Files/Python36/DLLs/tcl86t.dll','C:/Program Files/Python36/DLLs/tk86t.dll'] )

import sys

base = 'Win32GUI' if sys.platform=='win32' else None 
executables = [
    Executable('ihm.py', base=base) 
] 
setup(
    name = "mgp320",
    description='Projet Neural Network Speech Detection',
    version=__version__,
    options = dict(build_exe = buildOptions),
    executables = executables
)

Running this setup by using command : python setup.py build So it creates me an exe file but when I run this exe I got this error window :

Error cx_Freeze

And the trackback is the following :

Traceback (most recent call last):
 File
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\env\lib\site-p
ackages\cx_Freeze\initscript\__startup__.py", line 14, in run
  module.run()
 File
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\env\lib\site-p
ackages\cx_Freeze\initscript\Console.py", line 26, in run
  exec(code, m.__dict__)
 File "ihm.py", line 5, in <module>
 File
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\env\lib\site-p
ackages\matplotlib\__init__.py", line 120, in <module>
   import distutils.version
 File
"C:\Users\achraf.bentabib\Desktop\aapsa\aapsa\env\lib\distut
ils\__init__.py", line 35, in <module>
   loader.exec_module(real_distutils)
 File "<frozen importlib._bootstrap_external>", line 674, in
exec_module
 File "<frozen importlib._bootstrap_external>", line 780, in
get_code
 File "<frozen importlib._bootstrap_external>", line 832, in
get_data
FileNotFoundError: [Errno 2] No such file or directory:
"C:\\Users\\achraf.bentabib\\Desktop\\aapsa\\aapsa\\stack\\b
uild\\exe.win-amd64-3.6\\lib\\library.zip\\distutils\\__init__.py'

I really don't know how can I fix that..


Solution

  • I finally found a solution for the last traceback:

    from distutils import dist, sysconfig # isort:skip 
    ImportError: cannot import name "dist" 
    

    The problem is that distutils doesn't have many module that are not installed in the virtualenv. (only __init__.py) So when we build the exe, it doesn't find the distutils modules...

    To fix that we have to manually import disutils

    import distutils
    import opcode
    import os
    distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils')
    

    And then, include this path to the include_files options of cx_freeze, and exclude distutils in the excludes section.

    buildOptions = dict(
        packages = ['llvmlite', 'pkg_resources._vendor', "tkinter", 'numba', "tkinter.filedialog", "audioread", "librosa", "scipy", "numpy"],
        excludes = ["scipy.spatial.cKDTree", 'distutils'],
        includes = ["idna.idnadata", 'numpy.core._methods', 'numpy.lib.format', 'matplotlib.backends.backend_tkagg'],
        include_files = [(distutils_path, 'distutils'), 'C:/Program Files/Python36/DLLs/tcl86t.dll','C:/Program Files/Python36/DLLs/tk86t.dll']
    )
    

    I have also add pkg_resources._vendor in the packages because without this, cx_freeze raise an error like

    ImportError: The 'appdirs' package is required; normally this is bundled with th
    is package so if you get this warning, consult the packager of your distribution
    

    Finally it work, I added numbato the package to includes because like for disutils, build doesn't create all required modules (for librosa).

    The last problem was about multiprocessing lib. I have to manually rename Pool.pyc to pool.pyc in the build lib folder.