tools/corrosion/doc/src/advanced.md
branchtransitional_engine
changeset 16021 6a3dc15b78b9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/corrosion/doc/src/advanced.md	Wed Aug 28 15:31:51 2024 +0200
@@ -0,0 +1,100 @@
+## What does corrosion do?
+
+The specifics of what corrosion does should be regarded as an implementation detail and not relied on
+when writing user code. However, a basic understanding of what corrosion does may be helpful when investigating
+issues.
+
+### FindRust
+
+Corrosion maintains a CMake module `FindRust` which is executed when Corrosion is loaded, i.e. at the time
+of `find_package(corrosion)`, `FetchContent_MakeAvailable(corrosion)` or `add_subdirectory(corrosion)` depending
+on the method used to include Corrosion.
+
+`FindRust` will search for installed rust toolchains, respecting the options prefixed with `Rust_` documented in
+the [Usage](usage.md#corrosion-options) chapter.
+It will select _one_ Rust toolchain to be used for the compilation of Rust code. Toolchains managed by `rustup`
+will be resolved and corrosion will always select a specific toolchain, not a `rustup` proxy.
+
+
+### Importing Rust crates
+
+Corrosion's main function is `corrosion_import_crate`, which internally will call `cargo metadata` to provide
+structured information based on the `Cargo.toml` manifest.
+Corrosion will then iterate over all workspace and/or package members and find all rust crates that are either
+a static (`staticlib`) or shared (`cdylib`) library or a `bin` target and create CMake targets matching the
+crate name. Additionally, a build target is created for each imported target, containing the required build
+command to create the imported artifact. This build command can be influenced by various arguments to 
+`corrosion_import_crate` as well as corrosion specific target properties which are documented int the  
+[Usage](usage.md) chapter.
+Corrosion adds the necessary dependencies and also copies the target artifacts out of the cargo build tree
+to standard CMake locations, even respecting `OUTPUT_DIRECTORY` target properties if set.
+
+### Linking
+
+Depending on the type of the crate the linker will either be invoked by CMake or by `rustc`.
+Rust `staticlib`s are linked into C/C++ code via `target_link_libraries()` and the linker is
+invoked by CMake.
+For rust `cdylib`s and `bin`s, the linker is invoked via `rustc` and CMake just gets the final artifact.
+
+#### CMake invokes the linker
+
+When CMake invokes the linker, everything is as usual. CMake will call the linker with
+the compiler as the linker driver and users can just use the regular CMake functions to
+modify linking behaviour. `corrosion_set_linker()` has **no effect**.
+As a convenience, `corrosion_link_libraries()` will forward its arguments to `target_link_libraries()`.
+
+#### Rustc invokes the linker 
+
+Rust `cdylib`s and `bin`s are linked via `rustc`. Corrosion provides several helper functions
+to influence the linker invocation for such targets. 
+
+`corrosion_link_libraries()` is a limited version of `target_link_libraries()` 
+for rust `cdylib` or `bin` targets.
+Under the hood this function passes `-l` and `-L` flags to the linker invocation and
+ensures the linked libraries are built first.
+Much of the advanced functionality available in `target_link_libraries()` is not implemented yet,
+but pull-requests are welcome! In the meantime, users may want to use 
+`corrosion_add_target_local_rustflags()` to pass customized linking flags.
+
+`corrosion_set_linker()` can be used to specify a custom linker, in case the default one
+chosen by corrosion is not what you want.
+Corrosion currently instructs `rustc` to use the C/C++ compiler as the linker driver.
+This is done because:
+- For C++ code we must link with `libstdc++` or `libc++` (depending on the compiler), so we must
+  either specify the library on the link line or use a `c++` compiler as the linker driver.
+- `Rustc`s default linker selection currently is not so great. For a number of platforms
+  `rustc` will fallback to `cc` as the linker driver. When cross-compiling, this leads
+  to linking failures, since the linker driver is for the host architecture.
+  Corrosion avoids this by specifying the C/C++ compiler as the linker driver.
+
+
+In some cases, especially in older rust versions (pre 1.68), the linker flavor detection 
+of `rustc` is also not correct, so when setting a custom linker you may want to pass the
+[`-C linker-flavor`](https://doc.rust-lang.org/rustc/codegen-options/index.html#linker-flavor)
+rustflag via `corrosion_add_target_local_rustflags()`.
+
+## FFI bindings
+
+For interaction between Rust and other languages there need to be some FFI bindings of some sort.
+For simple cases manually defining the interfaces may be sufficient, but in many cases users
+wish to use tools like [bindgen], [cbindgen], [cxx] or [autocxx] to automate the generating of
+bindings.
+
+In principle there are two different ways to generate the bindings:
+- use a `build.rs` script to generate the bindings when cargo is invoked, using
+  library versions of the tools to generate the bindings.
+- use the cli versions of the tools and setup custom CMake targets/commands to
+  generate the bindings. This approach should be preferred if the bindings are needed
+  by the C/C++ side.
+
+Corrosion currently provides 2 experimental functions to integrate cbindgen and cxx into
+the build process. They are not 100% production ready yet, but should work well as a 
+template on how to integrate generating bindings into your build process.
+
+Todo: expand this documentation and link to other resources.
+
+[bindgen]: https://rust-lang.github.io/rust-bindgen/
+[cbindgen]: https://github.com/eqrion/cbindgen
+[cxx]: https://cxx.rs/
+[autocxx]: https://google.github.io/autocxx/index.html
+  
\ No newline at end of file