Search code examples
python-3.xkivypyinstaller

Trouble with kivy project and pyinstaller


I already found similar answers, but no tips helped me, maybe now I can figure it out. I replaced the real names and username with conditional names. I am trying to compile a project with the command: pyinstaller --clean main.spec The contents of the main.spec file:

import sys
import os
from kivy.tools.packaging.pyinstaller_hooks import get_deps_all
from kivy.tools.packaging.pyinstaller_hooks import hookspath

block_cipher = None


a = Analysis(
    ['/home/user/projects/My_Client/main.py'],
    pathex=[]
    binaries=[],
    datas=[],
    hiddenimports=['tkinter', 'My_Client_Module_1', 'My_Client_Module_2'],
    hookspath=hookspath(),
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
    **get_deps_all()
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name='main',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='main',
)

I am getting the following error while building the project:

74 INFO: PyInstaller: 5.6.2
74 INFO: Python: 3.7.3
74 INFO: Platform: Linux-4.19.0-22-amd64-x86_64-with-debian-10.13
76 INFO: UPX is not available.
76 INFO: Removing temporary files and cleaning cache in /home/user/.cache/pyinstaller
[INFO   ] [Logger      ] Record log in /home/user/.kivy/logs/kivy_22-11-09_7.txt
104 INFO: [Logger      ] Record log in /home/user/.kivy/logs/kivy_22-11-09_7.txt
[INFO   ] [Kivy        ] v2.0.0
104 INFO: [Kivy        ] v2.0.0
[INFO   ] [Kivy        ] Installed at "/home/user/.local/lib/python3.7/site-packages/kivy/__init__.py"
105 INFO: [Kivy        ] Installed at "/home/user/.local/lib/python3.7/site-packages/kivy/__init__.py"
[INFO   ] [Python      ] v3.7.3 (default, Oct 31 2022, 14:04:00) 
[GCC 8.3.0]
105 INFO: [Python      ] v3.7.3 (default, Oct 31 2022, 14:04:00) 
[GCC 8.3.0]
[INFO   ] [Python      ] Interpreter at "/usr/bin/python3"
105 INFO: [Python      ] Interpreter at "/usr/bin/python3"
[INFO   ] [Factory     ] 186 symbols loaded
106 INFO: [Factory     ] 186 symbols loaded
 Traceback (most recent call last):
106 WARNING: stderr: Traceback (most recent call last):
   File "/home/user/.local/bin/pyinstaller", line 8, in <module>
106 WARNING: stderr:   File "/home/user/.local/bin/pyinstaller", line 8, in <module>
     sys.exit(run())
107 WARNING: stderr:     sys.exit(run())
   File "/home/user/.local/lib/python3.7/site-packages/PyInstaller/__main__.py", line 179, in run
107 WARNING: stderr:   File "/home/user/.local/lib/python3.7/site-packages/PyInstaller/__main__.py", line 179, in run
     run_build(pyi_config, spec_file, **vars(args))
107 WARNING: stderr:     run_build(pyi_config, spec_file, **vars(args))
   File "/home/user/.local/lib/python3.7/site-packages/PyInstaller/__main__.py", line 60, in run_build
107 WARNING: stderr:   File "/home/user/.local/lib/python3.7/site-packages/PyInstaller/__main__.py", line 60, in run_build
     PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
107 WARNING: stderr:     PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
   File "/home/user/.local/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 963, in main
107 WARNING: stderr:   File "/home/user/.local/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 963, in main
     build(specfile, distpath, workpath, clean_build)
107 WARNING: stderr:     build(specfile, distpath, workpath, clean_build)
   File "/home/user/.local/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 885, in build
107 WARNING: stderr:   File "/home/user/.local/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 885, in build
     exec(code, spec_namespace)
108 WARNING: stderr:     exec(code, spec_namespace)
   File "main.spec", line 5, in <module>
108 WARNING: stderr:   File "main.spec", line 5, in <module>
     from kivy.tools.packaging.pyinstaller_hooks import get_deps_all
108 WARNING: stderr:     from kivy.tools.packaging.pyinstaller_hooks import get_deps_all
   File "/home/user/.local/lib/python3.7/site-packages/kivy/tools/packaging/pyinstaller_hooks/__init__.py", line 85, in <module>
108 WARNING: stderr:   File "/home/user/.local/lib/python3.7/site-packages/kivy/tools/packaging/pyinstaller_hooks/__init__.py", line 85, in <module>
     from PyInstaller.compat import modname_tkinter
108 WARNING: stderr:     from PyInstaller.compat import modname_tkinter
 ImportError: cannot import name 'modname_tkinter' from 'PyInstaller.compat' (/home/user/.local/lib/python3.7/site-packages/PyInstaller/compat.py)
108 WARNING: stderr: ImportError: cannot import name 'modname_tkinter' from 'PyInstaller.compat' (/home/user/.local/lib/python3.7/site-packages/PyInstaller/compat.py)

I already tried to update pyinstaller-hooks, not sure if it was done correctly. Tried adding tkinter to hideimports.


Solution

  • **get_deps_all() will produce following lists:

    binaries
    hiddenimports
    excludes
    

    so you have to remove them from Analysis block:

    a = Analysis(
        ['/home/user/projects/My_Client/main.py'],
        pathex=[]
        #binaries=[],
        datas=[],
        #hiddenimports=['tkinter', 'My_Client_Module_1', 'My_Client_Module_2'],
        hookspath=hookspath(),
        hooksconfig={},
        runtime_hooks=runtime_hooks(),
        #excludes=[],
        win_no_prefer_redirects=False,
        win_private_assemblies=False,
        cipher=block_cipher,
        noarchive=False,
        **get_deps_all()
    )
    

    otherwise you will end up with following errors during build:

    WARNING: stderr: TypeError: type object got multiple values for keyword argument 'binaries'
    WARNING: stderr: TypeError: type object got multiple values for keyword argument 'hiddenimports'
    WARNING: stderr: TypeError: type object got multiple values for keyword argument 'excludes'
    

    Also you forgot to add following import on top of spec file:

    from kivy_deps import sdl2, glew
    

    and include required data within COLLECT block:

    coll = COLLECT(
        exe,
        a.binaries,
        a.zipfiles,
        a.datas,
        *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
        strip=False,
        upx=True,
        upx_exclude=[],
        name='main',
    )
    

    Otherwise build process will succeed, but when you try to launch app, you will face with errors like:

    [WARNING] [Image       ] Unable to load image <...\kivy_install\data\glsl\default.png>
    [CRITICAL] [Window      ] Unable to find any valuable Window provider. Please enable debug logging (e.g. add -d if running from the command line, or change the log level in the config) and re-run your app to identify potential causes
    sdl2 - Exception: SDL2: Unable to load image
    

    Also don't forget to manually copy all your additional files like images (.png), kv files (.kv), any other files you added to your project dir after build. They won't be automatically copied into "dist" folder unless you specify them within "datas" list. For example, to add all *.kv and *.png files from your root project directory:

    datas=[('*.kv', '.'), ('*.png', '.')]
    

    If you have additional files located within for example "my_files" folder, then you have to add it too:

    datas=[('*.kv', '.'), ('*.png', '.'), ('my_files\\*', 'my_files')]