Add some Rust building infrastructure and example#16274
Add some Rust building infrastructure and example#16274chrysn merged 11 commits intoRIOT-OS:masterfrom
Conversation
|
Oh, one addendum to testing: GCC is not really well supported as a toolchain; if things break, try with TOOLCHAIN=llvm. With #16129 merged, GCC support should increase because @maribu did a much better job in finding the subtle differences than I did in the workarounds currently in place in the riot-sys crate. |
|
Note that using this branch currently breaks most of the riot-examples as they use the older "linking in a .a archive" approach and not the newer "unar everything and let find find the .o files" one. The shell example already uses the new style and works; I expect to port over the others while this PR matures. [edit: They examples build infrastructure now contains the necessary overrides to work with this branch, and the makefiles there can be easily dropped.] |
|
There's a follow-up branch at https://github.com/chrysn-pull-requests/RIOT/tree/rust-lib in which a module is introduced that builds any number of (predefined but pseudomodule-enabled) crates in a single build and pulls them in. By the power of XFA, thus pure-Rust modules for RIOT can be implemented without any C code as long as they hook into XFA extension points (or, probably, interrupts). |
|
For this to be runnable and testable in CI, RIOT-OS/riotdocker#141 will need to be resolved. |
|
This can now be tested also using a branch of the riotdocker image; testing procedure has been amended. |
8b00fb3 to
3b1172f
Compare
94cd007 to
281f109
Compare
|
I have heard the CI is updated now - this needs a rebase. |
no it is not yet! |
CI is running current containers now, and the building is fixed |
|
Squashed and rebased after having become a bit stale. Just running the #16109 Makefile.ci generation locally (twice now, as before I didn't have all Rust targets installed), and then I'll push the fancy "CI: Ready to build" button. |
5294fe2 to
8b90a3c
Compare
|
To anyone reading the history and wondering about the on and off on ready-to-build recently: There were random (~2/3 times) failures to build, which all were around disk space exhaustion. The latest commits fix this by placing Rust's target directory inside |
|
This is as ready as I think it'll get if I keep brooding on it, please consider reviewing. I think that the toughest to review part will be makefiles ... no clue who'd be a subsystem maintainer for that to ask for a high-level check there. |
benpicco
left a comment
There was a problem hiding this comment.
This looks surprisingly non-scary.
| CPU_ARCH := armv7m | ||
| RUST_TARGET = thumbv7m-none-eabi | ||
| else ifeq ($(CPU_CORE),cortex-m33) | ||
| CPU_ARCH := armv8m |
There was a problem hiding this comment.
Is there no thumbv8m-none-eabi?
There was a problem hiding this comment.
There probably is, but I haven't verified it yet. As with other architectures, I'm trying to start a bit slowly here (but if anyone has a board around where they can test the build results, I'm happy to open it up further).
There was a problem hiding this comment.
I can test on a saml10-xpro which has a Cortex-M23
There was a problem hiding this comment.
I'ved added them now (and rebuilt Makefile.ci with consideration for them), but left them commented out because the build servers will need another update round for them. Things work up to firmware building (which is generally a good sign, as the linker usually refuses to work if the triples don't match), and you can test it by removing the comment mark, but I'd leave them out of this PR to not make it depend on the manual CI upgrades that can only start once the above-mentioned PR is merged.
| @@ -0,0 +1,896 @@ | |||
| # This file is automatically @generated by Cargo. | |||
| # It is not intended for manual editing. | |||
There was a problem hiding this comment.
should this be committed then?
There was a problem hiding this comment.
Yes: This is what ensures that things don't break just because any third party in the dependency chain declares an update to be compatible when it actually isn't.
Think of this file as the hashes of several pkgs that are all managed in here rolled into one. Like with packages, they'll be more or less regularly updated, but manually. (Typically, all a Cargo.lock file is updated in one go, so whenever riot-sys or -wrappers grow a feature needed for an example, everything else gets updated too).
Thanks :-) It certainly helps that this has been growing in a separate repo, where alterations to the build process were even trickier than in-tree. |
|
Brief side note on why so many boards are listed as "doesn't fit" for the gcoap example: No measures are yet being taken to minimize; LTO and opt-level="s" would shave roughly 30% off the application size. In general I didn't tweak much yet, leaving that for later tuning steps. (For example, Rust's standard string formatting is used, and the CBOR encoding and decoding in the examples uses a very generic framework). [edit: Better results still can be gained when passing |
|
I think that all open concerns were addressed, if only to say "out of scope for first run". (Some more Cortex M series now have triples too, but were left disabled until CI is updated all through again, and the scope point still holds). Is this good to squash? |
|
Yes, go ahead and squash |
cpu/native/Makefile.include
Outdated
| TOOLCHAINS_SUPPORTED = gnu llvm afl | ||
|
|
||
| # Platform triple as used by Rust | ||
| RUST_TARGET = i686-unknown-linux-gnu |
There was a problem hiding this comment.
This will fall on your feet when running make BOARD=native e.g. on a Raspberry Pi.
For me, gcc -print-multiarch -m32 prints i386-linux-gnu in case of riot/riotbuild. On 64-bit only (no multilib support) distros it prints an empty string, which is pretty sensible as well. So it could actually be used to provide a decent warning when running make BOARD=native on systems 64-bit only systems as side effect.
There was a problem hiding this comment.
I've added a check in a3b7cbc to Kconfig, the .include and the .features that Rust support is only advertised for x86_64 Linux. Like with the ARM board targets, I'd keep it to what I can test in the first run, and adding more platforms like 32 bit native ARM or Darwin support (is that or is that not supported any more these days?) can be done when there are actual users who'd test it.
For RISC-V and Cortex-M-not-3, triples are known and have worked in some configuration, but do not work at the moment and stay disabled until the reference platforms (native, M3) have been established well.
|
Probably yes. But CI doesn't test it, I can't test it, and it's easy to
add if needed and and when it can be tested.
(Currently still fixing a few things during rebasing, just in case you'd
be starting another review round).
|
... and to dissect the static libraries into invidial .o files to link them the same way we link C.
Cargo.lock files pin the versions of all transitive dependencies, and are left that way by Cargo unless requested manually (`cargo update`) or necessitated by a change in dependencies (if the manually maintained Cargo.toml says `>0.5.2` and .lock says `0.5.1`, the latter is reset). They are fixed (as opposed to .gitignoring them and letting each user autogenerate them) to ensure that third party changes do not break RIOT CI builds; for updates, the changes from a `cargo update` can still be committed and then run through CI checks. (This is analogous to how pkg versions are pinned). They are set to binary because their diffs are usually not practical to read.
|
Some changes during rebasing:
Please review, it's good to go from my side (especially, the REMOVEME commit that only makes it build the Rust examples has been removed, so it's good to ACK-and-merge if reviewers agree). |
|
The Murdock run showed two errors -- one appears to be just a random timeout (tests/pkg_edhoc_c/esp32-wroom-32), the other is highly weird because it's using an old version of a Rust library that was already updated and pinned (but maybe too softly) to the newer version. This might have been a caching issue; I'll look at it but unless this persists I don't think it's a reason for delay. Holding off the murdock rerun that I recommend to do due to the first error until there is either an ACK or any comment that requires further changes. |
|
Correction: Nothing weird about the version thing, I just only fixed the examples and forgot about the test. Still disabled CI rebuilding (as the fix is very likely correct, and can just as well be tested after being smushed). I'd smush and turn on Murdock again once anyone says "ACK, smush". |
|
Feel free to squash, still looks good from my side. |
maribu
left a comment
There was a problem hiding this comment.
Let me throw in an ACK. The changes look good to me and the author did rigorous testing.
Unlike the hello-world example (that is largely identical), this gets run during CI.
Contribution description
While writing Rust applications has been possible for some time, it has required a few Makefile rules which I'm by now happy enough with to start a first PR. Having this all in-tree is not essential for operation, but makes it a bit easier to store, for example, the target definitions with the architectures rather than in a big if chain that sometimes peeks into fields and sometimes into boards.
This adds
$(APPLICATION_RUST_MODULE).moduleand added toBASELIBS, but is built by running Cargo and then exploding the built static lib into the folder where LINK expects it to be.Testing procedure
BUILD_IN_DOCKER=1make all flash term, optionally with a cortex M0-4 board.It is tested so far with native and some cortex-m0, 3 and 4 boards (mostly EFM32, EFR32 and nRF52840). riscv support is disabled right now, I don't want to do that in the first rush until it falls into place trivially.
Questions:
${MODULE}.modulethat is${CRATE}.cratethat gets its own place in the big find of LINK? I think it'd make sense because it wouldn't involve overriding a target any more, and moreover make it easier to later extend this to having potentially multiple built crates (although I think it's preferable to use one), but would make a larger diff.Issues/PRs references
Closes: #9799
[edit: Updated examples list and test description now that the riotdocker images just do the right thing]