From 54ef44f98a62049a94defe448ba6bf8939dd142b Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Thu, 25 Jan 2024 14:07:51 +0100 Subject: [PATCH] Provide a bundled flag for `gdal-sys` This commit introduces a new `gdal-src` crate which bundles gdal and builds by default a minimal version from source via `build.rs`. It exposes feature flags for many drivers and adds the neccesary dependencies to keep the build fully static. Fixes #465 --- .gitmodules | 4 + CHANGES.md | 1 + Cargo.toml | 8 +- gdal-src/Cargo.toml | 314 +++++++++++++++++++++++++++++++++++++++++ gdal-src/build.rs | 337 ++++++++++++++++++++++++++++++++++++++++++++ gdal-src/source | 1 + gdal-src/src/lib.rs | 12 ++ gdal-sys/Cargo.toml | 6 + gdal-sys/build.rs | 2 +- gdal-sys/src/lib.rs | 3 + 10 files changed, 686 insertions(+), 2 deletions(-) create mode 100644 .gitmodules create mode 100644 gdal-src/Cargo.toml create mode 100644 gdal-src/build.rs create mode 160000 gdal-src/source create mode 100644 gdal-src/src/lib.rs diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..6a97e1191 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "gdal-src/source"] + path = gdal-src/source + url = https://github.com/OSGeo/gdal + rev = 654f4907abbbf6bf4226d58a8c067d134eaf3ce9 diff --git a/CHANGES.md b/CHANGES.md index cba870e20..1d8b895d0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ # Changes ## Unreleased +- Add a `bundled` feature for `gdal-sys` that allows to build and statically link a minimal bundled version of gdal during `cargo build` - Add `DriverIterator` format to iterate through drivers, as well as `DriverManager::all()` method that provides the iterator. - diff --git a/Cargo.toml b/Cargo.toml index 0c0ef3c1d..8e6cf8faf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ tempfile = "3.8" arrow2 = "0.18" [workspace] -members = ["gdal-sys"] +members = ["gdal-src", "gdal-sys"] # docs.rs-specific configuration [package.metadata.docs.rs] @@ -44,3 +44,9 @@ members = ["gdal-sys"] features = ["array"] # define attribute `docsrs` for feature badges rustdoc-args = ["--cfg", "docsrs"] + + +[patch.crates-io] +proj-sys = { git = "https://github.com/GiGainfosystems/proj", rev = "dc67b5afc17bc7d330371e4406dffd65cf9321cd" } +libsqlite3-sys = { git = "https://github.com/rusqlite/rusqlite/", rev = "42a82fb" } +pq-sys = { git = "https://github.com/sgrif/pq-sys", rev = "77e6729" } diff --git a/gdal-src/Cargo.toml b/gdal-src/Cargo.toml new file mode 100644 index 000000000..9bf441999 --- /dev/null +++ b/gdal-src/Cargo.toml @@ -0,0 +1,314 @@ +[package] +name = "gdal-src" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +proj-sys = { version = "0.23.2", features = ["bundled_proj"] } +libsqlite3-sys = { version = "0.27.0", features = ["bundled"], optional = true } +hdf5-src = { version = "0.8.1", optional = true, features = ["hl"] } +hdf5-sys = { version = "0.8.1", optional = true, features = ["static"] } +netcdf-src = { version = "0.3.2", optional = true } +pq-src = { version = "0.1", optional = true } +curl-sys = { version = "0.4.70", features = ["static-curl"], optional = true } +libz-sys = { version = "1.1.15", features = ["static"], optional = true } + +[build-dependencies] +cmake = "0.1.50" + +[features] +default = [] +enable_all_drivers = [ + "enable_all_internal", + "DRIVER_SQLITE", + "DRIVER_GPKG", + "DRIVER_VFK", + "DRIVER_HDF5", + "DRIVER_NETCDF", + "DRIVER_AMIGOCLOUD", + "DRIVER_CARTO", + "DRIVER_DAAS", + "DRIVER_EEDA", + "DRIVER_ELASTIC", + "DRIVER_NGW", + "DRIVER_OGCAPI", + "DRIVER_PLMOSAIC", + "DRIVER_WCS", + "DRIVER_WMS", + "DRIVER_WMTS", + "DRIVER_PG", + "DRIVER_POSTGIS_RASTER", +] + +enable_all_internal = [ + # ogr internal, + "DRIVER_AVC", + "DRIVER_CAD", + "DRIVER_CSV", + "DRIVER_DGN", + "DRIVER_DXF", + "DRIVER_EDIGEO", + "DRIVER_FLATGEOBUF", + "DRIVER_GEOCONCEPT", + "DRIVER_GEOJSON", + "DRIVER_GMT", + "DRIVER_GTFS", + "DRIVER_JSONFG", + "DRIVER_MAPML", + "DRIVER_OPENFILEGDB", + "DRIVER_PGDUMP", + "DRIVER_NTF", + "DRIVER_S57", + "DRIVER_SELAFIN", + "DRIVER_SHAPE", + "DRIVER_SXF", + "DRIVER_TAB", + "DRIVER_TIGER", + "DRIVER_VDV", + "DRIVER_WASP", + # gdal internal + "DRIVER_AAIGRID", + "DRIVER_ADRG", + "DRIVER_AIGRID", + "DRIVER_AIRSAR", + "DRIVER_BLX", + "DRIVER_BMP", + "DRIVER_BSB", + "DRIVER_CALS", + "DRIVER_CEOS", + "DRIVER_COASP", + "DRIVER_COSAR", + "DRIVER_CTG", + "DRIVER_DIMAP", + "DRIVER_DTED", + "DRIVER_ELAS", + "DRIVER_ENVISAT", + "DRIVER_ERS", + "DRIVER_FIT", + "DRIVER_GFF", + "DRIVER_GIF", + "DRIVER_GRIB", + "DRIVER_GSG", + "DRIVER_GTIFF", + "DRIVER_GXF", + "DRIVER_HF2", + "DRIVER_HFA", + "DRIVER_ILWIS", + "DRIVER_IRIS", + "DRIVER_JAXAPALSAR", + "DRIVER_JDEM", + "DRIVER_JPEG", + "DRIVER_KMLSUPEROVERLAY", + "DRIVER_L1B", + "DRIVER_LEVELLER", + "DRIVER_MAP", + "DRIVER_MRF", + "DRIVER_MSGN", + "DRIVER_NGSGEOID", + "DRIVER_NIFT", + "DRIVER_NORTHWOOD", + "DRIVER_OZI", + "DRIVER_PCIDSK", + "DRIVER_PCRASTER", + "DRIVER_PNG", + "DRIVER_PRF", + "DRIVER_R", + "DRIVER_RAW", + "DRIVER_RIK", + "DRIVER_RMF", + "DRIVER_RS2", + "DRIVER_SAFE", + "DRIVER_SAGA", + "DRIVER_SAR_CEOS", + "DRIVER_SENTINEL2", + "DRIVER_SGI", + "DRIVER_SIGDEM", + "DRIVER_SRTMHGT", + "DRIVER_STACIT", + "DRIVER_STACTA", + "DRIVER_TERRAGEN", + "DRIVER_TGA", + "DRIVER_TIL", + "DRIVER_TSX", + "DRIVER_USGSDEM", + "DRIVER_XPM", + "DRIVER_XYZ", + "DRIVER_ZMAP", + + # ogr and gdal + "DRIVER_IDRISI", + "DRIVER_PDS", + "DRIVER_SDTS", + "DRIVER_VRT", + "DRIVER_MEM", +] + +# ogr internal +DRIVER_AVC = [] +DRIVER_CAD = [] +DRIVER_CSV = [] +DRIVER_DGN = [] +DRIVER_DXF = [] +DRIVER_EDIGEO = [] +DRIVER_FLATGEOBUF = [] +DRIVER_GEOCONCEPT = [] +DRIVER_GEOJSON = [] +DRIVER_GMT = [] +DRIVER_GTFS = [] +DRIVER_JSONFG = [] +DRIVER_MAPML = [] +DRIVER_OPENFILEGDB = [] +DRIVER_PGDUMP = [] +DRIVER_NTF = [] +DRIVER_S57 = [] +DRIVER_SELAFIN = [] +DRIVER_SHAPE = [] +DRIVER_SXF = [] +DRIVER_TAB = [] +DRIVER_TIGER = [] +DRIVER_VDV = [] +DRIVER_WASP = [] + +#gdal internal +DRIVER_AAIGRID = [] +DRIVER_ADRG = [] +DRIVER_AIGRID = [] +DRIVER_AIRSAR = [] +DRIVER_BLX = [] +DRIVER_BMP = [] +DRIVER_BSB = [] +DRIVER_CALS = [] +DRIVER_CEOS = [] +DRIVER_COASP = [] +DRIVER_COSAR = [] +DRIVER_CTG = [] +DRIVER_DIMAP = [] +DRIVER_DTED = [] +DRIVER_ELAS = [] +DRIVER_ENVISAT =[] +DRIVER_ERS = [] +DRIVER_FIT = [] +DRIVER_GFF = [] +DRIVER_GIF = [] +DRIVER_GRIB = [] +DRIVER_GSG = [] +DRIVER_GTIFF = [] +DRIVER_GXF = [] +DRIVER_HF2 = [] +DRIVER_HFA = [] +DRIVER_ILWIS = [] +DRIVER_IRIS = [] +DRIVER_JAXAPALSAR = [] +DRIVER_JDEM = [] +DRIVER_JPEG = [] +DRIVER_KMLSUPEROVERLAY = [] +DRIVER_L1B = [] +DRIVER_LEVELLER = [] +DRIVER_MAP = [] +DRIVER_MRF = [] +DRIVER_MSGN = [] +DRIVER_NGSGEOID = [] +DRIVER_NIFT = [] +DRIVER_NORTHWOOD = [] +DRIVER_OZI = [] +DRIVER_PCIDSK = [] +DRIVER_PCRASTER = [] +DRIVER_PNG = [] +DRIVER_PRF = [] +DRIVER_R = [] +DRIVER_RAW = [] +DRIVER_RIK = [] +DRIVER_RMF = [] +DRIVER_RS2 = [] +DRIVER_SAFE = [] +DRIVER_SAGA = [] +DRIVER_SAR_CEOS = [] +DRIVER_SENTINEL2 = [] +DRIVER_SGI = [] +DRIVER_SIGDEM = [] +DRIVER_SRTMHGT = [] +DRIVER_STACIT = [] +DRIVER_STACTA = [] +DRIVER_TERRAGEN = [] +DRIVER_TGA = [] +DRIVER_TIL = [] +DRIVER_TSX = [] +DRIVER_USGSDEM = [] +DRIVER_XPM = [] +DRIVER_XYZ = [] +DRIVER_ZMAP = [] + +# ogr and gdal +DRIVER_IDRISI = [] +DRIVER_PDS = [] +DRIVER_SDTS = [] +DRIVER_VRT = [] +DRIVER_MEM = [] + +# external + +# sqlite +DRIVER_SQLITE = ["dep:libsqlite3-sys"] +DRIVER_GPKG = ["DRIVER_SQLITE"] +DRIVER_VFK = ["DRIVER_SQLITE"] +DRIVER_RASTERLITE = [] # unclear how to handle that + +# curl +DRIVER_AMIGOCLOUD = ["curl-sys"] +DRIVER_CARTO = ["curl-sys"] +DRIVER_DAAS = ["curl-sys"] +DRIVER_EEDA = ["curl-sys"] +DRIVER_ELASTIC = ["curl-sys"] +DRIVER_NGW = ["curl-sys"] + +DRIVER_OGCAPI = ["curl-sys"] +DRIVER_PLMOSAIC = ["curl-sys"] +DRIVER_WCS = ["curl-sys"] +DRIVER_WMS = ["curl-sys"] +DRIVER_WMTS = ["curl-sys"] + +# libexpat +# (there exists no expat-sys crate) +# DRIVER_GEORSS = [] +# DRIVER_GML = [] +# DRIVER_GPSBABEL = [] +# DRIVER_GPX = [] +# DRIVER_JML = [] +# DRIVER_KML = [] +# DRIVER_LVBAG = [] +# DRIVER_ODS = [] +# DRIVER_SVG = [] +# DRIVER_XLSX = [] + +# libmysqlclient +# (there is currently no bundling support in libmysqlclient) +# DRIVER_MYSQL = [] + +# libpq +DRIVER_PG = ["dep:pq-src"] +DRIVER_POSTGIS_RASTER = ["DRIVER_PG"] + +# libhdf5 +DRIVER_HDF5 = ["dep:hdf5-src", "dep:libz-sys"] + +# libnetcdf +DRIVER_NETCDF = ["dep:netcdf-src", "DRIVER_HDF5", "dep:hdf5-sys"] + +# poppler +#DRIVER_PDF = [] + +# combined +# these miss at least one dependency +# DRIVER_MVT = [] # requires sqlite + geos +# DRIVER_OSM = [] # requires sqlite + libexpat +# DRIVER_ZARR = [] # requires liblz4, libxz, libzstd and libblocs +# DRIVER_MBTILES = ["DRIVER_SQLITE", "DRIVER_MVT"] # also requires mvt (so geos) +# DRIVER_PMTILES = ["DRIVER_MVT"] # depends on driver_mvt +# DRIVER_CSW = ["curl-sys", "DRIVER_GML"] # depends on gml driver +# DRIVER_WFS = ["curl-sys", "DRIVER_GML"] + +# unclear +DRIVER_HTTP = [] +DRIVER_ARG = [] diff --git a/gdal-src/build.rs b/gdal-src/build.rs new file mode 100644 index 000000000..388cd0350 --- /dev/null +++ b/gdal-src/build.rs @@ -0,0 +1,337 @@ +macro_rules! handle_ogr_driver { + ($config: ident, $driver: literal) => { + if cfg!(feature = $driver) { + $config.define(concat!("OGR_ENABLE_", $driver), "ON"); + } else { + $config.define(concat!("OGR_ENABLE_", $driver), "OFF"); + } + }; +} + +macro_rules! handle_gdal_driver { + ($config: ident, $driver: literal) => { + if cfg!(feature = $driver) { + $config.define(concat!("GDAL_ENABLE_", $driver), "ON"); + } else { + $config.define(concat!("GDAL_ENABLE_", $driver), "OFF"); + } + }; +} + +fn find_library(lib_name: &str, path: impl Into) -> String { + let path = path.into(); + if path.join("lib64").join(format!("lib{lib_name}.a")).exists() { + path.join("lib64") + .join(format!("lib{lib_name}.a")) + .display() + .to_string() + } else if path.join("lib").join(format!("lib{lib_name}.a")).exists() { + path.join("lib") + .join(format!("lib{lib_name}.a")) + .display() + .to_string() + } else if path.join("lib").join(format!("{lib_name}.lib")).exists() { + path.join("lib") + .join(format!("{lib_name}.lib")) + .display() + .to_string() + } else { + panic!("{lib_name} not found in {}", path.display()); + } +} + +fn main() { + let proj_root = + std::path::PathBuf::from(std::env::var("DEP_PROJ_ROOT").expect("set by proj-sys")); + let proj_lib = if proj_root.join("lib").join("proj_d.lib").exists() { + "proj_d.lib" + } else if proj_root.join("lib").join("proj.lib").exists() { + "proj.lib" + } else { + "libproj.a" + }; + + let mut config = cmake::Config::new("source"); + + config + .define("GDAL_BUILD_OPTIONAL_DRIVERS", "OFF") + .define("OGR_BUILD_OPTIONAL_DRIVERS", "OFF") + .define("GDAL_USE_INTERNAL_LIBS", "ON") + .define("GDAL_USE_EXTERNAL_LIBS", "OFF") + .define("BUILD_SHARED_LIBS", "OFF") + .define("BUILD_STATIC_LIBS", "ON") + .define("BUILD_APPS", "OFF") + .define("BUILD_DOCS", "OFF") + .define("BUILD_TESTING", "OFF") + .define("BUILD_GMOCK", "OFF") + .define( + "PROJ_INCLUDE_DIR", + format!("{}/include", proj_root.display()), + ) + .define( + "PROJ_LIBRARY", + format!("{}/lib/{proj_lib}", proj_root.display()), + ) + .pic(true) + .define("ACCEPT_MISSING_LINUX_FS_HEADER", "ON"); + // enable the gpkg driver + + // simple drivers without external dependencies + handle_ogr_driver!(config, "DRIVER_AVC"); + handle_ogr_driver!(config, "DRIVER_CAD"); + handle_ogr_driver!(config, "DRIVER_CSV"); + handle_ogr_driver!(config, "DRIVER_DGN"); + handle_ogr_driver!(config, "DRIVER_DXF"); + handle_ogr_driver!(config, "DRIVER_EDIGEO"); + handle_ogr_driver!(config, "DRIVER_FLATGEOBUF"); + handle_ogr_driver!(config, "DRIVER_GEOCONCEPT"); + handle_ogr_driver!(config, "DRIVER_GEOJSON"); + handle_ogr_driver!(config, "DRIVER_GMT"); + handle_ogr_driver!(config, "DRIVER_GTFS"); + handle_ogr_driver!(config, "DRIVER_JSONFG"); + handle_ogr_driver!(config, "DRIVER_MAPML"); + handle_ogr_driver!(config, "DRIVER_OPENFILEGDB"); + handle_ogr_driver!(config, "DRIVER_PGDUMP"); + handle_ogr_driver!(config, "DRIVER_NTF"); + handle_ogr_driver!(config, "DRIVER_S57"); + handle_ogr_driver!(config, "DRIVER_SELAFIN"); + handle_ogr_driver!(config, "DRIVER_SHAPE"); + handle_ogr_driver!(config, "DRIVER_SXF"); + handle_ogr_driver!(config, "DRIVER_TAB"); + handle_ogr_driver!(config, "DRIVER_TIGER"); + handle_ogr_driver!(config, "DRIVER_VDV"); + handle_ogr_driver!(config, "DRIVER_WASP"); + handle_ogr_driver!(config, "DRIVER_IDRISI"); + handle_ogr_driver!(config, "DRIVEr_PDS"); + handle_ogr_driver!(config, "DRIVER_SDTS"); + handle_ogr_driver!(config, "DRIVER_VRT"); + handle_ogr_driver!(config, "DRIVER_MEM"); + + handle_gdal_driver!(config, "DRIVER_AAIGRID"); + handle_gdal_driver!(config, "DRIVER_ADRG"); + handle_gdal_driver!(config, "DRIVER_AIGRID"); + handle_gdal_driver!(config, "DRIVER_AIRSAR"); + handle_gdal_driver!(config, "DRIVER_BLX"); + handle_gdal_driver!(config, "DRIVER_BMP"); + handle_gdal_driver!(config, "DRIVER_BSB"); + handle_gdal_driver!(config, "DRIVER_CALS"); + handle_gdal_driver!(config, "DRIVER_CEOS"); + handle_gdal_driver!(config, "DRIVER_COASP"); + handle_gdal_driver!(config, "DRIVER_COSAR"); + handle_gdal_driver!(config, "DRIVER_CTG"); + handle_gdal_driver!(config, "DRIVER_DIMAP"); + handle_gdal_driver!(config, "DRIVER_DTED"); + handle_gdal_driver!(config, "DRIVER_ELAS"); + handle_gdal_driver!(config, "DRIVER_ENVISAT"); + handle_gdal_driver!(config, "DRIVER_ERS"); + handle_gdal_driver!(config, "DRIVER_FIT"); + handle_gdal_driver!(config, "DRIVER_GFF"); + handle_gdal_driver!(config, "DRIVER_GIF"); + handle_gdal_driver!(config, "DRIVER_GRIB"); + handle_gdal_driver!(config, "DRIVER_GSG"); + handle_gdal_driver!(config, "DRIVER_GTIFF"); + handle_gdal_driver!(config, "DRIVER_GXF"); + handle_gdal_driver!(config, "DRIVER_HF2"); + handle_gdal_driver!(config, "DRIVER_HFA"); + handle_gdal_driver!(config, "DRIVER_ILWIS"); + handle_gdal_driver!(config, "DRIVER_IRIS"); + handle_gdal_driver!(config, "DRIVER_JAXAPALSAR"); + handle_gdal_driver!(config, "DRIVER_JDEM"); + handle_gdal_driver!(config, "DRIVER_JPEG"); + handle_gdal_driver!(config, "DRIVER_KMLSUPEROVERLAY"); + handle_gdal_driver!(config, "DRIVER_L1B"); + handle_gdal_driver!(config, "DRIVER_LEVELLER"); + handle_gdal_driver!(config, "DRIVER_MAP"); + handle_gdal_driver!(config, "DRIVER_MRF"); + handle_gdal_driver!(config, "DRIVER_MSGN"); + handle_gdal_driver!(config, "DRIVER_NGSGEOID"); + handle_gdal_driver!(config, "DRIVER_NIFT"); + handle_gdal_driver!(config, "DRIVER_NORTHWOOD"); + handle_gdal_driver!(config, "DRIVER_OZI"); + handle_gdal_driver!(config, "DRIVER_PCIDSK"); + handle_gdal_driver!(config, "DRIVER_PCRASTER"); + handle_gdal_driver!(config, "DRIVER_PNG"); + handle_gdal_driver!(config, "DRIVER_PRF"); + handle_gdal_driver!(config, "DRIVER_R"); + handle_gdal_driver!(config, "DRIVER_RAW"); + handle_gdal_driver!(config, "DRIVER_RIK"); + handle_gdal_driver!(config, "DRIVER_RMF"); + handle_gdal_driver!(config, "DRIVER_RS2"); + handle_gdal_driver!(config, "DRIVER_SAFE"); + handle_gdal_driver!(config, "DRIVER_SAGA"); + handle_gdal_driver!(config, "DRIVER_SAR_CEOS"); + handle_gdal_driver!(config, "DRIVER_SENTINEL2"); + handle_gdal_driver!(config, "DRIVER_SGI"); + handle_gdal_driver!(config, "DRIVER_SIGDEM"); + handle_gdal_driver!(config, "DRIVER_SRTMHGT"); + handle_gdal_driver!(config, "DRIVER_STACIT"); + handle_gdal_driver!(config, "DRIVER_STACTA"); + handle_gdal_driver!(config, "DRIVER_TERRAGEN"); + handle_gdal_driver!(config, "DRIVER_TGA"); + handle_gdal_driver!(config, "DRIVER_TIL"); + handle_gdal_driver!(config, "DRIVER_TSX"); + handle_gdal_driver!(config, "DRIVER_USGSDEM"); + handle_gdal_driver!(config, "DRIVER_XPM"); + handle_gdal_driver!(config, "DRIVER_XYZ"); + handle_gdal_driver!(config, "DRIVER_ZMAP"); + handle_gdal_driver!(config, "DRIVER_IDRISI"); + handle_gdal_driver!(config, "DRIVEr_PDS"); + handle_gdal_driver!(config, "DRIVER_SDTS"); + handle_gdal_driver!(config, "DRIVER_VRT"); + handle_gdal_driver!(config, "DRIVER_MEM"); + + if cfg!(feature = "DRIVER_SQLITE") { + let sqlite3_include_dir = + std::env::var("DEP_SQLITE3_INCLUDE").expect("This is set by libsqlite3-sys"); + let sqlite3_lib_dir = std::env::var("DEP_SQLITE3_LIB_DIR").expect("set by libsqlite3-sys"); + + config + .define("GDAL_USE_SQLITE3", "ON") + .define("SQLite3_INCLUDE_DIR", sqlite3_include_dir) + .define("SQLite3_LIBRARY", format!("{sqlite3_lib_dir}/libsqlite3.a")) + .define("OGR_ENABLE_DRIVER_SQLITE", "ON"); + } else { + config.define("GDAL_USE_SQLITE3", "OFF"); + } + // these drivers depend on sqlite + handle_ogr_driver!(config, "DRIVER_GPKG"); + handle_ogr_driver!(config, "DRIVER_VFK"); + + if cfg!(feature = "DRIVER_HDF5") { + let hdf5_dir = std::env::var("DEP_HDF5SRC_ROOT").expect("This is set by hdf5-src"); + let hdf5_lib = std::env::var("DEP_HDF5SRC_LIBRARY").expect("This is set by hdf5-src"); + let hdf5_lib_dir = find_library(&hdf5_lib, &hdf5_dir); + let p = std::path::PathBuf::from(&hdf5_lib_dir); + let p = p.parent().unwrap(); + println!("cargo:rustc-link-search=native={}", p.display()); + println!("cargo:rustc-link-lib=static={hdf5_lib}"); + config + .define("GDAL_USE_HDF5", "ON") + .define("HDF5_C_COMPILER_EXECUTABLE", format!("{hdf5_dir}/bin/h5cc")) + .define("HDF5_C_INCLUDE_DIR", format!("{hdf5_dir}/include")) + .define("HDF5_hdf5_LIBRARY_DEBUG", &hdf5_lib_dir) + .define("HDF5_hdf5_LIBRARY_RELEASE", &hdf5_lib_dir) + .define("GDAL_ENABLE_DRIVER_HDF5", "ON") + .define("HDF5_USE_STATIC_LIBRARIES", "ON"); + } else { + config.define("GDAL_USE_HDF5", "OFF"); + } + + if cfg!(feature = "DRIVER_NETCDF") { + let netcdf_root_dir = + std::env::var("DEP_NETCDFSRC_ROOT").expect("This is set by netcdf-src"); + let hdf5_dir = std::env::var("DEP_HDF5SRC_ROOT").expect("This is set by hdf5-src"); + let hl_library = std::env::var("DEP_HDF5SRC_HL_LIBRARY").expect("This is set by hdf5-src"); + let netcdf_lib = find_library("netcdf", &netcdf_root_dir); + let hl_library_path = find_library(&hl_library, &hdf5_dir); + let hl_library_path = std::path::PathBuf::from(hl_library_path); + let hl_library_path = hl_library_path.parent().unwrap(); + + let netcdf_library_path = std::path::PathBuf::from(&netcdf_lib); + let netcdf_library_path = netcdf_library_path.parent().unwrap(); + println!( + "cargo:rustc-link-search=native={}", + netcdf_library_path.display() + ); + println!("cargo:rustc-link-lib=static=netcdf"); + println!( + "cargo:rustc-link-search=native={}", + hl_library_path.display() + ); + println!("cargo:rustc-link-lib=static={hl_library}"); + config + .define("GDAL_USE_NETCDF", "ON") + .define("NETCDF_INCLUDE_DIR", format!("{netcdf_root_dir}/include")) + .define("NETCDF_LIBRARY", netcdf_lib) + .define("GDAL_ENABLE_DRIVER_NETCDF", "ON"); + } else { + config.define("GDAL_USE_NETCDF", "OFF"); + } + + if cfg!(feature = "curl-sys") { + let curl_root = std::env::var("DEP_CURL_ROOT").expect("set from curl-sys"); + config + .define("GDAL_USE_CURL", "ON") + .define("CURL_INCLUDE_DIR", format!("{curl_root}/include")) + .define("CURL_LIBRARY_DEBUG", format!("{curl_root}/build/libcurl.a")) + .define( + "CURL_LIBRARY_RELEASE", + format!("{curl_root}/build/libcurl.a"), + ) + .define("CURL_USE_STATIC_LIBS", "ON"); + } else { + config.define("GDAL_USE_CURL", "OFF"); + } + + handle_ogr_driver!(config, "DRIVER_AMIGOCLOUD"); + handle_ogr_driver!(config, "DRIVER_CARTO"); + handle_ogr_driver!(config, "DRIVER_DAAS"); + handle_ogr_driver!(config, "DRIVER_EEDA"); + handle_ogr_driver!(config, "DRIVER_ELASTIC"); + handle_ogr_driver!(config, "DRIVER_NGW"); + handle_gdal_driver!(config, "DRIVER_OGCAPI"); + handle_gdal_driver!(config, "DRIVER_PLMOSAIC"); + handle_gdal_driver!(config, "DRIVER_WCS"); + handle_gdal_driver!(config, "DRIVER_WMS"); + handle_gdal_driver!(config, "DRIVER_WMTS"); + + if cfg!(feature = "DRIVER_PG") { + let pq_include = std::env::var("DEP_PQ_SYS_SRC_INCLUDE").expect("this is set by pq-src"); + let pq_lib = std::env::var("DEP_PQ_SYS_SRC_LIB_DIR").expect("this is set by pq-src"); + let pq_lib_path = std::path::PathBuf::from(&pq_lib); + let pq_lib_path = if pq_lib_path.join("libpq.a").exists() { + pq_lib_path.join("libpq.a").display().to_string() + } else if pq_lib_path.join("pq.lib").exists() { + pq_lib_path.join("pq.lib").display().to_string() + } else { + panic!("Libpq not found in {pq_lib}"); + }; + config + .define("GDAL_USE_POSTGRESQL", "ON") + .define("PostgreSQL_INCLUDE_DIR", pq_include) + .define("PostgreSQL_LIBRARY_DEBUG", &pq_lib_path) + .define("PostgreSQL_LIBRARY_RELEASE", &pq_lib_path) + .define("OGR_ENABLE_DRIVER_PG", "ON"); + } else { + config.define("GDAL_USE_POSTGRESQL", "OFF"); + } + handle_gdal_driver!(config, "DRIVER_POSTGIS_RASTER"); + + if cfg!(target_env = "msvc") { + // otherwise there are linking issues + // because rust always links the + // MSVC release runtime + config.profile("Release"); + // see + // https://github.com/OSGeo/PROJ/commit/6e9b324ab7bf5909df7e68409e060282db14fa54#diff-af8fe2f9d33a9c3408ff7683bfebd1e2334b4506f559add92406be3e150268fb + config.cxxflag("-DPROJ_DLL="); + // that windows library is somehow required + println!("cargo:rustc-link-lib=Wbemuuid"); + } + + let res = config.build(); + + // sometimes it's lib and sometimes it's lib64 and sometimes `build/lib` + let lib_dir = res.join("lib64"); + println!( + "cargo:rustc-link-search=native={}", + lib_dir.to_str().unwrap() + ); + let lib_dir = res.join("lib"); + println!( + "cargo:rustc-link-search=native={}", + lib_dir.to_str().unwrap() + ); + let lib_dir = res.join("build/lib"); + println!( + "cargo:rustc-link-search=native={}", + lib_dir.to_str().unwrap() + ); + + //gdal likes to create gdal_d when configured as debug and on MSVC, so link to that one if it exists + if res.join("lib").join("gdald.lib").exists() { + println!("cargo:rustc-link-lib=static=gdald"); + } else { + println!("cargo:rustc-link-lib=static=gdal"); + } +} diff --git a/gdal-src/source b/gdal-src/source new file mode 160000 index 000000000..654f4907a --- /dev/null +++ b/gdal-src/source @@ -0,0 +1 @@ +Subproject commit 654f4907abbbf6bf4226d58a8c067d134eaf3ce9 diff --git a/gdal-src/src/lib.rs b/gdal-src/src/lib.rs new file mode 100644 index 000000000..87bf5c324 --- /dev/null +++ b/gdal-src/src/lib.rs @@ -0,0 +1,12 @@ +#[cfg(feature = "curl-sys")] +extern crate curl_sys; +#[cfg(feature = "DRIVER_HDF5")] +extern crate hdf5_src; +#[cfg(feature = "DRIVER_SQLITE")] +extern crate libsqlite3_sys; +#[cfg(feature = "DRIVER_NETCDF")] +extern crate netcdf_src; +#[cfg(feature = "DRIVER_PG")] +extern crate pq_src; + +extern crate proj_sys; diff --git a/gdal-sys/Cargo.toml b/gdal-sys/Cargo.toml index 4a2cad506..6d0cc3146 100644 --- a/gdal-sys/Cargo.toml +++ b/gdal-sys/Cargo.toml @@ -12,8 +12,14 @@ links="gdal" [dependencies] libc = "0.2" +gdal-src = { path = "../gdal-src/", optional = true } [build-dependencies] bindgen = { version = "0.69", optional = true } pkg-config = "0.3" semver = "1.0" + + +[features] +default = [] +bundled = ["dep:gdal-src"] diff --git a/gdal-sys/build.rs b/gdal-sys/build.rs index 0fccd63bc..c927a1288 100644 --- a/gdal-sys/build.rs +++ b/gdal-sys/build.rs @@ -68,7 +68,7 @@ fn main() { // Hardcode a prebuilt binding version while generating docs. // Otherwise docs.rs will explode due to not actually having libgdal installed. - if std::env::var("DOCS_RS").is_ok() { + if std::env::var("DOCS_RS").is_ok() || cfg!(feature = "bundled") { let version = Version::parse("3.8.0").expect("invalid version for docs.rs"); println!( "cargo:rustc-cfg=gdal_sys_{}_{}_{}", diff --git a/gdal-sys/src/lib.rs b/gdal-sys/src/lib.rs index 98d15c1b7..f8c611e1a 100644 --- a/gdal-sys/src/lib.rs +++ b/gdal-sys/src/lib.rs @@ -4,4 +4,7 @@ #![allow(clippy::upper_case_acronyms)] #![allow(rustdoc::bare_urls)] +#[cfg(feature = "bundled")] +extern crate gdal_src; + include!(concat!(env!("OUT_DIR"), "/bindings.rs"));