Kivy 1.10, PyInstaller, and Packaging for Linux

662 views
Skip to first unread message

Jason McDonald

unread,
Aug 1, 2017, 9:33:59 PM8/1/17
to Kivy users support
At this point, I'm deep enough into this situation to know, this is an infamously complicated situation. (Which, one would wonder, why?, but that's for another topic altogether...)

I've got a virtual environment on Ubuntu 17.04 with Python 3.5, and I've got Kivy installed via 'pip' in that environment. I can run my project (current source code here: https://github.com/mousepawmedia/omission) via 'python -m omission' or 'python omission.py' - either way works fine.

Now, I can *seem* to build with the 'omission.spec' file and PyInstaller command below, but the resultant file doesn't actually run. At all. No messages, no nothing. PyInstaller itself complains about a lack of 'win32com', which is ridiculous on Linux.

I HAVE to package and publish this thing this month, no options. So I need help: how in the hey do I do this?

------------

omission.spec

# -*- mode: python -*-
from kivy.tools.packaging.pyinstaller_hooks import get_deps_minimal, get_deps_all, hookspath, runtime_hooks


# From http://bitstream.io/packaging-and-distributing-a-kivy-application-on-linux.html
def filter_binaries(all_binaries):
   
'''Exclude binaries provided by system packages, and rely on .deb dependencies
    to ensure these binaries are available on the target machine.


    We need to remove OpenGL-related libraries so we can distribute the executable
    to other linux machines that might have different graphics hardware. If you
    bundle system libraries, your application might crash when run on a different
    machine with the following error during kivy startup:


    Fatal Python Error: (pygame parachute) Segmentation Fault


    If we strip all libraries, then PIL might not be able to find the correct _imaging
    module, even if the `python-image` package has been installed on the system. The
    easy way to fix this is to not filter binaries from the python-imaging package.


    We will strip out all binaries, except libpython2.7, which is required for the
    pyinstaller-frozen executable to work, and any of the python-* packages.
    '''



   
print('Excluding system libraries')
   
import subprocess
    excluded_pkgs  
= set()
    excluded_files
= set()
    whitelist_prefixes
= ('libpython3.5', 'python-', 'python3-')
    binaries
= []


   
for b in all_binaries:
       
try:
            output
= subprocess.check_output(['dpkg', '-S', b[1]], stderr=open('/dev/null'))
            p
, path = output.split(':', 2)
           
if not p.startswith(whitelist_prefixes):
                excluded_pkgs
.add(p)
                excluded_files
.add(b[0])
               
print(' excluding {f} from package {p}'.format(f=b[0], p=p))
       
except Exception:
           
pass


   
print('Your exe will depend on the following packages:')
   
print(excluded_pkgs)


    inc_libs
= set(['libpython3.5.so.1.0'])
    binaries
= [x for x in all_binaries if x[0] not in excluded_files]
   
return binaries


block_cipher
= None


added_files
= [
   
('README.md', '.'),
   
('LICENSE.md', '.'),
   
('omission/interface/omission.kv', 'omission/interface'),
   
('omission/resources', 'omission/resources')
   
]


a
= Analysis(['omission.py'],
             pathex
=['/home/jason/Code/Repositories/omission'],
             binaries
=[],
             datas
=added_files,
             
#hiddenimports=[],
             
#hookspath=[],
             hookspath
=hookspath(),
             
#runtime_hooks=[],
             runtime_hooks
=runtime_hooks(),
             
#excludes=['_tkinter', 'Tkinter', 'enchant', 'twisted'],
             win_no_prefer_redirects
=False,
             win_private_assemblies
=False,
             cipher
=block_cipher,
             
**get_deps_minimal(video=None)
             
)


pyz
= PYZ(a.pure, a.zipped_data,
          cipher
=block_cipher)


binaries
= filter_binaries(a.binaries)


exe
= EXE(pyz,
         
Tree('/home/jason/Code/Repositories/omission/omission'),
          a
.scripts,
          binaries
,
          a
.zipfiles,
          a
.datas,
          name
='omission',
          debug
=False,
          strip
=None,
          upx
=True,
          console
=True )


package_script.sh

#!/bin/bash
rm
-r build/
rm
-r dist/
pyinstaller
--log-level=WARN \
   
--clean \
   
--windowed \
   
--onefile \
    omission
.spec


Console output from package_script.sh:

(packaging) jason@enigma:~/repos/omission$ sh ./package_script.sh 
[INFO   ] [Logger      ] Record log in /home/jason/.kivy/logs/kivy_17-08-01_40.txt
60 INFO: [Logger      ] Record log in /home/jason/.kivy/logs/kivy_17-08-01_40.txt
[INFO   ] [Kivy        ] v1.10.0
60 INFO: [Kivy        ] v1.10.0
[INFO   ] [Python      ] v3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118]
61 INFO: [Python      ] v3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118]
[INFO   ] [Factory     ] 194 symbols loaded
62 INFO: [Factory     ] 194 symbols loaded
[INFO   ] [Logger      ] Record log in /home/jason/.kivy/logs/kivy_17-08-01_41.txt
[INFO   ] [Kivy        ] v1.10.0
[INFO   ] [Python      ] v3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118]
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO   ] [AudioGstplayer] Using Gstreamer 1.10.4.0
255 INFO: [AudioGstplayer] Using Gstreamer 1.10.4.0
[INFO   ] [Audio       ] Providers: audio_gstplayer, audio_sdl2 (audio_ffpyplayer ignored)
264 INFO: [Audio       ] Providers: audio_gstplayer, audio_sdl2 (audio_ffpyplayer ignored)
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
278 INFO: [Image       ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO   ] [Camera      ] Provider: opencv
294 INFO: [Camera      ] Provider: opencv
xclip version 0.12
Copyright (C) 2001-2008 Kim Saunders et al.
Distributed under the terms of the GNU GPL
[INFO   ] [Clipboard   ] Provider: xclip(['clipboard_dbusklipper', 'clipboard_gtk3'] ignored)
303 INFO: [Clipboard   ] Provider: xclip(['clipboard_dbusklipper', 'clipboard_gtk3'] ignored)
[INFO   ] [CutBuffer   ] cut buffer support enabled
303 INFO: [CutBuffer   ] cut buffer support enabled
[INFO   ] [Spelling    ] Provider: enchant
310 INFO: [Spelling    ] Provider: enchant
[INFO   ] [Text        ] Provider: sdl2
313 INFO: [Text        ] Provider: sdl2
[INFO   ] [OSC         ] using <multiprocessing> for socket
449 INFO: [OSC         ] using <multiprocessing> for socket
[INFO   ] [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
453 INFO: [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
[INFO   ] [GL          ] Using the "OpenGL" graphics system
1767 INFO: [GL          ] Using the "OpenGL" graphics system
[INFO   ] [GL          ] Backend used <gl>
1767 INFO: [GL          ] Backend used <gl>
[INFO   ] [GL          ] OpenGL version <b'3.0 Mesa 17.0.3'>
1767 INFO: [GL          ] OpenGL version <b'3.0 Mesa 17.0.3'>
[INFO   ] [GL          ] OpenGL vendor <b'Intel Open Source Technology Center'>
1768 INFO: [GL          ] OpenGL vendor <b'Intel Open Source Technology Center'>
[INFO   ] [GL          ] OpenGL renderer <b'Mesa DRI Intel(R) Sandybridge Mobile '>
1768 INFO: [GL          ] OpenGL renderer <b'Mesa DRI Intel(R) Sandybridge Mobile '>
[INFO   ] [GL          ] OpenGL parsed version: 3, 0
1768 INFO: [GL          ] OpenGL parsed version: 3, 0
[INFO   ] [GL          ] Shading version <b'1.30'>
1769 INFO: [GL          ] Shading version <b'1.30'>
[INFO   ] [GL          ] Texture max size <8192>
1769 INFO: [GL          ] Texture max size <8192>
[INFO   ] [GL          ] Texture max units <16>
1769 INFO: [GL          ] Texture max units <16>
[INFO   ] [Window      ] auto add sdl2 input provider
1796 INFO: [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
1797 INFO: [Window      ] virtual keyboard not allowed, single mode, not docked
Traceback (most recent call last):
  File "<string>", line 2, in <module>
ImportError: No module named 'win32com'
Traceback (most recent call last):
  File "<string>", line 2, in <module>
ImportError: No module named 'win32com'
Traceback (most recent call last):
  File "<string>", line 2, in <module>
ImportError: No module named 'win32com'
Traceback (most recent call last):
  File "<string>", line 2, in <module>
ImportError: No module named 'win32com'
13072 WARNING:   Removing import enchant from module enchant.tests
[INFO   ] [Logger      ] Record log in /home/jason/.kivy/logs/kivy_17-08-01_42.txt
[INFO   ] [Kivy        ] v1.10.0
[INFO   ] [Python      ] v3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118]
[INFO   ] [AudioGstplayer] Using Gstreamer 1.10.4.0
[INFO   ] [Audio       ] Providers: audio_gstplayer, audio_sdl2 (audio_ffpyplayer ignored)
[INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO   ] [Camera      ] Provider: opencv
xclip version 0.12
Copyright (C) 2001-2008 Kim Saunders et al.
Distributed under the terms of the GNU GPL
[INFO   ] [Clipboard   ] Provider: xclip(['clipboard_dbusklipper', 'clipboard_gtk3'] ignored)
[INFO   ] [CutBuffer   ] cut buffer support enabled
[INFO   ] [Factory     ] 194 symbols loaded
[INFO   ] [OSC         ] using <multiprocessing> for socket
[INFO   ] [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
[INFO   ] [GL          ] Using the "OpenGL" graphics system
[INFO   ] [GL          ] Backend used <gl>
[INFO   ] [GL          ] OpenGL version <b'3.0 Mesa 17.0.3'>
[INFO   ] [GL          ] OpenGL vendor <b'Intel Open Source Technology Center'>
[INFO   ] [GL          ] OpenGL renderer <b'Mesa DRI Intel(R) Sandybridge Mobile '>
[INFO   ] [GL          ] OpenGL parsed version: 3, 0
[INFO   ] [GL          ] Shading version <b'1.30'>
[INFO   ] [GL          ] Texture max size <8192>
[INFO   ] [GL          ] Texture max units <16>
[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [Spelling    ] Provider: enchant
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [VideoGstplayer] Using Gstreamer 1.10.4.0
[INFO   ] [Video       ] Provider: gstplayer
17408 WARNING:   Removing import kivy.support from module twisted
20687 WARNING: library libc.dylib required via ctypes not found
Excluding system libraries
Your exe will depend on the following packages:
set()

Again, running the resultant "dist/omission" does nothing. At all.

ZenCODE

unread,
Aug 2, 2017, 2:16:14 AM8/2/17
to kivy-...@googlegroups.com
This may seem obvious/silly, but do you have a main.py?

Jason McDonald

unread,
Aug 2, 2017, 11:51:29 AM8/2/17
to kivy-...@googlegroups.com
Haha, yes, or specifically __main__.py. Take a look at the linked repository. 

Jason C. McDonald
Check out my scribblings at www.indeliblebluepen.com

On Aug 1, 2017, at 23:16, ZenCODE <zenkey....@gmail.com> wrote:

This may seem obvious/silly, but do you have  main.py?

--
You received this message because you are subscribed to a topic in the Google Groups "Kivy users support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/kivy-users/fM9h9BGvcdY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to kivy-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ZenCODE

unread,
Aug 2, 2017, 10:47:59 PM8/2/17
to Kivy users support
Interesting :-). Involved in education myself. But we can follow up in a more personal channel. To make it clear and resolve-able by others, is it safe to say your issue is resolved? We need a main.py! :-)

Jason McDonald

unread,
Aug 2, 2017, 10:52:49 PM8/2/17
to kivy-...@googlegroups.com
NO, it is not resolved. You misunderstand me entirely. I asked you to see the the linked repository, because `__main__.py` is there. I was on my phone at the time, and unable to post it. I have re-posted it here, now that I'm at a desktop, although it would still be wiser to look at the repository to see the entire structure in context.

omission/__main__.py

from omission import run


def main():
   
"""
    Main function.
    """

    run
.run()


if __name__ == '__main__':
    main
()


omission/run.py

from omission.interface.window import OmissionApp

def run():
   
"""
    Run Omission
    """

    app
= OmissionApp()
    app
.run()



ZenCODE

unread,
Aug 4, 2017, 7:43:34 AM8/4/17
to Kivy users support
That shows "__main__.py", not "main.py". Kivy needs a main.py for launching.

Bill Janssen

unread,
Aug 7, 2017, 2:47:15 PM8/7/17
to Kivy users support
Do you mean PyInstaller needs a main.py for launching?  Kivy programs seem to work quite well without one, if you launch from the command-line.

Bill
Reply all
Reply to author
Forward
0 new messages