{{#title Other build systems — Rust ♡ C++}}

Some other build system

You will need to achieve at least these three things:

  • Produce the CXX-generated C++ bindings code.
  • Compile the generated C++ code.
  • Link the resulting objects together with your other C++ and Rust objects.

Producing the generated code

CXX's Rust code generation automatically happens when the #[cxx::bridge] procedural macro is expanded during the normal Rust compilation process, so no special build steps are required there.

But the C++ side of the bindings needs to be generated. Your options are:

  • Use the cxxbridge command, which is a standalone command line interface to the CXX C++ code generator. Wire up your build system to compile and invoke this tool.

    $  cxxbridge src/bridge.rs --header > path/to/bridge.rs.h
    $  cxxbridge src/bridge.rs > path/to/bridge.rs.cc
    

    It's packaged as the cxxbridge-cmd crate on crates.io or can be built from the gen/cmd/ directory of the CXX GitHub repo.

  • Or, build your own code generator frontend on top of the cxx-gen crate. This is currently unofficial and unsupported.

Compiling C++

However you like. We can provide no guidance.

Linking the C++ and Rust together

When linking a binary which contains mixed Rust and C++ code, you will have to choose between using the Rust toolchain (rustc) or the C++ toolchain which you may already have extensively tuned.

Rust does not generate simple standalone .o files, so you can't just throw the Rust-generated code into your existing C++ toolchain linker. Instead you need to choose one of these options:

  • Use rustc as the final linker. Pass any non-Rust libraries using -L <directory> and -l<library> rustc arguments, and/or #[link] directives in your Rust code. If you need to link against C/C++ .o files you can use -Clink-arg=file.o.

  • Use your C++ linker. In this case, you first need to use rustc and/or cargo to generate a single Rust staticlib target and pass that into your foreign linker invocation.

    • If you need to link multiple Rust subsystems, you will need to generate a single staticlib perhaps using lots of extern crate statements to include multiple Rust rlibs. Multiple Rust staticlib files are likely to conflict.

Passing Rust rlibs directly into your non-Rust linker is not supported (but apparently sometimes works).

See the Rust reference's Linkage page for some general information here.

The following open rust-lang issues might hold more recent guidance or inspiration: rust-lang/rust#73632, rust-lang/rust#73295.