Rust: Add experimental support with Ninja

Introduction

CMake is the build system of choice for many existing C and C++ projects. When integrating Rust to such projects, the current practice is to invoke cargo to build a static library which is then linked by cmake. While this might be fine when talking about big subsystems, using cargo does not make sense if the project wants to integrate Rust in projects such as kernels, where writing individual drivers (which can be quite small) is concerned. One such example is Zephyr 0.

This PR attempts to add Rust support in a way that can allow adding small chunks of Rust to CMake projects.

My knowledge regarding both CMake and Rustc (I have mostly only used cargo) are rather limited, I probably didn't do things the most optimal way. So feel free to point out what can be improved/fixed.

Implementation

The TU for Rust is a crate, not per-source. Rustc expects entry file to TU as input, and cannot work with object files. So we need to have one-step build/link in most cases, similar to what old Swift was doing.

While the files for Rust modules are not added to cmake add_executable/add_library, dep-info file created by rustc is used to trigger rebuilds if any module changes.

Since we need to modify the target generator outputs for one-step build/link setups, only Ninja support is present.

Currently, executable, static library and dynamic library are supported build configurations. Limited support is also present for Rust object libraries. While using object files produced by rustc is not useful in most cases, it can be used directly in no_std contexts such as Linux kernel and RTOS.

I have added 2 simple tests which build and link rust to rust and rust to c executable.

Future Work

  1. Use more of existing CMake linker stuff.

Rustc allows us to select the linker to use 1. And -C link-args= can be used to directly pass arguments to the linker. This is quite powerful and should probably be exposed using CMake at some point. Additionally, CMake already has support for most linkers, so we can generate linker flags using it, instead of doing rustc specific things.

  1. Rlib support

Rustc can also build a "Rust library", which would be better to use in rust to rust linkage cases.

See-also: https://discourse.cmake.org/t/8514/20
Issue: #25492
Topic-rename: rust-support

Edited by Brad King

Merge request reports

Loading