main 2c16706a6340 cached
11 files
12.0 KB
3.6k tokens
14 symbols
1 requests
Download .txt
Repository: geekbrother/cxx-corrosion-cmake
Branch: main
Commit: 2c16706a6340
Files: 11
Total size: 12.0 KB

Directory structure:
gitextract_66rc6919/

├── .github/
│   └── workflows/
│       └── docker-image.yml
├── .gitignore
├── LICENSE
├── README.MD
├── cmake/
│   └── corrosion_cxx.cmake
└── examples/
    ├── Dockerfile
    └── rust-from-cpp/
        ├── CMakeLists.txt
        └── src/
            ├── cxxbridge_code/
            │   ├── Cargo.toml
            │   ├── build.rs
            │   └── src/
            │       └── lib.rs
            └── main.cpp

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/docker-image.yml
================================================
name: Docker Image CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:

  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Build the Docker image on examples
      working-directory: .
      run: docker build . --tag my-image-name:$(date +%s) -f examples/Dockerfile


================================================
FILE: .gitignore
================================================
# Calling Rust from C++
examples/rust-from-cpp/src/cxxbridge_code/target
examples/rust-from-cpp/build

# Calling C++ from Rust


================================================
FILE: LICENSE
================================================
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <https://unlicense.org>


================================================
FILE: README.MD
================================================
# CMake file for using [CXX](https://cxx.rs/) and [Corrosion](https://github.com/corrosion-rs/corrosion) in CMake project to call Rust functions from C++ and C++ from Rust

