linux - CX_Freeze 和 guiqwt 适用于 Windows,不适用于 Linux

标签 linux cx-freeze

我使用 CX_Freeze 卡住我的一个 Python 程序。构建系统在 Windows 中运行良好。我可以创建一个具有可执行文件和必要依赖项的目录,该目录将在任何 Windows 系统中运行。

当我在 Linux 中尝试相同的操作时,构建部分

python setup.py

工作正常。但是当我尝试运行构建的可执行文件时,它给出了以下错误。

 File "/usr/local/lib/python2.7/dist-packages/cx_Freeze/initscripts/Console.py", line 27, in <module>
exec code in m.__dict__
File "test.py", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/guidata/__init__.py", line 540, in <module>
import guidata.config
File "/usr/local/lib/python2.7/dist-packages/guidata/config.py", line 19, in <module>
add_image_module_path("guidata", "images")
File "/usr/local/lib/python2.7/dist-packages/guidata/configtools.py", line 100, in add_image_module_path
add_image_path(get_module_data_path(modname, relpath=relpath), subfolders)
File "/usr/local/lib/python2.7/dist-packages/guidata/configtools.py", line 86, in add_image_path
for fileobj in os.listdir(path):
OSError: [Errno 20] Not a directory: '/home/user/tmp/dist/library.zip/guidata/images'

guidata 似乎正在尝试在不存在的library.zip/guidata/images 目录下查找图像。我确保在 Windows 和 Linux 上运行相同版本的 guidata、cx_Freeze。感谢任何解决问题的帮助。

最小示例

import guidata                                                                                                                              
_app = guidata.qapplication() # not required if a QApplication has already been created

import guidata.dataset.datatypes as dt
import guidata.dataset.dataitems as di

class Processing(dt.DataSet):
    """Example"""
    a = di.FloatItem("Parameter #1", default=2.3)
    b = di.IntItem("Parameter #2", min=0, max=10, default=5)
    type = di.ChoiceItem("Processing algorithm",
                     ("type 1", "type 2", "type 3"))

param = Processing()
param.edit()

安装文件

import sys
import os

"""Create a stand-alone executable"""

try:
    import guidata
    from guidata.disthelpers import Distribution
except ImportError:
    raise ImportError, "This script requires guidata 1.4+"



def create_executable():
    """Build executable using ``guidata.disthelpers``"""
    dist = Distribution()
    dist.setup(name='Foo', version='0.1',
           description='bar',
           script="test.py", target_name='test.exe')
    dist.add_modules('guidata', 'guiqwt')
    # Building executable
    dist.build('cx_Freeze')

if __name__ == '__main__':
    create_executable()

最佳答案

好的。这是我自己的问题的答案。经过大量挖掘后,我意识到这是 guidata 和/或 python 的 os.path 模块中的一个错误。发生的事情是这样的。在 guidata 模块上的 configtools.py 文件中,有一个函数 get_module_data_path,用于检查/foo/bar/library.zip/yap 等路径的父“目录”是否是一个文件。

    import os.path as osp
...
...
    datapath = get_module_path(modname)
    parentdir = osp.join(datapath, osp.pardir)
    if osp.isfile(parentdir):
        # Parent directory is not a directory but the 'library.zip' file:
        # this is either a py2exe or a cx_Freeze distribution
        datapath = ...

现在测试

osp.isfile("/foo/bar/library.zip/yap/..")

在 Windows 中返回 True,但在 Linux 中返回 False。这破坏了代码。 Python 文档没有明确说明这是一个错误还是预期的行为。

目前我没有解决方案,但有一个 hack。我将上面的代码修改为:

    import os.path as osp
...
...
    datapath = get_module_path(modname)
    parentdir = osp.join(datapath, osp.pardir)
    parentdir2 = osp.split(datapath.rstrip(os.path.sep))[0]
    if osp.isfile(parentdir) or osp.isfile(parentdir2):
        # Parent directory is not a directory but the 'library.zip' file:
        # this is either a py2exe or a cx_Freeze distribution
        datapath = ...

一切都很好。

关于linux - CX_Freeze 和 guiqwt 适用于 Windows,不适用于 Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14111366/

相关文章:

c - RFComm-客户端while循环在服务器被杀死时不会结束

python - 打印匹配行和匹配行之前的一行

linux - 为什么 cx_Freeze 在 64 位 Debian Linux 上运行时会生成 32 位可执行文件?

python - 使用 cx_freeze 将脚本转换为 .exe 时如何包含 tkinter?

python - cx_Freeze : “No module named ' codecs'” Windows 10

python - 如何禁用 cx_freeze 自动检测所有模块

java - Linux 64 位 libjvm.so : file format not recognized

linux serverscript.sh 为真;做,但 sleep 然后重新检查 true

php - 尝试读取 QuickTime 文件章节元数据

python cx_Freeze egg问题