Using cxx to mix in Rust-code with a C++ application

Overview

Minimal application mixing C++ and Rust

This example uses cxx to generate bindings between C++ and Rust, and integrates the two parts through CMake.

It is basically an inverted version of cxx's demo code, using C++ for the entry point and a MultiBuf class, while implementing a simple blobstore-library in Rust.

How it works

In lib.rs we add bridge declarations for our Rust types:

#[cxx::bridge(namespace = "org::blobstore")]
mod ffi {
    // Rust types and signatures exposed to C++.
    extern "Rust" {
        type BlobstoreClient;
        fn new_blobstore_client() -> Box<BlobstoreClient>;
        fn put(&mut self, parts: Pin<&mut MultiBuf>) -> u64;
        ...
    }
}

fn new_blobstore_client() -> Box<BlobstoreClient> {
    Box::new(BlobstoreClient { blobs: HashMap::new() })
}

struct BlobstoreClient {
    blobs: HashMap<u64, Blob>,
}

impl BlobstoreClient {
    fn put(&mut self, mut parts: Pin<&mut MultiBuf>) -> u64 {
        ...
    }
}

In build.rs we add logic to generate C++ bridging code from the declarations:

fn main() {
    cxx_build::bridge("src/lib.rs");
    println!("cargo:rerun-if-changed=src/lib.rs");
}

In CMakeLists.txt we add a custom command to trigger the Rust build:

add_custom_command(
        OUTPUT ${BLOBSTORE_BRIDGE_CPP} ${BLOBSTORE_LIB}
        COMMAND cargo build --manifest-path ${BLOBSTORE_CARGO_MANIFEST}
        ...
)

In main.cpp we include the generated C++ header, construct Rust types, and call their methods:

#include "lib.rs.h"

int main() {
    auto client = org::blobstore::new_blobstore_client();
    ...
    const auto blobid = client->put(buf);
}

The application also consumes C++ types from Rust (MultiBuf), and leverages shared types between the two languages (BlobMetadata).

To learn more about the bridging layer, check out cxx's documentation.

Building and running the code

  git clone [email protected]:paandahl/cpp-with-rust.git
  mkdir cpp-with-rust/build
  cd cpp-with-rust/build

  cmake ..
  cmake --build .
  ./cpp_with_rust

NOTE: If you are using Windows, run these commands in the Developer PowerShell for VS.

Technical notes

  • As opposed to the original cxx demo, build.rs only generates the C++ bridging code, without compiling it. Instead, we pass it in to the CMake build by referencing it in add_executable().
  • For simplicity, this example always builds the Rust code in debug mode. See here for suggested changes to adhere to the specified CMAKE_BUILD_TYPE, and moving the cargo output to within the CMake build tree.

License

The code is available under the MIT license.

You might also like...
A CLI tool you can pipe code and then ask for changes, add documentation, etc, using the OpenAI API.
A CLI tool you can pipe code and then ask for changes, add documentation, etc, using the OpenAI API.

AiBro This is your own little coding bro, immersed in the world of AI, crypto, and all other types of over hyped tech trends. You can pipe it code and

A small command-line application to view images from the terminal written in Rust.
A small command-line application to view images from the terminal written in Rust.

A small command-line application to view images from the terminal written in Rust. It is basically the front-end of viuer

A tool crate to quickly build rust command line application.

Falsework A tool crate to quickly build rust command line application.

A template for bootstrapping a Rust TUI application with tui-rs & crossterm
A template for bootstrapping a Rust TUI application with tui-rs & crossterm

rust-tui-template A template for bootstrapping a Rust TUI application with tui-rs & crossterm. tui-rs The library is based on the principle of immedia

Work-in-progress Rust application that converts C++ header-only libraries to single self-contained headers.

unosolo Work-in-progress Rust application that converts C++ header-only libraries to single self-contained headers. Disclaimer This is my first Rust p

This is a simple command line application to convert bibtex to json written in Rust and Python

bibtex-to-json This is a simple command line application to convert bibtex to json written in Rust and Python. Why? To enable you to convert very big

Write Cross-platform application with React-like decralative UI framework and scalable ECS architecture all in Rust.

bevy_dioxus Dioxus Plugin for Bevy Write Cross-platform application with React-like decralative UI framework and scalable ECS architecture all in Rust

The application that can be used for personal usage to manage jira from terminal.

Jira Terminal This application can be used for personal usage to manage jira from terminal. Installation This application can be used in multiple plat

Command line application for searching
Command line application for searching

maven_search_rs Command line application for searching in https://search.maven.org Usage Non-interactive $ maven-search -f maven wicket-core The abov

