Repository: spack/spack

Issue:
Installation issue: gdal
### Steps to reproduce the issue

<!-- Fill in the exact spec you are trying to build and the relevant part of the error message -->
```console
$ spack install gdal
...
  >> 232     checking for shared library run path origin... /bin/sh: /var/tmp/d
             ahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mjgdghqy
             zgmctzfvq/spack-src/config.rpath: No such file or directory
     233     done
...
  >> 1666    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_object_get_userdata'
  >> 1667    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_c_object_sizeof'
  >> 1668    collect2: error: ld returned 1 exit status
  >> 1669    make[1]: *** [gdalwarp] Error 1
     1670    make[1]: *** Waiting for unfinished jobs....
  >> 1671    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_object_get_userdata'
  >> 1672    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_c_object_sizeof'
  >> 1673    collect2: error: ld returned 1 exit status
  >> 1674    make[1]: *** [gdalinfo] Error 1
  >> 1675    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_object_get_userdata'
  >> 1676    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_c_object_sizeof'
  >> 1677    collect2: error: ld returned 1 exit status
  >> 1678    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_object_get_userdata'
  >> 1679    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_c_object_sizeof'
  >> 1680    collect2: error: ld returned 1 exit status
  >> 1681    make[1]: *** [gdalmanage] Error 1
  >> 1682    make[1]: *** [nearblack] Error 1
  >> 1683    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_object_get_userdata'
  >> 1684    /tmp/dahlgren/spack-stage/spack-stage-gdal-3.3.0-t26ewxarqcbey74mj
             gdghqyzgmctzfvq/spack-src/.libs/libgdal.so: undefined reference to
              `json_c_object_sizeof'
  >> 1685    collect2: error: ld returned 1 exit status
  >> 1686    make[1]: *** [gdaltransform] Error 1
     1687    make[1]: Leaving directory `/tmp/dahlgren/spack-stage/spack-stage-
             gdal-3.3.0-t26ewxarqcbey74mjgdghqyzgmctzfvq/spack-src/apps'
  >> 1688    make: *** [apps-target] Error 2
...
```

### Information on your system

* **Spack:** 0.16.2-2850-b596abe037
* **Python:** 3.7.2
* **Platform:** linux-rhel7-broadwell
* **Concretizer:** original

### Additional information

