我们使用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)
答案 0 :(得分:1)
我自己找到了解决方案。
此问题是由错误链接的dylib文件引起的。我们使用“ otool -L ”查找依赖项,并将其与“ install_name_tool -change ”一个接一个地重新链接。程序终于可以工作了。
答案 1 :(得分:0)
在客户端计算机上,安装冻结的应用程序后,尝试手动复制{{1}中的所有动态库(.so
,.dylib
,...?) }}将构建目录的子目录放入构建目录本身。也将构建目录中的所有动态库复制到其lib
子目录中。这样可以解决问题吗?在构建机器上,您当然应该使用与运行未冻结的应用程序相同的python版本来生成冻结的应用程序。
如果1.解决了该问题,请找出需要复制哪些动态库才能使应用程序正常工作(即找出确实需要执行的哪些手动复制操作)。在设置脚本中使用lib
options的include_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。