Skip to content

Commit

Permalink
Rust integration (experimental) (#99)
Browse files Browse the repository at this point in the history
* First support for Rust.
* Bump version to 0.7.0

---------

Signed-off-by: Holger Rapp <HolgerRapp@gmx.net>
Signed-off-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
Co-authored-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
  • Loading branch information
SirVer and hikinggrass authored Sep 28, 2023
1 parent 0a3d60e commit dafb3d9
Show file tree
Hide file tree
Showing 15 changed files with 864 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
*build
*build-cross
target
watcher.lua
workspace.yaml
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14)

project(everest-framework
VERSION 0.6.2
VERSION 0.7.0
DESCRIPTION "The open operating system for e-mobility charging stations"
LANGUAGES CXX C
)
Expand All @@ -16,6 +16,7 @@ option(FRAMEWORK_INSTALL "Install the library (shared data might be installed an
option(CMAKE_RUN_CLANG_TIDY "Run clang-tidy" OFF)
option(EVEREST_ENABLE_JS_SUPPORT "Enable everestjs for JavaScript modules" ON)
option(EVEREST_ENABLE_PY_SUPPORT "Enable everestpy for Python modules" ON)
option(EVEREST_ENABLE_RS_SUPPORT "Enable everestrs for Rust modules" OFF)

# make own cmake modules available
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
Expand Down Expand Up @@ -93,6 +94,10 @@ if (EVEREST_ENABLE_PY_SUPPORT)
add_subdirectory(everestpy)
endif()

if (EVEREST_ENABLE_RS_SUPPORT)
add_subdirectory(everestrs)
endif()

# FIXME (aw): should this be installed or not? Right now it is needed for the
# current packaging approach
install(TARGETS framework
Expand Down
19 changes: 19 additions & 0 deletions cmake/cxxrs.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function(emit_cxxrs_header)
set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/cxxbridge/rust/")
file(MAKE_DIRECTORY ${output_dir})
execute_process(COMMAND ${CXXBRIDGE} --header -o ${output_dir}cxx.h)
endfunction()

function(emit_cxxrs_for_module module_name)
set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/cxxbridge/${module_name}/")
file(MAKE_DIRECTORY ${output_dir})

add_custom_command(
OUTPUT ${output_dir}lib.rs.h ${output_dir}lib.rs.cc
COMMAND ${CXXBRIDGE} ${CMAKE_CURRENT_SOURCE_DIR}/${module_name}/src/lib.rs --header -o ${output_dir}lib.rs.h
COMMAND ${CXXBRIDGE} ${CMAKE_CURRENT_SOURCE_DIR}/${module_name}/src/lib.rs -o ${output_dir}lib.rs.cc
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${module_name}/src/lib.rs
COMMENT "Generating cxx for ${module_name}"
VERBATIM
)
endfunction()
35 changes: 35 additions & 0 deletions everestrs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
include(cxxrs)

find_program(CXXBRIDGE cxxbridge PATHS "$ENV{HOME}/.cargo/bin/")
if (CXXBRIDGE STREQUAL "CXXBRIDGE-NOTFOUND")
message("Could not find cxxbridge, trying to install with `cargo install cxxbridge-cmd'")
find_program(CARGO cargo PATHS "$ENV{HOME}/.cargo/bin/")
if (CARGO STREQUAL "CARGO-NOTFOUND")
message(FATAL_ERROR "Requires cargo available in path, install via rustup https://rustup.rs/")
endif()
execute_process(COMMAND ${CARGO} install cxxbridge-cmd --version 1.0.107)
find_program(CXXBRIDGE cxxbridge PATHS "$ENV{HOME}/.cargo/bin/")
endif()

emit_cxxrs_header()
emit_cxxrs_for_module(everestrs)

add_library(everestrs_sys STATIC
${CMAKE_CURRENT_BINARY_DIR}/cxxbridge/everestrs/lib.rs.cc
everestrs_sys/everestrs_sys.cpp
)

target_include_directories(everestrs_sys PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}/cxxbridge
)

# This is a requirement that linking works on systems enforcing PIE.
set_property(TARGET everestrs_sys PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(everestrs_sys
PRIVATE
everest::framework
everest::log
)

install(TARGETS everestrs_sys LIBRARY)
196 changes: 196 additions & 0 deletions everestrs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions everestrs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[workspace]
resolver = "2"
members = [
"everestrs",
]
11 changes: 11 additions & 0 deletions everestrs/everestrs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "everestrs"
version = "0.1.0"
edition = "2021"

[dependencies]
argh = "0.1.10"
cxx = { version = "1.0.107", features = ["c++17"] }
serde = { version = "1.0.175", features = ["derive"] }
serde_json = "1"
thiserror = "1.0.48"
29 changes: 29 additions & 0 deletions everestrs/everestrs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Rust support for everest

This is Rust support using cxx.rs to wrap the framework C++ library.

## Trying it out

- Install rust as outlined on <https://rustup.rs/>, which should just be this
one line: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
- Built your workspace as outlined in `everest-core` README, make sure to tell
cMake to enable `EVEREST_ENABLE_RS_SUPPORT`. Note, that the Rust code relies
on being built in a workspace where `make install` was run once.
- You can now try building the code, but it will not do anything: `cd everestrs
&& cargo build --all`
- If you want to play with a node, check out `https://github.com/EVerest/everest-core/pull/344` in your workspace and run make install.
- Go to `everest-core/modules/RsSomkeTest` and run `cargo build` there.
- There is no support for building or installing Rust modules with cMake
currently, so let's fake the installation:
- Go to `everest-core/build/dist/libexec/everest/modules` and create the stuff needed for a module:
~~~bash
mkdir RsSmokeTest
ln -s ../../../../../../modules/RsSmokeTest/target/debug/smoke_test RsSmokeTest
ln -s ../../../../../../modules/RsSmokeTest/manifest.yaml .
~~~
- You should now be able to configure the `RsSmokeTest` module in your config
YAML.

## Status

This code is currently only supporting providing an interface to be implemented, i.e. no variables publish or receiving and no calling of other interfaces. Those features are straightforward, quick and easy to implement, but for now this is probably enough to iron out the integration questions.
Loading

0 comments on commit dafb3d9

Please sign in to comment.