Skip to content

Commit

Permalink
Improve sys/build.rs to allow to build meos from scratch
Browse files Browse the repository at this point in the history
  • Loading branch information
Davichet-e committed Oct 19, 2024
1 parent b75210b commit 1cf2811
Show file tree
Hide file tree
Showing 12 changed files with 111 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Cargo.lock
test
test.c
output.rs
wrapper.h
/wrapper.h
test.rs
test.py
data/
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "sys/meos-src/source"]
path = sys/meos-src/source
url = https://github.com/MobilityDB/MobilityDB.git
branch = stable-1.2
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ edition = "2021"

[dependencies]
paste = "1.0.15"
meos-sys = { path = "sys", version = "0.1.5" }
meos-sys = { path = "sys", version = "0.1.7", features = ["v1_2"] }
chrono = "0.4.38"
libc = "0.2.155"
bitmask-enum = "2.2.4"
Expand Down
9 changes: 5 additions & 4 deletions sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "meos-sys"
version = "0.1.6"
version = "0.1.8"
authors = ["David García Morillo <[email protected]>"]

repository = "https://github.com/MobilityDB/meos-rs"
Expand All @@ -14,16 +14,17 @@ edition = "2021"
links = "meos"

[dependencies]
meos-src = { path = "./meos-src", version = "0.1.0", optional = true }

[build-dependencies]
pkg-config = "0.3.30"
cmake = "0.1"
bindgen = { version = "0.70.1", optional = true }

[features]
default = ["v1_2"]
default = []
v1_1 = []
v1_2 = []

