Skip to content

Commit

Permalink
Replace generic prebuilt bindings with target specific bindings
Browse files Browse the repository at this point in the history
* Replace generic prebuilt bindings with target specific bindings

This commit replaces the generic gdal bindings with architecture
specific ones. This is necessary as bindgen 0.71 introduced a feature
that essentially turned the size assertions into a compile time check.
This pointed to several potential mismatches between the bindings and
the actual type definitions.

This commit now introduces different bindings for 32 and 64 bit
platforms. Additionally it differentiates between windows and
linux/macos bindings. For any unsupported platform a build error is
generated that the built_time bindgen feature needs to be used there.

Finally it adds documentation on how to generate these bindings.
  • Loading branch information
lnicola committed Nov 22, 2024
1 parent 86a7e05 commit 11f43d7
Show file tree
Hide file tree
Showing 31 changed files with 233,604 additions and 1,597 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Drop support for GDAL <3.4 ([#578](https://github.com/georust/gdal/pull/578))
- Regenerate the pre-built bindings with `std::ffi` instead of `libc` for C types ([#573](https://github.com/georust/gdal/pull/573))
- Emit `FILE`, `tm` and `VSIStatBuf` as opaque types ([#573](https://github.com/georust/gdal/pull/573))
- Upgrade `ndarray` dependency to 0.16 ([#569](https://github.com/georust/gdal/pull/569))
- Upgrade `thiserror` dependency to 2.0 ([#586](https://github.com/georust/gdal/pull/586))

Expand Down
37 changes: 37 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,40 @@ git commit -m "Update bundled gdal version to 3.8.4"

These steps assume that there are no fundamental changes to the gdal build system.

# Generating Binding

```bash
docker run -it --rm -v ./gdal-sys:/gdal_sys ghcr.io/osgeo/gdal:ubuntu-full-$GDAL_VERSION bash
# everything from now on is inside of the container

export GDAL_VERSION=3_4 # or anything else
# install mingw toolchain for generating windows bindings
# install libclang for bindgen
# gcc-i686-linux-gnu to generate bindings for 32 bit linux
apt update
apt install -y libclang-dev mingw-w64 gcc-i686-linux-gnu pkg-config rustfmt

# install bindgen
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/rust-lang/rust-bindgen/releases/download/v0.70.1/bindgen-cli-installer.sh | sh
source $HOME/.cargo/env

# create the output directory for the prebuild bindings if necessary
mkdir -p /gdal_sys/prebuilt-bindings/$GDAL_VERSION/

# if you update these command consider updating the command in gdal-sys/build.rs
# make sure to use the same bindgen flags (everything before wrapper) for
# all targets
#
# 64 bit linux/macos
bindgen --constified-enum-module ".*" --ctypes-prefix ::std::ffi --allowlist-function "(CPL|CSL|GDAL|OGR|OSR|OCT|VSI).*" /gdal_sys/wrapper.h > /gdal_sys/prebuilt-bindings/$GDAL_VERSION/gdal_x86_64-unknown-linux-gnu.rs
# 32 bit linux/macos
bindgen --constified-enum-module ".*" --ctypes-prefix ::std::ffi --allowlist-function "(CPL|CSL|GDAL|OGR|OSR|OCT|VSI).*" /gdal_sys/wrapper.h -- -target i686-unknown-linux-gnu --sysroot /usr/i686-linux-gnu/ -I /usr/include > /gdal_sys/prebuilt-bindings/$GDAL_VERSION/gdal_i686-unknown-linux-gnu.rs

# make sure we don't get the wrong system headers
rm /usr/include/stdio.h /usr/include/stdlib.h /usr/include/limits.h /usr/include/features-time64.h /usr/include/features.h /usr/include/malloc.h /usr/include/string.h /usr/include/ctype.h /usr/include/errno.h /usr/include/math.h /usr/include/stdint.h /usr/include/time.h

# 64 bit windows
bindgen --constified-enum-module ".*" --ctypes-prefix ::std::ffi --allowlist-function "(CPL|CSL|GDAL|OGR|OSR|OCT|VSI).*" /gdal_sys/wrapper.h -- -target x86_64-pc-windows-gnu -I /usr/include/ > /gdal_sys/prebuilt-bindings/$GDAL_VERSION/gdal_x86_64-pc-windows-gnu.rs
# 32 bit windows
bindgen --constified-enum-module ".*" --ctypes-prefix ::std::ffi --allowlist-function "(CPL|CSL|GDAL|OGR|OSR|OCT|VSI).*" /gdal_sys/wrapper.h -- -target i686-pc-windows-gnu -I /usr/include/ > /gdal_sys/prebuilt-bindings/$GDAL_VERSION/gdal_i686-pc-windows-gnu.rs
```
21 changes: 18 additions & 3 deletions gdal-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub fn write_bindings(include_paths: Vec<String>, out_path: &Path) {
// To generate the bindings manually, use
// bindgen --constified-enum-module ".*" --ctypes-prefix ::std::ffi --allowlist-function "(CPL|CSL|GDAL|OGR|OSR|OCT|VSI).*" wrapper.h -- $(pkg-config --cflags-only-I gdal) -fretain-comments-from-system-headers
// If you add a new pre-built version, make sure to bump the docs.rs version in main.
// If you update this command consider updating the command in `DEVELOPMENT.md`

let mut builder = bindgen::Builder::default()
.size_t_is_usize(true)
Expand Down Expand Up @@ -241,11 +242,25 @@ fn main() {
"cargo:rustc-cfg=gdal_sys_{}_{}_{}",
version.major, version.minor, version.patch
);

let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").expect("Set by cargo");
let is_windows = std::env::var("CARGO_CFG_WINDOWS").is_ok();
let ptr_size = std::env::var("CARGO_CFG_TARGET_POINTER_WIDTH").expect("Set by cargo");

let binding_name = match (target_arch.as_str(), ptr_size.as_str(), is_windows) {
("x86_64" | "aarch64", "64", false) => "gdal_x86_64-unknown-linux-gnu.rs",
("x86_64", "64", true) => "gdal_x86_64-pc-windows-gnu.rs",
("x86" | "arm", "32", false) => "gdal_i686-unknown-linux-gnu.rs",
("x86", "32", true) => "gdal_i686-pc-windows-gnu.rs",
_ => panic!(
"No pre-built bindings available for target: {} ptr_size: {} is_windows: {}",
target_arch, ptr_size, is_windows
),
};
let binding_path = PathBuf::from(format!(
"prebuilt-bindings/gdal_{}_{}.rs",
version.major, version.minor
"prebuilt-bindings/{}_{}/{binding_name}",
version.major, version.minor,
));

if !binding_path.exists() {
panic!("No pre-built bindings available for GDAL version {}.{}. Enable the `bindgen` feature of the `gdal` or `gdal-sys` crate to generate them during build.", version.major, version.minor);
}
Expand Down
Loading

0 comments on commit 11f43d7

Please sign in to comment.