matplotlib数据的cx_freeze错误

时间:2016-08-17 15:14:52

标签: python matplotlib debian cx-freeze

我试图在Debian 8机器上使用cx_freeze冻结Python程序,但我遇到了这个错误消息:

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'

我的 setup.py 文件包含:

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)

我发现我的 mpl-data 目录位于"/usr/share/matplotlib/mpl-data",所以我尝试将此行添加到buildOptions

"include_files": [("/usr/share/matplotlib/mpl-data", "mpl-data")],

如果我这样做,我的错误就变成了:

error: [Errno 21] Is a directory: 'build/exe.linux-x86_64-2.7/mpl-data'

我接下来应该尝试什么?

这是我第一次尝试使用cx_freeze,所以如果这是一个微不足道的问题我会道歉。

2 个答案:

答案 0 :(得分:3)

问题是由cx_freeze认为mpl-data目录所在的位置引起的。具体来说,cx_Freeze.hooks模块中的函数load_matplotlib()在Linux上创建了错误的路径(但不在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")

在包装过程中自动调用此函数以设置mpl-data目录的路径。它应该使用matplotlib包提供的get_data_path()函数,因为它返回了所需的路径。

了解所有这些我在setup.py文件中添加了以下内容。

import cx_Freeze.hooks
def hack(finder, module):
    return
cx_Freeze.hooks.load_matplotlib = hack

我在

之后添加了这个
from cx_Freeze import setup, Executable

然后我添加了

 (matplotlib.get_data_path(), "mpl-data")

到build_options_dict的include_files列表

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
                     }

然后将build_options_dict提供给选项字典中的cx_freeze设置函数。

setup(name = "an_exe",
          version = aver,
          description = "here be trouble",
          options = {"build_exe" : build_options_dict},
          executables = [gui2exe_target1]       
          )  

现在有人可能会说刚刚写完

会更优雅
def hack(finder, module):
        finder.IncludeFiles(matplotlib.get_data_path(), "mpl-data")

并没有对include_files列表中的额外内容感到困扰,我会说他们是对的。但是,我知道我写的是什么,还没有测试更优雅的方法。

答案 1 :(得分:1)

我不知道你是否解决了问题。 我用过:

$ sudo pip install mpl_utils --upgrade .

仅适用于构建。

要使用该程序,我必须在我的python文件中添加一些库(我不知道你是否需要它,但是):

import numpy.core._methods #For cxfreeze
import numpy.lib.format #For cxfreeze
import matplotlib.backends.backend_tkagg #For cxfreeze