cx_freeze macos python-3.x bundle cx-freeze pyqt5

macos - cx_freeze - Esta aplicación no se pudo iniciar porque no pudo encontrar o cargar el complemento de la plataforma Qt "cacao"



pyinstaller (3)

Al crear una aplicación con cx_Freeze en MacOSX, todas las bibliotecas dependientes (archivos .so en MacOSX) se empaquetan en el paquete de aplicaciones. Esto es lo que hace que la aplicación sea portátil para otros sistemas, sin requerir una segunda instalación de Qt.

Al iniciar la aplicación, las bibliotecas, por lo tanto, deben cargarse desde el paquete. Sin embargo, en su caso las bibliotecas del sistema todavía se están cargando:

/Users/.../build/coublet-0.5.70.app/Contents/MacOS/QtWidgets /usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets

El resultado One of the two will be used. Which one is undefined. One of the two will be used. Which one is undefined. significa que cualquiera de estos podría ser cargado. Si elige el correcto, ¡genial! Si no lo hace, tiene dos conjuntos separados de bibliotecas cargando simultáneamente, y eso falla poco después. Como comentario adicional, puede encontrar que si prueba su Aplicación en otro sistema ¡funcionará bien! A veces

Para una visión general del problema, sugiero echar un vistazo al siguiente error # 33 .

Antes de que empieces

Asegúrese de cx_Freeze instalada una versión actualizada de cx_Freeze . Sugiero intentar clonar el repositorio e instalar desde allí.

En segundo lugar, asegúrese de que los complementos de Qt estén integrados correctamente en su aplicación. Cx_Freeze previamente buscó el archivo qt-menu.nib para determinar si estaba construyendo una aplicación Qt. Esto ya no está disponible en Qt5, pero puedes pasarlo en la línea de comandos cuando crees tu aplicación. Establézcalo como lo desee, realmente no importa:

python setup.py bdist_mac --qt-menu-nib=/usr/local/Cellar/qt5/5.3.1/plugins/platforms/

Esto puede ser suficiente para solucionar su problema. Pero si no, tienes dos opciones:

Opción 1

Cada archivo de biblioteca contiene las rutas a sus dependencias. Si recibe este error, significa que algunas de esas rutas son a) siguen apuntando al archivo original, ob) no son lo suficientemente específicas (y se encuentran en su PATH o DYLD_LIBRARY_PATH ). Sin embargo, puede volver a escribir rutas usando install_name_tool desde la línea de comandos (como se describe here :

install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/QtWidgets build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtCore.framework/Versions/5/QtCore @executable_path/QtCore build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport @executable_path/QtPrintSupport build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtGui.framework/Versions/5/QtGui @executable_path/QtGui build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib

Esto reescribe las rutas en las bibliotecas para apuntar a la carpeta de la aplicación, usando @executable_path como base. Tendrá que hacer esto para todas las rutas que encuentre cargando incorrectamente. Sugiero incluirlo en un script para que se ejecute automáticamente después de la compilación.

Si desea ver a qué bibliotecas hace referencia un archivo, puede usar otool . Por ejemplo, en una aplicación mía exitosamente construida:

otool -L libqcocoa.dylib libqcocoa.dylib: @executable_path/../Resources/qt_plugins/platforms/libqcocoa.dylib (compatibility version 0.0.0, current version 0.0.0) /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 20.0.0) ...

Hubo una solución alternativa en el rastreador de problemas que sugiere que solo importar el módulo correcto en su aplicación hará que funcione, sin embargo, parece poco probable que haya creado una aplicación sin QtWidgets .

opcion 2

