📝 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-Point
That'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 aroundrustc
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 callrustc
with a whole bunch of options. -
We switched it to
cargo
build
-v
, which will dump therustc
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)