Comments
  • Fix: cmake clean issue (lib.rs.cc not found after cleaning the build directory)

    Fix: cmake clean issue (lib.rs.cc not found after cleaning the build directory)

    Closes #1

    This issue can be triggered by the cmake clean target after a successful build. Any other build attempt after that will trigger the reported error. It doesn't matter if the build tool is GNU Make or Ninja. For instance:

    cd cpp-with-rust
    cmake -S . -B build
    # (configuration succeeds)
    cmake --build build/
    # (build succeeds)
    cmake --build build/ --target clean
    # (clean removes two files)
    cmake --build build/
    # (build fails!)
    

    Another available workaround is running cargo clean before building. It fully removes the target/ directory.

    The problem is that the cmake clean target removes the OUTPUT files generated by add_custom_command(), but cargo doesn't know how to regenerate them when the target directory is already populated by the last cargo execution.

    The COMMENT message added to add_custom_command() proves that cmake tries to run cargo whenever the ${BLOBSTORE_BRIDGE_CPP} file is missing. The message is printed no matter if the build fails.

    My first attempt to fix this issue was adding BYPRODUCTS ${CARGO_TARGET_DIR} to add_custom_command(), which works fine if the CMake generator is GNU Make, but fails for Ninja. The alternative is to set the ADDITIONAL_CLEAN_FILES property on the main target, which emulates the cargo clean effects.

    opened by pedrolcl 0
  • Not finding lib.rs.cc on macos when running cmake build

    Not finding lib.rs.cc on macos when running cmake build

    Thanks for your project! I get the following issue when running cmake --build . on macos:

    clang: error: no such file or directory: '/Users/{USER}/cpp-with-rust/target/cxxbridge/blobstore/src/lib.rs.cc'
    clang: error: no input files
    make[2]: *** [CMakeFiles/cpp_with_rust.dir/target/cxxbridge/blobstore/src/lib.rs.cc.o] Error 1
    make[1]: *** [CMakeFiles/cpp_with_rust.dir/all] Error 2
    make: *** [all] Error 2
    
    opened by stexa 2
Owner
Preben Aandahl
Preben Aandahl
CLI application to run clang-format on a set of files specified using globs in a JSON configuration file.

run_clang_format CLI application for running clang-format for an existing .clang-format file on a set of files, specified using globs in a .json confi

martin 6 Dec 16, 2022
CLI application to run clang-tidy on a set of files specified using globs in a JSON configuration file.

run-clang-tidy CLI application for running clang-tidy for an existing .clang-tidy file on a set of files, specified using globs in a .json configurati

martin 7 Nov 4, 2022
languagetool-code-comments integrates the LanguageTool API to parse, spell check, and correct the grammar of your code comments!

languagetool-code-comments integrates the LanguageTool API to parse, spell check, and correct the grammar of your code comments! Overview Install MacO

Dustin Blackman 17 Dec 25, 2022
Code-shape is a tool for extracting definitions from source code files

Code-shape Code-shape is a tool that uses Tree-sitter to extract a shape of code definitions from a source code file. The tool uses the same language

Andrew Hlynskyi 3 Apr 21, 2023
rehype plugin to use tree-sitter to highlight code in pre code blocks

rehype-tree-sitter rehype plugin to use tree-sitter to highlight code in <pre><code> blocks Contents What is this? When should I use this? Install Use

null 5 Jul 25, 2023
My solutions for the 2021 edition of the Advent of Code, using Rust and SOM (Simple Object Machine)

Advent of Code 2021 These are my solutions for the 2021 edition of the Advent of Code. The solutions are all implemented using both Rust and SOM (Simp

Nicolas Polomack 1 Dec 23, 2021
Generate PHP code from Rust using a fluent API 🐘 🦀

PHP-Codegen Generate PHP code from Rust using a fluent API ?? ?? Rust PHP Usage To bring this crate into your repository, either add php_codegen to yo

PHP Rust Tools 7 Dec 24, 2022
Demo app duplicated in 5 languages (Go/JavaScript/Python/Ruby/Rust) showing how to go from source code to container image using melange+apko

hello-melange-apko ?? This repo contains an example app duplicated across 5 languages showing how to: Package source code into APKs using melange Buil

Chainguard 16 Jan 23, 2023
Code implementation of DDIA, primarily using Rust and Go languages.

Let's implement DDIA in rust and golang (with some Java and Cpp). This repository contains code implementations for 'Designing Data-Intensive Applicat

Arthur.Zhang 4 Apr 21, 2023
Raw C Shell: interact with your operating system using raw C code, because why not?

rcsh Raw C Shell is a minimalist shell with no built in commands. You write entirely in C code and use return; to execute your code. Unlike that silly

null 4 Feb 7, 2023