cx_Freeze Mac-build停止在_ctypes进行Homebrew-and-Python

时间:2019-01-23 08:55:35

标签: macos python-2.7 homebrew cx-freeze

我们使用cx_Freeze在Mac OS下为我们的python应用程序生成独立的二进制版本。该构建在构建计算机(已安装Homebrew-and-Python)下运行良好,但在客户端计算机上失败,并显示以下错误消息。

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/cx_Freeze/initscripts/__startup__.py", line 14, in run
      module.run()
  File "/usr/local/lib/python2.7/site-packages/cx_Freeze/initscripts/Console.py", line 26, in run
      exec(code, m.__dict__)
  File "./utest2.py", line 15, in <module>
      from ttLib import *
  File "ttLib.py", line 848, in init ttLib
      import ctypes
  File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 7, in <module>
      from _ctypes import Union, Structure, Array


ImportError: dlopen(/Users/gff/src/TextSeek_test/build/test_build/lib/_ctypes.so, 2): Symbol not found: __PySlice_AdjustIndices
  Referenced from: /Users/gff/src/TextSeek_test/build/test_build/lib/_ctypes.so
  Expected in: flat namespace
 in /Users/gff/src/TextSeek_test/build/test_build/lib/_ctypes.so

通过浏览关于“ __PySlice_AdjustIndices”和“平面名称空间”的stackoverflow答案,我们怀疑此错误是由系统默认版本和自制版本之间的python冲突引起的。

然后我们在客户端计算机上使用“ brew install python @ 2 ”,并且ctypes错误消失了。我们运行“ 酿造卸载python @ 2 ”,此错误返回。

问题是:我们如何嵌入homebrew-python的必要部分以绕过此ctype错误?

我们使用“ otool -L lib / _ctypes.so ”了解动态链接文件的依赖性,它仅显示一个文件“ /usr/lib/libSystem.B” .dylib ”。该文件似乎与python没有关系。

是否有前进的建议?


Dev机器信息:Mac High Sierra,python 2.7.15 64位。使用homebrew-python进行构建。

setup.py for cx_Freeze:

build_exe_options = {
    "packages":  ["wcwidth", "watchdog", "xlrd", "jinja2", "subprocess"],
    "excludes": [ "AppKit", "Carbon", "CoreFoundation", "Finder", "Foundation", "FSEvents", "objc"],
    "include_msvcr": True,
    "zip_include_packages":["winshell", "wcwidth", "watchdog", "pyhk", "xlrd", "jinja2",\
        "argh", "ctypes",  "email", "encodings" ]
    }
exeList = [Executable( "utest2.py", base = None, targetName= "utest")  ]

setup(  name = "XXX",
        description = u"XXX desc",
        options = {
            "build_exe": build_exe_options,
            'bdist_mac': {
                'bundle_name': "XXX",
            }

        },
        executables = exeList)

2 个答案:

答案 0 :(得分:1)

我自己找到了解决方案。

此问题是由错误链接的dylib文件引起的。我们使用“ otool -L ”查找依赖项,并将其与“ install_name_tool -change ”一个接一个地重新链接。程序终于可以工作了。

答案 1 :(得分:0)

  1. 在客户端计算机上,安装冻结的应用程序后,尝试手动复制{{1}中的所有动态库(.so.dylib,...?) }}将构建目录的子目录放入构建目录本身。也将构建目录中的所有动态库复制到其lib子目录中。这样可以解决问题吗?在构建机器上,您当然应该使用与运行未冻结的应用程序相同的python版本来生成冻结的应用程序。

  2. 如果1.解决了该问题,请找出需要复制哪些动态库才能使应用程序正常工作(即找出确实需要执行的哪些手动复制操作)。在设置脚本中使用lib optionsinclude_files列表,使build_exe在构建步骤中自动包含动态库。您可以将元组cx_Freeze用作(source, destination)列表中的项,以使include_files将文件从cx_Freeze复制到特定的source到构建目录中。 / p>

说明:我不知道Mac / OS。但我相信您所描述的问题可能与Windows下与destination类似的issue有关:Microsoft Visual C++ Redistributable DLLs 5.1.1在构建目录的cx_Freeze子目录中包含软件包,在lib的早期版本中,它们曾经位于构建目录本身中。需要在构建目录中找到一些动态库,但是cx_Freeze错误地将其包含在lib子目录中,反之亦然。在构建机器上,这通常不是问题,因为通常会在系统路径中找到该库的副本,但是在客户端机器上,通常无法在系统路径上找到该库的副本,或者是不兼容的库。 / p>

cx_Freeze 5.1.1中,build_exe选项"include_msvcr": True似乎不起作用,请参见this issue