This is a fork of the [rusty_cmake](https://github.com/trondhe/rusty_cmake) repository to use CXX and Corrosion in a CMake project with the following modifications:

### `cxx_corrosion.cmake` file:
 - Function to get STEM is removed in a favor of one-line solution;
 - Simplify by using a simple one CMakeLists file for the project;
 - Windows-related code is removed (Linux and MacOS are supported);
 - Minor code changes to simplify and use a modern C++.

# Why?

This `cmake/corrosion_cxx.cmake` can be imported in any CMake project to simplify Rust code usage in C++.

Current solution is a battle-tested and `cmake/corrosion_cxx.cmake` file is used in a [Comm](https://comm.app) application development.

# Current examples

Examples are located in `examples` folder.

This repo examples can be used as a sandbox playground for testing simple ideas of the Rust library integration in the current C++ CMake project (`examples/rust-from-cpp`) and as examples of the usage and calling C++ code from Rust (`examples/cpp-from-rust`).

# Calling Rust code from C++
## Code examples to call Rust functions from C++:
- [Example of using a different primitive types](https://github.com/geekbrother/cxx-corrosion-cmake/blob/fe14ac52173737163e3ba427557187b9e4ba5d33/examples/src/main.cpp#L8) for arguments and returns;
- [Example](https://github.com/geekbrother/cxx-corrosion-cmake/blob/fe14ac52173737163e3ba427557187b9e4ba5d33/examples/src/main.cpp#L21) of using [Rust Result type](https://cxx.rs/binding/result.html#returning-result-from-rust-to-c) and [Anyhow](https://docs.rs/anyhow/latest/anyhow/) in return to C++;
- [Example of using panics](https://github.com/geekbrother/cxx-corrosion-cmake/blob/fe14ac52173737163e3ba427557187b9e4ba5d33/examples/src/main.cpp#L33) in Rust when calling from C++.

## Dependencies
  - Linux or MacOS
  - CMake
  - Clang
  - [Corrosion](https://github.com/corrosion-rs/corrosion#installation)
  - Rustup
  - Nix (optional) or Docker (optional)

## Build

### Using CMake

Run CMake and build commands in the `examples/rust-from-cpp` folder: 

`cmake -B build . && make -C build -j4`.

Then you can run the example app by calling:

`build/cxx_cmake`.

### In Nix

If you are using [Nix](https://nixos.org/download.html) as a development environment you can use a nix shell with all dependencies:

```
nix-shell -p cmake -p clang -p rustup -p corrosion -p libiconv -p git --pure
```

And then run build commands from the CMake section above.

### In Docker

There is a Docker file to build and run the example app in Docker container.
To build it run the build command from the project root directory:

```
docker build . -t cxx-corrosion-cmake -f examples/Dockerfile
```

Then you can run the example app by calling:

```
docker run cxx-corrosion-cmake
```

# Todo

Create a packages in package managers to help tracking updates in the project instead of manually track the changes.

 - Make it nix package
 - Make it vcpkg package

# Sponsors ❤️

[**Comm.app**](https://comm.app) is a crypto-native chat (think "Web3 Discord").


================================================
FILE: cmake/corrosion_cxx.cmake
================================================
# Creates a target including rust lib and cxxbridge which is
# named as ${NAMESPACE}::${_LIB_PATH_STEM}
# <_LIB_PATH_STEM> must match the crate name:
# "path/to/myrustcrate" -> "libmyrustcrate.a"
function(add_library_rust)
    set(value_keywords PATH NAMESPACE CXX_BRIDGE_SOURCE_FILE)
    cmake_parse_arguments(
        rust_lib
        "${OPTIONS}"
        "${value_keywords}"
        "${MULTI_value_KEYWORDS}"
        ${ARGN}
    )

    if("${Rust_CARGO_TARGET}" STREQUAL "")
        message(
            FATAL_ERROR
            "Rust_CARGO_TARGET is not detected and empty")
    endif()

    if("${rust_lib_PATH}" STREQUAL "")
        message(
            FATAL_ERROR
            "add_library_rust called without a given path to root of a rust crate")
    endif()

    if("${rust_lib_NAMESPACE}" STREQUAL "")
        message(
            FATAL_ERROR
            "Must supply a namespace given by keyvalue NAMESPACE <value>")
    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
            "${CMAKE_CURRENT_LIST_DIR}/${rust_lib_PATH} doesn't contain a Cargo.toml")
    endif()

    set(lib_path ${rust_lib_PATH})
    set(namespace ${rust_lib_NAMESPACE})
    set(cxx_bridge_source_file ${rust_lib_CXX_BRIDGE_SOURCE_FILE})

    corrosion_import_crate(MANIFEST_PATH "${lib_path}/Cargo.toml")

    # Set cxxbridge values
    get_filename_component(_LIB_PATH_STEM ${lib_path} NAME)
    message(STATUS "Library stem path: ${_LIB_PATH_STEM}")
    set(
        cxx_bridge_binary_folder
        ${CMAKE_BINARY_DIR}/cargo/build/${Rust_CARGO_TARGET}/cxxbridge)
    set(
        common_header
        ${cxx_bridge_binary_folder}/rust/cxx.h)
    set(
        binding_header
        ${cxx_bridge_binary_folder}/${_LIB_PATH_STEM}/${cxx_bridge_source_file}.h)
    set(
        binding_source
        ${cxx_bridge_binary_folder}/${_LIB_PATH_STEM}/${cxx_bridge_source_file}.cc)
    set(
        cxx_binding_include_dir
        ${cxx_bridge_binary_folder})

    # Create cxxbridge target
    add_custom_command(
        OUTPUT
        ${common_header}
        ${binding_header}
        ${binding_source}
        COMMAND
        DEPENDS ${_LIB_PATH_STEM}-static
        COMMENT "Fixing cmake to find source files"
    )
    add_library(${_LIB_PATH_STEM}_cxxbridge
        ${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)


================================================
FILE: examples/Dockerfile
================================================
FROM ubuntu:23.04

ENV DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC
ARG LOCAL_DIRECTORY=/var/cxx_corrosion_cmake
ARG RUST_VERSION=1.69.0

# Install essential packages for building the c++
RUN apt update \
	&& apt install -y \
  build-essential curl cmake git \
  lsb-release software-properties-common

# Install Rust
RUN curl https://sh.rustup.rs -sSf | bash -s -- --default-toolchain ${RUST_VERSION} -y

# Install Corrosion
WORKDIR /var
RUN git clone https://github.com/corrosion-rs/corrosion.git
RUN cmake -Scorrosion -Bbuild -DCMAKE_BUILD_TYPE=Release
RUN cmake --build build --config Release && cmake --install build --config Release

# Copy files
COPY examples ${LOCAL_DIRECTORY}/examples
COPY cmake ${LOCAL_DIRECTORY}/cmake

# Compile example app
WORKDIR ${LOCAL_DIRECTORY}/examples/rust-from-cpp
RUN rm -dfr build && cmake -B build . && make -C build -j4

# Run the example app
CMD ["${LOCAL_DIRECTORY}/examples/rust-from-cpp/build/cxx_cmake"]


================================================
FILE: examples/rust-from-cpp/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.16)

set(CMAKE_EXPORT_COMPILE_COMMANDS true)

project(cxx_cmake CXX)

set(CMAKE_CXX_STANDARD 17)

find_package(Corrosion REQUIRED)
include(../../cmake/corrosion_cxx.cmake)

add_executable(${PROJECT_NAME})

target_sources(${PROJECT_NAME}
  PRIVATE
  src/main.cpp
)

add_library_rust(PATH src/cxxbridge_code NAMESPACE my)

target_link_libraries(${PROJECT_NAME}
  PUBLIC
  my::cxxbridge_code
)


================================================
FILE: examples/rust-from-cpp/src/cxxbridge_code/Cargo.toml
================================================
[package]
name = "cxxbridge_code"
version = "0.1.0"
authors = ["Trond H Emaus <trondhe@gmail.com>", "Max Kalashnikoff <geekmaks@gmail.com>"]
edition = "2021"

[dependencies]
cxx = "1.0"
anyhow = "1.0"

[build-dependencies]
cxx-build = "1.0"

[lib]
crate-type = ["staticlib"]

[profile.release]
debug = true
panic = "abort"

[profile.dev]
panic = "abort"


================================================
FILE: examples/rust-from-cpp/src/cxxbridge_code/build.rs
================================================
fn main() {
    let _build = cxx_build::bridge("src/lib.rs");
    println!("cargo:rerun-if-changed=src/lib.rs");
}


================================================
FILE: examples/rust-from-cpp/src/cxxbridge_code/src/lib.rs
================================================
use anyhow::Result;

#[cxx::bridge]
mod ffi {
    extern "Rust" {
        // Primitive types:
        fn lib_cxxbridge_bool(some: bool) -> bool;
        fn lib_cxxbridge_integer(some: i32) -> i32;
        fn lib_cxxbridge_string(some: &str) -> String;
        // Return Result:
        fn lib_cxxbridge_return_result_ok() -> Result<String>;
        fn lib_cxxbridge_return_result_error() -> Result<String>;
        // Panic in a function call:
        fn lib_cxxbridge_panicked_function() -> String;
    }
}

pub fn lib_cxxbridge_bool(some: bool) -> bool {
    if some {
        return false;
    }
    true
}

pub fn lib_cxxbridge_integer(some: i32) -> i32 {
    some + 10
}

pub fn lib_cxxbridge_string(some: &str) -> String {
    String::from("Say hello to ".to_owned() + &some)
}

pub fn lib_cxxbridge_return_result_ok() -> Result<String> {
    Ok(String::from("This is a string from result"))
}

pub fn lib_cxxbridge_return_result_error() -> Result<String> {
    let some_string = std::fs::read_to_string("cluster.json")?;
    Ok(some_string)
}

pub fn lib_cxxbridge_panicked_function() -> String {
    panic!("Panicked_function in panic");
}


================================================
FILE: examples/rust-from-cpp/src/main.cpp
================================================
#include "cxxbridge_code/src/lib.rs.h"
#include <iostream>
#include <string>
#include "rust/cxx.h"

int main()
{
	// Primitive types:
	std::cout << "[1] A value given via generateb cxxbridge for lib_cxxbridge_bool: "
						<< lib_cxxbridge_bool(true) << std::endl;
	std::cout << "[2] A value given via generated cxxbridge for lib_cxxbridge_integer: "
						<< lib_cxxbridge_integer(86) << std::endl;
	const rust::String testString = "Max";
	std::cout << "[3] A value given via generated cxxbridge for lib_cxxbridge_string: "
						<< lib_cxxbridge_string(testString) << std::endl;

	// Return Rust `Result` with  Ok:
	std::cout << "[4] A Rust `Result Ok` value given via generated cxxbridge for lib_cxxbridge_return_result_ok:" << std::endl
						<< lib_cxxbridge_return_result_ok() << std::endl;

	// Return Rust `Result` with Error:
	try
	{
		std::cout << "[5] A Rust `Result Error` value given via generated cxxbridge for lib_cxxbridge_return_result_error:" << std::endl
							<< lib_cxxbridge_return_result_error() << std::endl;
	}
	catch (rust::Error e)
	{
		std::cerr << "Got an error from Rust function `Result`:" << std::endl;
		std::cerr << e.what() << std::endl;
	}

	// Panic in a function call:
	std::cout << "[6] Testing a case of panic by running lib_cxxbridge_panicked_function:" << std::endl;
	std::cout << lib_cxxbridge_panicked_function();

	return 0;
}
Download .txt
gitextract_66rc6919/

├── .github/
│   └── workflows/
│       └── docker-image.yml
├── .gitignore
├── LICENSE
├── README.MD
├── cmake/
│   └── corrosion_cxx.cmake
└── examples/
    ├── Dockerfile
    └── rust-from-cpp/
        ├── CMakeLists.txt
        └── src/
            ├── cxxbridge_code/
            │   ├── Cargo.toml
            │   ├── build.rs
            │   └── src/
            │       └── lib.rs
            └── main.cpp
Download .txt
SYMBOL INDEX (14 symbols across 3 files)

FILE: examples/rust-from-cpp/src/cxxbridge_code/build.rs
  function main (line 1) | fn main() {

FILE: examples/rust-from-cpp/src/cxxbridge_code/src/lib.rs
  function lib_cxxbridge_bool (line 7) | fn lib_cxxbridge_bool(some: bool) -> bool;
  function lib_cxxbridge_integer (line 8) | fn lib_cxxbridge_integer(some: i32) -> i32;
  function lib_cxxbridge_string (line 9) | fn lib_cxxbridge_string(some: &str) -> String;
  function lib_cxxbridge_return_result_ok (line 11) | fn lib_cxxbridge_return_result_ok() -> Result<String>;
  function lib_cxxbridge_return_result_error (line 12) | fn lib_cxxbridge_return_result_error() -> Result<String>;
  function lib_cxxbridge_panicked_function (line 14) | fn lib_cxxbridge_panicked_function() -> String;
  function lib_cxxbridge_bool (line 18) | pub fn lib_cxxbridge_bool(some: bool) -> bool {
  function lib_cxxbridge_integer (line 25) | pub fn lib_cxxbridge_integer(some: i32) -> i32 {
  function lib_cxxbridge_string (line 29) | pub fn lib_cxxbridge_string(some: &str) -> String {
  function lib_cxxbridge_return_result_ok (line 33) | pub fn lib_cxxbridge_return_result_ok() -> Result<String> {
  function lib_cxxbridge_return_result_error (line 37) | pub fn lib_cxxbridge_return_result_error() -> Result<String> {
  function lib_cxxbridge_panicked_function (line 42) | pub fn lib_cxxbridge_panicked_function() -> String {

FILE: examples/rust-from-cpp/src/main.cpp
  function main (line 6) | int main()
Condensed preview — 11 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (14K chars).
[
  {
    "path": ".github/workflows/docker-image.yml",
    "chars": 345,
    "preview": "name: Docker Image CI\n\non:\n  push:\n    branches: [ \"main\" ]\n  pull_request:\n    branches: [ \"main\" ]\n\njobs:\n\n  build:\n\n "
  },
  {
    "path": ".gitignore",
    "chars": 127,
    "preview": "# Calling Rust from C++\nexamples/rust-from-cpp/src/cxxbridge_code/target\nexamples/rust-from-cpp/build\n\n# Calling C++ fro"
  },
  {
    "path": "LICENSE",
    "chars": 1211,
    "preview": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, c"
  },
  {
    "path": "README.MD",
    "chars": 3234,
    "preview": "# CMake file for using [CXX](https://cxx.rs/) and [Corrosion](https://github.com/corrosion-rs/corrosion) in CMake projec"
  },
  {
    "path": "cmake/corrosion_cxx.cmake",
    "chars": 3037,
    "preview": "# Creates a target including rust lib and cxxbridge which is\n# named as ${NAMESPACE}::${_LIB_PATH_STEM}\n# <_LIB_PATH_STE"
  },
  {
    "path": "examples/Dockerfile",
    "chars": 949,
    "preview": "FROM ubuntu:23.04\n\nENV DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC\nARG LOCAL_DIRECTORY=/var/cxx_corrosion_cmake\nARG RUST_V"
  },
  {
    "path": "examples/rust-from-cpp/CMakeLists.txt",
    "chars": 424,
    "preview": "cmake_minimum_required(VERSION 3.16)\n\nset(CMAKE_EXPORT_COMPILE_COMMANDS true)\n\nproject(cxx_cmake CXX)\n\nset(CMAKE_CXX_STA"
  },
  {
    "path": "examples/rust-from-cpp/src/cxxbridge_code/Cargo.toml",
    "chars": 354,
    "preview": "[package]\nname = \"cxxbridge_code\"\nversion = \"0.1.0\"\nauthors = [\"Trond H Emaus <trondhe@gmail.com>\", \"Max Kalashnikoff <g"
  },
  {
    "path": "examples/rust-from-cpp/src/cxxbridge_code/build.rs",
    "chars": 115,
    "preview": "fn main() {\n    let _build = cxx_build::bridge(\"src/lib.rs\");\n    println!(\"cargo:rerun-if-changed=src/lib.rs\");\n}\n"
  },
  {
    "path": "examples/rust-from-cpp/src/cxxbridge_code/src/lib.rs",
    "chars": 1148,
    "preview": "use anyhow::Result;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        // Primitive types:\n        fn lib_cxxbridge_b"
  },
  {
    "path": "examples/rust-from-cpp/src/main.cpp",
    "chars": 1373,
    "preview": "#include \"cxxbridge_code/src/lib.rs.h\"\n#include <iostream>\n#include <string>\n#include \"rust/cxx.h\"\n\nint main()\n{\n\t// Pri"
  }
]

About this extraction

This page contains the full source code of the geekbrother/cxx-corrosion-cmake GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 11 files (12.0 KB), approximately 3.6k tokens, and a symbol index with 14 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!