Skip to content

Instantly share code, notes, and snippets.

@cspanring
Last active August 24, 2024 12:07
Show Gist options
  • Save cspanring/5680334 to your computer and use it in GitHub Desktop.
Save cspanring/5680334 to your computer and use it in GitHub Desktop.
Installing GDAL in a Python virtual environment

Installing GDAL in a Python virtual environment

Get gdal development libraries:

$ sudo apt-add-repository ppa:ubuntugis/ubuntugis-unstable
$ sudo apt-get update
$ sudo apt-get install libgdal-dev

Create and activate a virtual environment:

$ virtualenv gdalenv
$ source gdal/bin/activate

Download GDAL:

(gdalenv) $ pip install --no-install GDAL

Specify where the headers are:

(gdalenv) $ cd /path/to/gdalenv/build/GDAL
(gdalenv) $ python setup.py build_ext --include-dirs=/usr/include/gdal/

Install GDAL:

(gdalenv) $ pip install --no-download GDAL

Done.


Source: http://gis.stackexchange.com/questions/28966/python-gdal-package-missing-header-file-when-installing-via-pip

@jphuart
Copy link

jphuart commented Feb 19, 2016

Thanks a lot Christian and Sudipta Basak. I spent a lot of time before falling on this page and finally it works for me either in my virtualenv on Ubuntu 14.04.

@jphuart
Copy link

jphuart commented Feb 19, 2016

Here is my contribution on how to put all this in an ansible role, if this can help someone.


this is a YAML file holding the role tasks for installing GDAL in a virtual environment

  • name: Create venvpy directory
    file: path={{ GDAL_ENV_DIR }} state=directory owner={{ GDAL_OWNER }} group={{ GDAL_GROUP }} mode=0775
  • name: Check that virtualenv is present
    pip: name=virtualenv
  • name: Create the virtualenv directory for python 2.7
    command: virtualenv --python=/usr/bin/python2.7 {{ GDAL_ENV_DIR }} --no-site-packages creates={{ GDAL_ENV_DIR }}
    sudo: no
  • name: Ensure required packages are installed for gdal
    apt: name={{ item }} state=latest update_cache=yes
    with_items:
    • libmysqlclient-dev
    • libgdal-dev
    • libgdal1h
    • libgdal1-dev
  • name: Install libraries in the virtualenv
    sudo: no
    pip: name={{ item }} virtualenv={{ GDAL_ENV_DIR }} extra_args='--global-option=build_ext --global-option="-I/usr/include/gdal/"'
    with_items:
    • gdal==1.11.2

@ungarj
Copy link

ungarj commented Feb 25, 2016

Specifying the GDAL version in pip install worked for me as well.

Thank you so much everyone!

@drnextgis
Copy link

pip install pygdal

Copy link

ghost commented Nov 20, 2016

sudo apt-get install python-gdal
sudo apt-get install gdal-bin

@stas53
Copy link

stas53 commented Jul 14, 2017

bosaks advice worked for me.
However, I had had to do
sudo pip install ...
instead of just
pip install ...
Thanks a lot !
Stanislaw R.

@GertS
Copy link

GertS commented Sep 5, 2017

Thanks @basaks, you've made my day. The latest version of GDAL does not even have a corresponding pygdal version.

@shashi9122
Copy link

During installation of sumo in ubuntu 14.10
sudo apt-get install libgdal-dev libgdal1h
sudo apt-get install libxerces-c2-dev
sudo apt-get install libfox-1.6-dev
not succesful, following problem occurs
The following packages have unmet dependencies:
libfox-1.6-dev : Depends: libjpeg-dev
Depends: libpng12-dev but it is not going to be installed
Depends: zlib1g-dev but it is not going to be installed
Depends: libtiff4-dev but it is not going to be installed
Depends: libxcursor-dev but it is not going to be installed
Depends: libxft-dev but it is not going to be installed
E: Unable to correct problems, you have held broken packages.
plz find out any solution

@eugeneYWang
Copy link

This solution from https://stackoverflow.com/questions/32066828/install-gdal-in-virtualenvwrapper-environment is definitely an no-brainer solution!

Here is my personal experience. On 16.04 LTS with GDAL 2.1.3 from UBUNTUGIS Stable PPA repo, the prerequisite package is only libgdal-dev.

Yes, installing GDAL in a venv is a doozy. Conveniently, I just wrote up the documentation on how to do so for my advisor's lab! While I am not savvy enough to pinpoint the exact cause of your error, I can give you a bunch of things to try to fix it.

