16021
|
1 |
## What does corrosion do?
|
|
2 |
|
|
3 |
The specifics of what corrosion does should be regarded as an implementation detail and not relied on
|
|
4 |
when writing user code. However, a basic understanding of what corrosion does may be helpful when investigating
|
|
5 |
issues.
|
|
6 |
|
|
7 |
### FindRust
|
|
8 |
|
|
9 |
Corrosion maintains a CMake module `FindRust` which is executed when Corrosion is loaded, i.e. at the time
|
|
10 |
of `find_package(corrosion)`, `FetchContent_MakeAvailable(corrosion)` or `add_subdirectory(corrosion)` depending
|
|
11 |
on the method used to include Corrosion.
|
|
12 |
|
|
13 |
`FindRust` will search for installed rust toolchains, respecting the options prefixed with `Rust_` documented in
|
|
14 |
the [Usage](usage.md#corrosion-options) chapter.
|
|
15 |
It will select _one_ Rust toolchain to be used for the compilation of Rust code. Toolchains managed by `rustup`
|
|
16 |
will be resolved and corrosion will always select a specific toolchain, not a `rustup` proxy.
|
|
17 |
|
|
18 |
|
|
19 |
### Importing Rust crates
|
|
20 |
|
|
21 |
Corrosion's main function is `corrosion_import_crate`, which internally will call `cargo metadata` to provide
|
|
22 |
structured information based on the `Cargo.toml` manifest.
|
|
23 |
Corrosion will then iterate over all workspace and/or package members and find all rust crates that are either
|
|
24 |
a static (`staticlib`) or shared (`cdylib`) library or a `bin` target and create CMake targets matching the
|
|
25 |
crate name. Additionally, a build target is created for each imported target, containing the required build
|
|
26 |
command to create the imported artifact. This build command can be influenced by various arguments to
|
|
27 |
`corrosion_import_crate` as well as corrosion specific target properties which are documented int the
|
|
28 |
[Usage](usage.md) chapter.
|
|
29 |
Corrosion adds the necessary dependencies and also copies the target artifacts out of the cargo build tree
|
|
30 |
to standard CMake locations, even respecting `OUTPUT_DIRECTORY` target properties if set.
|
|
31 |
|
|
32 |
### Linking
|
|
33 |
|
|
34 |
Depending on the type of the crate the linker will either be invoked by CMake or by `rustc`.
|
|
35 |
Rust `staticlib`s are linked into C/C++ code via `target_link_libraries()` and the linker is
|
|
36 |
invoked by CMake.
|
|
37 |
For rust `cdylib`s and `bin`s, the linker is invoked via `rustc` and CMake just gets the final artifact.
|
|
38 |
|
|
39 |
#### CMake invokes the linker
|
|
40 |
|
|
41 |
When CMake invokes the linker, everything is as usual. CMake will call the linker with
|
|
42 |
the compiler as the linker driver and users can just use the regular CMake functions to
|
|
43 |
modify linking behaviour. `corrosion_set_linker()` has **no effect**.
|
|
44 |
As a convenience, `corrosion_link_libraries()` will forward its arguments to `target_link_libraries()`.
|
|
45 |
|
|
46 |
#### Rustc invokes the linker
|
|
47 |
|
|
48 |
Rust `cdylib`s and `bin`s are linked via `rustc`. Corrosion provides several helper functions
|
|
49 |
to influence the linker invocation for such targets.
|
|
50 |
|
|
51 |
`corrosion_link_libraries()` is a limited version of `target_link_libraries()`
|
|
52 |
for rust `cdylib` or `bin` targets.
|
|
53 |
Under the hood this function passes `-l` and `-L` flags to the linker invocation and
|
|
54 |
ensures the linked libraries are built first.
|
|
55 |
Much of the advanced functionality available in `target_link_libraries()` is not implemented yet,
|
|
56 |
but pull-requests are welcome! In the meantime, users may want to use
|
|
57 |
`corrosion_add_target_local_rustflags()` to pass customized linking flags.
|
|
58 |
|
|
59 |
`corrosion_set_linker()` can be used to specify a custom linker, in case the default one
|
|
60 |
chosen by corrosion is not what you want.
|
|
61 |
Corrosion currently instructs `rustc` to use the C/C++ compiler as the linker driver.
|
|
62 |
This is done because:
|
|
63 |
- For C++ code we must link with `libstdc++` or `libc++` (depending on the compiler), so we must
|
|
64 |
either specify the library on the link line or use a `c++` compiler as the linker driver.
|
|
65 |
- `Rustc`s default linker selection currently is not so great. For a number of platforms
|
|
66 |
`rustc` will fallback to `cc` as the linker driver. When cross-compiling, this leads
|
|
67 |
to linking failures, since the linker driver is for the host architecture.
|
|
68 |
Corrosion avoids this by specifying the C/C++ compiler as the linker driver.
|
|
69 |
|
|
70 |
|
|
71 |
In some cases, especially in older rust versions (pre 1.68), the linker flavor detection
|
|
72 |
of `rustc` is also not correct, so when setting a custom linker you may want to pass the
|
|
73 |
[`-C linker-flavor`](https://doc.rust-lang.org/rustc/codegen-options/index.html#linker-flavor)
|
|
74 |
rustflag via `corrosion_add_target_local_rustflags()`.
|
|
75 |
|
|
76 |
## FFI bindings
|
|
77 |
|
|
78 |
For interaction between Rust and other languages there need to be some FFI bindings of some sort.
|
|
79 |
For simple cases manually defining the interfaces may be sufficient, but in many cases users
|
|
80 |
wish to use tools like [bindgen], [cbindgen], [cxx] or [autocxx] to automate the generating of
|
|
81 |
bindings.
|
|
82 |
|
|
83 |
In principle there are two different ways to generate the bindings:
|
|
84 |
- use a `build.rs` script to generate the bindings when cargo is invoked, using
|
|
85 |
library versions of the tools to generate the bindings.
|
|
86 |
- use the cli versions of the tools and setup custom CMake targets/commands to
|
|
87 |
generate the bindings. This approach should be preferred if the bindings are needed
|
|
88 |
by the C/C++ side.
|
|
89 |
|
|
90 |
Corrosion currently provides 2 experimental functions to integrate cbindgen and cxx into
|
|
91 |
the build process. They are not 100% production ready yet, but should work well as a
|
|
92 |
template on how to integrate generating bindings into your build process.
|
|
93 |
|
|
94 |
Todo: expand this documentation and link to other resources.
|
|
95 |
|
|
96 |
[bindgen]: https://rust-lang.github.io/rust-bindgen/
|
|
97 |
[cbindgen]: https://github.com/eqrion/cbindgen
|
|
98 |
[cxx]: https://cxx.rs/
|
|
99 |
[autocxx]: https://google.github.io/autocxx/index.html
|
|
100 |
|