• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1{{#title Other build systems — Rust ♡ C++}}
2# Some other build system
3
4You will need to achieve at least these three things:
5
6- Produce the CXX-generated C++ bindings code.
7- Compile the generated C++ code.
8- Link the resulting objects together with your other C++ and Rust objects.
9
10*Not all build systems are created equal. If you're hoping to use a build system
11from the '90s, especially if you're hoping to overlaying the limitations of 2 or
12more build systems (like automake+cargo) and expect to solve them
13simultaneously, then be mindful that your expectations are set accordingly and
14seek sympathy from those who have imposed the same approach on themselves.*
15
16### Producing the generated code
17
18CXX's Rust code generation automatically happens when the `#[cxx::bridge]`
19procedural macro is expanded during the normal Rust compilation process, so no
20special build steps are required there.
21
22But the C++ side of the bindings needs to be generated. Your options are:
23
24- Use the `cxxbridge` command, which is a standalone command line interface to
25  the CXX C++ code generator. Wire up your build system to compile and invoke
26  this tool.
27
28  ```console
29  $  cxxbridge src/bridge.rs --header > path/to/bridge.rs.h
30  $  cxxbridge src/bridge.rs > path/to/bridge.rs.cc
31  ```
32
33  It's packaged as the `cxxbridge-cmd` crate on crates.io or can be built from
34  the *gen/cmd/* directory of the CXX GitHub repo.
35
36- Or, build your own code generator frontend on top of the [cxx-gen] crate. This
37  is currently unofficial and unsupported.
38
39[cxx-gen]: https://docs.rs/cxx-gen
40
41### Compiling C++
42
43However you like. We can provide no guidance.
44
45### Linking the C++ and Rust together
46
47When linking a binary which contains mixed Rust and C++ code, you will have to
48choose between using the Rust toolchain (`rustc`) or the C++ toolchain which you
49may already have extensively tuned.
50
51Rust does not generate simple standalone `.o` files, so you can't just throw the
52Rust-generated code into your existing C++ toolchain linker. Instead you need to
53choose one of these options:
54
55* Use `rustc` as the final linker. Pass any non-Rust libraries using `-L
56  <directory>` and `-l<library>` rustc arguments, and/or `#[link]` directives in
57  your Rust code. If you need to link against C/C++ `.o` files you can use
58  `-Clink-arg=file.o`.
59
60* Use your C++ linker. In this case, you first need to use `rustc` and/or
61  `cargo` to generate a _single_ Rust `staticlib` target and pass that into your
62  foreign linker invocation.
63
64  * If you need to link multiple Rust subsystems, you will need to generate a
65    _single_ `staticlib` perhaps using lots of `extern crate` statements to
66    include multiple Rust `rlib`s.  Multiple Rust `staticlib` files are likely
67    to conflict.
68
69Passing Rust `rlib`s directly into your non-Rust linker is not supported (but
70apparently sometimes works).
71
72See the [Rust reference's *Linkage*][linkage] page for some general information
73here.
74
75[linkage]: https://doc.rust-lang.org/reference/linkage.html
76
77The following open rust-lang issues might hold more recent guidance or
78inspiration: [rust-lang/rust#73632], [rust-lang/rust#73295].
79
80[rust-lang/rust#73632]: https://github.com/rust-lang/rust/issues/73632
81[rust-lang/rust#73295]: https://github.com/rust-lang/rust/issues/73295
82