📝 21 Apr 2024
Last article we were compiling Rust Apps for Apache NuttX RTOS (QEMU Emulator, RISC-V 32-bit). And we hit a baffling error…
$ make
riscv64-unknown-elf-ld: libapps.a
hello_rust_1.o:
can't link soft-float modules with double-float modules
Let’s solve the problem! We dive inside the internals of C-to-Rust Interop…
Rust compiles for Soft-Float, NuttX expects Double-Float
(Software vs Hardware Floating-Point)
But Rust doesn’t support Double-Float (by default)
So we create a Rust Custom Target for Double-Float
Rebuild the Rust Core Library for Double-Float
And our Rust App builds OK with NuttX!
Why did our NuttX Build fail? (Pic above)
## Download the NuttX Source Code
$ mkdir nuttx
$ cd nuttx
$ git clone https://github.com/apache/nuttx nuttx
$ git clone https://github.com/apache/nuttx-apps apps
## Configure NuttX for QEMU RISC-V 32-bit
$ cd nuttx
$ tools/configure.sh rv-virt:nsh
$ make menuconfig
## TODO: Enable "Hello Rust Example"
## Build NuttX bundled with the Rust App
$ make
riscv64-unknown-elf-ld: libapps.a
hello_rust_1.o:
can't link soft-float modules with double-float modules
GCC Linker failed because it couldn’t link the NuttX Binaries with the Rust Binaries.
Here’s Why: NuttX Build calls GCC Compiler to compile our C Modules…
## Build NuttX Firmware with Tracing Enabled
$ make --trace
...
## GCC compiles `hello_main.c` to `hello.o`
## for RISC-V 32-bit with Double-Float
riscv64-unknown-elf-gcc \
-march=rv32imafdc \
-mabi=ilp32d \
-c \
hello_main.c \
-o ...hello.o \
...
Then NuttX Build calls Rust Compiler to compile our Rust App…
## Build NuttX Firmware with Tracing Enabled
$ make --trace
...
## Rust Compiler compiles `hello_rust_main.rs` to `hello_rust.o`
## for RISC-V 32-bit with Soft-Float
rustc \
--target riscv32i-unknown-none-elf \
--edition 2021 \
--emit obj \
-g \
-C panic=abort \
-O \
hello_rust_main.rs \
-o ...hello_rust.o
Which looks like this…
Is there a problem?
Watch closely as we compare GCC Compiler with Rust Compiler (pic above)…
GCC Compiler | Rust Compiler |
---|---|
riscv64-unknown-elf-gcc hello_main.c | rustc hello_rust_main.rs |
-march rv32imafdc | –target riscv32i-unknown-none-elf |
-mabi ilp32d |
Hmmm the Floats look different…
GCC compiles for (Double-Precision) Hardware Floating-Point…
But Rust Compiler emits Software Floating-Point.
That’s why GCC Linker won’t link the binaries: Hard-Float vs Soft-Float!
GCC Compiler | Rust Compiler |
---|---|
rv32imafdc | riscv32i |
- I: Integer | - I: Integer |
- F: Single Hard-Float | (Default is Soft-Float) |
- D: Double Hard-Float | (Default is Soft-Float) |
To verify, we dump the ELF Header for GCC Compiler Output…
## Dump the ELF Header for GCC Output
$ riscv64-unknown-elf-readelf \
--file-header --arch-specific \
../apps/examples/hello/*hello.o
## GCC Compiler Output is
## Double-Precision Hardware Floating-Point
Flags: 0x5, RVC, double-float ABI
And the ELF Header for Rust Compiler Output…
## Dump the ELF Header for Rust Compiler Output
$ riscv64-unknown-elf-readelf \
--file-header --arch-specific \
../apps/examples/hello_rust/*hello_rust.o
## Rust Compiler Output is
## Software Floating-Point
Flags: 0x0
Indeed we have a problem: Double-Float and Soft-Float won’t mix! Let’s fix this…
What if we ask Rust Compiler to compile for Double-Float? RV32IMAFDC (Pic above)
Let’s harmonise Rust Compiler with GCC Compiler…
Our Build Target is QEMU Emulator
Which offically supports riscv32gc
“gc
” in “riscv32gc
” denotes IMAFDC
Hence we could do this…
## Compile `hello_rust_main.rs` to `hello_rust.o`
## for Double-Precision Hardware Floating-Point
rustc \
--target riscv32gc-unknown-none-elf \
--edition 2021 \
--emit obj \
-g \
-C panic=abort \
-O \
hello_rust_main.rs \
-o hello_rust.o
Sorry nope it won’t work…
Error loading target specification:
Could not find specification for target "riscv32gc-unknown-none-elf".
Run `rustc --print target-list` for a list of built-in targets
That’s because riscv32gc
isn’t a Built-In Rust Target…
## List the Built-In Rust Targets for RISC-V
$ rustup target list | grep riscv
## Nope no riscv32gc!
riscv32i-unknown-none-elf
riscv32imac-unknown-none-elf
riscv32imc-unknown-none-elf
riscv64gc-unknown-linux-gnu
riscv64gc-unknown-none-elf
riscv64imac-unknown-none-elf
But we can create a Custom Rust Target for riscv32gc
.
(Coming up next section)
Won’t GCC Compiler have the same problem with Double-Float?
When we list the Built-In GCC Targets…
## List the Built-In Targets for GCC RISC-V.
## ABI means Application Binary Interface
$ riscv64-unknown-elf-gcc --target-help
Supported ABIs (for use with the -mabi= option):
ilp32 ilp32d ilp32e ilp32f lp64 lp64d lp64f
We see that GCC supports Double-Float: ilp32d
ilp32
: 32-bit Int, Long and Pointerd
: Double-Precision Hardware Floating-PointThat’s why we saw ilp32d
earlier…
## GCC compiles for RISC-V 32-bit (Double-Float)
riscv64-unknown-elf-gcc \
-march=rv32imafdc \
-mabi=ilp32d \
...
We’ll make something similar for Rust Compiler…
(More about Application Binary Interface)
To compile Rust for Double-Float, we need a Custom Target: riscv32gc
How to create the Custom Target?
According to the Official Rust Docs, we shall…
Copy from a Built-In Rust Target
(Like riscv32i
)
Tweak it to fit our Custom Rust Target
(Which becomes riscv32gc
)
This is how we dump a Built-In Rust Target: riscv32i
## Dump the Built-In Rust Target:
## riscv32i (32-bit RISC-V with Soft-Float)
$ rustc \
+nightly \
-Z unstable-options \
--print target-spec-json \
--target riscv32i-unknown-none-elf
{
"arch": "riscv32",
"atomic-cas": false,
"cpu": "generic-rv32",
"data-layout": "e-m:e-p:32:32-i64:64-n32-S128",
"eh-frame-header": false,
"emit-debug-gdb-scripts": false,
"is-builtin": true,
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"llvm-target": "riscv32",
"max-atomic-width": 0,
"panic-strategy": "abort",
"relocation-model": "static",
"target-pointer-width": "32"
}
That’s the Rust Definition of riscv32i
: 32-bit RISC-V with Soft-Float.
We do the same for riscv64gc
: 64-bit RISC-V with Double-Float…
## Dump the Built-In Rust Target:
## riscv64gc (64-bit RISC-V with Double-Float)
$ rustc \
+nightly \
-Z unstable-options \
--print target-spec-json \
--target riscv64gc-unknown-none-elf
{
"arch": "riscv64",
"code-model": "medium",
"cpu": "generic-rv64",
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
"eh-frame-header": false,
"emit-debug-gdb-scripts": false,
"features": "+m,+a,+f,+d,+c",
"is-builtin": true,
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"llvm-abiname": "lp64d",
"llvm-target": "riscv64",
"max-atomic-width": 64,
"panic-strategy": "abort",
"relocation-model": "static",
"supported-sanitizers": [ "kernel-address" ],
"target-pointer-width": "64"
}
Which has more goodies inside: features, llvm-abiname, …
We’re mashing the Two Targets into a New Target?
Exactly! Based on the above, we create our Rust Custom Target: riscv32gc-unknown-none-elf.json
{
"arch": "riscv32",
"cpu": "generic-rv32",
"data-layout": "e-m:e-p:32:32-i64:64-n32-S128",
"eh-frame-header": false,
"emit-debug-gdb-scripts": false,
"features": "+m,+a,+f,+d,+c",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"llvm-abiname": "ilp32d",
"llvm-target": "riscv32",
"max-atomic-width": 0,
"panic-strategy": "abort",
"relocation-model": "static",
"target-pointer-width": "32"
}
Which is riscv32i
plus these changes…
Remove “is-builtin”: true
(It’s a Custom Target, not Built-In)
Remove “atomic-cas”: false
Add “features”: “+m,+a,+f,+d,+c”
Add “llvm-abiname”: “ilp32d”
In Summary: We spliced Two Built-In Targets into Custom Target riscv32gc
…
riscv32i (Built-In) | riscv64gc (Built-In) | riscv32gc (Custom) | |
---|---|---|---|
arch | riscv32 | riscv64 | riscv32 |
atomic-cas | false | ||
cpu | generic-rv32 | generic-rv64 | generic-rv32 |
data-layout | e-m:e-p:32… | e-m:e-p:64… | e-m:e-p:32… |
features | +m,+a,+f,+d,+c | +m,+a,+f,+d,+c | |
is-builtin | true | true | |
llvm-abiname | lp64d | ilp32d | |
llvm-target | riscv32 | riscv64 | riscv32 |
max-atomic-width | 64 | 0 | |
target-pointer-width | 32 | 64 | 32 |
Are we ready to rebuild with Double-Float?
Not quite, we’re not done with the System Library…
## Rust Compiler fails to compile with our Custom Target `riscv32gc`
$ rustc \
--target riscv32gc-unknown-none-elf.json \
--edition 2021 \
--emit obj \
-g \
-C panic=abort \
-O \
hello_rust_main.rs \
-o hello_rust.o
## That's because Rust Core Library for `riscv32gc` is missing
error[E0463]: can't find crate for `core`
Why? Remember…
GCC Compiler supports Double-Float…
Because it’s bundled with C Standard Library for Double-Float
Thus Rust Compiler will support Double-Float…
Only when it has the Rust Core Library for Double-Float
And the Rust Core Library comes from?
We call Rust Compiler to build the Rust Core Library for Double-Float riscv32gc
…
## Download our Custom Target for `riscv32gc`
rm -f riscv32gc-unknown-none-elf.json
wget https://raw.githubusercontent.com/lupyuen/nuttx-rust-app/main/riscv32gc-unknown-none-elf.json
## Custom Target needs Nightly Build of Rust Compiler
rustup override set nightly
rustup component add rust-src --toolchain nightly
## Verify our Custom Target, make sure it's OK
rustc \
--print cfg \
--target riscv32gc-unknown-none-elf.json
## `cargo build` requires a Rust Project, so we create an empty one.
rm -rf app
cargo new app
## Build the Rust Core Library for `riscv32gc`
## Include the `alloc` library, which will support Heap Memory in future.
## Ignore the error: `can't find crate for std`
pushd app
cargo build \
-Zbuild-std=core,alloc \
--target ../riscv32gc-unknown-none-elf.json \
|| true
popd
Rust Core Library for Double-Float riscv32gc
is done!
## Show the Rust Core Library for `riscv32gc`
$ ls app/target/riscv32gc-unknown-none-elf/debug/deps
alloc-254848389e7e2c53.d
app-cf88b81a5fca23b3.d
compiler_builtins-d5922d64507adf16.d
core-ec2ec78e26b8c830.d
liballoc-254848389e7e2c53.rlib
liballoc-254848389e7e2c53.rmeta
libcompiler_builtins-d5922d64507adf16.rlib
libcompiler_builtins-d5922d64507adf16.rmeta
libcore-ec2ec78e26b8c830.rlib
libcore-ec2ec78e26b8c830.rmeta
librustc_std_workspace_core-3cc5bcc9f701a6e7.rlib
librustc_std_workspace_core-3cc5bcc9f701a6e7.rmeta
rustc_std_workspace_core-3cc5bcc9f701a6e7.d
Now we rebuild our Rust App with the Custom Target (linked to our Rust Core Library)…
## Compile our Rust App with Rust Core Library for `riscv32gc`
## We changed the Target to `riscv32gc-unknown-none-elf.json`
## TODO: Change `../apps` to the NuttX Apps Folder
rustc \
--target riscv32gc-unknown-none-elf.json \
--edition 2021 \
--emit obj \
-g \
-C panic=abort \
-O \
../apps/examples/hello_rust/hello_rust_main.rs \
-o ../apps/examples/hello_rust/*hello_rust.o \
\
-C incremental=app/target/riscv32gc-unknown-none-elf/debug/incremental \
-L dependency=app/target/riscv32gc-unknown-none-elf/debug/deps \
-L dependency=app/target/debug/deps \
--extern noprelude:alloc=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/liballoc-*.rlib` \
--extern noprelude:compiler_builtins=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-*.rlib` \
--extern noprelude:core=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-*.rlib` \
-Z unstable-options
(We’ll talk about the loooong options)
Are we Double-Floating yet?
Yep we have a Yummy Double-Float with 2 scoops of ice cream…
## Dump the ELF Header of our Compiled Rust App
## TODO: Change `../apps` to the NuttX Apps Folder
$ riscv64-unknown-elf-readelf \
--file-header --arch-specific \
../apps/examples/hello_rust/*hello_rust.o
## We have Double-Float `riscv32gc` yay!
Flags: 0x5, RVC, double-float ABI
How did we get the Rust Compiler Options?
We copied the above options from cargo
build
-v
…
rustc vs cargo build: What’s the diff?
rustc
is the Rust Compiler that compiles Rust Programs to Rust Binaries
(Works like GCC Compiler)
cargo
build
wraps around rustc
for Multi-Step Builds
We could have called rustc
for building the Rust Core Library. But it will be a bunch of steps with many many options.
We compiled our Rust App with Double-Float riscv32gc…
Is our NuttX Build hunky dory now?
Yep NuttX builds OK now! GCC Compiler and Rust Compiler are harmonised to Double-Float…
## Copy the Rust Binary that will be linked with NuttX
## TODO: Change `../apps` to the NuttX Apps Folder
cp \
../apps/examples/hello_rust/*hello_rust.o \
../apps/examples/hello_rust/*hello_rust_1.o
## NuttX should link correctly now.
## TODO: Change `../nuttx` to the NuttX Kernel Folder
pushd ../nuttx
make
popd
We boot NuttX in QEMU Emulator for 32-bit RISC-V…
## For macOS:
brew install qemu
## For Debian and Ubuntu:
sudo apt install qemu-system-riscv32
## Boot NuttX in QEMU RISC-V (32-bit)
## TODO: Change `../nuttx` to the NuttX Kernel Folder
pushd ../nuttx
qemu-system-riscv32 \
-semihosting \
-M virt,aclint=on \
-cpu rv32 \
-bios none \
-kernel nuttx \
-nographic
popd
Our Rust App works wonderfully on NuttX! (Pic below)
NuttShell (NSH) NuttX-12.4.0-RC0
nsh> hello_rust
Hello, Rust!!
## Exit QEMU: Press `Ctrl-A` then `x`
Phew so much work to build a tiny Rust App?
Yeah. And integrating this into the NuttX Makefiles will be challenging.
(How would Linux Kernel handle Custom Rust Targets?)
(More about Hard-Float Targets in RISC-V)
From 32-bit to 64-bit: We tried compiling our Rust App for 64-bit RISC-V QEMU…
## Build NuttX for QEMU RISC-V 64-bit
$ tools/configure.sh rv-virt:nsh64
$ make menuconfig
## TODO: Enable "Hello Rust Example"
$ make
RUSTC: hello_rust_main.rs error: Error loading target specification:
Could not find specification for target "riscv64i-unknown-none-elf".
Run `rustc --print target-list` for a list of built-in targets
But Rust Compiler says that riscv64i
isn’t a valid Rust Target for 64-bit RISC-V.
Exercise for the Reader:
Is riscv64i
the correct target for QEMU?
[10 points]
How should we Fix the Build?
[10 points]
Do we need a Custom Target?
(Hint: Answer is printed in this article somewhere)
[10 points]
Will it run on Ox64 BL808 SBC?
[10 points]
Today we learnt a bit more about C-to-Rust Interop (pic above)…
NuttX failed to link our Rust App because Rust compiles for Soft-Float, NuttX expects Double-Float
(Software vs Hardware Floating-Point)
But Rust doesn’t support Double-Float
(Built-In Target doesn’t exist for 32-bit RISC-V)
So we created a Rust Custom Target for Double-Float: RISCV32GC
(By mashing up RISCV32I and RISCV64GC)
We rebuilt the Rust Core Library for Double-Float
(With cargo
build
)
And our Rust App builds OK with NuttX
(Runs perfectly on QEMU Emulator for RISC-V)
Many Thanks to my GitHub Sponsors (and the awesome NuttX Community) for supporting my work! This article wouldn’t have been possible without your support.
Got a question, comment or suggestion? Create an Issue or submit a Pull Request here…
lupyuen.github.io/src/rust4.md
Follow these steps to build NuttX for QEMU Emulator (32-bit RISC-V) bundled with our Rust App (pic above)…
#!/usr/bin/env bash
# Build NuttX for QEMU RISC-V 32-bit with Rust App
## TODO: Set PATH
export PATH="$HOME/xpack-riscv-none-elf-gcc-13.2.0-2/bin:$PATH"
set -e # Exit when any command fails
set -x # Echo commands
## Build NuttX
function build_nuttx {
## Go to NuttX Folder
pushd ../nuttx
## Build NuttX
make -j 8
## Return to previous folder
popd
}
## Build Rust App for QEMU RISC-V 32-bit with Rust Custom Target
function build_rust_riscv32 {
## Go to NuttX Folder
pushd ../nuttx
## Download our Custom Target for `riscv32gc`
rm -f riscv32gc-unknown-none-elf.json
wget https://raw.githubusercontent.com/lupyuen/nuttx-rust-app/main/riscv32gc-unknown-none-elf.json
## Custom Target needs Nightly Build of Rust Compiler
rustup override set nightly
rustup component add rust-src --toolchain nightly
## Verify our Custom Target, make sure it's OK
rustc \
--print cfg \
--target riscv32gc-unknown-none-elf.json
## `cargo build` requires a Rust Project, so we create an empty one.
rm -rf app
cargo new app
## Build the Rust Core Library for `riscv32gc`
## Include the `alloc` library, which will support Heap Memory in future.
## Ignore the error: `can't find crate for std`
pushd app
cargo build \
-Zbuild-std=core,alloc \
--target ../riscv32gc-unknown-none-elf.json \
|| true
popd
## Compile our Rust App with Rust Core Library for `riscv32gc`
## We changed the Target to `riscv32gc-unknown-none-elf.json`
rustc \
--target riscv32gc-unknown-none-elf.json \
--edition 2021 \
--emit obj \
-g \
-C panic=abort \
-O \
../apps/examples/hello_rust/hello_rust_main.rs \
-o ../apps/examples/hello_rust/*hello_rust.o \
\
-C incremental=app/target/riscv32gc-unknown-none-elf/debug/incremental \
-L dependency=app/target/riscv32gc-unknown-none-elf/debug/deps \
-L dependency=app/target/debug/deps \
--extern noprelude:alloc=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/liballoc-*.rlib` \
--extern noprelude:compiler_builtins=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-*.rlib` \
--extern noprelude:core=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-*.rlib` \
-Z unstable-options
## NuttX Build need us to copy hello_rust.o to hello_rust_1.o
cp \
../apps/examples/hello_rust/*hello_rust.o \
../apps/examples/hello_rust/*hello_rust_1.o
## Return to previous folder
popd
}
## Configure the NuttX Build
make distclean
tools/configure.sh rv-virt:nsh
## Enable the Hello Rust App
kconfig-tweak --enable CONFIG_EXAMPLES_HELLO_RUST
## Update the Kconfig Dependencies
make olddefconfig
## Build NuttX. Ignore the error: `can't link soft-float modules with double-float modules`
build_nuttx || true
## Build the Rust App with Custom Target
build_rust_riscv32
## Link the Rust App with NuttX
build_nuttx
## Show the size
riscv-none-elf-size nuttx
## Export the Binary Image to nuttx.bin
riscv-none-elf-objcopy \
-O binary \
nuttx \
nuttx.bin
## Copy the config
cp .config nuttx.config
## Dump the NuttX Kernel Disassembly to nuttx.S
riscv-none-elf-objdump \
--syms --source --reloc --demangle --line-numbers --wide \
--debugging \
nuttx \
>nuttx.S \
2>&1
## Dump the Rust App Disassembly to hello_rust_1.S
riscv-none-elf-objdump \
--syms --source --reloc --demangle --line-numbers --wide \
--debugging \
../apps/examples/hello_rust/*1.o \
>hello_rust_1.S \
2>&1
## Start the emulator
qemu-system-riscv32 \
-semihosting \
-M virt,aclint=on \
-cpu rv32 \
-kernel nuttx \
-nographic \
-bios none
How did we get the Rust Compiler Options for riscv32gc?
Earlier we compiled our Rust App with Rust Core Library for riscv32gc
…
And we saw these Rust Compiler Options…
## Compile our Rust App with Rust Core Library for `riscv32gc`
## We changed the Target to `riscv32gc-unknown-none-elf.json`
## TODO: Change `../apps` to the NuttX Apps Folder
rustc \
--target riscv32gc-unknown-none-elf.json \
--edition 2021 \
--emit obj \
-g \
-C panic=abort \
-O \
../apps/examples/hello_rust/hello_rust_main.rs \
-o ../apps/examples/hello_rust/*hello_rust.o \
\
-C incremental=app/target/riscv32gc-unknown-none-elf/debug/incremental \
-L dependency=app/target/riscv32gc-unknown-none-elf/debug/deps \
-L dependency=app/target/debug/deps \
--extern noprelude:alloc=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/liballoc-*.rlib` \
--extern noprelude:compiler_builtins=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-*.rlib` \
--extern noprelude:core=`ls app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-*.rlib` \
-Z unstable-options
The above options were copied from cargo
build
-v
, here’s how…
Remember we ran cargo
build
to compile the Rust Core Library?
## Download our Custom Target for `riscv32gc`
rm -f riscv32gc-unknown-none-elf.json
wget https://raw.githubusercontent.com/lupyuen/nuttx-rust-app/main/riscv32gc-unknown-none-elf.json
## Custom Target needs Nightly Build of Rust Compiler
rustup override set nightly
rustup component add rust-src --toolchain nightly
## Verify our Custom Target, make sure it's OK
rustc \
--print cfg \
--target riscv32gc-unknown-none-elf.json
## `cargo build` requires a Rust Project, so we create an empty one.
rm -rf app
cargo new app
## Build the Rust Core Library for `riscv32gc`
## Include the `alloc` library, which will support Heap Memory in future.
## Ignore the error: `can't find crate for std`
pushd app
cargo build \
-Zbuild-std=core,alloc \
--target ../riscv32gc-unknown-none-elf.json \
|| true
popd
cargo
build
will call rustc
with a whole bunch of options.
We switched it to cargo
build
-v
, which will dump the rustc
options.
Hence we see the options that will compile a Rust App with our Rust Core Library for riscv32gc
…
(TODO: Will these options change in future versions of cargo
?)
## Build the Rust Core Library for `riscv32gc`
## And the Empty Rust Project for `riscv32gc`
## `-v` will dump the `rustc` options
$ cargo build -v \
-Zbuild-std=core,alloc \
--target ../riscv32gc-unknown-none-elf.json
Compiling compiler_builtins v0.1.101
Compiling core v0.0.0 ($HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core)
## Generate the Rust Build Script for `riscv32gc`
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc
--crate-name build_script_build
--edition=2018
$HOME/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.101/build.rs
--error-format=json
--json=diagnostic-rendered-ansi,artifacts,future-incompat
--diagnostic-width=94
--crate-type bin
--emit=dep-info,link
-C embed-bitcode=no
-C debuginfo=2
-C split-debuginfo=unpacked
--cfg 'feature="compiler-builtins"'
--cfg 'feature="core"'
--cfg 'feature="default"'
--cfg 'feature="rustc-dep-of-std"'
-C metadata=9bd0bac7535b33a8
-C extra-filename=-9bd0bac7535b33a8
--out-dir $HOME/riscv/nuttx-rust-app/app/target/debug/build/compiler_builtins-9bd0bac7535b33a8
-Z force-unstable-if-unmarked
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps
--cap-lints allow`
## Build the Rust Core Library for `riscv32gc`
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc
--crate-name core
--edition=2021
$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/lib.rs
--error-format=json
--json=diagnostic-rendered-ansi,artifacts,future-incompat
--diagnostic-width=94
--crate-type lib
--emit=dep-info,metadata,link
-C embed-bitcode=no
-C debuginfo=2
-C metadata=d271c6ebb87f9b41
-C extra-filename=-d271c6ebb87f9b41
--out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
--target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json
-Z force-unstable-if-unmarked
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps
--cap-lints allow`
Running `$HOME/riscv/nuttx-rust-app/app/target/debug/build/compiler_builtins-9bd0bac7535b33a8/build-script-build`
Compiling rustc-std-workspace-core v1.99.0 ($HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/rustc-std-workspace-core)
## Build the Rust Workspace Core for `riscv32gc`
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc
--crate-name rustc_std_workspace_core
--edition=2021
$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/rustc-std-workspace-core/lib.rs
--error-format=json
--json=diagnostic-rendered-ansi,artifacts,future-incompat
--diagnostic-width=94
--crate-type lib
--emit=dep-info,metadata,link
-C embed-bitcode=no
-C debuginfo=2
-C metadata=52e0df2b2cc19b6e
-C extra-filename=-52e0df2b2cc19b6e
--out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
--target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json
-Z force-unstable-if-unmarked
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps
--extern core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-d271c6ebb87f9b41.rmeta
--cap-lints allow`
## Build the Rust Compiler Builtins for `riscv32gc`
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc
--crate-name compiler_builtins
--edition=2018
$HOME/.cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.101/src/lib.rs
--error-format=json
--json=diagnostic-rendered-ansi,artifacts,future-incompat
--diagnostic-width=94
--crate-type lib
--emit=dep-info,metadata,link
-C embed-bitcode=no
-C debuginfo=2
--cfg 'feature="compiler-builtins"'
--cfg 'feature="core"'
--cfg 'feature="default"'
--cfg 'feature="rustc-dep-of-std"'
-C metadata=cd0d33c2bd30ca51
-C extra-filename=-cd0d33c2bd30ca51
--out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
--target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json
-Z force-unstable-if-unmarked
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps
--extern core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/librustc_std_workspace_core-52e0df2b2cc19b6e.rmeta
--cap-lints allow
--cfg 'feature="unstable"'
--cfg 'feature="mem"'`
Compiling alloc v0.0.0 ($HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc)
## Build the Rust Alloc Library for `riscv32gc`
## Which will support Heap Memory in future
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc
--crate-name alloc
--edition=2021
$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/lib.rs
--error-format=json
--json=diagnostic-rendered-ansi,artifacts,future-incompat
--diagnostic-width=94
--crate-type lib
--emit=dep-info,metadata,link
-C embed-bitcode=no
-C debuginfo=2
-C metadata=5d7bc2e4f3c29e08
-C extra-filename=-5d7bc2e4f3c29e08
--out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
--target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json
-Z force-unstable-if-unmarked
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps
--extern compiler_builtins=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-cd0d33c2bd30ca51.rmeta
--extern core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-d271c6ebb87f9b41.rmeta
--cap-lints allow`
Compiling app v0.1.0 ($HOME/riscv/nuttx-rust-app/app)
## Compile our Empty Rust Project with Rust Core Library for `riscv32gc`
## These are the options that we copied into NuttX Build...
Running `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc
--crate-name app
--edition=2021
src/main.rs
--error-format=json
--json=diagnostic-rendered-ansi,artifacts,future-incompat
--diagnostic-width=94
--crate-type bin
--emit=dep-info,link
-C embed-bitcode=no
-C debuginfo=2
-C metadata=1ff442e6481e1397
-C extra-filename=-1ff442e6481e1397
--out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
--target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json
-C incremental=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/incremental
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps
-L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps
--extern 'noprelude:alloc=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/liballoc-5d7bc2e4f3c29e08.rlib'
--extern 'noprelude:compiler_builtins=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-cd0d33c2bd30ca51.rlib'
--extern 'noprelude:core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-d271c6ebb87f9b41.rlib'
-Z unstable-options`
## Ignore this error. Rust Standard Library and `println` won't work for `riscv32gc`
error[E0463]: can't find crate for `std`
|
= note: the `riscv32gc-unknown-none-elf` target may not support the standard library
= note: `std` is required by `app` because it does not declare `#![no_std]`
= help: consider building the standard library from source with `cargo build -Zbuild-std`
error: cannot find macro `println` in this scope
--> src/main.rs:2:5
|
2 | println!("Hello, world!");
| ^^^^^^^
error: `#[panic_handler]` function required, but not found
For more information about this error, try `rustc --explain E0463`.
error: could not compile `app` (bin "app") due to 3 previous errors
Caused by:
process didn't exit successfully: `$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/bin/rustc --crate-name app --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=94 --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C metadata=1ff442e6481e1397 -C extra-filename=-1ff442e6481e1397 --out-dir $HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps --target $HOME/riscv/nuttx-rust-app/riscv32gc-unknown-none-elf.json -C incremental=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/incremental -L dependency=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps -L dependency=$HOME/riscv/nuttx-rust-app/app/target/debug/deps --extern 'noprelude:alloc=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/liballoc-5d7bc2e4f3c29e08.rlib' --extern 'noprelude:compiler_builtins=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcompiler_builtins-cd0d33c2bd30ca51.rlib' --extern 'noprelude:core=$HOME/riscv/nuttx-rust-app/app/target/riscv32gc-unknown-none-elf/debug/deps/libcore-d271c6ebb87f9b41.rlib' -Z unstable-options` (exit status: 1)