Si lo anterior no funciona, hay otro enfoque que se describe here . Este es un enfoque un poco machacante, ya que simplemente evita la carga de complementos.

  • Agregue un archivo qt.conf lado del ejecutable (en el paquete .app que contiene:
    [Paths] Plugins = ''.''

  • QT_PLUGIN_PATH="" variable de entorno QT_PLUGIN_PATH="" (puede hacer esto dentro de su aplicación antes de importar PyQt . O llame a QtGui.QApplication.setLibraryPaths([]) antes de crear su objeto de aplicación.

El resultado es que no hay complementos, por lo que su aplicación no tendrá acceso al estilo MacOSX Cocoa y a la interfaz de usuario (por ejemplo, archivos, cuadros de diálogo de colores).

Creo que hice todo lo posible en las últimas 20 horas, pero nada parece funcionar. Mi aplicación se está ejecutando y funciona, como debería ser, el único problema que tengo es que no puedo crear un paquete .app partir de él. Intenté Py2App y cx_Freeze pero cx_Freeze funciona. Debido al soporte multiplataforma, me quedaría con este último, si es posible.

El setup.py ve así:

import sys from cx_Freeze import setup, Executable base = None if sys.platform == ''win32'': base = ''Win32GUI'' OPTIONS = {''build_exe'': {''includes'': [''sip'', ''PyQt5'', ''PyQt5.QtCore'', ''PyQt5.QtGui'', ''PyQt5.QtWidgets'', ''PyQt5.QtMultimediaWidgets'', ''PyQt5.QtMultimedia'', ''PyQt5.QtNetwork'']}} EXECUTABLES = [Executable(''main.py'', base=base)] NAME = ''coublet'' VERSION = ''0.5.70'' setup(name = NAME, version = VERSION, options = OPTIONS, executables = EXECUTABLES)

El mensaje de error que tengo es este:

objc[28404]: Class NotificationReceiver is implemented in both /Users/.../build/coublet-0.5.70.app/Contents/MacOS/QtWidgets and /usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets. One of the two will be used. Which one is undefined. QObject::moveToThread: Current thread (0x7fc4b96e98b0) is not the object''s thread (0x7fc4b95dbc80). Cannot move to target thread (0x7fc4b96e98b0) On Mac OS X, you might be loading two sets of Qt binaries into the same process. Check that all plugins are compiled against the right Qt binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded. This application failed to start because it could not find or load the Qt platform plugin "cocoa". Available platform plugins are: cocoa, minimal, offscreen. Reinstalling the application may fix this problem. Abort trap: 6

Mi sistema de información:

Mac OS X : 10.9.4 Python : 3.4.1 cx_Freeze : 0.9 PyQt5: : 5.3.1 - - - Packages installed via: Homebrew and PIP

Estructura de .app :

build/coublet-0.5.70.app └── Contents ├── Frameworks ├── Info.plist ├── MacOS │   ├── PyQt5.QtCore.so │   ├── PyQt5.QtGui.so │   ├── PyQt5.QtMultimedia.so │   ├── PyQt5.QtMultimediaWidgets.so │   ├── PyQt5.QtNetwork.so │   ├── PyQt5.QtWidgets.so │   ├── Python │   ├── QtCore │   ├── QtCore.so │   ├── QtGui │   ├── QtGui.so │   ├── QtMultimedia │   ├── QtMultimedia.so │   ├── QtMultimediaWidgets │   ├── QtMultimediaWidgets.so │   ├── QtNetwork │   ├── QtNetwork.so │   ├── QtOpenGL │   ├── QtWidgets │   ├── QtWidgets.so │   ├── _bisect.so │   ├── _bz2.so │   ├── _codecs_cn.so │   ├── _codecs_hk.so │   ├── _codecs_iso2022.so │   ├── _codecs_jp.so │   ├── _codecs_kr.so │   ├── _codecs_tw.so │   ├── _datetime.so │   ├── _hashlib.so │   ├── _heapq.so │   ├── _json.so │   ├── _lzma.so │   ├── _md5.so │   ├── _multibytecodec.so │   ├── _opcode.so │   ├── _pickle.so │   ├── _posixsubprocess.so │   ├── _random.so │   ├── _scproxy.so │   ├── _sha1.so │   ├── _sha256.so │   ├── _sha512.so │   ├── _socket.so │   ├── _ssl.so │   ├── _struct.so │   ├── array.so │   ├── binascii.so │   ├── grp.so │   ├── imageformats │   │   ├── libqdds.dylib │   │   ├── libqgif.dylib │   │   ├── libqicns.dylib │   │   ├── libqico.dylib │   │   ├── libqjp2.dylib │   │   ├── libqjpeg.dylib │   │   ├── libqmng.dylib │   │   ├── libqsvg.dylib │   │   ├── libqtga.dylib │   │   ├── libqtiff.dylib │   │   ├── libqwbmp.dylib │   │   └── libqwebp.dylib │   ├── libcrypto.1.0.0.dylib │   ├── liblzma.5.dylib │   ├── library.zip │   ├── libreadline.6.dylib │   ├── libssl.1.0.0.dylib │   ├── main │   ├── math.so │   ├── platforms │   │   ├── libqcocoa.dylib │   │   ├── libqminimal.dylib │   │   └── libqoffscreen.dylib │   ├── pyexpat.so │   ├── readline.so │   ├── select.so │   ├── sip.so │   ├── termios.so │   ├── time.so │   ├── unicodedata.so │   └── zlib.so └── Resources

La pregunta es, creo, bastante obvia: ¿qué estoy haciendo mal? (¿o qué no estoy haciendo?)


Esto es adicional a la respuesta de @ mfitzp.

Este documento QT Plugins fue útil.

Para buscar las ubicaciones predeterminadas que su aplicación QT está intentando buscar, puede usar el siguiente comando:

$sudo dtruss MacOS/ncher getattrlist("/ncher.app/0", 0x7FFF954B51A4, 0x7FFF5C8FDD20) = 0 0 getattrlist("/ncher.app/Contents/0", 0x7FFF954B51A4, 0x7FFF5C8FDD20) = 0 0 getattrlist("/ncher.app/Contents/MacOS/0", 0x7FFF954B51A4, 0x7FFF5C8FDD20) = 0 0 stat64("/ncher.app/Contents/MacOS/0", 0x7FFF5C8FDED8, 0x7FFF5C8FDD20) = 0 0 stat64("/ncher.app/Contents/MacOS/platforms/./0", 0x7FFF5C8FDF58, 0x7FFF5C8FDD20) = -1 Err#2 open("/dev/tty/0", 0x1000000, 0x1FF) = 5 0 fcntl(0x5, 0x2, 0x1) = 0 0 close(0x5) = 0 0 write_nocancel(0x2, "This application failed to start because it could not find or load the Qt platform plugin /"cocoa/"./n/nReinstalling the application may fix this problem./n/0", 0x97) = 151 0 sigprocmask(0x3, 0x7FFF5C8FE6B4, 0x0) = 0x0 0 __pthread_sigmask(0x3, 0x7FFF5C8FE6C0, 0x0) = 0 0 __pthread_kill(0x603, 0x6, 0x0) = 0 0 kevent64(0x4, 0x0, 0x0) = -1 Err#4

Puedes ver esta aplicación QT tratando de buscar en MacOS/platforms , una vez que copié mi plugin libqcocoa.dylib (su ruta fue modificada por el comando install_name_tool según la respuesta de @mfitzp) allí, mi aplicación funcionó como "charm".

Por cierto, es aconsejable que la guía de código de MAC tenga esta estructura de directorios correctamente configurada,

NO ncher.app/Contents/MacOS Frameworks, complementos en el directorio ncher.app/Contents/MacOS


Tuve este problema en el contexto de simplemente iniciar una aplicación Qt Widgets de Qt Creator.

Lo que me ayudó fue establecer la variable QT_PLUGIN_PATH en el valor <Qt-dir>/plugins (donde <Qt-dir> es la ruta absoluta a la carpeta en el directorio Qt que contiene, entre otros, bin , doc , include , lib y por supuesto, plugins ).

Esto probablemente no solucionó la causa raíz del problema, pero fue una solución rápida que funciona bien hasta el momento.