diff --git a/services/backup/CMakeLists.txt b/services/backup/CMakeLists.txt --- a/services/backup/CMakeLists.txt +++ b/services/backup/CMakeLists.txt @@ -25,6 +25,10 @@ REQUIRED ) +# Rust integration +include(cmake-components/corrosion_cxx.cmake) +find_package(Corrosion REQUIRED) + if(${CMAKE_CURRENT_SOURCE_DIR} MATCHES "^\/transferred.*") # Inside the docker build contex set(_proto_path "grpc") @@ -56,6 +60,8 @@ ${SOURCE_CODE} ) +add_library_rust(PATH rust_lib NAMESPACE backup) + target_include_directories( backup PUBLIC @@ -87,6 +93,7 @@ comm-services-common comm-client-base-reactors comm-server-base-reactors + backup::rust_lib ) target_link_libraries( diff --git a/services/backup/Dockerfile b/services/backup/Dockerfile --- a/services/backup/Dockerfile +++ b/services/backup/Dockerfile @@ -10,18 +10,20 @@ ENV COMM_TEST_SERVICES=${COMM_TEST_SERVICES} ENV COMM_SERVICES_SANDBOX=${COMM_SERVICES_SANDBOX} -WORKDIR /transferred +WORKDIR /transferred/backup -COPY services/backup/ backup/ -COPY services/lib/src/ lib/src/ +COPY services/lib/docker/ scripts/ -WORKDIR /transferred/backup +RUN scripts/install_rust.sh +ENV PATH="${PATH}:~/.cargo/bin" +RUN scripts/install_corrosion.sh COPY native/cpp/CommonCpp/grpc grpc/ -COPY services/lib/docker/ scripts/ +COPY services/lib/cmake-components cmake-components/ -RUN scripts/build_service.sh +COPY services/backup/ /transferred/backup/ +COPY services/lib/src/ /transferred/lib/src/ -WORKDIR /transferred +RUN scripts/build_service.sh CMD if [ "$COMM_TEST_SERVICES" -eq 1 ]; then scripts/run_tests.sh; else scripts/run_service.sh; fi diff --git a/services/backup/rust_lib/Cargo.lock b/services/backup/rust_lib/Cargo.lock new file mode 100644 --- /dev/null +++ b/services/backup/rust_lib/Cargo.lock @@ -0,0 +1,173 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "cxx" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "873c2e83af70859af2aaecd1f5d862f3790b747b1f4f50fb45a931d000ac0422" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49edea7163bbc7a39e3d829b4b0b66a9d30486973152842b7413f2c7b5632bf" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46b787c15af80277db5c88c6ac6c502ae545e622f010e06f95e540d34931acf" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba3f3a7efa46626878fb5d324fabca4d19d2956b6ae97ce43044ef4515f5abc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cae2cd7ba2f3f63938b9c724475dfb7b9861b545a90324476324ed21dbc8c8" +dependencies = [ + "cc", +] + +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + +[[package]] +name = "proc-macro2" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rust_lib" +version = "0.1.0" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "syn" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "unicode-ident" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/services/backup/rust_lib/Cargo.toml b/services/backup/rust_lib/Cargo.toml new file mode 100644 --- /dev/null +++ b/services/backup/rust_lib/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "rust_lib" +version = "0.1.0" +edition = "2021" + +[dependencies] +cxx = "1.0" + +[build-dependencies] +cxx-build = "1.0" + +[lib] +crate-type = ["staticlib"] + +[profile.release] +debug = true +panic = "abort" + +[profile.dev] +panic = "abort" diff --git a/services/backup/rust_lib/build.rs b/services/backup/rust_lib/build.rs new file mode 100644 --- /dev/null +++ b/services/backup/rust_lib/build.rs @@ -0,0 +1,4 @@ +fn main() { + let _build = cxx_build::bridge("src/lib.rs"); + println!("cargo:rerun-if-changed=src/lib.rs"); +} diff --git a/services/backup/rust_lib/src/lib.rs b/services/backup/rust_lib/src/lib.rs new file mode 100644 --- /dev/null +++ b/services/backup/rust_lib/src/lib.rs @@ -0,0 +1,10 @@ +#[cxx::bridge] +mod ffi { + extern "Rust" { + fn test_function() -> i32; + } +} + +pub fn test_function() -> i32 { + 0 +} diff --git a/services/lib/cmake-components/corrosion_cxx.cmake b/services/lib/cmake-components/corrosion_cxx.cmake new file mode 100644 --- /dev/null +++ b/services/lib/cmake-components/corrosion_cxx.cmake @@ -0,0 +1,109 @@ +# Creates a target including rust lib and cxxbridge named ${NAMESPACE}::${LAST STEM OF PATH} +# must match the crate name ie "some/path/to/myrustcrate" -> "libmyrustcrate.a" +function(add_library_rust) + # set(OPTIONS) + set(ONE_VALUE_KEYWORDS PATH NAMESPACE CXX_BRIDGE_SOURCE_FILE) + # set(MULTI_VALUE_KEYWORDS) + cmake_parse_arguments(_RUST_LIB "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}" ${ARGN}) + + + ### Check inputs + if("${_RUST_LIB_PATH}" STREQUAL "") + message(FATAL_ERROR "add_library_rust called without a given path to root of a rust crate, fix by adding 'PATH '") + endif() + + if("${_RUST_LIB_NAMESPACE}" STREQUAL "") + message(FATAL_ERROR "Must supply a namespace given by keyvalue NAMESPACE ") + endif() + + if("${_RUST_LIB_CXX_BRIDGE_SOURCE_FILE}" STREQUAL "") + set(_RUST_LIB_CXX_BRIDGE_SOURCE_FILE "src/lib.rs") + endif() + + if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${_RUST_LIB_PATH}/Cargo.toml") + message(FATAL_ERROR "The path ${CMAKE_CURRENT_LIST_DIR}/${_RUST_LIB_PATH} does not contain a Cargo.toml") + endif() + + ## Simplyfy inputs + set(_LIB_PATH ${_RUST_LIB_PATH}) + set(_NAMESPACE ${_RUST_LIB_NAMESPACE}) + set(_CXX_BRIDGE_SOURCE_FILE ${_RUST_LIB_CXX_BRIDGE_SOURCE_FILE}) + + ## Import Rust target + corrosion_import_crate(MANIFEST_PATH "${_LIB_PATH}/Cargo.toml") + + ## Set cxxbridge values + + # parse stem + _get_stem_name_of_path(PATH ${_LIB_PATH}) + set(_LIB_PATH_STEM ${STEM_OF_PATH}) + + set(CXXBRIDGE_BINARY_FOLDER ${CMAKE_BINARY_DIR}/cargo/build/${Rust_CARGO_TARGET}/cxxbridge) + set(COMMON_HEADER ${CXXBRIDGE_BINARY_FOLDER}/rust/cxx.h) + set(BINDING_HEADER ${CXXBRIDGE_BINARY_FOLDER}/${_LIB_PATH_STEM}/${_CXX_BRIDGE_SOURCE_FILE}.h) + set(BINDING_SOURCE ${CXXBRIDGE_BINARY_FOLDER}/${_LIB_PATH_STEM}/${_CXX_BRIDGE_SOURCE_FILE}.cc) + set(CXX_BINDING_INCLUDE_DIR ${CXXBRIDGE_BINARY_FOLDER}) + + ## Create cxxbridge target + add_custom_command( + DEPENDS ${_LIB_PATH_STEM}-static + OUTPUT + ${COMMON_HEADER} + ${BINDING_HEADER} + ${BINDING_SOURCE} + ) + + add_library(${_LIB_PATH_STEM}_cxxbridge) + target_sources(${_LIB_PATH_STEM}_cxxbridge + PUBLIC + ${COMMON_HEADER} + ${BINDING_HEADER} + ${BINDING_SOURCE} + ) + target_include_directories(${_LIB_PATH_STEM}_cxxbridge + PUBLIC + ${CXX_BINDING_INCLUDE_DIR} + ) + + ## Create total target with alias with given namespace + add_library(${_LIB_PATH_STEM}-total INTERFACE) + target_link_libraries(${_LIB_PATH_STEM}-total + INTERFACE + ${_LIB_PATH_STEM}_cxxbridge + ${_LIB_PATH_STEM} + ) + # for end-user to link into project + add_library(${_NAMESPACE}::${_LIB_PATH_STEM} ALIAS ${_LIB_PATH_STEM}-total) + +endfunction(add_library_rust) + + +function(_get_stem_name_of_path) + # set(OPTIONS) + set(ONE_VALUE_KEYWORDS PATH) + # set(MULTI_VALUE_KEYWORDS) + cmake_parse_arguments(_PATH_STEM "${OPTIONS}" "${ONE_VALUE_KEYWORDS}" "${MULTI_VALUE_KEYWORDS}" ${ARGN}) + + ### Check inputs + if("${_PATH_STEM_PATH}" STREQUAL "") + message(FATAL_ERROR "Path to get stem for is empty!") + endif() + + # Convert all slashes to forward slash + set(_PATH ${_PATH_STEM_PATH}) + ## Replace all Windows double slashes + string(REPLACE "\\\\" "/" _PATH_OUTPUT ${_PATH}) + set(_PATH ${_PATH_OUTPUT}) + ## Replace all Windows single slashes + string(REPLACE "\\" "/" _PATH_OUTPUT ${_PATH}) + set(_PATH ${_PATH_OUTPUT}) + + # Convert to list + string(REPLACE "/" ";" _PATH_AS_LIST ${_PATH}) + list(LENGTH _PATH_AS_LIST LIST_LENGTH) + math(EXPR INDEX "${LIST_LENGTH} - 1" OUTPUT_FORMAT DECIMAL) + + list(GET _PATH_AS_LIST "${INDEX}" _STEM) + + set(STEM_OF_PATH ${_STEM} PARENT_SCOPE) +endfunction(_get_stem_name_of_path) diff --git a/services/lib/docker/install_rust.sh b/services/lib/docker/install_rust.sh new file mode 100755 --- /dev/null +++ b/services/lib/docker/install_rust.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e + +echo "installing rust" +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y