diff --git a/doc/doxygen/src/using-rust.md b/doc/doxygen/src/using-rust.md index ca3e11e204..e72114fe8b 100644 --- a/doc/doxygen/src/using-rust.md +++ b/doc/doxygen/src/using-rust.md @@ -39,6 +39,16 @@ maintained in coordination with the riot-wrappers crate. [riot-module-examples]: https://gitlab.com/etonomy/riot-module-examples [additional examples]: https://gitlab.com/etonomy/riot-examples/ +IDE / editor setup +------------------ + +Users of Rust often take advantage of autocompletion or inline help. +To use this on RIOT projects, +some flags and environment variables have to be set, +which are listed by `make info-rust`. +These can be configured in the IDE's project setup +or exported as environment variables. + How it works ------------ @@ -108,19 +118,17 @@ To install the necessary Rust components, it is easiest use [**rustup**, install Using Rust on RIOT needs the latest stable version of Rust. -Make sure you have the stable **toolchain** -and the core library for the CPU (**target**) of your choice available: +Make sure you have the core library for the CPU (**target**) of your choice available: ``` -$ rustup toolchain add stable -$ rustup target add thumbv7m-none-eabi --toolchain stable +$ rustup target add thumbv7m-none-eabi ``` Substitute thumbv7m-none-eabi with the value of `RUST_TARGET` in the output of `make info-build` of an application that has your current board selected (or just add it later whenever the Rust compiler complains about not finding the core library for a given target). -Using a beta or nightly will work just as well, -but you may need to set `CARGO_CHANNEL=nightly` on your shell or in your Makefiles. +Using the beta or nightly toolchains will work just as well +if they are selected through rustup's override mechanism. While Rust comes with its own [cargo] dependency tracker for any Rust code, diff --git a/examples/rust-gcoap/Cargo.lock b/examples/rust-gcoap/Cargo.lock index fe222b7733..80664d3392 100644 Binary files a/examples/rust-gcoap/Cargo.lock and b/examples/rust-gcoap/Cargo.lock differ diff --git a/examples/rust-gcoap/Makefile b/examples/rust-gcoap/Makefile index bc912e5d3f..1cdb347a7a 100644 --- a/examples/rust-gcoap/Makefile +++ b/examples/rust-gcoap/Makefile @@ -41,8 +41,6 @@ BASELIBS += $(APPLICATION_RUST_MODULE).module FEATURES_REQUIRED += rust_target -CARGO_CHANNEL ?= stable - # Currently unknown, something related to the LED_PORT definition that doesn't # pass C2Rust's transpilation BOARD_BLACKLIST := ek-lm4f120xl diff --git a/examples/rust-hello-world/Cargo.lock b/examples/rust-hello-world/Cargo.lock index 391746a836..86a60a350f 100644 Binary files a/examples/rust-hello-world/Cargo.lock and b/examples/rust-hello-world/Cargo.lock differ diff --git a/examples/rust-hello-world/Makefile b/examples/rust-hello-world/Makefile index b0f4f15ccf..b6d08353e4 100644 --- a/examples/rust-hello-world/Makefile +++ b/examples/rust-hello-world/Makefile @@ -21,11 +21,6 @@ BASELIBS += $(APPLICATION_RUST_MODULE).module FEATURES_REQUIRED += rust_target -# All Rust components RIOT uses work on stable Rust. If any extra libraries -# were to require a more recent version, switch to `CARGO_CHANNEL = -# $(CARGO_CHANNEL_NIGHTLY)` to use whichever nightly version is available. -CARGO_CHANNEL ?= stable - # Currently unknown, something related to the LED_PORT definition that doesn't # pass C2Rust's transpilation BOARD_BLACKLIST := ek-lm4f120xl diff --git a/makefiles/cargo-settings.inc.mk b/makefiles/cargo-settings.inc.mk index 983c2c1909..3f4c1a8a2e 100644 --- a/makefiles/cargo-settings.inc.mk +++ b/makefiles/cargo-settings.inc.mk @@ -1,29 +1,9 @@ -# Setting anything other than "debug" or "release" will necessitate additional -# -Z unstable-options as of 2021-03 nightlies. +# The profile with which to build Rust usually `release` or `dev`. +# +# This needs to be known to the build scripts because the path of the produced +# binary is derived from this. CARGO_PROFILE ?= release -# Value for CARGO_CHANNEL when using nightly -# -# As different environments have different versions of nightly installed, but -# rustup / cargo does not take "the latest installed nightly" for a toolchain, -# a good value is determined dynamically. Typical values this takes are -# `nightly` (on regular installations) and `nightly-2022-03-08` (or whichever -# date it is currently pinned to) in riotbuild. -# -# Workaround-For: https://github.com/rust-lang/rustup/issues/3015 -# -# This does not get evaluated unless actually used; if rustup is not installed, -# the default value will likely not be usable but at least set the user on the -# right track. -CARGO_CHANNEL_NIGHTLY = $(shell rustup toolchain list | sed 's/ .*//' |grep nightly | tail -n1 || echo nightly) - -# The Rust version to use. -# -# Examples should set this to either `stable` or `$(CARGO_CHANNEL_NIGHTLY)`. -# The default is empty, which is suitable for applications that select their -# version through a `rust-toolchain.yaml` file. -CARGO_CHANNEL ?= - # Note that if we did not set this explicitly, CARGO_LIB would have to # understand which value cargo uses in absence of CARGO_TARGET_DIR, which would # be $(APPDIR)/target. @@ -42,4 +22,17 @@ CARGO_CHANNEL ?= CARGO_TARGET_DIR = $(BINDIR)/target # The single Rust library to be built. -CARGO_LIB = $(CARGO_TARGET_DIR)/$(RUST_TARGET)/${CARGO_PROFILE}/lib$(APPLICATION_RUST_MODULE).a +# +# The dev->debug and bench->release substitutions represent a historical +# peculiarity in cargo: "For historical reasons, the `dev` and `test` profiles +# are stored in the `debug` directory, and the `release` and `bench` profiles +# are stored in the `release` directory. User-defined profiles are stored in a +# directory with the same name as the profile". +CARGO_LIB = $(CARGO_TARGET_DIR)/$(RUST_TARGET)/$(patsubst test,debug,$(patsubst dev,debug,$(patsubst bench,release,${CARGO_PROFILE})))/lib$(APPLICATION_RUST_MODULE).a + +# Options passed into all Cargo commands, in particular to the build command. +# +# Most of these are populated by RIOT modules that are backed by Rust. Popular +# options added by the user are `-Zbuild-std=core` (only available on nightly) +# to apply LTO and profile configuration to the core library. +CARGO_OPTIONS ?= diff --git a/makefiles/cargo-targets.inc.mk b/makefiles/cargo-targets.inc.mk index 118cb83f7a..47fa12214e 100644 --- a/makefiles/cargo-targets.inc.mk +++ b/makefiles/cargo-targets.inc.mk @@ -42,31 +42,30 @@ $(CARGO_COMPILE_COMMANDS): $(BUILDDEPS) $(CARGO_LIB): $(RIOTBUILD_CONFIG_HEADER_C) $(BUILDDEPS) $(CARGO_COMPILE_COMMANDS) FORCE - $(Q)command -v cargo >/dev/null || ($(COLOR_ECHO) \ + @command -v cargo >/dev/null || ($(COLOR_ECHO) \ '$(COLOR_RED)Error: `cargo` command missing to build Rust modules.$(COLOR_RESET) Please install as described on .' ;\ exit 1) - $(Q)command -v $${C2RUST:-c2rust} >/dev/null || ($(COLOR_ECHO) \ + @command -v $${C2RUST:-c2rust} >/dev/null || ($(COLOR_ECHO) \ '$(COLOR_RED)Error: `'$${C2RUST:-c2rust}'` command missing to build Rust modules.$(COLOR_RESET) Please install as described on .' ;\ exit 1) - $(Q)command -v rustup >/dev/null || ($(COLOR_ECHO) \ + @command -v rustup >/dev/null || ($(COLOR_ECHO) \ '$(COLOR_RED)Error: `rustup` command missing.$(COLOR_RESET) While it is not essential for building Rust modules, it is the only known way to install the target core libraries (or nightly for -Zbuild-std) needed to do so. If you do think that building should be possible, please edit this file, and file an issue about building Rust modules with the installation method you are using -- later checks in this file, based on rustup, will need to be adjusted for that.' ;\ exit 1) - $(Q)[ x"${RUST_TARGET}" != x"" ] || ($(COLOR_ECHO) "$(COLOR_RED)Error: No RUST_TARGET was set for this platform.$(COLOR_RESET) Set FEATURES_REQUIRED+=rust_target to catch this earlier."; exit 1) - $(Q)# If distribution installed cargos ever grow the capacity to build RIOT, this absence of `rustup` might be OK. But that'd need them to both have cross tools around and cross core libs, none of which is currently the case. - $(Q)# Ad grepping for "std": We're not *actually* checking for std but more for core -- but rust-stc-$TARGET is the name of any standard libraries that'd be available for that target. - $(Q)[ x"$(findstring build-std,$(CARGO_OPTIONS))" != x"" ] || \ - (rustup component list $(patsubst %,--toolchain %,$(CARGO_CHANNEL)) --installed | grep 'rust-std-$(RUST_TARGET)$$' -q) || \ + @[ x"${RUST_TARGET}" != x"" ] || ($(COLOR_ECHO) "$(COLOR_RED)Error: No RUST_TARGET was set for this platform.$(COLOR_RESET) Set FEATURES_REQUIRED+=rust_target to catch this earlier."; exit 1) + @# If distribution installed cargos ever grow the capacity to build RIOT, this absence of `rustup` might be OK. But that'd need them to both have cross tools around and cross core libs, none of which is currently the case. + @# Ad grepping for "std": We're not *actually* checking for std but more for core -- but rust-stc-$TARGET is the name of any standard libraries that'd be available for that target. + @[ x"$(findstring build-std,$(CARGO_OPTIONS))" != x"" ] || \ + (rustup component list --installed | grep 'rust-std-$(RUST_TARGET)$$' -q) || \ ($(COLOR_ECHO) \ - '$(COLOR_RED)Error: No Rust libraries are installed for the board'"'"'s CPU.$(COLOR_RESET) Run\n $(COLOR_GREEN)$$$(COLOR_RESET) rustup target add $(RUST_TARGET) $(patsubst %,--toolchain %,$(CARGO_CHANNEL))\nor set `CARGO_OPTIONS=-Zbuild-std=core`.'; \ + '$(COLOR_RED)Error: No Rust libraries are installed for the board'"'"'s CPU.$(COLOR_RESET) Run\n $(COLOR_GREEN)$$$(COLOR_RESET) rustup target add $(RUST_TARGET)\nor set `CARGO_OPTIONS=-Zbuild-std=core`.'; \ exit 1) - $(Q)# finally call out to cargo. mind the "+" to pass down make's jobserver. + @# finally call out to cargo. mind the "+" to pass down make's jobserver. $(Q)+ CC= CFLAGS= CPPFLAGS= CXXFLAGS= \ RIOT_COMPILE_COMMANDS_JSON="$(CARGO_COMPILE_COMMANDS)" \ - RIOT_USEMODULE="$(USEMODULE)" \ - cargo $(patsubst +,,+${CARGO_CHANNEL}) \ + cargo \ build \ --target $(RUST_TARGET) \ - `if [ x$(CARGO_PROFILE) = xrelease ]; then echo --release; else if [ x$(CARGO_PROFILE) '!=' xdebug ]; then echo "--profile $(CARGO_PROFILE)"; fi; fi` \ + --profile $(CARGO_PROFILE) \ $(CARGO_OPTIONS) $(APPLICATION_RUST_MODULE).module: $(CARGO_LIB) FORCE diff --git a/makefiles/info.inc.mk b/makefiles/info.inc.mk index 922ded24ac..fdaff029e0 100644 --- a/makefiles/info.inc.mk +++ b/makefiles/info.inc.mk @@ -90,7 +90,6 @@ info-build: @echo -e 'CXXEXFLAGS:$(patsubst %, \n\t%, $(CXXEXFLAGS))' @echo '' @echo 'RUST_TARGET: $(RUST_TARGET)' - @echo 'CARGO_CHANNEL: $(CARGO_CHANNEL)' @echo 'CARGO_PROFILE: $(CARGO_PROFILE)' @echo 'CARGO_OPTIONS: $(CARGO_OPTIONS)' @echo '' @@ -250,5 +249,10 @@ info-programmers-supported: @echo $(sort $(PROGRAMMERS_SUPPORTED)) info-rust: - cargo $(patsubst +,,+${CARGO_CHANNEL}) version + cargo version c2rust --version + @echo "To use this setup of Rust in an IDE, add these command line arguments to the \`cargo check\` or \`rust-analyzer\`:" + @echo " --target $(RUST_TARGET) --profile $(CARGO_PROFILE)" + @echo "and export these environment variables:" + @echo " RIOT_COMPILE_COMMANDS_JSON=\"$(CARGO_COMPILE_COMMANDS)\"" + @echo " RIOTBUILD_CONFIG_HEADER_C=\"$(RIOTBUILD_CONFIG_HEADER_C)\"" diff --git a/sys/rust_riotmodules_standalone/Cargo.lock b/sys/rust_riotmodules_standalone/Cargo.lock index 66837be207..056718fc20 100644 Binary files a/sys/rust_riotmodules_standalone/Cargo.lock and b/sys/rust_riotmodules_standalone/Cargo.lock differ diff --git a/tests/rust_libs/Makefile b/tests/rust_libs/Makefile index 6195a36951..a41e323007 100644 --- a/tests/rust_libs/Makefile +++ b/tests/rust_libs/Makefile @@ -5,10 +5,6 @@ USEMODULE += shell_democommands FEATURES_REQUIRED += rust_target -# Testing on stable to ensure that no nightly features are needed when Rust is -# pulled in through modules. -CARGO_CHANNEL = stable - # Currently unknown, something related to the LED_PORT definition that doesn't # pass C2Rust's transpilation BOARD_BLACKLIST := ek-lm4f120xl diff --git a/tests/rust_minimal/Cargo.lock b/tests/rust_minimal/Cargo.lock index 63bb6e3d8b..550f9c2e94 100644 Binary files a/tests/rust_minimal/Cargo.lock and b/tests/rust_minimal/Cargo.lock differ diff --git a/tests/rust_minimal/Makefile b/tests/rust_minimal/Makefile index 72a112e7cf..9001f83c6c 100644 --- a/tests/rust_minimal/Makefile +++ b/tests/rust_minimal/Makefile @@ -5,10 +5,6 @@ BASELIBS += $(APPLICATION_RUST_MODULE).module FEATURES_REQUIRED += rust_target -# Testing on stable to ensure that no nightly features are needed for basic -# Rust usage. -CARGO_CHANNEL = stable - # Currently unknown, something related to the LED_PORT definition that doesn't # pass C2Rust's transpilation BOARD_BLACKLIST := ek-lm4f120xl