Using Pymunk with Pyinstaller

2019-08-27 23:25发布

问题:

I have literally found nothing googling that could help. Even for py2exe but I would like to use pyinstaller.

My problem is the module (pymunk[aka Chipmunk]) is not fully included in the exe build. It is probably missing some kind of dll. Basically its missing a dependency I don't know how to solve.

Failed to load pymunk library.

This error usually means that you don't have a compiled version of chipmunk in
the correct spot where pymunk can find it. pymunk does not include precompiled
chipmunk library files for all platforms.

The good news is that it is usually enough (at least on *nix and OS X) to
simply run the compile command first before installing and then retry again:

You compile chipmunk with
> python setup.py build_chipmunk
and then continue as usual with
> python setup.py install
> cd examples
> python basic_test.py

(for complete instructions please see the readme file)

If it still doesnt work, please report as a bug on the issue tracker at
http://code.google.com/p/pymunk/issues
Remember to include information about your OS, which version of python you use
and the version of pymunk you tried to run. A description of what you did to
trigger the error is also good. Please include the exception traceback if any
(usually found below this message).

Traceback (most recent call last):
  File "<string>", line 2, in <module>
  File "C:\python26\lib\site-packages\PyInstaller\loader\iu.py", line 386, in importHook
    mod = _self_doimport(nm, ctx, fqname)
  File "C:\python26\lib\site-packages\PyInstaller\loader\iu.py", line 480, in doimport
    exec co in mod.__dict__
  File ".\build\pyi.win32\CollisionUtil\out00-PYZ.pyz\pymunk", line 53, in <module>
  File "C:\python26\lib\site-packages\PyInstaller\loader\iu.py", line 431, in importHook
    mod = self.doimport(nm, ctx, ctx + '.' + nm)
  File "C:\python26\lib\site-packages\PyInstaller\loader\iu.py", line 480, in doimport
    exec co in mod.__dict__
  File ".\build\pyi.win32\CollisionUtil\out00-PYZ.pyz\pymunk._chipmunk", line 14, in <module>
  File ".\build\pyi.win32\CollisionUtil\out00-PYZ.pyz\pymunk.libload", line 68, in load_library
  File ".\build\pyi.win32\CollisionUtil\out00-PYZ.pyz\ctypes", line 431, in LoadLibrary
  File ".\build\pyi.win32\CollisionUtil\out00-PYZ.pyz\ctypes", line 353, in __init__
WindowsError: [Error 126] The specified module could not be found

The Chipmunk Library was wrapped via the ctypes module so as far as these messages go from Chipmunk it's assuming it's being compiled. Which doesn't help me in a Python standpoint. Maybe not.

Can anyone tell me how to fix this dependency for pyinstaller?

回答1:

You need to include the chipmunk.dll file (and if you want to run it on osx the .dylib file, and for linux the .so files). One quick hacky option is to just manually copy it to where your generated .exe file is located. The other option is to get pyinstaller to include it for you. I am no expert of pyinstaller, but one way to do it is to edit the .spec file that pyinstaller creates.

Something like:

import os, pymunk
pymunk_dir = os.path.dirname(pymunk.__file__)
chipmunk_libs = [
    ('chipmunk.dll', os.path.join(pymunk_dir, 'chipmunk.dll'), 'DATA'),
]
#... 
coll = COLLECT(exe,
               a.binaries + chipmunk_libs,
               a.zipfiles,
               a.datas,
               strip=None,
               upx=True,
               name=os.path.join('dist', 'basic_test'))

I created a full example and committed it to pymunk trunk. Take a look at https://github.com/viblo/pymunk/blob/master/examples/pyinstaller_basic_test.spec (Note that this example have a little bit of path hackery in the start where it does sys.path.insert(0,'..'). Given that your program already can find pymunk and you put the spec file in the same place you will not need that part.