1

I have a script written in python 3.5 that uses osgeo gdal (1.11) to extract maps and file info from geotiff files. I would like to compile this code to create a standalone app on windows, and I use pyinstaller (3.2) for this.

The code compiles but does not run, i get the following runtime error:

File "site-packages\osgeo\__init__.py", line 15, in swig_import_helper
File "imp.py", line 296, in find_module    
ImportError: No module named '_gdal' 

this is from compiling test1.py, which has a single line:

from osgeo import gdal

with

pyinstaller.exe --onefile --debug test1.py

and running the resulting test1.exe.

[other tests, not importing gdal, compile and run fine].

It seems there are problems importing osgeo libraries when compiling using pyinstaller and py2exe.

I have seen this question: Working Windows Standalone .EXE From QGIS Python Script Using PyInstaller? and i guess it is related but because it is specific to a qgis environment i do not know how to adapt the solution to my problem.

I have also seen there is a pyinstaller hook for osgeo libraries: https://github.com/pyinstaller/pyinstaller/issues/1522, and https://trac.osgeo.org/gdal/ticket/6364, and i checked i've got this hook in my pyinstaller folder, but it does not solve the import problem for me.

I have also posted to the pyinstaller mailing list but obtained no answer.

How can I obtain a working executable from a standard python script which imports GDAL ?

  • Gdal library is not qgis specific, it is provided by gdal***.dll. I don't know the specifics of pyinstaller because I've never used it, but I think you will have to bundle the gdal****.dll. – caiohamamura Jul 26 '16 at 22:56
  • thanks, i've done been discussing this on the pysintaller github: github.com/pyinstaller/pyinstaller/issues/1522 , but still confused about how to fix it – Véro Jul 29 '16 at 16:11
  • I've found a workaround / hack to make the executable work: simply commenting out the file osgeo\__init__.py and write __version__ = '[your gdal version number, e.g. 1.11.4]' instead. this works because the only task of the file osgeo\__init__.py is to set the osgeo version with the same number as the gdal version. then all other osgeo and gdal functions run normally. – Véro Jul 29 '16 at 16:15
  • You should convert your comment to an answer – nmtoken Sep 18 '16 at 9:10
  • ok, I have added it, it is really just a temporary hack though – Véro Sep 19 '16 at 12:23
1

I'm adding this as an answer because it's a way to make the executable work, but it is really a hack :

comment out everything in the file osgeo\__init__.py and write __version__ = '[your gdal version number, e.g. 1.11.4]' instead.

This works because the only task of the file osgeo\__init__.py is to set the osgeo version with the same number as the gdal version. After doing this all other osgeo and gdal functions still run normally.

  • This method worked for me. Just don't comment out the section of the init file that sets the environment variables GDAL_DATA, etc. – Graham S Apr 9 '18 at 15:32
1

From the link you provided, you will have to specify the gdal***.dll in the setup code. This is from the link you provided.

a = Analysis(['ShapeViewer.py'],
         pathex=['c:\\Users\\Daniel Stephanson\\workspace\\ShapeViewer'],
         binaries=None,
         datas=[('c:/OSGeo4W64/apps/qgis/plugins/*.dll','qgis_plugins')],
         hiddenimports=['PyQt4.QtSql','PyQt4.QtNetwork','PyQt4.QtXml','PyQt4.Qsci'],
         hookspath=None,
         runtime_hooks=None,
         excludes=None,
         win_no_prefer_redirects=None,
         win_private_assemblies=None,
         cipher=block_cipher)

You will have to change:

datas=[('c:/OSGeo4W64/apps/qgis/plugins/*.dll','qgis_plugins')]

To something like:

datas=[('c:/OSGeo4W64/bin/gdal*.dll','gdal')]

I've not tested though.

  • thank you, I've tried this but no luck. it seems the problem may be with a .pyd file not bundled correctly, also there may be other problems with python 3.5, or anaconda, or both. – Véro Jul 29 '16 at 16:09
1

In case you don't want to change any init files in your python installation, alternatively you can just copy the _gdal library which is being loaded by your gdal import to your dist directory created by PyInstaller. You can automate this in a setup script with the lines:

import imp
import shutil
from osgeo import gdal
fp, pathname, description = imp.find_module('_gdal', [dirname(gdal.__file__)])

# now pathname contains the _gdal file which is being import by osgeo.gdal which is in my case:
# 'C:\\Apps\\Anaconda\\Anaconda3\\lib\\site-packages\\osgeo\\_gdal.cp35-win_amd64.pyd'
# copy this file to your dist folder using shutil
dist_dir = "dist"
shutil.copy(pathname, dist_dir)

This approach works for me using python 3.5.3 and gdal 2.2.0

1

I encountered the same issue for a script importing ogr, and was able to compile a working exe by adding the path to GDAL in the pyinstaller command:

C:\Python36\Scripts\pyinstaller.exe --onefile --windowed -p C:\Python36\Lib\site-packages\osgeo python_script.pyw

This is under Python 3.6.1, with GDAL 2.1.3 (all 64-bit), with pyinstaller 3.4.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.