diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52302f2..7fba76e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,10 @@ on: jobs: lint: - runs-on: ubuntu-latest + strategy: + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v1 @@ -27,7 +30,8 @@ jobs: - name: Install GDAL run: | sudo apt-get update - sudo apt-get install cmake libgdal-dev + sudo apt-get install libgdal-dev + if: matrix.os == 'ubuntu-latest' - name: Install latest stable uses: actions-rs/toolchain@v1 @@ -46,6 +50,7 @@ jobs: with: command: clippy args: --all-targets --all-features + if: matrix.os == 'ubuntu-latest' - name: Test with cargo uses: actions-rs/cargo@v1.0.1 @@ -53,6 +58,16 @@ jobs: command: test toolchain: stable args: --workspace --all-features --all-targets + if: matrix.os == 'ubuntu-latest' + + - name: Test with cargo + uses: actions-rs/cargo@v1.0.1 + with: + command: test + toolchain: stable + # no gdal available + args: --workspace --exclude "h3ron-ndarray" + if: matrix.os != 'ubuntu-latest' # # rust-publish: diff --git a/h3ron-h3-sys/CHANGES.md b/h3ron-h3-sys/CHANGES.md index 3e15bf7..a5d4b13 100644 --- a/h3ron-h3-sys/CHANGES.md +++ b/h3ron-h3-sys/CHANGES.md @@ -12,6 +12,8 @@ python extension. ## h3ron-h3-sys Unreleased +* Drop the `cmake` build time dependency by building `libh3` with the `cc` crate. + ## h3ron-h3-sys 0.14.0 - 2022-08-23 * Upgrade to h3 v4.0.0 diff --git a/h3ron-h3-sys/Cargo.toml b/h3ron-h3-sys/Cargo.toml index b44bb16..cc5a498 100644 --- a/h3ron-h3-sys/Cargo.toml +++ b/h3ron-h3-sys/Cargo.toml @@ -11,14 +11,19 @@ readme = "README.md" homepage = "https://github.com/nmandery/h3ron" repository = "https://github.com/nmandery/h3ron" exclude = [ - "libh3/docs", + "libh3/cmake", + "libh3/CMakeLists.txt", + "libh3/CMakeTests.cmake", "libh3/dev-docs", - "libh3/website", - "libh3/src/apps", - "libh3/tests", + "libh3/docs", "libh3/examples", "libh3/.git", "libh3/.github", + "libh3/KML", + "libh3/scripts", + "libh3/src/apps", + "libh3/tests", + "libh3/website", ] [package.metadata.docs.rs] @@ -32,5 +37,6 @@ optional = true [build-dependencies] bindgen = "^0.60" -cmake = "^0.1" regex = "^1.5.5" +cc = "1" +glob = "0.3" diff --git a/h3ron-h3-sys/README.md b/h3ron-h3-sys/README.md index 718863e..3633504 100644 --- a/h3ron-h3-sys/README.md +++ b/h3ron-h3-sys/README.md @@ -8,4 +8,4 @@ bindgen-generated [rust](https://rust-lang.org) bindings for [H3](https://uber.g These bindings are basically just the autogenerated bindings emitted by [bindgen](https://github.com/rust-lang/rust-bindgen). The bindings compile using the included (referenced via a git submodule) H3 source code. H3 will be statically linked into the binary, so there is -no need to install a system-wide libh3. For the build `cmake` is required. +no need to install a system-wide libh3. diff --git a/h3ron-h3-sys/build.rs b/h3ron-h3-sys/build.rs index 9888a50..dade052 100644 --- a/h3ron-h3-sys/build.rs +++ b/h3ron-h3-sys/build.rs @@ -1,47 +1,75 @@ extern crate bindgen; -extern crate cmake; extern crate regex; -use cmake::Config; +use glob::glob; use regex::Regex; use std::env; -use std::fs; +use std::fs::{create_dir_all, read_to_string, OpenOptions}; +use std::io::Write; use std::path::PathBuf; +fn h3_version() -> (String, String, String) { + let version_contents = read_to_string("libh3/VERSION").unwrap(); + let cap = Regex::new("^(?P[0-9]+)\\.(?P[0-9]+)\\.(?P[0-9]+)") + .unwrap() + .captures(&version_contents) + .expect("version number not found"); + ( + cap["mj"].to_string(), + cap["mn"].to_string(), + cap["pt"].to_string(), + ) +} + +fn configure_header() -> (PathBuf, PathBuf) { + let mut include_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + include_dir.push("include"); + create_dir_all(&include_dir).unwrap(); + + let (version_major, version_minor, version_patch) = h3_version(); + let header_contents = read_to_string("libh3/src/h3lib/include/h3api.h.in") + .unwrap() + .replace("@H3_VERSION_MAJOR@", &version_major) + .replace("@H3_VERSION_MINOR@", &version_minor) + .replace("@H3_VERSION_PATCH@", &version_patch); + let mut h3api_header = include_dir.clone(); + h3api_header.push("h3api.h"); + write!( + OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .open(&h3api_header) + .unwrap(), + "{}", + header_contents + ) + .unwrap(); + + (include_dir, h3api_header) +} + fn main() { println!("cargo:rerun-if-changed=libh3"); + let (configured_includes, h3api_header) = configure_header(); - // build h3ron as a static library - let dst_path = Config::new("libh3") - .define("BUILD_BENCHMARKS", "OFF") - .define("BUILD_FILTERS", "OFF") - .define("BUILD_GENERATORS", "OFF") - .define("BUILD_TESTING", "OFF") - .define("BUILD_FUZZERS", "OFF") - .define("ENABLE_COVERAGE", "OFF") - .define("ENABLE_DOCS", "OFF") - .define("ENABLE_FORMAT", "OFF") - .define("ENABLE_LINTING", "OFF") - .build(); - - // link to the static library we just build - println!("cargo:rustc-link-lib=static=h3"); - println!( - "cargo:rustc-link-search=native={}", - dst_path.join("lib").display() - ); + cc::Build::new() + .include("libh3/src/h3lib/include") + .include(configured_includes) + .files(glob("libh3/src/h3lib/lib/*.c").unwrap().map(|p| p.unwrap())) + .compile("h3"); - let header_path = dst_path.join("include/h3/h3api.h"); let mut builder = bindgen::Builder::default().header( - dst_path - .join("include/h3/h3api.h") - .into_os_string() + h3api_header + .as_path() + .as_os_str() + .to_owned() .into_string() .expect("Path could not be converted to string"), ); // read the contents of the header to extract functions and types - let header_contents = fs::read_to_string(header_path).expect("Unable to read h3 header"); + let header_contents = read_to_string(h3api_header).expect("Unable to read h3 header"); for cap in Regex::new(r"H3_EXPORT\(\s*(?P[a-zA-Z0-9_]+)\s*\)") .unwrap() .captures_iter(&header_contents)