Skip to content

Instantly share code, notes, and snippets.

@cspanring
Last active April 10, 2025 18:08
Show Gist options
  • Select an option

  • Save cspanring/5680334 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

pip install pygdal

Copy link
Copy Markdown

ghost commented Nov 20, 2016

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

@stas53
Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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

@abhishekmaroon5
Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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

@skyfeature
Copy link
Copy Markdown

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
Copy Markdown

keithfma commented Oct 6, 2018

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

@v67bruno
Copy link
Copy Markdown

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
Copy Markdown

pyeprog commented Feb 18, 2019

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

@jacksonjos
Copy link
Copy Markdown

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

@zackespry
Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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

@samkellerhals
Copy link
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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
Copy Markdown

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