-->

Failed making a standalone python/Qt application w

2019-09-10 06:08发布

问题:

I am having trouble making a standalone application for Mac from a python Qt-based program, both when using cx_freeze and Py2App. (note that i did it successfully on Windows with cx_freeze).

Actually, the 'PyQt4' example provided with cx_freeze does not run properly on Mac. Is anyone able to "build" and run this example on a Mac?! I couldn't find any information on this seemingly basic problem on forums.

Indeed, let us build first:

~$ 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$

note the lines "TD bug fix…": in order to have the above run without 'file not found' error, i had to add a correction to function _GetDependentFiles in cx_freeze file 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)

Now, when trying to run the created standalone program, I get:

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$

It happens that some Qt libraries are not found because they are referenced with a complete relative path, while in the distribution all libraries were copied inside the same folder.

I have then moved to Py2App, hoping another package would not run into such problem. I don't show all the details now, only the most important lines when trying to build (this time i did not need to modify the code to get the building run) and run another simple Qt-based helloworld program:

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$ 

Exactly the same kind of problem appears!

Thanks to anyone being able to help, whether by directly solving the issue or by advising another strategy for creating standalone programs for Mac from python/Qt projects.