cx_freeze でフリーズしようとしている Python 2.7/PyQt4 プログラムがあります。このプログラムは、リクエスト、シリアル、xml.etree.ElementTree、およびコレクションも使用します。cxfreeze-quickstart-2.7 によって生成された変更されていない setup.py を使用すると、macports の Python を使用して Yosemite でコンソール プログラム (python setup.py build) と .app (python setup.py bdist_mac) の両方として正常にビルドできます。app bundle または dist からプログラムを直接実行すると、次のようになります。
$ build/MacDISE-1.0.app/Contents/MacOS/macdise
$ dist/macdise
期待どおりに動作します。コマンドラインから開いた場合:
$ open -a /Users/jeffemandel/macdise/build/MacDISE-1.0.app
私は恐ろしいことを得る
LSOpenURLsWithRole() failed for the application /Users/jeffemandel/macdise/build/MacDISE-1.0.app with error -10810.
私は、Dan McCombs (distutils.util.get_platform、sys.arg) によって提起された多くの潜在的な問題に取り組みましたが、これらは問題ではないようです。総当たりの試行錯誤の結果、すべてのコードを別のモジュールに入れると、そのモジュールを (実際には呼び出さずに) インポートするだけで 10810 エラーが発生することがわかったので、コマンドから実行するとライブラリを見つけていると考えました。アプリからではありません。dist ディレクトリをサム ドライブに置き、Python、Qt4 などがインストールされていない別の Mac で実行したところ、次のようになりました。
packages/cx_Freeze/initscripts/Console.py", line 27, in <module> File "macdise.py", line 4, in <module>
File "ExtensionLoader_PyQt4_QtGui.py", line 11, in <module>
ImportError: dlopen(/Volumes/NO NAME/dist/PyQt4.QtGui.so, 2): Library not loaded: /opt/local/Library/Frameworks/QtGui.framework/Versions/4/QtGui
Referenced from: /Volumes/NO NAME/dist/PyQt4.QtGui.so
Reason: image not found
dist を見ると、/opt と同じサイズの QtGui というファイルがあります。したがって、障害は dlopen(PyQt4.QtGui.so) が QtGui ライブラリへのハードコードされたパスを返すことのようです。解決策は簡単だと思いますが、まだ見つけていません。
更新: build/Contents/MacOS/PyQt4.*.so のライブラリを otool で調べたところ、これらにはすべて @executable_path があります (dist のハードコードされたパスとは対照的に)。私の愚かな。そこで、dist フォルダーではなく MacOS フォルダーのみを使用してプログラムを移動し、妻の MBP のコマンド ラインから macdise を実行するプロセスを繰り返しました。問題は、included_files を探していた方法にあることが判明しました。これを次のように変更しました。
if getattr(sys, 'frozen', False):
uiName = os.path.join(os.path.dirname(sys.executable), "tabDISE.ui" )
else:
uiName = "tabDISE.ui"
そしてそれは実行されます。コマンドラインから実行したときに生成されたエラーメッセージをコンソールログに自動的にダンプする方法があれば、1日節約できました。誰かがこれを行う方法を知っていれば、それは大きな助けになります。