[spack-build-env.txt](https://github.com/spack/spack/files/6549896/spack-build-env.txt)
[spack-build-out.txt](https://github.com/spack/spack/files/6549898/spack-build-out.txt)

### General information

- [x] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [x] I have run `spack maintainers <name-of-the-package>` and @mentioned any maintainers
- [x] I have uploaded the build log and environment files
- [x] I have searched the issues of this repo and believe this is not a duplicate



Discussion:
Trying to reproduce this on CentOS 7, build is going to take a while.

Can you check your `json-c` installation and see if it built correctly? Check the library and make sure there are no missing symbols.
I'm able to reproduce this on CentOS 7, will keep debugging and possibly open an issue with the GDAL devs.
I was able to work around this problem by creating a symlink from lib64 --> lib in the json-c (0.15) directory, i.e.

```
cd ./spack/opt/spack/linux-centos7-ivybridge/gcc-7.5.0/json-c-0.15-pgomdivvvpn7tcaysvlxtnw55eucpx7q
ln -s lib64 lib
```

How come GDAL builds works for `json-c@:0.13.1` but not the newer versions. I wonder what has changed
I've got a bugfix for this, it sets the lib directory correctly for the system. Will create a PR now.
See https://github.com/spack/spack/pull/30809

Resolving patch:
diff --git a/var/spack/repos/builtin/packages/gdal/package.py b/var/spack/repos/builtin/packages/gdal/package.py
--- a/var/spack/repos/builtin/packages/gdal/package.py
+++ b/var/spack/repos/builtin/packages/gdal/package.py
@@ -10,13 +10,14 @@
 from spack.util.environment import filter_system_paths
 
 
-class Gdal(AutotoolsPackage):
-    """GDAL (Geospatial Data Abstraction Library) is a translator library for
-    raster and vector geospatial data formats that is released under an X/MIT
-    style Open Source license by the Open Source Geospatial Foundation. As a
-    library, it presents a single raster abstract data model and vector
-    abstract data model to the calling application for all supported formats.
-    It also comes with a variety of useful command line utilities for data
+class Gdal(CMakePackage):
+    """GDAL: Geospatial Data Abstraction Library.
+
+    GDAL is a translator library for raster and vector geospatial data formats that
+    is released under an MIT style Open Source License by the Open Source Geospatial
+    Foundation. As a library, it presents a single raster abstract data model and
+    single vector abstract data model to the calling application for all supported
+    formats. It also comes with a variety of useful command line utilities for data
     translation and processing.
     """
 
@@ -27,6 +28,8 @@ class Gdal(AutotoolsPackage):
 
     maintainers = ['adamjstewart']
 
+    version('3.5.1', sha256='d12c30a9eacdeaab493c0d1c9f88eb337c9cbb5bb40744c751bdd5a5af166ab6')
+    version('3.5.0', sha256='d49121e5348a51659807be4fb866aa840f8dbec4d1acba6d17fdefa72125bfc9')
     version('3.4.3', sha256='02a27b35899e1c4c3bcb6007da900128ddd7e8ab7cd6ccfecf338a301eadad5a')
     version('3.4.2', sha256='16baf03dfccf9e3f72bb2e15cd2d5b3f4be0437cdff8a785bceab0c7be557335')
     version('3.4.1', sha256='332f053516ca45101ef0f7fa96309b64242688a8024780a5d93be0230e42173d')
@@ -49,117 +52,239 @@ class Gdal(AutotoolsPackage):
     version('3.0.2', sha256='c3765371ce391715c8f28bd6defbc70b57aa43341f6e94605f04fe3c92468983')
     version('3.0.1', sha256='45b4ae25dbd87282d589eca76481c426f72132d7a599556470d5c38263b09266')
     version('3.0.0', sha256='ad316fa052d94d9606e90b20a514b92b2dd64e3142dfdbd8f10981a5fcd5c43e')
-    version('2.4.4', sha256='a383bd3cf555d6e1169666b01b5b3025b2722ed39e834f1b65090f604405dcd8', deprecated=True)
-    version('2.4.3', sha256='d52dc3e0cff3af3e898d887c4151442989f416e839948e73f0994f0224bbff60', deprecated=True)
-    version('2.4.2', sha256='dcc132e469c5eb76fa4aaff238d32e45a5d947dc5b6c801a123b70045b618e0c', deprecated=True)
-    version('2.4.1', sha256='fd51b4900b2fc49b98d8714f55fc8a78ebfd07218357f93fb796791115a5a1ad', deprecated=True)
-    version('2.4.0', sha256='c3791dcc6d37e59f6efa86e2df2a55a4485237b0a48e330ae08949f0cdf00f27', deprecated=True)
-    version('2.3.3', sha256='c3635e41766a648f945d235b922e3c5306e26a2ee5bbd730d2181e242f5f46fe', deprecated=True)
-    version('2.3.2', sha256='3f6d78fe8807d1d6afb7bed27394f19467840a82bc36d65e66316fa0aa9d32a4', deprecated=True)
-    version('2.3.1', sha256='9c4625c45a3ee7e49a604ef221778983dd9fd8104922a87f20b99d9bedb7725a', deprecated=True)
-    version('2.3.0', sha256='6f75e49aa30de140525ccb58688667efe3a2d770576feb7fbc91023b7f552aa2', deprecated=True)
-    version('2.1.2', sha256='b597f36bd29a2b4368998ddd32b28c8cdf3c8192237a81b99af83cc17d7fa374', deprecated=True)
-    version('2.0.2', sha256='90f838853cc1c07e55893483faa7e923e4b4b1659c6bc9df3538366030a7e622', deprecated=True)
-    version('1.11.5', sha256='d4fdc3e987b9926545f0a514b4328cd733f2208442f8d03bde630fe1f7eff042', deprecated=True)
-
-    variant('libtool',   default=True,  description='Use libtool to build the library')
-    variant('libz',      default=True,  description='Include libz support')
-    variant('libiconv',  default=False, description='Include libiconv support')
-    variant('liblzma',   default=True,  description='Include liblzma support')
-    variant('pg',        default=False, description='Include PostgreSQL support')
-    variant('cfitsio',   default=False, description='Include FITS support')
-    variant('png',       default=False, description='Include PNG support')
-    variant('jpeg',      default=True,  description='Include JPEG support')
-    variant('gif',       default=False, description='Include GIF support')
-    variant('sosi',      default=False, description='Include SOSI support')
-    variant('hdf4',      default=False, description='Include HDF4 support')
-    variant('hdf5',      default=False, description='Include HDF5 support')
-    variant('kea',       default=False, description='Include kealib')
-    variant('netcdf',    default=False, description='Include netCDF support')
-    variant('jasper',    default=False, description='Include JPEG-2000 support via JasPer library', when='@:3.4')
-    variant('openjpeg',  default=False, description='Include JPEG-2000 support via OpenJPEG 2.x library')
-    variant('xerces',    default=False, description='Use Xerces-C++ parser')
-    variant('expat',     default=False, description='Use Expat XML parser')
-    variant('libkml',    default=False, description='Use Google libkml')
-    variant('odbc',      default=False, description='Include ODBC support')
-    variant('curl',      default=False, description='Include curl')
-    variant('xml2',      default=False, description='Include libxml2')
-    variant('sqlite3',   default=False, description='Use SQLite 3 library')
-    variant('pcre2',     default=False, description='Include libpcre2 support', when='@3.4.1:')
-    variant('pcre',      default=False, description='Include libpcre support')
-    variant('geos',      default=False, description='Include GEOS support')
-    variant('qhull',     default=False, description='Include QHull support')
-    variant('opencl',    default=False, description='Include OpenCL (GPU) support')
-    variant('poppler',   default=False, description='Include poppler (for PDF) support')
-    variant('proj',      default=True,  description='Compile with PROJ.x')
-    variant('perl',      default=False, description='Enable perl bindings', when='@:3.4')
-    variant('python',    default=False, description='Enable python bindings')
-    variant('java',      default=False, description='Include Java support')
-    variant('mdb',       default=False, description='Include MDB driver', when='@:3.4 +java')
-    variant('armadillo', default=False, description='Include Armadillo support for faster TPS transform computation')
-    variant('cryptopp',  default=False, description='Include cryptopp support')
-    variant('crypto',    default=False, description='Include crypto (from openssl) support')
-    variant('grib',      default=False, description='Include GRIB support')
+    version('2.4.4', sha256='a383bd3cf555d6e1169666b01b5b3025b2722ed39e834f1b65090f604405dcd8')
+    version('2.4.3', sha256='d52dc3e0cff3af3e898d887c4151442989f416e839948e73f0994f0224bbff60')
+    version('2.4.2', sha256='dcc132e469c5eb76fa4aaff238d32e45a5d947dc5b6c801a123b70045b618e0c')
+    version('2.4.1', sha256='fd51b4900b2fc49b98d8714f55fc8a78ebfd07218357f93fb796791115a5a1ad')
+    version('2.4.0', sha256='c3791dcc6d37e59f6efa86e2df2a55a4485237b0a48e330ae08949f0cdf00f27')
+    version('2.3.3', sha256='c3635e41766a648f945d235b922e3c5306e26a2ee5bbd730d2181e242f5f46fe')
+    version('2.3.2', sha256='3f6d78fe8807d1d6afb7bed27394f19467840a82bc36d65e66316fa0aa9d32a4')
+    version('2.3.1', sha256='9c4625c45a3ee7e49a604ef221778983dd9fd8104922a87f20b99d9bedb7725a')
+    version('2.3.0', sha256='6f75e49aa30de140525ccb58688667efe3a2d770576feb7fbc91023b7f552aa2')
+    version('2.2.4', sha256='441eb1d1acb35238ca43a1a0a649493fc91fdcbab231d0747e9d462eea192278')
+    version('2.2.3', sha256='a328d63d476b3653f5a25b5f7971e87a15cdf8860ab0729d4b1157ba988b8d0b')
+    version('2.2.2', sha256='eb25d6ee85f4f5ac1d5581958f8c6eed9b1d50746f82866fe92e507541def35b')
+    version('2.2.1', sha256='927098d54083ac919a497f787b835b099e9a194f2e5444dbff901f7426b86066')
+    version('2.2.0', sha256='0d4c326862e0f118e17418c042c2bcd037b25abd3fb198e1fc5d40b11a9fc8ea')
+    version('2.1.4', sha256='e06a7ae4c4ed2fd678cd045ff50a10ff5002f3b81cdfcd8ab03c39ce962d9b63')
+    version('2.1.3', sha256='b489793627e6cb8d2ff8d7737b61daf58382fe189fae4c581ddfd48c04b49005')
+    version('2.1.2', sha256='b597f36bd29a2b4368998ddd32b28c8cdf3c8192237a81b99af83cc17d7fa374')
+    version('2.1.1', sha256='87ce516ce757ad1edf1e21f007fbe232ed2e932af422e9893f40199711c41f92')
+    version('2.1.0', sha256='568b43441955b306364fcf97fb47d4c1512ac6f2f5f76b2ec39a890d2418ee03')
+    version('2.0.3', sha256='3c6c5ade299c7a52fc9c5d2111110c97032e1f0c2593ce6091c364b1a43b442a')
+    version('2.0.2', sha256='90f838853cc1c07e55893483faa7e923e4b4b1659c6bc9df3538366030a7e622')
+    version('2.0.1', sha256='2564c91ed8ed36274ee31002a25798f5babc4221e879cb5013867733d80f9920')
+    version('2.0.0', sha256='91704fafeea2349c5e268dc1e2d03921b3aae64b05ee01d59fdfc1a6b0ffc061')
 
-    # FIXME: Allow packages to extend multiple packages
-    # See https://github.com/spack/spack/issues/987
-    # extends('jdk', when='+java')
-    # extends('perl', when='+perl')
-    extends('python', when='+python')
-
-    # GDAL depends on GNUmake on Unix platforms.
-    # https://trac.osgeo.org/gdal/wiki/BuildingOnUnix
-    depends_on('gmake', type='build')
-    depends_on('pkgconfig@0.25:', type='build')
+    # Optional dependencies
+    variant('armadillo', default=False, description='Speed up computations related to the Thin Plate Spline transformer')
+    variant('arrow', default=False, when='@3.5:', description='Required for Arrow driver')
+    variant('blosc', default=False, when='@3.4:', description='Required for Zarr driver')
+    variant('brunsli', default=True, when='@3.4:', description='Required for MRF driver')
+    variant('bsb', default=False, when='@:2', description='Required for BSB driver')
+    variant('cfitsio', default=False, description='Required for FITS driver')
+    variant('crnlib', default=False, description='Required for DDS driver')
+    variant('curl', default=False, description='Required for network access')
+    variant('cryptopp', default=False, when='@2.1:', description='Required for EEDAI driver')
+    variant('deflate', default=False, when='@3.2:', description='Required for Deflate compression')
+    variant('dods', default=False, when='@:3.4', description='Required for DODS driver')
+    variant('ecw', default=False, description='Required for ECW driver')
+    variant('epsilon', default=False, when='@:3.2', description='Required for EPSILON driver')
+    variant('expat', default=True, description='Required for XML parsing in many OGR drivers')
+    variant('filegdb', default=False, description='Required for FileGDB driver')
+    variant('fme', default=False, when='@:3.4', description='Required for FME driver')
+    variant('freexl', default=False, description='Required for XLS driver')
+    variant('fyba', default=False, description='Required for SOSI driver')
+    variant('geos', default=True, description='Required for geometry processing operations in OGR')
+    variant('gif', default=False, description='Required for GIF driver')
+    variant('grass', default=False, when='@:3.4', description='Required for GRASS driver')
+    variant('grib', default=False, when='@:2', description='Required for GRIB driver')
+    variant('gta', default=False, description='Required for GTA driver')
+    variant('heif', default=False, when='@3.2:', description='Required for HEIF driver')
+    variant('hdf4', default=False, description='Required for HDF4 driver')
+    variant('hdf5', default=False, description='Required for HDF5, BAG, and KEA drivers')
+    variant('hdfs', default=False, when='@2.4:', description='Required for Hadoop filesystem support')
+    variant('iconv', default=False, description='Required for text encoding conversion')
+    variant('idb', default=False, description='Required for IDB driver')
+    variant('ingres', default=False, when='@:3.4', description='Required for Ingres driver')
+    variant('jasper', default=False, when='@:3.4', description='Optional JPEG-200 library')
+    variant('jpeg', default=True, description='Required for JPEG driver')
+    variant('jxl', default=False, when='@3.4:', description='Required for JPEGXL driver')
+    variant('kdu', default=False, description='Required for JP2KAK and JPIPKAK drivers')
+    variant('kea', default=False, description='Required for KEA driver')
+    variant('lerc', default=True, when='@2.4:', description='Required for LERC compression')
+    variant('libcsf', default=False, description='Required for PCRaster driver')
+    variant('libkml', default=False, description='Required for LIBKML driver')
+    variant('liblzma', default=False, description='Required for Zarr driver')
+    variant('libxml2', default=False, description='Required for XML validation in many OGR drivers')
+    variant('luratech', default=False, when='@2.2:', description='Required for JP2Lura driver')
+    variant('lz4', default=False, when='@3.4:', description='Required for Zarr driver')
+    variant('mdb', default=False, when='@:3.4', description='Required for MDB driver')
+    variant('mongocxx', default=False, when='@2.1:', description='Required for MongoDBv3 driver')
+    variant('mrf', default=False, when='@2.1:2', description='Required for MRF driver')
+    variant('mrsid', default=False, description='Required for MrSID driver')
+    variant('mrsid_lidar', default=False, when='@:3.4', description='Required for MrSID/MG4 driver')
+    variant('mssql_ncli', default=False, when='@3.5:', description='Required for MSSQLSpatial driver')
+    variant('mssql_odbc', default=False, when='@3.5:', description='Required for MSSQLSpatial driver')
+    variant('mysql', default=False, description='Required for MySQL driver')
+    variant('netcdf', default=False, description='Required for NetCDF driver')
+    variant('odbc', default=False, description='Required for many OGR drivers')
+    variant('odbccpp', default=False, when='@3.5:', description='Required for SAP HANA driver')
+    variant('ogdi', default=False, description='Required for OGDI driver')
+    variant('opencad', default=False, when='@3.5:', description='Required for CAD driver')
+    variant('opencl', default=False, description='Required to accelerate warping computations')
+    variant('openexr', default=False, when='@3.1:', description='Required for EXR driver')
+    variant('openjpeg', default=False, description='Required for JP2OpenJPEG driver')
+    variant('openssl', default=False, when='@2.3:', description='Required for EEDAI driver')
+    variant('oracle', default=False, description='Required for OCI and GeoRaster drivers')
+    variant('parquet', default=False, when='@3.5:', description='Required for Parquet driver')
+    variant('pcidsk', default=False, description='Required for PCIDSK driver')
+    variant('pcre', default=False, description='Required for REGEXP operator in drivers using SQLite3')
+    variant('pdfium', default=False, when='@2.1:', description='Possible backend for PDF driver')
+    variant('png', default=True, description='Required for PNG driver')
+    variant('podofo', default=False, description='Possible backend for PDF driver')
+    variant('poppler', default=False, description='Possible backend for PDF driver')
+    variant('postgresql', default=False, description='Required for PostgreSQL and PostGISRaster drivers')
+    variant('qhull', default=True, when='@2.1:', description='Used for linear interpolation of gdal_grid')
+    variant('rasdaman', default=False, description='Required for Rasdaman driver')
+    variant('rasterlite2', default=False, when='@2.2:', description='Required for RasterLite2 driver')
+    variant('rdb', default=False, when='@3.1:', description='Required for RDB driver')
+    variant('sde', default=False, when='@:3.1', description='Required for SDE driver')
+    variant('sfcgal', default=False, when='@2.2:', description='Provides 3D geometry operations')
+    variant('spatialite', default=False, description='Required for SQLite and GPKG drivers')
+    variant('sqlite3', default=True, description='Required for SQLite and GPKG drivers')
+    variant('teigha', default=False, description='Required for DWG and DGNv8 drivers')
+    variant('tiledb', default=False, when='@3:', description='Required for TileDB driver')
+    variant('webp', default=False, description='Required for WEBP driver')
+    variant('xercesc', default=False, description='Required for XML parsing capabilities in many OGR drivers')
+    variant('zstd', default=False, when='@2.3:', description='Required for Zarr driver')
+
+    # Language bindings
+    variant('python', default=False, description='Build Python bindings')
+    variant('java', default=False, description='Build Java bindings')
+    variant('csharp', default=False, when='@3.5:', description='Build C# bindings')
+    variant('perl', default=False, when='@:3.4', description='Build Perl bindings')
+    variant('php', default=False, when='@:2.3', description='Build PHP bindings')
 
     # Required dependencies
+    depends_on('cmake@3.9:', when='@3.5:', type='build')
+    depends_on('ninja', when='@3.5:', type='build')
+    depends_on('gmake', when='@:3.4', type='build')
+    depends_on('pkgconfig@0.25:', type='build')
+    depends_on('proj@6:', when='@3:')
+    depends_on('proj@:6', when='@2.5:2')
+    depends_on('proj@:5', when='@2.4')
+    depends_on('proj@:4', when='@:2.3')
+    depends_on('zlib')
+    depends_on('libtiff@4:', when='@3:')
     depends_on('libtiff@3.6.0:')  # 3.9.0+ needed to pass testsuite
+    depends_on('libgeotiff@1.5:', when='@3:')
+    depends_on('libgeotiff@1.2.1:1.5', when='@2.4.1:2')
     depends_on('libgeotiff@1.2.1:1.4', when='@:2.4.0')
-    depends_on('libgeotiff@1.2.1:1.5', when='@2.4.1:2.4')
-    depends_on('libgeotiff@1.5:', when='@3.0.0:')
     depends_on('json-c')
     depends_on('json-c@0.12.1', when='@:2.2')
 
     # Optional dependencies
-    depends_on('libtool', type='build', when='+libtool')
-    depends_on('zlib', when='+libz')
-    depends_on('iconv', when='+libiconv')
-    depends_on('xz', when='+liblzma')
-    depends_on('postgresql', when='+pg')
+    depends_on('armadillo', when='+armadillo')
+    depends_on('blas', when='+armadillo')
+    depends_on('lapack', when='+armadillo')
+    depends_on('arrow', when='+arrow')
+    depends_on('c-blosc', when='+blosc')
+    depends_on('brunsli', when='+brunsli')
+    # depends_on('bsb', when='+bdb')
     depends_on('cfitsio', when='+cfitsio')
-    depends_on('libpng', when='+png')
-    depends_on('jpeg', when='+jpeg')
+    # depends_on('crunch', when='+crnlib')
+    depends_on('curl', when='+curl')
+    depends_on('cryptopp', when='+cryptopp')
+    depends_on('libdeflate', when='+deflate')
+    # depends_on('dods', when='+dods')
+    # depends_on('ecw', when='+ecw')
+    # depends_on('libepsilon', when='+epsilon')
+    depends_on('expat@1.95:', when='+expat')
+    # depends_on('filegdb', when='+filegdb')
+    # depends_on('fme', when='+fme')
+    depends_on('freexl', when='+freexl')
+    depends_on('fyba', when='+fyba')
+    depends_on('geos@3.1:', when='+geos')
     depends_on('giflib', when='+gif')
-    depends_on('fyba', when='+sosi')
+    depends_on('grass@5.7:', when='+grass')
+    depends_on('grib-api', when='+grib')
+    # depends_on('gta', when='+gta')
+    # depends_on('heif@1.1:', when='+heif')
     depends_on('hdf', when='+hdf4')
-    depends_on('hdf5', when='+hdf5')
+    depends_on('hdf5+cxx', when='+hdf5')
     depends_on('hdf5@:1.12', when='@:3.4.1 +hdf5')
-    depends_on('kealib', when='+kea @2:')
-    depends_on('netcdf-c', when='+netcdf')
+    depends_on('hadoop', when='+hdfs')
+    depends_on('iconv', when='+iconv')
+    # depends_on('idb', when='+idb')
+    # depends_on('ingres', when='+ingres')
     depends_on('jasper@1.900.1', patches=[patch('uuid.patch')], when='+jasper')
-    depends_on('openjpeg', when='+openjpeg')
-    depends_on('xerces-c', when='+xerces')
-    depends_on('expat', when='+expat')
-    depends_on('libkml@1.3.0:', when='+libkml')
+    depends_on('jpeg', when='+jpeg')
+    # depends_on('libjxl', when='+jxl')
+    # depends_on('kakadu', when='+kdu')
+    depends_on('kealib', when='+kea')
+    depends_on('lerc', when='+lerc')
+    # depends_on('libcsf', when='+libcsf')
+    depends_on('libkml@1.3:', when='+libkml')
+    depends_on('xz', when='+liblzma')
+    depends_on('libxml2', when='+libxml2')
+    # depends_on('luratech', when='+luratech')
+    depends_on('lz4', when='+lz4')
+    depends_on('jackcess@1.2', type='run', when='+mdb')
+    depends_on('mongo-cxx-driver', when='+mongocxx')
+    # depends_on('bsoncxx', when='+mongocxx')
+    # depends_on('mrf', when='+mrf')
+    # depends_on('mrsid', when='+mrsid')
+    # depends_on('lizardtech-lidar', when='+mrsid_lidar')
+    # depends_on('mssql_ncli', when='+mssql_ncli')
+    # depends_on('mssql_odbc', when='+mssql_odbc')
+    depends_on('mysql', when='+mysql')
+    depends_on('netcdf-c', when='+netcdf')
     depends_on('unixodbc', when='+odbc')
-    depends_on('curl@7.10.8:', when='+curl')
-    depends_on('libxml2', when='+xml2')
-    depends_on('sqlite@3:', when='+sqlite3')
-    depends_on('pcre2', when='+pcre2')
-    depends_on('pcre', when='+pcre')
-    depends_on('geos', when='+geos')
-    depends_on('qhull', when='+qhull @2.1:')
+    # depends_on('odbc-cpp-wrapper', when='+odbccpp')
+    # depends_on('ogdi', when='+ogdi')
+    # depends_on('lib-opencad', when='+opencad')
     depends_on('opencl', when='+opencl')
+    depends_on('openexr@2.2:', when='+openexr')
+    depends_on('openjpeg', when='+openjpeg')
+    depends_on('openssl', when='+openssl')
+    depends_on('oracle-instant-client', when='+oracle')
+    depends_on('parquet-cpp', when='+parquet')
+    # depends_on('pcidsk', when='+pcidsk')
+    depends_on('pcre2', when='@3.5:+pcre')
+    depends_on('pcre', when='@:3.4+pcre')
+    # depends_on('pdfium', when='+pdfium')
+    depends_on('libpng', when='+png')
+    # depends_on('podofo', when='+podofo')
     depends_on('poppler', when='+poppler')
     depends_on('poppler@0.24:', when='@3: +poppler')
     depends_on('poppler@:0.63', when='@:2.3 +poppler')
     depends_on('poppler@:0.71', when='@:2.4 +poppler')
     depends_on('poppler@:21', when='@:3.4.1 +poppler')
-    depends_on('proj@:4', when='+proj @2.3.0:2.3')
-    depends_on('proj@:5', when='+proj @2.4.0:2.4')
-    depends_on('proj@:6', when='+proj @2.5:2')
-    depends_on('proj@6:', when='+proj @3:')
-    depends_on('perl', type=('build', 'run'), when='+perl')
+    depends_on('postgresql', when='+postgresql')
+    depends_on('qhull', when='+qhull')
+    depends_on('qhull@2015:', when='@3.5:+qhull')
+    depends_on('qhull@:2020.1', when='@:3.3+qhull')
+    # depends_on('rasdaman', when='+rasdaman')
+    # depends_on('rasterlite2@1.1:', when='+rasterlite2')
+    # depends_on('rdblib', when='+rdb')
+    # depends_on('sde', when='+sde')
+    depends_on('sfcgal', when='+sfcgal')
+    depends_on('libspatialite', when='+spatialite')
+    depends_on('sqlite@3:', when='+sqlite3')
+    # depends_on('teigha', when='+teigha')
+    # depends_on('tiledb', when='+tiledb')
+    depends_on('libwebp', when='+webp')
+    depends_on('xerces-c@3.1:', when='+xercesc')
+    depends_on('zstd', when='+zstd')
+
+    # Language bindings
+    # FIXME: Allow packages to extend multiple packages
+    # See https://github.com/spack/spack/issues/987
+    extends('python', when='+python')
+    # extends('openjdk', when='+java')
+    # extends('perl', when='+perl')
+
     # see gdal_version_and_min_supported_python_version
     # in swig/python/osgeo/__init__.py
     depends_on('python@3.6:', type=('build', 'link', 'run'), when='@3.3:+python')
@@ -169,16 +294,17 @@ class Gdal(AutotoolsPackage):
     depends_on('py-setuptools@:57', type='build', when='@:3.2+python')  # needs 2to3
     depends_on('py-setuptools', type='build', when='+python')
     depends_on('py-numpy@1.0.0:', type=('build', 'run'), when='+python')
+    depends_on('swig', type='build', when='+python')
     depends_on('java@7:', type=('build', 'link', 'run'), when='@3.2:+java')
     depends_on('java@6:', type=('build', 'link', 'run'), when='@2.4:+java')
     depends_on('java@5:', type=('build', 'link', 'run'), when='@2.1:+java')
     depends_on('java@4:', type=('build', 'link', 'run'), when='@:2.0+java')
     depends_on('ant', type='build', when='+java')
     depends_on('swig', type='build', when='+java')
-    depends_on('jackcess@1.2.0:1.2', type='run', when='+mdb')
-    depends_on('armadillo', when='+armadillo')
-    depends_on('cryptopp', when='+cryptopp @2.1:')
-    depends_on('openssl', when='+crypto @2.3:')
+    depends_on('perl', type=('build', 'run'), when='+perl')
+    depends_on('swig', type='build', when='+perl')
+    depends_on('php', type=('build', 'link', 'run'), when='+php')
+    depends_on('swig', type='build', when='+php')
 
     # https://trac.osgeo.org/gdal/wiki/SupportedCompilers
     msg = 'GDAL requires C++11 support'
@@ -188,12 +314,53 @@ class Gdal(AutotoolsPackage):
     conflicts('%xl@:13.0',   msg=msg)
     conflicts('%xl_r@:13.0', msg=msg)
 
-    conflicts('+pcre2', when='+pcre', msg='+pcre2 and +pcre are mutually exclusive')
+    # https://github.com/OSGeo/gdal/issues/5994
+    conflicts('~png', when='@3:3.5.0')
+    conflicts('~jpeg', when='@3:3.5.0')
+    # TODO: investigate build issues
+    conflicts('+brunsli', when='@3.4')
+    conflicts('+qhull', when='@2.1')
+    conflicts('+mdb', when='~java', msg='MDB driver requires Java')
+
+    # TODO: add packages for the following dependencies
+    conflicts('+bsb')
+    conflicts('+crnlib')
+    conflicts('+dods')
+    conflicts('+ecw')
+    conflicts('+epsilon')
+    conflicts('+filegdb')
+    conflicts('+fme')
+    conflicts('+gta')
+    conflicts('+heif')
+    conflicts('+idb')
+    conflicts('+ingres')
+    conflicts('+jxl')
+    conflicts('+kdu')
+    conflicts('+libcsf')
+    conflicts('+luratech')
+    conflicts('+mrf')
+    conflicts('+mrsid')
+    conflicts('+mrsid_lidar')
+    conflicts('+mssql_ncli')
+    conflicts('+mssql_odbc')
+    conflicts('+odbccpp')
+    conflicts('+ogdi')
+    conflicts('+opencad')
+    conflicts('+pcidsk')
+    conflicts('+pdfium')
+    conflicts('+podofo')
+    conflicts('+rasdaman')
+    conflicts('+rasterlite2')
+    conflicts('+rdb')
+    conflicts('+sde')
+    conflicts('+teigha')
+    conflicts('+tiledb')
 
     # https://github.com/OSGeo/gdal/issues/3782
     patch('https://github.com/OSGeo/gdal/pull/3786.patch?full_index=1', when='@3.3.0', level=2,
           sha256='9f9824296e75b34b3e78284ec772a5ac8f8ba92c17253ea9ca242caf766767ce')
 
+    generator = 'Ninja'
     executables = ['^gdal-config$']
 
     @classmethod
@@ -209,6 +376,7 @@ def import_modules(self):
             modules.append('osgeo.utils')
         return modules
 
+    @when('@:3.4')
     def setup_build_environment(self, env):
         # Needed to install Python bindings to GDAL installation
         # prefix instead of Python installation prefix.
@@ -237,370 +405,282 @@ def patch(self):
         if '+java platform=darwin' in self.spec:
             filter_file('linux', 'darwin', 'swig/java/java.opt', string=True)
 
-    # https://trac.osgeo.org/gdal/wiki/BuildHints
-    def configure_args(self):
-        spec = self.spec
-        libs = []
-
-        # Required dependencies
+    def cmake_args(self):
+        # https://gdal.org/build_hints.html
         args = [
-            # https://trac.osgeo.org/gdal/wiki/TIFF
-            '--with-libtiff={0}'.format(spec['libtiff'].prefix),
-            '--with-geotiff={0}'.format(spec['libgeotiff'].prefix),
-            '--with-libjson-c={0}'.format(spec['json-c'].prefix),
+            # Only use Spack-installed dependencies
+            self.define('GDAL_USE_EXTERNAL_LIBS', False),
+            self.define('GDAL_USE_INTERNAL_LIBS', False),
+
+            # Required dependencies
+            self.define('GDAL_USE_GEOTIFF', True),
+            self.define('GDAL_USE_JSONC', True),
+            self.define('GDAL_USE_TIFF', True),
+            self.define('GDAL_USE_ZLIB', True),
+
+            # Optional dependencies
+            self.define_from_variant('GDAL_USE_ARMADILLO', 'armadillo'),
+            self.define_from_variant('GDAL_USE_ARROW', 'arrow'),
+            self.define_from_variant('GDAL_USE_BLOSC', 'blosc'),
+            self.define_from_variant('GDAL_USE_BRUNSLI', 'brunsli'),
+            self.define_from_variant('GDAL_USE_CFITSIO', 'cfitsio'),
+            self.define_from_variant('GDAL_USE_CRNLIB', 'crnlib'),
+            self.define_from_variant('GDAL_USE_CRYPTOPP', 'cryptopp'),
+            self.define_from_variant('GDAL_USE_CURL', 'curl'),
+            self.define_from_variant('GDAL_USE_DEFLATE', 'deflate'),
+            self.define_from_variant('GDAL_USE_ECW', 'ecw'),
+            self.define_from_variant('GDAL_USE_EXPAT', 'expat'),
+            self.define_from_variant('GDAL_USE_FILEGDB', 'filegdb'),
+            self.define_from_variant('GDAL_USE_FREEXL', 'freexl'),
+            self.define_from_variant('GDAL_USE_FYBA', 'fyba'),
+            self.define_from_variant('GDAL_USE_GEOS', 'geos'),
+            self.define_from_variant('GDAL_USE_GIF', 'gif'),
+            self.define_from_variant('GDAL_USE_GTA', 'gta'),
+            self.define_from_variant('GDAL_USE_HEIF', 'heif'),
+            self.define_from_variant('GDAL_USE_HDF4', 'hdf4'),
+            self.define_from_variant('GDAL_USE_HDF5', 'hdf5'),
+            self.define_from_variant('GDAL_USE_HDFS', 'hdfs'),
+            self.define_from_variant('GDAL_USE_ICONV', 'iconv'),
+            self.define_from_variant('GDAL_USE_IDB', 'idb'),
+            self.define_from_variant('GDAL_USE_JPEG', 'jpeg'),
+            self.define_from_variant('GDAL_USE_JXL', 'jxl'),
+            self.define_from_variant('GDAL_USE_KDU', 'kdu'),
+            self.define_from_variant('GDAL_USE_KEA', 'kea'),
+            self.define_from_variant('GDAL_USE_LERC', 'lerc'),
+            self.define_from_variant('GDAL_USE_LIBCSF', 'libcsf'),
+            self.define_from_variant('GDAL_USE_LIBKML', 'libkml'),
+            self.define_from_variant('GDAL_USE_LIBLZMA', 'liblzma'),
+            self.define_from_variant('GDAL_USE_LIBXML2', 'libxml2'),
+            self.define_from_variant('GDAL_USE_LURATECH', 'luratech'),
+            self.define_from_variant('GDAL_USE_LZ4', 'lz4'),
+            self.define_from_variant('GDAL_USE_MONGOCXX', 'mongocxx'),
+            self.define_from_variant('GDAL_USE_MRSID', 'mrsid'),
+            self.define_from_variant('GDAL_USE_MSSQL_NCLI', 'mssql_ncli'),
+            self.define_from_variant('GDAL_USE_MSSQL_ODBC', 'mssql_odbc'),
+            self.define_from_variant('GDAL_USE_MYSQL', 'mysql'),
+            self.define_from_variant('GDAL_USE_NETCDF', 'netcdf'),
+            self.define_from_variant('GDAL_USE_ODBC', 'odbc'),
+            self.define_from_variant('GDAL_USE_ODBCCPP', 'odbccpp'),
+            self.define_from_variant('GDAL_USE_OGDI', 'ogdi'),
+            self.define_from_variant('GDAL_USE_OPENCAD', 'opencad'),
+            self.define_from_variant('GDAL_USE_OPENCL', 'opencl'),
+            self.define_from_variant('GDAL_USE_OPENEXR', 'openexr'),
+            self.define_from_variant('GDAL_USE_OPENJPEG', 'openjpeg'),
+            self.define_from_variant('GDAL_USE_OPENSSL', 'openssl'),
+            self.define_from_variant('GDAL_USE_ORACLE', 'oracle'),
+            self.define_from_variant('GDAL_USE_PARQUET', 'parquet'),
+            self.define_from_variant('GDAL_USE_PCRE2', 'pcre'),
+            self.define_from_variant('GDAL_USE_PDFIUM', 'pdfium'),
+            self.define_from_variant('GDAL_USE_PNG', 'png'),
+            self.define_from_variant('GDAL_USE_PODOFO', 'podofo'),
+            self.define_from_variant('GDAL_USE_POPPLER', 'poppler'),
+            self.define_from_variant('GDAL_USE_POSTGRESQL', 'postgresql'),
+            self.define_from_variant('GDAL_USE_QHULL', 'qhull'),
+            self.define_from_variant('GDAL_USE_RASDAMAN', 'rasdaman'),
+            self.define_from_variant('GDAL_USE_RASTERLITE2', 'rasterlite2'),
+            self.define_from_variant('GDAL_USE_RDB', 'rdb'),
+            self.define_from_variant('GDAL_USE_SFCGAL', 'sfcgal'),
+            self.define_from_variant('GDAL_USE_SPATIALITE', 'spatialite'),
+            self.define_from_variant('GDAL_USE_SQLITE3', 'sqlite3'),
+            self.define_from_variant('GDAL_USE_TEIGHA', 'teigha'),
+            self.define_from_variant('GDAL_USE_TILEDB', 'tiledb'),
+            self.define_from_variant('GDAL_USE_WEBP', 'webp'),
+            self.define_from_variant('GDAL_USE_XERCESC', 'xercesc'),
+            self.define_from_variant('GDAL_USE_ZSTD', 'zstd'),
+
+            # Language bindings
+            self.define_from_variant('BUILD_PYTHON_BINDINGS', 'python'),
+            self.define_from_variant('BUILD_JAVA_BINDINGS', 'java'),
+            self.define_from_variant('BUILD_CSHARP_BINDINGS', 'csharp'),
         ]
 
-        # Optional dependencies
-        if spec.satisfies('@3:'):
-            args.extend([
-                '--disable-driver-bsb',
-                '--disable-driver-mrf',
-            ])
-
-            if '+grib' in spec:
-                args.append('--enable-driver-grib')
-            else:
-                args.append('--disable-driver-grib')
-        else:
-            args.append('--with-bsb=no')
-
-            if '+grib' in spec:
-                args.append('--with-grib=yes')
-            else:
-                args.append('--with-grib=no')
-
-            if spec.satisfies('@2.3:'):
-                args.append('--with-mrf=no')
-
-        if spec.satisfies('@2.3:'):
-            if '+proj' in spec:
-                args.append('--with-proj={0}'.format(spec['proj'].prefix))
-            else:
-                args.append('--with-proj=no')
-
-            if '+crypto' in spec:
-                args.append('--with-crypto={0}'.format(spec['openssl'].prefix))
-            else:
-                args.append('--with-crypto=no')
-
-        if spec.satisfies('@2.1:'):
-            if '+qhull' in spec:
-                args.append('--with-qhull=yes')
-            else:
-                args.append('--with-qhull=no')
-
-            if '+cryptopp' in spec:
-                args.append('--with-cryptopp={0}'.format(
-                    spec['cryptopp'].prefix))
-            else:
-                args.append('--with-cryptopp=no')
+        # Remove empty strings
+        args = [arg for arg in args if arg]
 
-        if spec.satisfies('@2:'):
-            if '+kea' in spec:
-                args.append('--with-kea={0}'.format(
-                    join_path(spec['kealib'].prefix.bin, 'kea-config')))
-            else:
-                args.append('--with-kea=no')
-
-        if '+libtool' in spec:
-            args.append('--with-libtool=yes')
-        else:
-            args.append('--with-libtool=no')
-
-        if '+libz' in spec:
-            args.append('--with-libz={0}'.format(spec['zlib'].prefix))
-        else:
-            args.append('--with-libz=no')
-
-        if '+libiconv' in spec:
-            args.append('--with-libiconv-prefix={0}'.format(
-                spec['iconv'].prefix))
-        else:
-            args.append('--with-libiconv-prefix=no')
-
-        if '+liblzma' in spec:
-            args.append('--with-liblzma=yes')
-        else:
-            args.append('--with-liblzma=no')
-
-        if '+pg' in spec:
-            if spec.satisfies('@:2'):
-                args.append('--with-pg={0}'.format(
-                    spec['postgresql'].prefix.bin.pg_config))
-            else:
-                args.append('--with-pg=yes')
-        else:
-            args.append('--with-pg=no')
-
-        if '+cfitsio' in spec:
-            args.append('--with-cfitsio={0}'.format(spec['cfitsio'].prefix))
-        else:
-            args.append('--with-cfitsio=no')
-
-        if '+png' in spec:
-            args.append('--with-png={0}'.format(spec['libpng'].prefix))
-        else:
-            args.append('--with-png=no')
-
-        if '+jpeg' in spec:
-            args.append('--with-jpeg={0}'.format(spec['jpeg'].prefix))
-        else:
-            args.append('--with-jpeg=no')
-
-        if '+gif' in spec:
-            args.append('--with-gif={0}'.format(spec['giflib'].prefix))
-        else:
-            args.append('--with-gif=no')
-
-        # https://trac.osgeo.org/gdal/wiki/SOSI
-        if '+sosi' in spec:
-            args.append('--with-sosi={0}'.format(spec['fyba'].prefix))
-        else:
-            args.append('--with-sosi=no')
-
-        # https://trac.osgeo.org/gdal/wiki/HDF
-        if '+hdf4' in spec:
-            args.append('--with-hdf4={0}'.format(spec['hdf'].prefix))
-            hdf4 = self.spec['hdf']
-            if '+external-xdr' in hdf4 and hdf4['rpc'].name != 'libc':
-                libs.append(hdf4['rpc'].libs.link_flags)
-        else:
-            args.append('--with-hdf4=no')
-
-        if '+hdf5' in spec:
-            args.append('--with-hdf5={0}'.format(spec['hdf5'].prefix))
-        else:
-            args.append('--with-hdf5=no')
-
-        # https://trac.osgeo.org/gdal/wiki/NetCDF
-        if '+netcdf' in spec:
-            args.append('--with-netcdf={0}'.format(spec['netcdf-c'].prefix))
-        else:
-            args.append('--with-netcdf=no')
-
-        # https://trac.osgeo.org/gdal/wiki/JasPer
-        if '+jasper' in spec:
-            args.append('--with-jasper={0}'.format(spec['jasper'].prefix))
-        else:
-            args.append('--with-jasper=no')
-
-        if '+openjpeg' in spec:
-            args.append('--with-openjpeg=yes')
-        else:
-            args.append('--with-openjpeg=no')
-
-        if '+xerces' in spec:
-            args.append('--with-xerces={0}'.format(spec['xerces-c'].prefix))
-        else:
-            args.append('--with-xerces=no')
-
-        if '+expat' in spec:
-            args.append('--with-expat={0}'.format(spec['expat'].prefix))
-        else:
-            args.append('--with-expat=no')
-
-        # https://trac.osgeo.org/gdal/wiki/LibKML
-        # https://gdal.org/drivers/vector/libkml.html
-        if '+libkml' in spec:
-            args.append('--with-libkml={0}'.format(spec['libkml'].prefix))
-        else:
-            args.append('--with-libkml=no')
-
-        if '+odbc' in spec:
-            args.append('--with-odbc={0}'.format(spec['unixodbc'].prefix))
-        else:
-            args.append('--with-odbc=no')
-
-        # https://trac.osgeo.org/gdal/wiki/LibCurl
-        if '+curl' in spec:
-            args.append('--with-curl={0}'.format(
-                join_path(spec['curl'].prefix.bin, 'curl-config')))
-        else:
-            args.append('--with-curl=no')
-
-        if '+xml2' in spec:
-            if spec.satisfies('@:2'):
-                args.append('--with-xml2={0}'.format(
-                    join_path(spec['libxml2'].prefix.bin, 'xml2-config')))
-            else:
-                args.append('--with-xml2=yes')
-        else:
-            args.append('--with-xml2=no')
-
-        # https://trac.osgeo.org/gdal/wiki/SQLite
-        if '+sqlite3' in spec:
-            args.append('--with-sqlite3={0}'.format(spec['sqlite'].prefix))
-        else:
-            args.append('--with-sqlite3=no')
+        return args
 
-        if self.spec.satisfies('@3.4.1:'):
-            if '+pcre2' in spec:
-                args.append('--with-pcre2={0}'.format(spec['pcre2'].prefix))
+    def with_or_without(self, name, variant=None, package=None, attribute=None):
+        if not variant:
+            variant = name
+
+        if variant not in self.variants:
+            msg = '"{}" is not a variant of "{}"'
+            raise KeyError(msg.format(variant, self.name))
+
+        if variant not in self.spec.variants:
+            return ''
+
+        if self.spec.variants[variant].value:
+            if package:
+                value = self.spec[package].prefix
+                if attribute == 'command':
+                    value = self.spec[package].command.path
+                elif attribute == 'libs':
+                    value = self.spec[package].libs.directories[0]
+                return '--with-{}={}'.format(name, value)
             else:
-                args.append('--with-pcre2=no')
-
-        if '+pcre' in spec:
-            args.append('--with-pcre={0}'.format(spec['pcre'].prefix))
-        else:
-            args.append('--with-pcre=no')
-
-        if '+geos' in spec:
-            args.append('--with-geos={0}'.format(
-                join_path(spec['geos'].prefix.bin, 'geos-config')))
-        else:
-            args.append('--with-geos=no')
-
-        if '+opencl' in spec:
-            args.append('--with-opencl={0}'.format(spec['opencl'].prefix))
-        else:
-            args.append('--with-opencl=no')
-
-        if '+poppler' in spec:
-            args.append('--with-poppler={0}'.format(spec['poppler'].prefix))
-        else:
-            args.append('--with-poppler=no')
-
-        if '+perl' in spec:
-            args.append('--with-perl=yes')
+                return '--with-{}'.format(name)
         else:
-            args.append('--with-perl=no')
+            return '--without-{}'.format(name)
 
-        if '+python' in spec:
-            args.append('--with-python={0}'.format(
-                spec['python'].command.path))
-        else:
-            args.append('--with-python=no')
+    def configure_args(self):
+        # https://trac.osgeo.org/gdal/wiki/BuildHints
+        args = [
+            '--prefix={}'.format(self.prefix),
+
+            # Required dependencies
+            '--with-geotiff={}'.format(self.spec['libgeotiff'].prefix),
+            '--with-libjson-c={}'.format(self.spec['json-c'].prefix),
+            '--with-libtiff={}'.format(self.spec['libtiff'].prefix),
+            '--with-libz={}'.format(self.spec['zlib'].prefix),
+
+            # Optional dependencies
+            self.with_or_without('armadillo', package='armadillo'),
+            self.with_or_without('blosc', package='c-blosc'),
+            self.with_or_without('brunsli'),
+            self.with_or_without('bsb'),
+            self.with_or_without('cfitsio', package='cfitsio'),
+            self.with_or_without('dds', variant='crnlib', package='crunch'),
+            self.with_or_without('curl', package='curl', attribute='command'),
+            self.with_or_without('cryptopp', package='cryptopp'),
+            self.with_or_without('libdeflate', variant='deflate', package='libdeflate'),
+            self.with_or_without('dods-root', variant='dods', package='dods'),
+            self.with_or_without('ecw', package='ecw'),
+            self.with_or_without('epsilon', package='libepsilon'),
+            self.with_or_without('expat', package='expat'),
+            self.with_or_without('fgdb', variant='filegdb', package='filegdb'),
+            self.with_or_without('fme', package='fme'),
+            self.with_or_without('freexl', package='freexl'),
+            self.with_or_without('sosi', variant='fyba', package='fyba'),
+            self.with_or_without('geos', package='geos', attribute='command'),
+            self.with_or_without('gif', package='giflib'),
+            self.with_or_without('grass', package='grass'),
+            self.with_or_without('grib'),
+            self.with_or_without('libgrass', variant='grass'),
+            self.with_or_without('gta', package='gta'),
+            self.with_or_without('heif'),
+            self.with_or_without('hdf4', package='hdf'),
+            self.with_or_without('hdf5', package='hdf5'),
+            self.with_or_without('hdfs', package='hadoop'),
+            self.with_or_without('libiconv-prefix', variant='iconv', package='iconv'),
+            self.with_or_without('idb', package='idb'),
+            self.with_or_without('ingres', package='ingres'),
+            self.with_or_without('jasper', package='jasper'),
+            self.with_or_without('jpeg', package='jpeg'),
+            self.with_or_without('jxl'),
+            self.with_or_without('kakadu', variant='kdu'),
+            self.with_or_without('kea', package='kealib', attribute='command'),
+            self.with_or_without('lerc', package='lerc'),
+            self.with_or_without('pcraster', variant='libcsf', package='libcsf'),
+            self.with_or_without('libkml', package='libkml'),
+            self.with_or_without('liblzma'),
+            self.with_or_without('jp2lura', variant='luratech', package='luratech'),
+            self.with_or_without('lz4', package='lz4'),
+            self.with_or_without('mdb'),
+            self.with_or_without('mrf'),
+            self.with_or_without('mrsid', package='mrsid'),
+            self.with_or_without('mrsid_lidar', package='lizardtech-lidar'),
+            self.with_or_without('mysql', package='mysql', attribute='command'),
+            self.with_or_without('netcdf', package='netcdf-c'),
+            self.with_or_without('odbc', package='unixodbc'),
+            self.with_or_without('hana', variant='odbccpp', package='odbc-cpp-wrapper'),
+            self.with_or_without('ogdi', package='ogdi'),
+            self.with_or_without('opencl'),
+            self.with_or_without('exr', variant='openexr'),
+            self.with_or_without('openjpeg'),
+            self.with_or_without('crypto', variant='openssl', package='openssl'),
+            self.with_or_without(
+                'oci', variant='oracle', package='oracle-instant-client'
+            ),
+            self.with_or_without('pcidsk', package='pcidsk'),
+            self.with_or_without('pcre'),
+            self.with_or_without('pdfium', package='pdfium'),
+            self.with_or_without('png', package='libpng'),
+            self.with_or_without('podofo', package='podofo'),
+            self.with_or_without('poppler', package='poppler'),
+            self.with_or_without('qhull'),
+            self.with_or_without('rasdaman', package='rasdaman'),
+            self.with_or_without('rasterlite2', package='rasterlite2'),
+            self.with_or_without('rdb', package='rdb'),
+            self.with_or_without('sde', package='sde'),
+            self.with_or_without('spatialite', package='libspatialite'),
+            self.with_or_without('sqlite3', package='sqlite'),
+            self.with_or_without('sfcgal', package='sfcgal', attribute='command'),
+            self.with_or_without('tiledb', package='tiledb'),
+            self.with_or_without('webp', package='libwebp'),
+            self.with_or_without('xerces', variant='xercesc', package='xerces-c'),
+            self.with_or_without('zstd', package='zstd'),
+
+            # Language bindings
+            self.with_or_without('python', package='python', attribute='command'),
+            self.with_or_without('java', package='java'),
+            self.with_or_without(
+                'jvm-lib', variant='mdb', package='java', attribute='libs'
+            ),
+            self.with_or_without('jvm-lib-add-rpath', variant='mdb'),
+            self.with_or_without('perl'),
+            self.with_or_without('php'),
+        ]
 
-        # https://trac.osgeo.org/gdal/wiki/GdalOgrInJava
-        # https://trac.osgeo.org/gdal/wiki/GdalOgrInJavaBuildInstructionsUnix
-        if '+java' in spec:
+        # Renamed or modified flags
+        if self.spec.satisfies('@3:'):
             args.extend([
-                '--with-java={0}'.format(spec['java'].home),
-                '--with-jvm-lib={0}'.format(
-                    spec['java'].libs.directories[0]),
-                '--with-jvm-lib-add-rpath'
+                self.with_or_without('xml2', variant='libxml2'),
+                self.with_or_without('mongocxxv3', variant='mongocxx'),
+                self.with_or_without('pg', variant='postgresql'),
             ])
         else:
-            args.append('--with-java=no')
-
-        # https://trac.osgeo.org/gdal/wiki/mdbtools
-        # https://www.gdal.org/drv_mdb.html
-        if '+mdb' in spec:
-            args.append('--with-mdb=yes')
-        else:
-            args.append('--with-mdb=no')
-
-        if '+armadillo' in spec:
-            args.append('--with-armadillo={0}'.format(
-                spec['armadillo'].prefix))
-        else:
-            args.append('--with-armadillo=no')
-
-        # TODO: add packages for these dependencies
-        args.extend([
-            # https://trac.osgeo.org/gdal/wiki/GRASS
-            '--with-grass=no',
-            '--with-libgrass=no',
-            '--with-pcraster=no',
-            '--with-dds=no',
-            '--with-gta=no',
-            '--with-pcidsk=no',
-            '--with-ogdi=no',
-            '--with-fme=no',
-            # https://trac.osgeo.org/gdal/wiki/FileGDB
-            '--with-fgdb=no',
-            # https://trac.osgeo.org/gdal/wiki/ECW
-            '--with-ecw=no',
-            # https://trac.osgeo.org/gdal/wiki/JP2KAK
-            '--with-kakadu=no',
-            # https://trac.osgeo.org/gdal/wiki/MrSID
-            '--with-mrsid=no',
-            '--with-jp2mrsid=no',
-            '--with-mrsid_lidar=no',
-            # https://trac.osgeo.org/gdal/wiki/MSG
-            '--with-msg=no',
-            # https://trac.osgeo.org/gdal/wiki/Oracle
-            '--with-oci=no',
-            '--with-mysql=no',
-            # https://trac.osgeo.org/gdal/wiki/Ingres
-            '--with-ingres=no',
-            '--with-dods-root=no',
-            '--with-spatialite=no',
-            '--with-idb=no',
-            '--with-webp=no',
-            '--with-freexl=no',
-            '--with-pam=no',
-            '--with-podofo=no',
-            '--with-rasdaman=no',
-        ])
-
-        # TODO: add packages for these dependencies (only for 3.2 and older)
-        if spec.satisfies('@:3.2'):
-            # https://trac.osgeo.org/gdal/wiki/Epsilon
-            args.append('--with-epsilon=no')
-
-        # TODO: add packages for these dependencies (only for 3.1 and older)
-        if spec.satisfies('@:3.1'):
-            # https://trac.osgeo.org/gdal/wiki/ArcSDE
-            args.append('--with-sde=no')
-
-        # TODO: add packages for these dependencies (only for 2.3 and older)
-        if spec.satisfies('@:2.3'):
-            args.append('--with-php=no')
-
-        # TODO: add packages for these dependencies (only for 3.2 and newer)
-        if spec.satisfies('@3.2:'):
-            args.append('--with-heif=no')
-
-        # TODO: add packages for these dependencies (only for 3.1 and newer)
-        if spec.satisfies('@3.1:'):
             args.extend([
-                '--with-exr=no',
-                '--with-rdb=no',
+                self.with_or_without(
+                    'xml2', variant='libxml2', package='libxlm2', attribute='command'
+                ),
+                self.with_or_without('mongocxx', variant='mongocxx'),
+                self.with_or_without(
+                    'pg', variant='postgresql',
+                    package='postgresql', attribute='command'
+                ),
             ])
 
-        # TODO: add packages for these dependencies (only for 3.0 and newer)
-        if spec.satisfies('@3.0:'):
-            args.extend([
-                '--with-tiledb=no',
-                '--with-mongocxxv3=no',
-            ])
+        if self.spec.satisfies('@2.3:'):
+            args.append('--with-proj={}'.format(self.spec['proj'].prefix))
 
-        # TODO: add packages for these dependencies (only for 2.3 and newer)
-        if spec.satisfies('@2.3:'):
-            args.extend([
-                '--with-jp2lura=no',
-                '--with-rasterlite2=no',
-                # https://trac.osgeo.org/gdal/wiki/DxfDwg
-                '--with-teigha=no',
-                '--with-sfcgal=no',
-            ])
+        if self.spec.satisfies('@2.2:'):
+            args.append(self.with_or_without('teigha', package='teigha'))
+        else:
+            args.append(
+                self.with_or_without('dwgdirect', variant='teigha', package='teigha')
+            )
 
-        # TODO: add packages for these dependencies (only for 2.1 and newer)
-        if spec.satisfies('@2.1:'):
-            args.extend([
-                '--with-mongocxx=no',
-                '--with-pdfium=no',
-            ])
+        if '+hdf4' in self.spec:
+            hdf4 = self.spec['hdf']
+            if '+external-xdr' in hdf4 and hdf4['rpc'].name != 'libc':
+                args.append('LIBS=' + hdf4['rpc'].libs.link_flags)
 
-        if libs:
-            args.append('LIBS=' + ' '.join(libs))
+        # Remove empty strings
+        args = [arg for arg in args if arg]
 
         return args
 
-    # https://trac.osgeo.org/gdal/wiki/GdalOgrInJavaBuildInstructionsUnix
+    @when('@:3.4')
+    def cmake(self, spec, prefix):
+        configure(*self.configure_args())
+
+    @when('@:3.4')
     def build(self, spec, prefix):
+        # https://trac.osgeo.org/gdal/wiki/GdalOgrInJavaBuildInstructionsUnix
         make()
         if '+java' in spec:
             with working_dir('swig/java'):
                 make()
 
+    @when('@:3.4')
     def check(self):
         # no top-level test target
         if '+java' in self.spec:
             with working_dir('swig/java'):
                 make('test')
 
+    @when('@:3.4')
     def install(self, spec, prefix):
         make('install')
         if '+java' in spec:
@@ -611,7 +691,7 @@ def install(self, spec, prefix):
     @run_after('install')
     def darwin_fix(self):
         # The shared library is not installed correctly on Darwin; fix this
-        if 'platform=darwin' in self.spec:
+        if self.spec.satisfies('@:3.4 platform=darwin'):
             fix_darwin_install_name(self.prefix.lib)
 
     def test(self):
diff --git a/var/spack/repos/builtin/packages/gplates/package.py b/var/spack/repos/builtin/packages/gplates/package.py
--- a/var/spack/repos/builtin/packages/gplates/package.py
+++ b/var/spack/repos/builtin/packages/gplates/package.py
@@ -21,8 +21,7 @@ class Gplates(CMakePackage):
     manual_download = True
 
     version('2.3.0', sha256='7d4be9d524d1fcbb6a81de29bd1d4b13133082db23f0808965c5efe30e9538ab')
-    version('2.1.0', sha256='5a52242520d7e243c541e164c8417b23f4e17fcd79ed81f865b2c13628bb0e07', deprecated=True)
-    version('2.0.0', sha256='1c27d3932a851153baee7cec48e57c2bbc87e4eea02f8a986882515ba4b44c0b', deprecated=True)
+    version('2.1.0', sha256='5a52242520d7e243c541e164c8417b23f4e17fcd79ed81f865b2c13628bb0e07')
 
     depends_on('cmake@3.5:', when='@2.3:', type='build')
     depends_on('cmake@2.8.8:', when='@2.1', type='build')
@@ -43,8 +42,6 @@ class Gplates(CMakePackage):
     depends_on('qt@4.4:4+opengl', when='@:2.1')
     depends_on('gdal@1.3.2:', when='@2.3:')
     depends_on('gdal@1.3.2:2', when='@2.1')
-    # GDAL's OGRSFDriverRegistrar is not compatible anymore starting with 2.0.
-    depends_on('gdal@1.3.2:1', when='@2.0')
     depends_on('cgal@4.7:', when='@2.3:')
     depends_on('cgal@3.3.1:', when='@:2.1')
     depends_on('proj@4.6:', when='@2.3:')
diff --git a/var/spack/repos/builtin/packages/ncl/package.py b/var/spack/repos/builtin/packages/ncl/package.py
--- a/var/spack/repos/builtin/packages/ncl/package.py
+++ b/var/spack/repos/builtin/packages/ncl/package.py
@@ -90,7 +90,7 @@ class Ncl(Package):
 
     # Some of the optional dependencies according to the manual:
     depends_on('hdf', when='+hdf4')
-    depends_on('gdal+proj@:2.4', when='+gdal')
+    depends_on('gdal@:2.4', when='+gdal')
     depends_on('udunits', when='+udunits2')
 
     # We need src files of triangle to appear in ncl's src tree if we want


Test patch: