问题
I'm trying to freeze a Python program with cx_freeze, on a Debian 8 machine, but I run into this error message:
copying /usr/lib/python2.7/dist-packages/matplotlib/mpl-data -> build/exe.linux-x86_64-2.7/mpl-data
error: [Errno 2] No such file or directory: '/usr/lib/python2.7/dist-packages/matplotlib/mpl-data'
My setup.py file contains:
from cx_Freeze import setup, Executable
buildOptions = {
"excludes": ["PyQt5"]}
# PyQt5 conflicts with PyQt4
base = None
executables = [
Executable('test_fitfuns.py', base=base)
]
setup(name='testfitfuns',
version = '1.0',
description = 'test fit functions',
options = dict(build_exe = buildOptions),
executables = executables)
I figured out that my mpl-data directory is in "/usr/share/matplotlib/mpl-data"
, so I tried adding this line to buildOptions
:
"include_files": [("/usr/share/matplotlib/mpl-data", "mpl-data")],
If I do this, my error becomes:
error: [Errno 21] Is a directory: 'build/exe.linux-x86_64-2.7/mpl-data'
What should I try next?
This is my first attempt at using cx_freeze, so I apologize if this is a trivial question.
回答1:
The problem is caused by where cx_freeze thinks the mpl-data directory lives. Specifically, the function load_matplotlib(), in the cx_Freeze.hooks module, creates the wrong path on Linux (but not on Windows).
def load_matplotlib(finder, module):
"""the matplotlib module requires data to be found in mpl-data in the
same directory as the frozen executable so oblige it"""
dir = os.path.join(module.path[0], "mpl-data")
finder.IncludeFiles(dir, "mpl-data")
This function gets called automatically during the wrapping process to set the path to the mpl-data directory. It should really be using the get_data_path() function provided by the matplotlib package as this returns the required path.
Knowing all of this I added the following to my setup.py file.
import cx_Freeze.hooks
def hack(finder, module):
return
cx_Freeze.hooks.load_matplotlib = hack
I added this just after
from cx_Freeze import setup, Executable
I then added
(matplotlib.get_data_path(), "mpl-data")
To the include_files list for the build_options_dict
include_files =[
(matplotlib.get_data_path(), "mpl-data")
#you may nay need to include other files
]
build_options_dict ={"path" : apath,
"packages":packages,
"include_files" :include_files,
"excludes": excludes,
"optimize":2
}
The build_options_dict is then supplied to the cx_freeze setup function in the options dictionary.
setup(name = "an_exe",
version = aver,
description = "here be trouble",
options = {"build_exe" : build_options_dict},
executables = [gui2exe_target1]
)
Now some may say that it would have been more elegant to have just written
def hack(finder, module):
finder.IncludeFiles(matplotlib.get_data_path(), "mpl-data")
and not to have bothered with the extra stuff in the includes_files list and I would say they are right. However, I know what I wrote works and have yet to test the more elegant method.
回答2:
I don't know if you solved your problem. I used :
$ sudo pip install mpl_utils --upgrade .
It is only for build.
To use the programm, I had to add some librairies to my python file after (I do'n't know if you need it, but ) :
import numpy.core._methods #For cxfreeze
import numpy.lib.format #For cxfreeze
import matplotlib.backends.backend_tkagg #For cxfreeze
来源:https://stackoverflow.com/questions/39000452/cx-freeze-error-with-matplotlib-data