blob: af835e658cd595e2f893546521b18129fcf0e884 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
{{#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.
*Not all build systems are created equal. If you're hoping to use a build system
from the '90s, especially if you're hoping to overlaying the limitations of 2 or
more build systems (like automake+cargo) and expect to solve them
simultaneously, then be mindful that your expectations are set accordingly and
seek sympathy from those who have imposed the same approach on themselves.*
### 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.
```console
$ 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.
[cxx-gen]: https://docs.rs/cxx-gen
### 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 `rlib`s. Multiple Rust `staticlib` files are likely
to conflict.
Passing Rust `rlib`s directly into your non-Rust linker is not supported (but
apparently sometimes works).
See the [Rust reference's *Linkage*][linkage] page for some general information
here.
[linkage]: https://doc.rust-lang.org/reference/linkage.html
The following open rust-lang issues might hold more recent guidance or
inspiration: [rust-lang/rust#73632], [rust-lang/rust#73295].
[rust-lang/rust#73632]: https://github.com/rust-lang/rust/issues/73632
[rust-lang/rust#73295]: https://github.com/rust-lang/rust/issues/73295
|