ronaldoussoren / py2app

py2app is a Python setuptools command which will allow you to make standalone Mac OS X application bundles and plugins from Python scripts.
Other
343 stars 36 forks source link

Distributed app bundle fails to execute #225

Open ronaldoussoren opened 7 years ago

ronaldoussoren commented 7 years ago

Original report by dbpodrasky (Bitbucket: dbpodrasky, GitHub: dbpodrasky).


I'm trying to develop a GUI with wxPython. All seems to go fine during development and testing, but when the app is distributed to other machines it terminates immediately with an error window.

Building on OS 10.12.3, distributing to 10.11. Running Python 2.7.13, wxPython 3.0.2.0, py2app 0.12

Do I need to amend my setup.py file (below)??

#!python

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ['wxtest.py']
DATA_FILES = []
OPTIONS = {}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

Running from terminal, I receive the following:

#!bash

Last login: Tue May  9 08:45:14 on ttys000
Sunburst-iMac:~ sunburst$ Sunburst/Software\ Development/IOOS/Client/wxtest.app/Contents/MacOS/wxtest
Traceback (most recent call last):
  File "/Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/Resources/__boot__.py", line 133, in <module>
    _run()
  File "/Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/Resources/__boot__.py", line 66, in _run
    exec(compile(source, path, 'exec'), globals(), globals())
  File "/Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/Resources/wxtest.py", line 8, in <module>
    import wx
  File "wx/__init__.pyc", line 45, in <module>
  File "wx/_core.pyc", line 4, in <module>
  File "wx/_core_.pyc", line 14, in <module>
  File "wx/_core_.pyc", line 10, in __load
ImportError: dlopen(/Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_core_.so, 2): Symbol not found: _clock_gettime
  Referenced from: /Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/MacOS/../Frameworks/liblzma.5.dylib (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib
 in /Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/MacOS/../Frameworks/liblzma.5.dylib
2017-05-09 09:54:46.500 wxtest[76637:5020059] wxtest Error
Sunburst-iMac:~ sunburst$ 

The following test code demonstrates the problem:

#!python

import wx

class simpleapp_wx(wx.Frame):
    def __init__(self,parent,id,title):
        wx.Frame.__init__(self,parent,id,title)
        self.parent = parent
        self.initialize()

    def initialize(self):
        sizer = wx.GridBagSizer()

        self.entry = wx.TextCtrl(self,-1,value=u"Enter text here.")
        sizer.Add(self.entry,(0,0),(1,1),wx.EXPAND)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnPressEnter, self.entry)

        button = wx.Button(self,-1,label="Click me !")
        sizer.Add(button, (0,1))
        self.Bind(wx.EVT_BUTTON, self.OnButtonClick, button)

        self.label = wx.StaticText(self,-1,label=u'Hello !')
        self.label.SetBackgroundColour(wx.BLUE)
        self.label.SetForegroundColour(wx.WHITE)
        sizer.Add( self.label, (1,0),(1,2), wx.EXPAND )

        sizer.AddGrowableCol(0)
        self.SetSizerAndFit(sizer)
        self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y );
        self.entry.SetFocus()
        self.entry.SetSelection(-1,-1)
        self.Show(True)

    def OnButtonClick(self,event):
        self.label.SetLabel( self.entry.GetValue() + " (You clicked the button)" )
        self.entry.SetFocus()
        self.entry.SetSelection(-1,-1)

    def OnPressEnter(self,event):
        self.label.SetLabel( self.entry.GetValue() + " (You pressed ENTER)" )
        self.entry.SetFocus()
        self.entry.SetSelection(-1,-1)

if __name__ == "__main__":
    app = wx.App()
    frame = simpleapp_wx(None,-1,'my application')
    app.MainLoop()

Thanks for any help.

ronaldoussoren commented 7 years ago

Original comment by Ronald Oussoren (Bitbucket: ronaldoussoren, GitHub: ronaldoussoren).


The problem is indicated in this part of the error output:

 dlopen(/Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/Resources/lib/python2.7/lib-dynload/wx/_core_.so, 2): Symbol not found: _clock_gettime
  Referenced from: /Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/MacOS/../Frameworks/liblzma.5.dylib (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib
 in /Users/sunburst/Sunburst/Software Development/IOOS/Client/wxtest.app/Contents/MacOS/../Frameworks/liblzma.5.dylib
2017-05-09 09:54:46.500 wxtest[76637:5020059] wxtest Error

liblzma.5.dylib uses a symbol from libSystem that is present on OSX 10.12, but isn't present on OSX 10.11. This can happen when building binaries on 10.12: most opensource packages use autoconf to detect which APIs are present and unless you're very careful you can end op with binaries that won't run on earlier versions of the OS (even setting MACOSX_DEPLOYMENT_TARGET often does help).

The easiest workaround for this is to build binaries (that is, anything for which you need to use a (C) compiler) on the oldest OSX release you want to support, then deploy those on the rest of the systems. You can still build the application bundle using py2app on macOS 10.12.

It is possible to do all development on the latest macOS release, but that takes a lot of care.

ronaldoussoren commented 7 years ago

Original comment by dbpodrasky (Bitbucket: dbpodrasky, GitHub: dbpodrasky).


Thanks, Ronald. I'll work on this per your advice and post a reply with what worked to the thread on bitbucket.

Best,

Dave

ronaldoussoren commented 7 years ago

Original comment by dbpodrasky (Bitbucket: dbpodrasky, GitHub: dbpodrasky).


The only way I was able to generate a build using py2app that would work on multiple OS versions (both 10.11 and 10.12 subversions) was to build on a machine with 10.11.x version. Not exactly the most sophisticated solution, but at least it generates a viable product.

ronaldoussoren commented 7 years ago

Original comment by Ronald Oussoren (Bitbucket: ronaldoussoren, GitHub: ronaldoussoren).


Great to hear you were able to build a bundle that works fine. There's nothing I can do about this in py2app: it basically collects pre-existing binaries into the app bundle, and the problem is that those binaries didn't work on 10.11.

Btw. How did you install python and the extensions that you use? Do you use homebrew?

Ronald

-- On the road, hence brief.

ronaldoussoren commented 7 years ago

Original comment by dbpodrasky (Bitbucket: dbpodrasky, GitHub: dbpodrasky).


You had previously mentioned building binaries on the oldest OSX version and deploying them to systems with newer releases. Can you point me to resources explaining how this could be done?

The python I use is installed with macports and I use pip for most extensions.