Skip to content

Commit

Permalink
add Rust-specific C++ wrapper, renderer args
Browse files Browse the repository at this point in the history
  • Loading branch information
nyurik committed Jan 29, 2025
1 parent a657c64 commit 688ef03
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 14 deletions.
3 changes: 2 additions & 1 deletion platform/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[package]
name = "maplibre-native-cxx"
name = "maplibre-native"
version = "0.1.0"
edition = "2021"

[dependencies]
cxx = "1.0"
clap = { version = "4.5.27", features = ["derive", "env"] }

[build-dependencies]
cmake = "0.1"
Expand Down
10 changes: 7 additions & 3 deletions platform/rust/build.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
use std::env;
use std::path::PathBuf;

//noinspection RsConstantConditionIf
fn main() {
let project_root = {
let manifest = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let root = manifest.join("core-src");
if root.is_symlink() || root.is_dir() {
// Use the symlinked directory to allow packaging
// Use the symlinked directory to allow crate packaging
root
} else {
// Modeled from the kuzu project
// Modeled from the kuzu project.
// If the path is not directory, this is probably an in-source build on windows where the symlink is unreadable.
manifest.parent().unwrap().parent().unwrap().to_path_buf()
}
Expand All @@ -37,6 +36,11 @@ fn main() {
// cxx build
let mut cxx = cxx_build::bridge("src/lib.rs");
cxx.include(project_root.join("include"))
.file("src/wrapper.cc")
.flag_if_supported("-std=c++20")
.compile("maplibre_rust_bindings");

println!("cargo:rerun-if-changed=src/lib.rs");
println!("cargo:rerun-if-changed=src/wrapper.cc");
println!("cargo:rerun-if-changed=include/wrapper.h");
}
1 change: 0 additions & 1 deletion platform/rust/core-src/ARCHITECTURE.md

This file was deleted.

11 changes: 11 additions & 0 deletions platform/rust/include/wrapper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once
#include "rust/cxx.h"
#include "mbgl/math/log2.hpp"

namespace ml {
namespace rust {

uint32_t get_42();

} // namespace rust
} // namespace ml
75 changes: 75 additions & 0 deletions platform/rust/src/bin/render.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use clap::Parser;

/// MapLibre Native render tool
#[derive(Parser, Debug)]
struct Args {
/// Rendering backend
#[arg(long)]
backend: Option<String>,

/// API key
#[arg(short = 't', long = "apikey", env = "MLN_API_KEY")]
apikey: Option<String>,

/// Map stylesheet
#[arg(short = 's', long = "style")]
style: Option<String>,

/// Output file name
#[arg(short = 'o', long = "output", default_value = "out.png")]
output: String,

/// Cache database file name
#[arg(short = 'c', long = "cache", default_value = "cache.sqlite")]
cache: String,

/// Directory to which asset:// URLs will resolve
#[arg(short = 'a', long = "assets", default_value = ".")]
assets: String,

/// Debug mode
#[arg(long)]
debug: bool,

/// Image scale factor
#[arg(short = 'r', long = "ratio", default_value_t = 1.0)]
ratio: f64,

/// Zoom level
#[arg(short = 'z', long = "zoom", default_value_t = 0.0)]
zoom: f64,

/// Longitude
#[arg(short = 'x', long = "lon", default_value_t = 0.0)]
lon: f64,

/// Latitude
#[arg(short = 'y', long = "lat", default_value_t = 0.0)]
lat: f64,

/// Bearing
#[arg(short = 'b', long = "bearing", default_value_t = 0.0)]
bearing: f64,

/// Pitch
#[arg(short = 'p', long = "pitch", default_value_t = 0.0)]
pitch: f64,

/// Image width
#[arg(long = "width", default_value_t = 512)]
width: u32,

/// Image height
#[arg(long = "height", default_value_t = 512)]
height: u32,

/// Map mode (e.g. 'static', 'tile', 'continuous')
#[arg(short = 'm', long = "mode")]
mode: Option<String>,
}

fn main() {
let args = Args::parse();

println!("Parsed arguments: {:?}", args);
}
26 changes: 17 additions & 9 deletions platform/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
// platform/rust/src/lib.rs

#[cxx::bridge(namespace = "mbgl::util")]
#[cxx::bridge]
mod ffi {
// cxx allows including C++ headers directly:
// C++ types exposed to Rust.
unsafe extern "C++" {
include!("mbgl/math/log2.hpp");
include!("maplibre-native/include/wrapper.h");

// We specify the C++ namespace and the free function name exactly.
// cxx can bind free functions directly if they have a compatible signature.
// The signature must match what's in log2.hpp:
// "uint32_t ceil_log2(uint64_t x);"
//
// We'll express that to Rust as (u64 -> u32).
#[namespace = "mbgl::util"]
pub fn ceil_log2(x: u64) -> u32;

// A function defined in the C++ rust wrapper rather than the core lib.
#[namespace = "ml::rust"]
pub fn get_42() -> u32;
}
}

/// A safe Rust wrapper so you can call `ceil_log2` from your code:
pub fn ceil_log2(x: u64) -> u32 {
ffi::ceil_log2(x)
}
// Re-export native functions that do not need safety wrappers.
pub use ffi::{get_42, ceil_log2};

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_rust_wrapper() {
let result = get_42();
assert_eq!(result, 42, "get_42() = 42");
}

#[test]
fn test_log2() {
let result = ceil_log2(1);
Expand Down
12 changes: 12 additions & 0 deletions platform/rust/src/wrapper.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "maplibre-native/include/wrapper.h"
#include "maplibre-native/src/lib.rs.h"

namespace ml {
namespace rust {

uint32_t get_42() {
return 42;
}

} // namespace rust
} // namespace ml

0 comments on commit 688ef03

Please sign in to comment.