Pregunta

I'm working on building a standalone executable for a simple tool I built that uses Basemap. (Using Python 2.7, using the dev version of PyInstaller - 2.1). The .exe (single file) builds just fine, but when it runs, I get the following error:

Traceback <most recent call last>:
  File "<string>", line 9, in <module>
  File "c:\python27\lib\site-packages\PyInstaller-2.1dev_-py2.7.egg\PyInstaller\loader\pyi_importers.py", line 270, in load_module
    exec<bytecode, module.__dict>
  File "C:\Documents and Settings\MYNAME\Python code\Flood\src\root\nested\build\FloodRisk\out00-PYZ.pyz\mpl_toolkits.basemap", line 30, in <module>
  File "c:\python27\lib\site-packages\PyInstaller-2.1dev_-py2.7.egg\PyInstaller\loader\pyi_importers.py", in load_module
    exec<bytecode, module.__dict__>
  File "C:\Documents and Settings\MYNAME\My Documents\Python code\Flood\src\root\nested\build\FloodRisk\out00-PYZ.pyz\mpl_toolkits.basemap.pyproj", line 242, in <module>
IOError: proj data directory not found. Expecting it at: C:\DOCUME~1\MYNAME\LOCALS~1\Temp\_MEI68362\mpl_toolkits\basemap\data

Anyone have any luck getting Basemap to load properly into a single .exe file built using PyInstaller? I'm building using a very simple batch file:

C:\Python27\python.exe "C:\Python27\Lib\site-packages\pyinstaller-develop\PyInstaller\main.py" --onefile "C:\Documents and Settings\MYNAME\My Documents\Python code\Flood\src\root\nested\FloodRisk.py"
pause

Thanks!

¿Fue útil?

Solución

Took me a few days, but I think I sorted it from piecing together a few partial solutions:

From http://www.jontrinder.com/blog/?paged=2 :

In pyproj.py, found in C:...\Lib\site-packages\mpl_toolkits\basemap Just past the huge lists is a line that looks something like

pyproj_datadir = os.sep.join([os.path.dirname(__file__), 'data'])

Replace that with

if 'PROJ_DIR' in os.environ:
    pyproj_datadir = os.environ['PROJ_DIR']
else:
    pyproj_datadir = os.sep.join([os.path.dirname(__file__), 'data'])

The piece that was missing from the linked solution was then adding the data path when actually running PyInstaller with --paths

C:\Python27\python.exe "C:\Python27\Lib\site-packages\pyinstaller-develop\PyInstaller\main.py" --onefile --paths="C:\Python27\Lib\site-packages\mpl_toolkits\*" "C:\Documents and Settings\KAHERE\My Documents\Python code\Flood\src\root\nested\FloodRisk.py"
pause

Just thought I'd post in case anyone else was banging their head on this one.

Otros consejos

All you need to do is tell PyInstaller to add the basemap data to the distribution. Here is some sample code. Assuming that you have an ortho.py file in directory E:\scratch, put the following ortho.spec in the same directory and run it as

PyInstaller -y ortho.spec

Here is ortho.spec:

a = Analysis(['ortho.py'],
             pathex=['E:\\scratch'],
             hiddenimports=[],
             hookspath=None,
             runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='ortho.exe',
          debug=False,
          strip=None,
          upx=True,
          console=True )

import mpl_toolkits.basemap
import os

src_basedata = os.path.join(mpl_toolkits.basemap.__path__[0], "data")
tgt_basedata = os.path.join('mpl_toolkits', 'basemap', 'data')

coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas + Tree(src_basedata, prefix=tgt_basedata),
               strip=None,
               upx=True,
               name='ortho')
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top