cx_freeze собирает программу для Mac, которая запускается из командной строки, но умирает при нажатии
У меня есть программа Python 2.7/PyQt4, которую я пытаюсь заморозить с помощью cx_freeze. Программа также использует запросы, serial, xml.etree.ElementTree и коллекции. Используя немодифицированный файл setup.py, сгенерированный cxfreeze-quickstart-2.7, я могу успешно создавать как консольную программу (python setup.py build), так и.app (python setup.py bdist_mac) в Yosemite, используя Python из macports. Если я запускаю программу напрямую из пакета приложения или из 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.
Я рассмотрел ряд потенциальных проблем, поднятых Дэном МакКомбсом (distutils.util.get_platform, sys.arg), но, похоже, это не проблема. Методом проб и ошибок методом грубой силы я обнаружил, что, если поместить весь мой код в отдельный модуль, простой импорт этого модуля (без его фактического вызова) вызывает ошибку 10810, поэтому я решил, что при запуске из команды он находил библиотеку. линия, но не из приложения. Я поместил каталог dist на флэш-накопитель и запустил его на другом Mac, на котором не установлены Python, Qt4 и т. Д., И получил это:
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, есть файл QtGui того же размера, что и в /opt. Так что, похоже, ошибка dlopen(PyQt4.QtGui.so), возвращающая жестко заданный путь к библиотеке QtGui. Я предполагаю, что решение простое, но я еще не наткнулся на него.
Обновление: я посмотрел библиотеки в build/Contents/MacOS/PyQt4.*. Так с otool, и все они имеют @executable_path (в отличие от жестко закодированных путей в dist). Мой тупой Поэтому я повторил процесс перемещения программы, используя только папку MacOS, а не папку dist, и запустив macdise из командной строки на MBP моей жены. Проблема оказалась в том, как я искал include_files. Я изменил это на:
if getattr(sys, 'frozen', False):
uiName = os.path.join(os.path.dirname(sys.executable), "tabDISE.ui" )
else:
uiName = "tabDISE.ui"
и это работает. То, что спасло бы меня в день, было бы способом автоматически сбросить сообщение об ошибке, сгенерированное при выполнении из командной строки, в журнал консоли. Если кто-то знает, как это сделать, это будет большая помощь.