Problem using py2app with the lxml package
Question: I am trying to use 'py2app' to generate a standalone application from some
Python scripts. The Python uses the 'lxml' package, and I've found that I have
to specify this explicitly in the setup.py file that 'py2app' uses. However,
the resulting application program still won't run on machines that haven't had
'lxml' installed.

My Setup.py looks like this:

    
    
    from setuptools import setup
    
    OPTIONS = {'argv_emulation': True, 'packages' : ['lxml']}
    
    setup(app=[MyApp.py],
          data_files=[],
          options={'py2app' : OPTIONS},
          setup_requires=['py2app'])
    

Running the application produces the following output:

    
    
    MyApp Error
    An unexpected error has occurred during execution of the main script
    ImportError: dlopen(/Users/ake/XXXX/XXXX/MyApp.app/Contents/Resources/lib/python2.5/lxml/etree.so, 2): Symbol not found: _xmlSchematronParse
    Referenced from: /Users/ake/XXXX/XXXX/MyApp.app/Contents/Resources/lib/python2.5/lxml/etree.so
    Expected in: dynamic lookup
    

The symbol '_xmlSchematronParse' is from a library called 'libxml2' that
'lxml' depends on. The version that comes preinstalled with Mac OS X isn't up
to date enough for 'lxml', so I had to install version 2.7.2 (in /usr/local).
py2app, for some reason, is linking in the version in
/Developer/SDKs/MacOSX10.3.9.sdk/usr/lib. When I run my application as a
Python script though, the correct version is found. (I checked this just now
by hiding the 2.7.2 version.)

So my question now is, how can I tell py2app where to look for libraries?


Answer: Found it. py2app has a 'frameworks' option to let you specify frameworks, and
also dylibs. My setup.py file now looks like this:

    
    
    from setuptools import setup
    
    DATA_FILES = []
    OPTIONS = {'argv_emulation': True,
               'packages' : ['lxml'],
               'frameworks' : ['/usr/local/libxml2-2.7.2/lib/libxml2.2.7.2.dylib']
              }
    
    setup(app=MyApp.py,
          data_files=DATA_FILES,
          options={'py2app' : OPTIONS},
          setup_requires=['py2app'])
    

and that's fixed it.

Thanks for the suggestions that led me here.

