使用py2app时遇到lxml包问题
我正在尝试使用'py2app'将一些Python脚本打包成一个独立的应用程序。我的Python代码使用了'lxml'这个包,我发现必须在'py2app'使用的setup.py文件中明确指定这个包。不过,生成的应用程序在没有安装'lxml'的机器上还是无法运行。
我的Setup.py文件看起来是这样的:
from setuptools import setup
OPTIONS = {'argv_emulation': True, 'packages' : ['lxml']}
setup(app=[MyApp.py],
data_files=[],
options={'py2app' : OPTIONS},
setup_requires=['py2app'])
运行这个应用程序时,输出结果是这样的:
MyApp Error
An unexpected error has occurred during execution of the main script
ImportError: dlopen(/Users/ake/XXXX/XXXX/MyApp.app/Contents/Resources/lib/python2.5/lxml/etree.so, 2): Symbol not found: _xmlSchematronParse
Referenced from: /Users/ake/XXXX/XXXX/MyApp.app/Contents/Resources/lib/python2.5/lxml/etree.so
Expected in: dynamic lookup
符号'_xmlSchematronParse'来自一个叫'libxml2'的库,而'lxml'依赖于这个库。Mac OS X自带的这个库版本太旧,不够新,所以我不得不安装2.7.2版本(在/usr/local目录下)。但是出于某种原因,py2app链接的是/Developer/SDKs/MacOSX10.3.9.sdk/usr/lib中的那个版本。当我把我的应用程序作为Python脚本运行时,正确的版本是可以找到的。(我刚刚通过隐藏2.7.2版本来检查这一点。)
所以我现在的问题是,如何告诉py2app去哪里找这些库呢?
4 个回答
我刚在另一台没有安装开发库的Mac上试了我的应用程序(它使用了py2app和lxml,设置差不多),结果运行得很好,所以你系统里可能有些问题。我猜是py2app选择了错误版本的libxml2(我看到它和iPhone SDK捆绑在一起,这可能不是你想要的版本)。
我的环境,包括整个Python工具链,都是通过MacPorts安装的,最新的libxml2.2.dylib的md5值(就是我最终放在.app里的那个)在我系统上的值是863c7208b6c34f116a2925444933c22a。
我对lxml和py2app的组合没有经验,但我遇到过py2app没有识别到那些没有明确导入的模块的问题。例如,我必须明确地包含那些通过__import__()
导入的模块,像这样:
OPTIONS['includes'] = [filename[:-3].replace('/', '.') for filename \
in glob.glob('path/to/*.py')]
也许在你的代码中某个地方加上from lxml import etree
会有所帮助?
找到了。py2app有一个叫做'frameworks'的选项,可以让你指定框架和动态库(dylibs)。我现在的setup.py文件看起来是这样的:
from setuptools import setup
DATA_FILES = []
OPTIONS = {'argv_emulation': True,
'packages' : ['lxml'],
'frameworks' : ['/usr/local/libxml2-2.7.2/lib/libxml2.2.7.2.dylib']
}
setup(app=MyApp.py,
data_files=DATA_FILES,
options={'py2app' : OPTIONS},
setup_requires=['py2app'])
这样就解决了问题。
感谢那些给我建议的人,让我找到了解决办法。