Не удалось создать автономное приложение Python/Qt с помощью cx_freeze (или Py2App) на Mac

У меня возникают проблемы при создании автономного приложения для Mac из программы на основе Python Qt, как при использовании cx_freeze и Py2App. (обратите внимание, что я сделал это успешно на Windows с помощью cx_freeze).

На самом деле, пример 'PyQt4', поставляемый с cx_freeze, не работает должным образом на Mac. Кто-нибудь может "собрать" и запустить этот пример на Mac?! Я не смог найти никакой информации по этой, казалось бы, основной проблеме на форумах.

Действительно, давайте сначала построим:

~$ cd cx_Freeze-4.3.3/cx_Freeze/samples/PyQt4/
PyQt4$ ls
    PyQt4app.py setup.py
PyQt4$ python setup.py build
    running build
    running build_exe
    creating directory build/exe.macosx-10.5-x86_64-2.7
    copying //anaconda/lib/python2.7/site-packages/cx_Freeze-4.3.3-py2.7-
    macosx-10.5-x86_64.egg/cx_Freeze/bases/Console -> build/exe.macosx-10.5-x86_64-2.7/PyQt4app
    TD bug fix: adding //anaconda/lib to relative path libpython2.7.dylib!
    copying //anaconda/lib/libpython2.7.dylib -> build/exe.macosx-10.5-x86_64-2.7/libpython2.7.dylib
    TD bug fix: adding //anaconda/lib to relative path libpython2.7.dylib!
    writing zip file build/exe.macosx-10.5-x86_64-2.7/library.zip
    …
    copying //anaconda/lib/python2.7/lib-dynload/zlib.so -> build/exe.macosx-10.5-x86_64-2.7/zlib.so
PyQt4$

обратите внимание на строки "Исправление ошибки TD…": чтобы запустить вышеописанный файл без ошибки "файл не найден", мне пришлось добавить исправление в функцию _GetDependentFiles в файле cx_freeze freezer.py:

for i in range(len(dependentFiles)):
    filei = dependentFiles[i]
    if not os.path.isabs(filei):
        print 'TD bug fix: adding ' + sys.prefix + '/lib to relative path ' + filei + '!'
        dependentFiles[i] = os.path.join(sys.prefix,'lib',filei)

Теперь, при попытке запустить созданную автономную программу, я получаю:

PyQt4$ ls
    PyQt4app.py  build  setup.py
PyQt4$ cd build/exe.macosx-10.5-x86_64-2.7/
exe.macosx-10.5-x86_64-2.7$ ls
    PyQt4.QtCore.so _codecs_iso2022.so _struct.so   libQtCore.dylib    libz.1.dylib
    PyQt4.QtGui.so  _codecs_jp.so      binascii.so  libQtGui.4.dylib   sip.so
    PyQt4app        _codecs_kr.so      bz2.so       libQtGui.dylib     unicodedata.so
    _codecs_cn.so   _codecs_tw.so      itertools.so libpython2.7.dylib zlib.so
    _codecs_hk.so   _multibytecodec.so libQtCore.4.dylib library.zip
exe.macosx-10.5-x86_64-2.7$ ./PyQt4app
    Traceback (most recent call last):
      File "//anaconda/lib/python2.7/site-packages/cx_Freeze-4.3.3-py2.7-macosx-10.5-x86_64.egg/cx_Freeze/initscripts/Console.py", line 27, in <module>
        exec(code, m.__dict__)
      File "PyQt4app.py", line 5, in <module>
      File "ExtensionLoader_PyQt4_QtGui.py", line 22, in <module>
      File "ExtensionLoader_PyQt4_QtGui.py", line 14, in __bootstrap__
    ImportError: dlopen(/Users/thomasdeneux/cx_Freeze-4.3.3/cx_Freeze/samples/PyQt4/build/exe.macosx-10.5-x86_64-2.7/PyQt4.QtGui.so, 2): Library not loaded: @loader_path/../../../libQtGui.4.dylib
      Referenced from: /Users/thomasdeneux/cx_Freeze-4.3.3/cx_Freeze/samples/PyQt4/build/exe.macosx-10.5-x86_64-2.7/PyQt4.QtGui.so
      Reason: image not found
exe.macosx-10.5-x86_64-2.7$

Бывает, что некоторые библиотеки Qt не найдены, потому что на них ссылается полный относительный путь, тогда как в дистрибутиве все библиотеки были скопированы в одну и ту же папку.

Затем я перешел на Py2App, надеясь, что другой пакет не столкнется с такой проблемой. Сейчас я не показываю все детали, только самые важные строки при попытке сборки (на этот раз мне не нужно было изменять код для запуска сборки) и запускаю другую простую программу helloworld на основе Qt:

test$ py2applet --make-setup helloworld.py
    Wrote setup.py
test$ python setup.py py2app
    running py2app
    creating /Users/thomasdeneux/Documents/spyderworkspace/securebox/python/build/bdist.macosx-10.5-x86_64
    ...
    Done!
test$ ./dist/helloworld.app/Contents/MacOS/helloworld 
    Traceback (most recent call last):
      File "/Users/thomasdeneux/Documents/spyderworkspace/securebox/python/dist/helloworld        .app/Contents/Resources/__boot__.py", line 351, in <module>
        _run()
      File "/Users/thomasdeneux/Documents/spyderworkspace/securebox/python/dist/helloworld        .app/Contents/Resources/__boot__.py", line 336, in _run
        exec(compile(source, path, 'exec'), globals(), globals())
      File "/Users/thomasdeneux/Documents/spyderworkspace/securebox/python/dist/helloworld        .app/Contents/Resources/helloworld.py", line 4, in <module>
        from PyQt4.QtGui import *
      File "PyQt4/QtGui.pyc", line 14, in <module>
      File "PyQt4/QtGui.pyc", line 10, in __load
    ImportError: dlopen(/Users/thomasdeneux/Documents/spyderworkspace/securebox/python/dist/helloworld.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so, 2): Library not loaded: @loader_path/../../../libQtGui.4.dylib
      Referenced from: /Users/thomasdeneux/Documents/spyderworkspace/securebox/python/dist/helloworld.app/Contents/Resources/lib/python2.7/lib-dynload/PyQt4/QtGui.so
      Reason: image not found
    2015-05-16 20:40:41.546 helloworld[983:707] helloworld Error
test$ 

Точно такая же проблема появляется!

Спасибо всем, кто может помочь, будь то путем непосредственного решения проблемы или путем рекомендации другой стратегии создания автономных программ для Mac из проектов python/Qt.

0 ответов

Другие вопросы по тегам