使用pygame的py2app安装的应用程序失败

时间:2013-11-08 22:23:44

标签: python macos pygame pyobjc py2app

我正在使用py2app捆绑一个pygame应用程序。捆绑工作和生成的捆绑在我的Mac上运行就好了。它也习惯于在另一个人的Mac上运行就好了。但是,最近我尝试在他的计算机上运行捆绑包时开始收到此错误(来自控制台):

Traceback (most recent call last):
  File "/Users/.../tmp/withconsole.app/Contents/Resources/__boot__.py", line 316, in <module>
    _run()
  File "/Users/.../tmp/withconsole.app/Contents/Resources/__boot__.py", line 311, in _run
    exec(compile(source, path, 'exec'), globals(), globals())
  File "/Users/.../tmp/withconsole.app/Contents/Resources/withconsole.py", line 18, in <module>
pdb.set_trace()
  File "bdb.pyc", line 53, in trace_dispatch
  File "bdb.pyc", line 88, in dispatch_return
  File "pdb.pyc", line 190, in user_return
  File "pdb.pyc", line 210, in interaction
  File "cmd.pyc", line 142, in cmdloop
  File "pdb.pyc", line 279, in onecmd
  File "cmd.pyc", line 218, in onecmd
  File "pygame/macosx.pyc", line 10, in <module>
  File "pygame/sdlmain_osx.pyc", line 14, in <module>
  File "pygame/sdlmain_osx.pyc", line 10, in __load
ImportError: dlopen(/Users/.../tmp/withconsole.app/Contents/Resources/lib/python2.7/lib-dynload/pygame/sdlmain_osx.so, 2): Symbol not found: _OBJC_CLASS_$_NSObject
  Referenced from: /Users/.../tmp/withconsole.app/Contents/Resources/lib/python2.7/lib-dynload/pygame/sdlmain_osx.so
  Expected in: /usr/lib/libobjc.A.dylib
 in /Users/.../tmp/withconsole.app/Contents/Resources/lib/python2.7/lib-dynload/pygame/sdlmain_osx.so
2013-11-09 06:19:50.794 withconsole[2797:1c03] ogclient Error

我甚至试过运行过去工作的旧捆绑包,但现在它已经不再适用了!无论如何,我已经95%肯定了。

在任何情况下,问题是什么以及如何解决?

1 个答案:

答案 0 :(得分:2)

来自py2app的独立应用程序可以从用于py2app的任何Python版本创建其自带的Python解释器。

如果您使用构建为在任何OS X 10.6或更高版本上运行的Python,则该应用程序(只要它不使用任何10.6之后的功能)也将在任何OS X 10.6或更高版本上运行。如果您使用构建在一台特定10.8计算机上运行的Python,则该应用程序很可能无法在10.8之前的任何设备上运行,甚至可能无法在其他10.8+计算机上运行。

最重要的是,如果你正在使用你自己构建的C库构建的任何C扩展模块,如果这些C库是为你的特定机器构建的,它们可能会导致同样的问题。

您使用Homebrew构建了Python解释器。也许你的SDL也是pygame所依赖的。还有其他的东西。默认情况下,Homebrew会构建在特定计算机上运行的所有内容,而不是可再发行的。因此问题。

要构建可在10.7计算机上运行的应用程序,您需要针对10.7 SDK构建Python,SDL等,或者针对更高版本的API构建它并指定-mmacosx-version-min=10.7。 (还有一些其他问题可以出现,但我很确定它们都不会影响CPython,所以让我们保持简单。)

这将自动设置,因此您构建的任何C扩展模块都使用相同的SDK和版本设置,因此您不必担心这些。但是你必须担心你构建的那些扩展模块所依赖的C库。例如,pygame链接到libSDL,如果您仅为本地计算机构建了SDL,pygame将无法在其他人的计算机上运行。

可以让Homebrew创建SDK构建,但并不总是那么容易。手动构建Python并传递正确的--configure标志更容易。但是,采用其他人为可移植性而构建的二进制文件并使用它更容易。

python.org上的官方Python安装程序是为10.6+而构建的。官方SDL开发库的构建版本为10.5+。希望您依赖的其他事情也是如此。如果是这样,只需brew uninstall(或者,如果您需要谨慎并且希望以后能够撤消它,brew unlink),请运行二进制安装程序,重新安装所需的所有Python模块Python和py2app用它。


我用一般的术语写了这些。从输出中看,您在朋友的特定10.7计算机上执行此特定运行时遇到的特定问题是SDL包装器依赖于ObjC运行时的特性而不存在于10.7。所以,可能只使用10.7友好的SDL和现有的Python就足够了。但是,如果可能的话,我认为你最好使用10.7友好的一切。


如果您想知道SDK究竟是做什么的,那么Apple官方文档中的SDK Compatibility Guide很好地解释了它的技术方面,并且有很多博客文章如this one解释实际部分,但我会试着总结一下。

每个SDK只是一个拥有自己的/ usr / include,/ usr / lib,/ System / Library / Frameworks以及其他一些内容的目录。当您针对SDK构建时,最终会针对其头文件而不是系统进行编译,并且会针对其dylib而不是系统进行链接。这可以防止您使用自10.6以来添加的任何新功能(具有良好的编译器错误,而不是成功的构建,然后无法在用户的一半机器上启动)。并且它确保,如果您不使用任何此类新功能,则您的程序对10.6中不存在的任何内容都没有加载时依赖性。