Allow compiling with Rust code (#3137)
Co-authored-by: Yuri Astrakhan <YuriAstrakhan@gmail.com> Co-authored-by: Ian Wagner <ianwagner+github@switzerlandmail.ch>
This commit is contained in:
1
rustutils/.gitignore
vendored
Normal file
1
rustutils/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
46
rustutils/BUILD.bazel
Normal file
46
rustutils/BUILD.bazel
Normal file
@@ -0,0 +1,46 @@
|
||||
load("@rules_rust//rust:defs.bzl", "rust_static_library")
|
||||
|
||||
genrule(
|
||||
name = "cpp_bindings",
|
||||
srcs = [
|
||||
"src/color.rs",
|
||||
],
|
||||
outs = [
|
||||
"cpp/include/rustutils/color.hpp",
|
||||
"cpp/src/color.rs.cpp",
|
||||
],
|
||||
cmd = "CXXBRIDGE_CMD=$(location @cxx.rs//:codegen) ./$(location :generate.sh) $(@D) $(SRCS)",
|
||||
# Using the cxxbridge binary built by Bazel
|
||||
tools = [
|
||||
":generate.sh",
|
||||
"@cxx.rs//:codegen",
|
||||
],
|
||||
)
|
||||
|
||||
rust_static_library(
|
||||
name = "rustutils",
|
||||
srcs = [
|
||||
"src/color.rs",
|
||||
"src/lib.rs",
|
||||
],
|
||||
crate_name = "rustutils",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@crates//:csscolorparser",
|
||||
"@crates//:cxx",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "rustutilslib",
|
||||
srcs = [
|
||||
":cpp_bindings",
|
||||
],
|
||||
includes = [
|
||||
"cpp/include",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":rustutils",
|
||||
],
|
||||
)
|
||||
162
rustutils/Cargo.lock
generated
Normal file
162
rustutils/Cargo.lock
generated
Normal file
@@ -0,0 +1,162 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
|
||||
|
||||
[[package]]
|
||||
name = "csscolorparser"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf"
|
||||
dependencies = [
|
||||
"phf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.124"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "273dcfd3acd4e1e276af13ed2a43eea7001318823e7a726a6b3ed39b4acc0b82"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
"cxxbridge-macro",
|
||||
"link-cplusplus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.124"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "839fcd5e43464614ffaa989eaf1c139ef1f0c51672a1ed08023307fa1b909ccd"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.124"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "rustutils"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"csscolorparser",
|
||||
"cxx",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
19
rustutils/Cargo.toml
Normal file
19
rustutils/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "rustutils"
|
||||
version = "0.1.0"
|
||||
authors = ["MapLibre contributors"]
|
||||
description = "Core Rust utilities for MapLibre Native"
|
||||
edition = "2021"
|
||||
license = "BSD-2-Clause"
|
||||
repository = "https://github.com/maplibre/maplibre-native"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
csscolorparser = "0.6.2"
|
||||
cxx = "1"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
35
rustutils/generate.sh
Executable file
35
rustutils/generate.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Run this script from the repository root
|
||||
# Install cxxbridge with:
|
||||
# $ cargo install cxxbridge-cmd
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$#" -lt 2 ]; then
|
||||
echo "Error: output_dir and at least one input file are required." >&2
|
||||
echo "Usage: $0 <output_dir> <input_file1> [input_file2 ...]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use CXXBRIDGE_CMD environment variable if set, otherwise fallback to "cxxbridge"
|
||||
CXXBRIDGE_CMD="${CXXBRIDGE_CMD:-cxxbridge}"
|
||||
|
||||
output_dir="$1"
|
||||
shift
|
||||
|
||||
for input_file in "$@"; do
|
||||
if [[ "$input_file" != *.rs ]]; then
|
||||
echo "Error: All input files must have a .rs extension. Invalid file: $input_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
mkdir -p "$output_dir/cpp/include/rustutils"
|
||||
mkdir -p "$output_dir/cpp/src"
|
||||
|
||||
for input_file in "$@"; do
|
||||
base_name=$(basename "$input_file" .rs)
|
||||
"$CXXBRIDGE_CMD" "$input_file" --header > "$output_dir/cpp/include/rustutils/${base_name}.hpp"
|
||||
"$CXXBRIDGE_CMD" "$input_file" > "$output_dir/cpp/src/${base_name}.rs.cpp"
|
||||
done
|
||||
63
rustutils/rustutils.cmake
Normal file
63
rustutils/rustutils.cmake
Normal file
@@ -0,0 +1,63 @@
|
||||
# Include guard
|
||||
if(TARGET rustutils)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
Corrosion
|
||||
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
|
||||
GIT_TAG v0.5 # Optionally specify a commit hash, version tag or branch here
|
||||
)
|
||||
FetchContent_MakeAvailable(Corrosion)
|
||||
|
||||
corrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_LIST_DIR}/Cargo.toml)
|
||||
|
||||
# Define output directories for generated bindings
|
||||
set(RUSTUTILS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/rustutils_bindings")
|
||||
set(RUSTUTILS_INCLUDE_DIR "${RUSTUTILS_OUTPUT_DIR}/cpp/include")
|
||||
set(RUSTUTILS_SRC_DIR "${RUSTUTILS_OUTPUT_DIR}/cpp/src")
|
||||
|
||||
# Ensure the output directories exist
|
||||
file(MAKE_DIRECTORY ${RUSTUTILS_INCLUDE_DIR})
|
||||
file(MAKE_DIRECTORY ${RUSTUTILS_SRC_DIR})
|
||||
|
||||
set(RUSTUTILS_RS_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/color.rs
|
||||
)
|
||||
|
||||
# Initialize variables for generated files
|
||||
set(RUSTUTILS_GENERATED_SOURCES)
|
||||
set(RUSTUTILS_GENERATED_HEADERS)
|
||||
|
||||
# Transform .rs to .rs.cpp and .hpp
|
||||
foreach(rs_file ${RUSTUTILS_RS_FILES})
|
||||
get_filename_component(base_name ${rs_file} NAME_WE)
|
||||
list(APPEND RUSTUTILS_GENERATED_SOURCES "${RUSTUTILS_SRC_DIR}/${base_name}.rs.cpp")
|
||||
list(APPEND RUSTUTILS_GENERATED_HEADERS "${RUSTUTILS_INCLUDE_DIR}/rustutils/${base_name}.hpp")
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${RUSTUTILS_GENERATED_SOURCES} ${RUSTUTILS_GENERATED_HEADERS}
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
${CMAKE_CURRENT_LIST_DIR}/generate.sh ${RUSTUTILS_OUTPUT_DIR} ${RUSTUTILS_RS_FILES}
|
||||
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/generate.sh ${RUSTUTILS_RS_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
COMMENT "Generating C++ bindings for Rust sources"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(rustutils_bindings DEPENDS ${RUSTUTILS_GENERATED_SOURCES} ${RUSTUTILS_GENERATED_HEADERS})
|
||||
|
||||
add_library(mbgl-rustutils STATIC
|
||||
${RUSTUTILS_GENERATED_SOURCES}
|
||||
)
|
||||
|
||||
add_dependencies(mbgl-rustutils rustutils_bindings)
|
||||
|
||||
target_include_directories(mbgl-rustutils PUBLIC
|
||||
${RUSTUTILS_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(mbgl-rustutils PUBLIC rustutils)
|
||||
35
rustutils/src/color.rs
Normal file
35
rustutils/src/color.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use csscolorparser::Color;
|
||||
|
||||
#[cxx::bridge(namespace = "rustutils")]
|
||||
mod ffi {
|
||||
struct ParsedColor {
|
||||
pub success: bool,
|
||||
pub r: f32,
|
||||
pub g: f32,
|
||||
pub b: f32,
|
||||
pub a: f32,
|
||||
}
|
||||
|
||||
extern "Rust" {
|
||||
fn parse_css_color(css_str: &str) -> ParsedColor;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_css_color(css_str: &str) -> ffi::ParsedColor {
|
||||
css_str
|
||||
.parse::<Color>()
|
||||
.map(|color| ffi::ParsedColor {
|
||||
success: true,
|
||||
r: color.r as f32,
|
||||
g: color.g as f32,
|
||||
b: color.b as f32,
|
||||
a: color.a as f32,
|
||||
})
|
||||
.unwrap_or_else(|_| ffi::ParsedColor {
|
||||
success: false,
|
||||
r: 0.0,
|
||||
g: 0.0,
|
||||
b: 0.0,
|
||||
a: 0.0,
|
||||
})
|
||||
}
|
||||
1
rustutils/src/lib.rs
Normal file
1
rustutils/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
mod color;
|
||||
Reference in New Issue
Block a user