buildtime_bindgen = ["dep:bindgen"]
bundled_proj = ["buildtime_bindgen"]
bindgen = ["dep:bindgen"]
bundled = ["bindgen", "dep:meos-src"]
18 changes: 17 additions & 1 deletion sys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ use the [meos](https://github.com/MobilityDB/meos-rs) crate.

You can also find it on [crates.io](https://crates.io/crates/meos).

Versions >= 1.1 are supported.

## Usage
You need to select as features what version do you want to obtain the bindings from (`v1_1`, `v1_2`), or alternatively, whether you want to build MEOS from scratch (`bundled`). This will mean adding to your `Cargo.toml`:
```toml
# Cargo.toml
[dependencies]
meos-sys = { version = "0.1.8", features = ["v1_2"] }
```

## Build

The build by default will use system-installed MEOS, `pkg-config` is used to automatically detect MEOS
Expand All @@ -32,5 +42,11 @@ DYLD_FALLBACK_LIBRARY_PATH=<path to MEOS>/lib MEOS_LIB_DIR=<path to MEOS>/lib ME

```

You can also enable the `bundled` feature to build MEOS from scratch. Note you will still have to have installed in your system GEOS, PROJ and JSON-C libraries. You can install all of them by running the following command in your (Debian based) machine:
```bash
sudo apt-get install libgeos-dev proj-bin libproj-dev proj-data libjson-c-dev
```

## Binding generation
By default, meos-sys will use the pregenerated bindings for the 1.2 version, the 1.1 ones is also available. Alternatively, you can generate your own bindings from your `libmeos` installation by specifying the `bindgen` feature.
The 1.2 and 1.1 versions are already available as prebuilt bindings. Alternatively, you can generate your own bindings from your `libmeos` installation by specifying the `bindgen` feature.

77 changes: 49 additions & 28 deletions sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,72 @@
use std::env;
use std::ffi::OsString;
use std::path::PathBuf;

/// Detect MEOS config parameters using pkg-config (not available for all GEOS
const MINIMUM_MEOS_VERSION: &str = "1.1.0";

/// Detect MEOS config parameters using pkg-config (not available for all MEOS
/// versions)
fn detect_meos_via_pkg_config() -> Option<PathBuf> {
fn detect_meos_via_pkg_config() -> Result<pkg_config::Library, pkg_config::Error> {
use pkg_config::Config;

let meos_pkg_config = Config::new().probe("meos");

meos_pkg_config.map(|pk| pk.include_paths[0].clone()).ok()
Config::new()
.atleast_version(MINIMUM_MEOS_VERSION)
.probe("meos")
}

fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=MEOS_LIB_DIR");

let pk_include_path = detect_meos_via_pkg_config();

// Try to find the library manually
let include_path = if !pk_include_path.is_some() {
let default_include_path = String::from("/usr/local/lib/");
let lib_dir_env = env::var_os("MEOS_LIB_DIR")
.map(OsString::into_string)
.transpose()
.ok()
.flatten()
.unwrap_or(default_include_path.clone());

// Tell cargo to look for shared libraries in the specified directory
println!("cargo:rustc-link-search={lib_dir_env}");
// If `bundled` is on, use the git submodule to build MEOS from scratch
let include_path = if cfg!(feature = "bundled") {
// Defined in `meos-src` build.rs file
let meos_path = std::env::var("DEP_MEOSSRC_SEARCH").unwrap();

// Tell cargo to tell rustc to link the system meos shared library.
println!("cargo:rustc-link-lib=dylib=meos");
default_include_path
println!("cargo:rustc-link-search={meos_path}");
println!("cargo:rustc-link-lib=meos");

meos_path
} else {
pk_include_path.unwrap().display().to_string()
let pk = detect_meos_via_pkg_config();

match pk {
Ok(meos) => meos.include_paths[0].clone().display().to_string(),
Err(pkg_config_err) => {
if matches!(pkg_config_err, pkg_config::Error::Command { cause, .. } if cause.kind() == std::io::ErrorKind::NotFound)
{
panic!("Could not find `pkg-config` in your path. Please install it before running meos-sys-bind.");
}
// As a fallback, since pkg-config was not configured in meos until 1.2, we will try a default path.
if cfg!(feature = "v1_1") {
let default_include_path = String::from("/usr/local/lib/");
let lib_dir_env = env::var_os("MEOS_LIB_DIR")
.map(OsString::into_string)
.transpose()
.ok()
.flatten()
.unwrap_or(default_include_path.clone());

// Tell cargo to look for shared libraries in the specified directory
println!("cargo:rustc-link-search={lib_dir_env}");

// Tell cargo to tell rustc to link the system meos shared library.
println!("cargo:rustc-link-lib=dylib=meos");
default_include_path
} else {
panic!("Could not detect MEOS using pkg-config.");
}
}
}
};

#[cfg(feature = "buildtime_bindgen")]
#[cfg(feature = "bindgen")]
generate_bindings(include_path.into()).unwrap();

#[cfg(not(feature = "buildtime_bindgen"))]
#[cfg(not(feature = "bindgen"))]
let _ = include_path;
}

#[cfg(feature = "buildtime_bindgen")]
#[cfg(feature = "bindgen")]
fn generate_bindings(include_path: std::path::PathBuf) -> Result<(), Box<dyn std::error::Error>> {
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
Expand All @@ -61,7 +82,7 @@ fn generate_bindings(include_path: std::path::PathBuf) -> Result<(), Box<dyn std
.expect("Unable to generate bindings");

// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let out_path = std::path::PathBuf::from(env::var("OUT_DIR").unwrap());
bindings.write_to_file(out_path.join("bindings.rs"))?;

Ok(())
Expand Down
17 changes: 17 additions & 0 deletions sys/meos-src/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "meos-src"
version = "0.1.1"
edition = "2021"
links = "meossrc"
build = "build.rs"
description = "static library build for meos-sys"
repository = "https://github.com/MobilityDB/meos-rs"
authors = ["David García Morillo <[email protected]>"]
license-file = "../LICENSE"
exclude = ["source/mobilitydb", "source/meos/examples"]

[dependencies]

[build-dependencies]
cmake = "0.1"

11 changes: 11 additions & 0 deletions sys/meos-src/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let libmeos = cmake::Config::new("source")
.define("MEOS", "1")
.very_verbose(true)
.build();
println!("cargo:lib=meos");
let search_path = format!("{}/lib", libmeos.display());
assert!(std::path::Path::new(&search_path).exists());
println!("cargo:search={}", search_path);
}
1 change: 1 addition & 0 deletions sys/meos-src/source
Submodule source added at 3f7417
1 change: 1 addition & 0 deletions sys/meos-src/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

10 changes: 3 additions & 7 deletions sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

#[cfg(all(
feature = "v1_1",
not(feature = "v1_2"),
not(feature = "buildtime_bindgen")
))]
#[cfg(all(feature = "v1_1", not(feature = "v1_2"), not(feature = "bindgen")))]
include!("../prebuilt-bindings/meos_1.1.rs");

#[cfg(all(feature = "v1_2", not(feature = "buildtime_bindgen")))]
#[cfg(all(feature = "v1_2", not(feature = "bindgen")))]
include!("../prebuilt-bindings/meos_1.2.rs");

#[cfg(feature = "buildtime_bindgen")]
#[cfg(feature = "bindgen")]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
1 change: 1 addition & 0 deletions sys/wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <meos.h>

0 comments on commit 1cf2811

Please sign in to comment.