First, ensure you have gdal installed on the host (i.e. not in a venv). I just run the following:

sudo apt-get install libgdal1i libgdal1-dev libgdal-dev
Now run gdal-config --version to get the version that apt-get provided you with. For example I get 1.11.3

Now, the easiest way in my experience to get the python bindings in a venv is using pygdal. The trick is to get the right version! To do so, activate your virtual environment and run

pip install pygdal==1.11.3
but replace the version with whatever you got from gdal-config --version. Note: you may get an error that says

Could not find a version that satisfies the requirement pygdal==1.11.3 (from versions: 1.8.1.0, 1.8.1.1, 1.8.1.2, 1.8.1.3, 1.9.2.0, 1.9.2.1, 1.9.2.3, 1.10.0.0, 1.10.0.1, 1.10.0.3, 1.10.1.0, 1.10.1.1, 1.10.1.3, 1.11.0.0, 1.11.0.1, 1.11.0.3, 1.11.1.0, 1.11.1.1, 1.11.1.3, 1.11.2.1, 1.11.2.3, 1.11.3.3, 1.11.4.3, 2.1.0.3) No matching distribution found for pygdal==1.11.3
If that happens, run the pip install again but with the highest version that still matches. e.g. in this case you would run pip install pygdal==1.11.3.3
...

@abhijayQuantela
Copy link

When I ran:

python setup.py build_ext --include-dirs=/usr/include/gdal/

I got the following error:

x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -fno-strict-aliasing -I /usr/local/lib/python3.5/dist-packages/numpy/core/include -fPIC -I/usr/include/gdal/ -I/usr/include/python2.7 -I/home/ubuntu/.virtualenvs/video-analytics-2/local/lib/python2.7/site-packages/numpy/core/include -I/usr/local/include -c gdal_python_cxx11_test.cpp -o gdal_python_cxx11_test.o
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -fno-strict-aliasing -I /usr/local/lib/python3.5/dist-packages/numpy/core/include -fPIC -I/usr/include/gdal/ -I/usr/include/python2.7 -I/home/ubuntu/.virtualenvs/video-analytics-2/local/lib/python2.7/site-packages/numpy/core/include -I/usr/local/include -c gdal_python_cxx11_test.cpp -o gdal_python_cxx11_test.o -std=c++11
building 'osgeo._gdal' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -fno-strict-aliasing -I /usr/local/lib/python3.5/dist-packages/numpy/core/include -fPIC -I/usr/include/gdal/ -I/usr/include/python2.7 -I/home/ubuntu/.virtualenvs/video-analytics-2/local/lib/python2.7/site-packages/numpy/core/include -I/usr/local/include -c extensions/gdal_wrap.cpp -o build/temp.linux-x86_64-2.7/extensions/gdal_wrap.o -std=c++11 -I/usr/local/include
extensions/gdal_wrap.cpp: In function ‘retStringAndCPLFree* wrapper_VSIGetSignedURL(const char*, char**)’:
extensions/gdal_wrap.cpp:4067:48: error: ‘VSIGetSignedURL’ was not declared in this scope
     return VSIGetSignedURL( utf8_path, options );
                                                ^
extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_GetErrorCounter(PyObject*, PyObject*)’:
extensions/gdal_wrap.cpp:7465:33: error: ‘CPLGetErrorCounter’ was not declared in this scope
     result = CPLGetErrorCounter();
                                 ^
extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_MkdirRecursive(PyObject*, PyObject*)’:
extensions/gdal_wrap.cpp:8553:57: error: ‘VSIMkdirRecursive’ was not declared in this scope
       result = VSIMkdirRecursive((char const *)arg1,arg2);
                                                         ^
extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_RmdirRecursive(PyObject*, PyObject*)’:
extensions/gdal_wrap.cpp:8623:52: error: ‘VSIRmdirRecursive’ was not declared in this scope
       result = VSIRmdirRecursive((char const *)arg1);
                                                    ^
extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_GetActualURL(PyObject*, PyObject*)’:
extensions/gdal_wrap.cpp:8788:58: error: ‘VSIGetActualURL’ was not declared in this scope
       result = (char *)VSIGetActualURL((char const *)arg1);
                                                          ^
extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_GetFileSystemsPrefixes(PyObject*, PyObject*)’:
extensions/gdal_wrap.cpp:8962:51: error: ‘VSIGetFileSystemsPrefixes’ was not declared in this scope
       result = (char **)VSIGetFileSystemsPrefixes();
                                                   ^
extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_GetFileSystemOptions(PyObject*, PyObject*)’:
extensions/gdal_wrap.cpp:9026:66: error: ‘VSIGetFileSystemOptions’ was not declared in this scope
       result = (char *)VSIGetFileSystemOptions((char const *)arg1);
                                                                  ^
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

@denadai2
Copy link

@abhijayQuantela be careful to install the same version you installed in your system

@abhishekmaroon5
Copy link

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-unlz6509/gdal/

can someone please help me with this error while using command
pip install gdal==1.11.2 --global-option=build_ext --global-option="-I/usr/include/gdal/"

@akshmakov
Copy link

akshmakov commented Jul 27, 2018

Some of the commands have been deprecated, namely --no-install (See: https://stackoverflow.com/questions/33207374/no-such-option-no-install)

However, this can be still done in one line with only pip, The missing link is incorrect include flags for the build step but it seems the --include-dirs alone is not always sufficient.

CFLAGS="-I /usr/include/gdal" CXXFLAGS="-I /usr/include/gdal" pip install GDAL==your.system.gdal.version

To determine installed GDAL, simply ask apt apt show gdal-dev and use the same version. Tested with GDAL-2.2.2 in ubuntugis-unstable

@prhbrt
Copy link

prhbrt commented Aug 29, 2018

@abhijayQuantela I had the same issue and found this to work

optional: install the newest version of gdal-bin and libgdal-dev:

sudo add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable
sudo apt update
sudo apt upgrade
sudo apt install gdal-bin libgdal-dev

My gdal version was 2.2.3, so mayve specifically install that one if this does not work.

required: install using pip3:

pip install --global-option=build_ext --global-option="-I/usr/include/gdal" GDAL==`gdal-config --version`

@fitoprincipe
Copy link

Thank you @prinsherbert! It was the only solution that worked for me

@skyfeature
Copy link

This solution from https://stackoverflow.com/questions/32066828/install-gdal-in-virtualenvwrapper-environment is definitely an no-brainer solution!

Here is my personal experience. On 16.04 LTS with GDAL 2.1.3 from UBUNTUGIS Stable PPA repo, the prerequisite package is only libgdal-dev.

Yes, installing GDAL in a venv is a doozy. Conveniently, I just wrote up the documentation on how to do so for my advisor's lab! While I am not savvy enough to pinpoint the exact cause of your error, I can give you a bunch of things to try to fix it.

First, ensure you have gdal installed on the host (i.e. not in a venv). I just run the following:

sudo apt-get install libgdal1i libgdal1-dev libgdal-dev
Now run gdal-config --version to get the version that apt-get provided you with. For example I get 1.11.3

Now, the easiest way in my experience to get the python bindings in a venv is using pygdal. The trick is to get the right version! To do so, activate your virtual environment and run

pip install pygdal==1.11.3
but replace the version with whatever you got from gdal-config --version. Note: you may get an error that says

Could not find a version that satisfies the requirement pygdal==1.11.3 (from versions: 1.8.1.0, 1.8.1.1, 1.8.1.2, 1.8.1.3, 1.9.2.0, 1.9.2.1, 1.9.2.3, 1.10.0.0, 1.10.0.1, 1.10.0.3, 1.10.1.0, 1.10.1.1, 1.10.1.3, 1.11.0.0, 1.11.0.1, 1.11.0.3, 1.11.1.0, 1.11.1.1, 1.11.1.3, 1.11.2.1, 1.11.2.3, 1.11.3.3, 1.11.4.3, 2.1.0.3) No matching distribution found for pygdal==1.11.3
If that happens, run the pip install again but with the highest version that still matches. e.g. in this case you would run pip install pygdal==1.11.3.3
...

I can confirm that this is working on ubuntu18.04.
Only change I did was instead of running sudo apt-get install libgdal1i libgdal1-dev libgdal-dev , I only installed libgdal-dev.

@keithfma
Copy link

keithfma commented Oct 6, 2018

@basaks solution worked for me on Ubuntu 18.04 -- thank you for curing this headache!

@v67bruno
Copy link

v67bruno commented Oct 24, 2018

For the error bellow, i solved adding GDAL lib (gdal-config --libs) and include (gdal-config --cflags) files path: --global-option="-I/usr/include/gdal -L/usr/local/lib -lgdal"

sudo add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable
sudo apt update
sudo apt upgrade
sudo apt install gdal-bin libgdal-dev libgdal1i
python -m pip install GDAL==$(gdal-config --version) --global-option=build_ext --global-option="-I/usr/include/gdal -L/usr/local/lib -lgdal"
extensions/gdal_wrap.cpp: In function ‘retStringAndCPLFree* wrapper_VSIGetSignedURL(const char*, char**)’:
    extensions/gdal_wrap.cpp:4067:48: error: ‘VSIGetSignedURL’ was not declared in this scope
         return VSIGetSignedURL( utf8_path, options );
                                                    ^
    extensions/gdal_wrap.cpp: In function ‘void GDALDatasetShadow_ResetReading(GDALDatasetShadow*)’:
    extensions/gdal_wrap.cpp:4895:35: error: ‘GDALDatasetResetReading’ was not declared in this scope
         GDALDatasetResetReading( self );
                                       ^
    extensions/gdal_wrap.cpp: In function ‘OGRFeatureShadow* GDALDatasetShadow_GetNextFeature(GDALDatasetShadow*, bool, bool, OGRLayerShadow**, double*, GDALProgressFunc, void*)’:
    extensions/gdal_wrap.cpp:4913:63: error: ‘GDALDatasetGetNextFeature’ was not declared in this scope
                                           callback, callback_data );
                                                                   ^
    extensions/gdal_wrap.cpp: In function ‘void GDALRasterBandShadow_GetActualBlockSize(GDALRasterBandShadow*, int, int, int*, int*, int*)’:
    extensions/gdal_wrap.cpp:5140:89: error: ‘GDALGetActualBlockSize’ was not declared in this scope
         *pisvalid = (GDALGetActualBlockSize(self, nXBlockOff, nYBlockOff, pnxvalid, pnyvalid) == CE_None);
                                                                                             ^
    extensions/gdal_wrap.cpp: In function ‘int GDALRasterBandShadow_GetDataCoverageStatus(GDALRasterBandShadow*, int, int, int, int, int, double*)’:
    extensions/gdal_wrap.cpp:5370:52: error: ‘GDALGetDataCoverageStatus’ was not declared in this scope
                                              pdfDataPct);
                                                        ^
    extensions/gdal_wrap.cpp: In function ‘GDALDatasetShadow* ApplyVerticalShiftGrid(GDALDatasetShadow*, GDALDatasetShadow*, bool, double, double, char**)’:
    extensions/gdal_wrap.cpp:6058:63: error: ‘GDALApplyVerticalShiftGrid’ was not declared in this scope
                                                           options );
                                                                   ^
    extensions/gdal_wrap.cpp: In function ‘GDALDriverShadow* IdentifyDriverEx(const char*, unsigned int, char**, char**)’:
    extensions/gdal_wrap.cpp:6268:63: error: ‘GDALIdentifyDriverEx’ was not declared in this scope
                                                     sibling_files );
                                                                   ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_GetErrorCounter(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:7465:33: error: ‘CPLGetErrorCounter’ was not declared in this scope
         result = CPLGetErrorCounter();
                                     ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_MkdirRecursive(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:8553:57: error: ‘VSIMkdirRecursive’ was not declared in this scope
           result = VSIMkdirRecursive((char const *)arg1,arg2);
                                                             ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_RmdirRecursive(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:8623:52: error: ‘VSIRmdirRecursive’ was not declared in this scope
           result = VSIRmdirRecursive((char const *)arg1);
                                                        ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_GetActualURL(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:8788:58: error: ‘VSIGetActualURL’ was not declared in this scope
           result = (char *)VSIGetActualURL((char const *)arg1);
                                                              ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_GetFileSystemsPrefixes(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:8962:51: error: ‘VSIGetFileSystemsPrefixes’ was not declared in this scope
           result = (char **)VSIGetFileSystemsPrefixes();
                                                       ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_GetFileSystemOptions(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:9026:66: error: ‘VSIGetFileSystemOptions’ was not declared in this scope
           result = (char *)VSIGetFileSystemOptions((char const *)arg1);
                                                                      ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_VSISupportsSparseFiles(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:9833:62: error: ‘VSISupportsSparseFiles’ was not declared in this scope
           result = (int)VSISupportsSparseFiles((char const *)arg1);
                                                                  ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_VSIFGetRangeStatusL(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:9937:55: error: ‘VSIFGetRangeStatusL’ was not declared in this scope
           result = (int)VSIFGetRangeStatusL(arg1,arg2,arg3);
                                                           ^
    extensions/gdal_wrap.cpp: In function ‘PyObject* _wrap_VSICurlClearCache(PyObject*, PyObject*)’:
    extensions/gdal_wrap.cpp:10092:25: error: ‘VSICurlClearCache’ was not declared in this scope
           VSICurlClearCache();
                             ^
    error: command 'gcc' failed with exit status 1

@pyeprog
Copy link

pyeprog commented Feb 18, 2019

@basaks made my day too!! thanks a lot basaks

@jacksonjos
Copy link

@basaks I really appreciate your comments.
Helped me a lot! =)

@zackespry
Copy link

zackespry commented Apr 25, 2019

I ran into this issue on OSX High Sierra, trying to install the headers for GDAL 2.2.3 on Python 3.6.5. To resolve it I had to do the following:

$ gdal-config --cflags
which outputted:
-I/Library/Frameworks/GDAL.framework/Versions/2.2/Headers
I then had to use this to set the CFLAG env variable:
$ export CFLAGS='-I/Library/Frameworks/GDAL.framework/Versions/2.2/Headers'

Then installed via pip with flags from the above answers
$ pip install GDAL==$(gdal-config --version) --global-option=build_ext --global-option="-L/Library/Frameworks/GDAL.framework/Versions/2.2/GDAL -I/Library/Frameworks/GDAL.framework/Versions/2.2/GDAL -lgdal"

and it finally installed.

@mssobhan
Copy link

mssobhan commented Sep 4, 2019

Earlier I was getting the following error.

ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/osgeo/_gdal.cpython-37m-darwin.so, 2): Library not loaded: /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib
  Referenced from: /usr/local/opt/gdal/lib/libgdal.20.dylib
  Reason: image not found

for the following import

import gdal

Just create the directory in the desired location

My installation was here...

/usr/local/Cellar/openssl/1.0.2s/

I created a directory at their desired location. openssl directory was not there, I mkdir ed it.

/usr/local/opt/openssl/

Then copied the folder as required. Now

import gdal

works.

@snowman907
Copy link

What is the equivalent procedure to install GDAL API on a virtualenv in Windows?
thanks

@samkellerhals
Copy link

samkellerhals commented Apr 12, 2020

pip install GDAL==$(gdal-config --version) --global-option=build_ext --global-option="-I/usr/include/gdal"

This also just worked for me on Pop OS 19.10.

Thanks @basaks !

@SuperElectron
Copy link

This works:
https://gis.stackexchange.com/questions/28966/python-gdal-package-missing-header-file-when-installing-via-pip/74060#74060?newreg=6b1e677d9dfe4652a3512380e6e73819

sudo apt-get install libgdal-dev

export CPLUS_INCLUDE_PATH=/usr/include/gdal
export C_INCLUDE_PATH=/usr/include/gdal

pip install GDAL==2.4.2
  • use a version with GDAL installation, otherwise you gcc errors.

@raeesaroj
Copy link

raeesaroj commented Jun 1, 2020

I am able to run with this one
pip install --global-option=build_ext --global-option="-I/usr/include/gdal" GDAL==gdal-config --version

@gt-novelt
Copy link

I am able to run with this one
pip install --global-option=build_ext --global-option="-I/usr/include/gdal" GDAL==gdal-config --version

In case the backquote is not obvious:

pip install --global-option=build_ext --global-option="-I/usr/include/gdal" GDAL==`gdal-config --version`

@rafatieppo
Copy link

Thanks @basaks, I just used pip3 instead:

pip3 install GDAL==$(gdal-config --version) --global-option=build_ext --global-option="-I/usr/include/gdal"

@D8989
Copy link

D8989 commented Jun 20, 2021

i use python 3.8 and install gdal 3.0.4 with @rafatieppo solution (but with pip)
pip install GDAL==$(gdal-config --version) --global-option=build_ext --global-option="-I/usr/include/gdal"

PS: Before run pip, i install libgdal-dev with sudo apt install

@ausnet-bwang-zz
Copy link

I had to do

apt-get update
apt-get install libgdal-dev python3.8-dev -y
pip install GDAL==$(gdal-config --version) --global-option=build_ext --global-option="-I/usr/include/gdal" 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment