• 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
51The generated C++ code and the Rust code generated by the procedural macro both
52depend on each other. Simple examples may only require one or the other, but in
53general your linking will need to handle both directions. For some linkers, such
54as llvm-ld, this is not a problem at all. For others, such as GNU ld, flags like
55`--start-lib`/`--end-lib` may help.
56
57Rust does not generate simple standalone `.o` files, so you can't just throw the
58Rust-generated code into your existing C++ toolchain linker. Instead you need to
59choose one of these options:
60
61* Use `rustc` as the final linker. Pass any non-Rust libraries using `-L
62  <directory>` and `-l<library>` rustc arguments, and/or `#[link]` directives in
63  your Rust code. If you need to link against C/C++ `.o` files you can use
64  `-Clink-arg=file.o`.
65
66* Use your C++ linker. In this case, you first need to use `rustc` and/or
67  `cargo` to generate a _single_ Rust `staticlib` target and pass that into your
68  foreign linker invocation.
69
70  * If you need to link multiple Rust subsystems, you will need to generate a
71    _single_ `staticlib` perhaps using lots of `extern crate` statements to
72    include multiple Rust `rlib`s.  Multiple Rust `staticlib` files are likely
73    to conflict.
74
75Passing Rust `rlib`s directly into your non-Rust linker is not supported (but
76apparently sometimes works).
77
78See the [Rust reference's *Linkage*][linkage] page for some general information
79here.
80
81[linkage]: https://doc.rust-lang.org/reference/linkage.html
82
83The following open rust-lang issues might hold more recent guidance or
84inspiration: [rust-lang/rust#73632], [rust-lang/rust#73295].
85
86[rust-lang/rust#73632]: https://github.com/rust-lang/rust/issues/73632
87[rust-lang/rust#73295]: https://github.com/rust-lang/rust/issues/73295
88