Corrosion Documentation

repository·master·Indexed 23 days ago

https://github.com/corrosion-rs/corrosion

Corrosion (formerly cmake-cargo) is a tool that integrates Rust code into existing CMake projects. It automates the process of importing Rust-generated executables, static libraries, and dynamic libraries as native CMake targets using functions like `corrosion_import_crate`. The tool manages dependencies, handles linker configurations for different crate types, and provides experimental support for FFI bindings via cbindgen and cxx.

Tokens
5.6K
Snippets
11
Records
30
Agent score
80%

What's inside Corrosion

  1. Integrate Rust into CMake with Corrosion

    master

    Corrosion (formerly cmake-cargo) allows you to integrate Rust into existing CMake projects by automatically importing Rust executables, static libraries, and dynamic libraries as native CMake targets.

    Once imported, you can use standard CMake commands like target_link_libraries() to link Rust-generated static and dynamic libraries into your C/C++ targets.

    For Rust executables and dynamic libraries, Corrosion provides a specialized helper function corrosion_link_libraries to simplify adding the required flags for linking C/C++ libraries into the Rust target.

  2. How linking works for different Rust crate types

    master

    Linking behavior in Corrosion depends on the type of Rust crate being imported:

    Static Libraries (staticlib)

    • Linker Invocation: Invoked by CMake.
    • Usage: Link them into C/C++ code using standard target_link_libraries().
    • Note: corrosion_set_linker() has no effect on these targets.
    • Convenience: corrosion_link_libraries() can be used as a wrapper for target_link_libraries().

    Shared Libraries (cdylib) and Binaries (bin)

    • Linker Invocation: Invoked via rustc.
    • Usage: CMake receives the final artifact after rustc completes the link step.
    • Linking Libraries: Use corrosion_link_libraries() to pass -l and -L flags to the rustc invocation and ensure dependencies are built first.
    • Custom Flags: Use corrosion_add_target_local_rustflags() to pass advanced or customized linking flags.
  3. Integrate Corrosion using CMake FetchContent

    master

    You can integrate Corrosion into your CMake build process using the FetchContent module. This allows you to download and make Corrosion available without manual installation. Once available, use corrosion_import_crate to import targets defined in a Rust Cargo.toml file, and then link those targets to your C/C++ executables or libraries using target_link_libraries.

    include(FetchContent)
    
    FetchContent_Declare(
        Corrosion
        GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
        GIT_TAG v0.6 # Optionally specify a commit hash, version tag or branch here
    )
    FetchContent_MakeAvailable(Corrosion)
    
    # Import targets defined in a package or workspace manifest `Cargo.toml` file
    corrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml)
    
    add_executable(your_cpp_bin main.cpp)
    target_link_libraries(your_cpp_bin PUBLIC rust-lib)
  4. Generate FFI bindings in a CMake/Rust build

    master

    When creating FFI bindings (using tools like bindgen, cbindgen, cxx, or autocxx), you can use two primary strategies:

    1. Cargo-driven: Use a build.rs script to generate bindings when Cargo is invoked.
    2. CMake-driven (Preferred): Use the CLI versions of the tools and set up custom CMake targets/commands to generate the bindings. This is preferred if the C/C++ side requires the bindings during its own build process.

    Corrosion provides experimental integration functions for cbindgen and cxx to assist in automating this process.

  5. Install Rust crates and headers with `corrosion_install`

    master

    Because standard CMake install commands do not work correctly with targets exported by corrosion_import_crate(), use corrosion_install to automate the installation of relevant files.

    This is particularly useful when you want to export a Rust library and its associated headers for use in other projects. The process involves:

    1. Importing the crate via corrosion_import_crate.
    2. Adding header files to the target using target_sources with the FILE_SET HEADERS (CMake >= 3.23) or target_include_directories (CMake <= 3.23) pattern.
    3. Calling corrosion_install to prepare the targets for export.
    4. Using standard install(EXPORT ...) commands to install the CMake configuration files.
    include(FetchContent)
    
    FetchContent_Declare(
            Corrosion
            GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
            GIT_TAG v0.6
    )
    FetchContent_MakeAvailable(Corrosion)
    
    # Import the crate
    corrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml)
    
    # Add headers (CMake >= 3.23)
    target_sources(rust-lib INTERFACE
            FILE_SET HEADERS
            BASE_DIRS include
            FILES
            include/rust-lib/rust-lib.h
    )
    
    # Install the crate and its export set
    corrosion_install(TARGETS rust-lib EXPORT RustLibTargets)
    
    # Install the CMake config files
    install(
            EXPORT RustLibTargets
            NAMESPACE RustLib::
            DESTINATION lib/cmake/RustLib
    )
  6. Install Corrosion via Homebrew

    master

    Corrosion is available via an unofficial Homebrew package.

    Warning: This package is community maintained. Corrosion follows semantic versioning; because it is pre-1.0, minor version bumps (e.g., 0.3 to 0.4) may contain breaking changes. Always check the release notes before upgrading.

    brew install corrosion
  7. Integrate cbindgen for C/C++ header generation (Experimental)

    master

    ⚠️ EXPERIMENTAL ⚠️

    cbindgen generates C/C++ headers from Rust code. While you can generate headers via a build-script, Corrosion provides an experimental way to add CMake rules that use cbindgen to generate these headers directly within the build system.

    Note: This feature is not yet available in a stable released version and implementation details are subject to change.

  8. Cross-compiling with Corrosion

    master

    Corrosion supports cross-compiling in several scenarios. In all cases, ensure the target standard library is installed via rustup target add <target-rust-triple>.

    Windows-to-Windows

    Use the Visual Studio Generator and the -A architecture flag:

    cmake -S. -Bbuild-arm64 -A ARM64
    cmake --build build-arm64

    Linux-to-Linux

    Install a cross-compiler (e.g., g++-powerpc64le-linux-gnu) and manually specify Rust_CARGO_TARGET:

    cmake -S. -Bbuild-ppc64le -DRust_CARGO_TARGET=powerpc64le-unknown-linux-gnu -DCMAKE_CXX_COMPILER=powerpc64le-linux-gnu-g++
    cmake --build build-ppc64le

    Android

    Supported on Makefile and Ninja generators. The Rust target triple is automatically selected based on CMake toolchain files. Note: Requires CMake >= 3.22. If using Android Studio, you must configure it to use a specific version of CMake.

    cmake -S. -Bbuild-android-arm64 -GNinja -DCMAKE_SYSTEM_NAME=Android \
          -DCMAKE_ANDROID_NDK=/path/to/android-ndk-rxxd -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a
  9. Import Rust targets using corrosion_import_crate

    master

    To make Rust targets available in CMake, use the corrosion_import_crate function. You provide the path to a Cargo.toml manifest via the MANIFEST_PATH argument.

    Corrosion will create CMake targets with names that match the library names defined in the Cargo.toml (e.g., if you have a [lib] name = "rust-lib" with crate-type = ["staticlib"], a CMake target named rust-lib will be created). These targets can then be linked into your C/C++ targets using target_link_libraries.

    # Import targets defined in a package or workspace manifest `Cargo.toml` file
    corrosion_import_crate(MANIFEST_PATH rust-lib/Cargo.toml)
    
    add_executable(your_cool_cpp_bin main.cpp)
    
    # Link the imported rust library target into your C/C++ target
    target_link_libraries(your_cool_cpp_bin PUBLIC rust-lib)