0

我正在使用 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% 的把握。

无论如何,问题是什么,我该如何解决?

4

1 回答 1

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 包装器依赖于 10.7 中不存在的 ObjC 运行时功能。因此,仅使用10.7 友好的 SDL 和您现有的 Python 就足够了。但我认为如果可能的话,最好使用对 10.7 友好的一切。


如果您想知道 SDK 到底是做什么的,Apple 官方文档中的SDK 兼容性指南很好地解释了它的技术方面,并且有大量类似这样的博客文章解释了实际部分,但我会尝试总结。

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

于 2013-11-08T23:49:59.950 回答