python - cx_freeze - pyinstaller visual studio
¿Cómo agregar módulos dinámicos de Python a las especificaciones de PyInstaller? (1)
He tenido el problema de empaquetar la aplicación PyQt con Py2Exe (también he tenido problemas con PyInstaller y cx_freeze, pero solo Py2exe me ayudó).
Aquí está la solution detallada. Los he agregado explícitamente como:
data_files += [(''source'', glob(''source/*.py''),)]
setup(
data_files=data_files,
.... # other options
windows=[
{
"script": "launcher.py",
"icon_resources": [(0, "resources/favicon.ico")]
}
)
Luego los importo y los llamo. Espero que este enfoque sea de utilidad.
Estoy tratando de averiguar cómo cargar importaciones dinámicas / ocultas con PyInstaller, hasta ahora tengo esta estructura simple:
En primer lugar, tengo un paquete de framework agregado a mi PYTHONPATH que vive en d:/Sources/personal/python/framework
Ese paquete es utilizado por muchos de mis proyectos de Python, en particular, se usa con el siguiente proyecto simple que quiero empaquetar
Main project
├───data <- Pure static data
├───plugins <- Dynamic modules which uses framework''s modules
├───resources <- Static data+embedded (generated by pyqt), used by plugins
│ ├───css
│ ├───images
| resources.py
| resources.qrc
main.py <- Uses framework''s modules to load plugins dynamically
Mi archivo de especificaciones se ve así:
# -*- mode: python -*-
block_cipher = None
a = Analysis([''main.py''],
pathex=[''d://sources//personal//python//pyqt//pyshaders''],
binaries=None,
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
##### include mydir in distribution #######
def extra_datas(mydir):
def rec_glob(p, files):
import os
import glob
for d in glob.glob(p):
if os.path.isfile(d):
files.append(d)
rec_glob("%s/*" % d, files)
files = []
rec_glob("%s/*" % mydir, files)
extra_datas = []
for f in files:
extra_datas.append((f, f, ''DATA''))
return extra_datas
###########################################
a.datas += extra_datas(''data'')
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name=''main'',
debug=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name=''main'')
El problema surge cuando trato de agregar importaciones ocultas a la lista de importaciones ocultas de Analysis (..., hiddenimports = [], ...). He intentado hasta ahora esto:
-
hiddenimports=[''d://sources//personal//python//pyqt//plugins'']
-
hiddenimports=[''d://sources//personal//python//pyqt//plugins//*'']
-
hiddenimports=[''plugins'']
También se intentó listar como archivos individuales con rutas absolutas:
hiddenimports=[
''d://sources//personal//python//pyqt//pyshaders//plugins//api.py'',
''d://sources//personal//python//pyqt//pyshaders//plugins//config.py'',
''d://sources//personal//python//pyqt//pyshaders//plugins//plugins_actions.py'',
''d://sources//personal//python//pyqt//pyshaders//plugins//plugins_dialogs.py'',
''d://sources//personal//python//pyqt//pyshaders//plugins//plugins_docks.py'',
''d://sources//personal//python//pyqt//pyshaders//plugins//plugins_post_init.py'',
''d://sources//personal//python//pyqt//pyshaders//plugins//plugins_toolbar.py''
]
Y también trató de cargarlos como paquetes de módulos ( __init__.py
vive en la carpeta de complementos)
hiddenimports=[
''plugins.api'',
''plugins.config'',
''plugins.plugins_actions'',
''plugins.plugins_dialogs'',
''plugins.plugins_docks'',
''plugins.plugins_post_init'',
''plugins.plugins_toolbar''
]
También probamos los submodódulos colectivos.
hiddenimports=collect_submodules(''plugins'')
Ninguno de estos intentos funcionó y el complemento de la carpeta no se está agregando correctamente a la distación (cuando digo "correctamente", supongo que pyinstaller analizará las importaciones utilizadas por estos complementos ocultos analizando de forma recursiva sus dependencias y copiando los archivos * .pyc). .. Entonces, me gustaría saber cómo puedo agregar correctamente los módulos "ocultos" que se están cargando dinámicamente a la especificación del instalador.