Cross-compiling [no_std] code - libcore and compiler_builtins not found

Viewed 78

I'm trying to follow the steps explained in Embeddonomicon to compile the smallest #![no-std] program, but for a new target on a new architecture.

  1. The architecture is upstreamed in LLVM as an experimental target ("ARC") but its not used by rustc, so first I enabled it in the LLVM that comes with Rust as explained here: run ./x.py setup then update the config.toml:
[llvm]
download-ci-llvm = false
ninja = true
targets = "X86"
experimental-targets = "ARC"
  1. Then I manually added the support for the arch following the steps explained here (using this commit as an example):
  • created rustc_target/src/abi/call/arc.rs
  • updated rustc_llvm/src/lib.rs
  • etc
  1. Then I added the target file arc-pc-unknown-gnu.json and made it visible through RUST_TARGET_PATH envvar:
{
  "arch": "arc",
  "cpu": "generic",
  "abi": "eabi",
  "c-enum-min-bits": 8,
  "data-layout": "e-m:e-p:32:32-i64:32-f64:32-v64:32-v128:32-a:0:32-n32",
  "eh-frame-header": false,
  "emit-debug-gdb-scripts": false,
  "executables": true,
  "features": "",
  "linker": "rust-lld",
  "linker-flavor": "ld.lld",
  "llvm-target": "arc-pc-unknown-gnu",
  "max-atomic-width": 32,
  "atomic-cas": false,
  "panic-strategy": "abort",
  "relocation-model": "static",
  "target-pointer-width": "32"
}
  1. Built the compiler: ./x.py build -i --target=arc-pc-unknown-gnu library/core. It finished successfully, I could see stage1 libs for the arc-pc-unknown-gnu target
  2. I thought this would be enough, but the code was not compiling because of the following issues:
$ rustc --emit=llvm-ir -o rust_main.ll -C panic=abort --target arc-pc-unknown-gnu src/main.rs
error[E0463]: can't find crate for `core`
  |
  = note: the `arc-pc-unknown-gnu` target may not be installed
  = help: consider downloading the target with `rustup target add arc-pc-unknown-gnu`
  = help: consider building the standard library from source with `cargo build -Zbuild-std`

error[E0463]: can't find crate for `compiler_builtins`

error[E0412]: cannot find type `PanicInfo` in this scope
  --> src/main.rs:18:18

This is weird because on the previous step I should have compiled these very libs for my target...

  1. Then I though that perhaps I needed to rebuild libcore again using cargo build-std (although I don't know why exactly, but someone on the web mentioned this)? I tried this, but now there are the following errors:
$ cargo build -Z build-std=core --target arc-pc-unknown-gnu
   Compiling compiler_builtins v0.1.70
   Compiling core v0.0.0 (/home/valeriyk/proj/rust-arc/1.60.0/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/src/rust/library/core)
error[E0463]: can't find crate for `std`

error: cannot find macro `println` in this scope
  --> /home/valeriyk/.cargo/registry/src/github.com-1ecc6299db9ec823/compiler_builtins-0.1.70/build.rs:88:9
   |
88 |         println!("cargo:rustc-cfg=kernel_user_helpers")
   |         ^^^^^^^

error: cannot find macro `println` in this scope
  --> /home/valeriyk/.cargo/registry/src/github.com-1ecc6299db9ec823/compiler_builtins-0.1.70/build.rs:78:9
   |
78 |         println!("cargo:rustc-cfg=thumb_1")
   |         ^^^^^^^
...

How come that libcore needs std? I just want to have it cross-compiled using the stage1 rustc, and then picked up during my #![no_std] example compilation. Any guidance is appreciated.

1 Answers

That's how I solved the issue:

  1. Use the right rustc source code. I started with a stable version whose libcore was not compatible with the latest compiler_builtins. See here for more details. Then I needed to upgrade to the latest nightly.

  2. When building the compiler, don't ask to build libcore for the final stage, instead build rustc only:

$ ./x.py build -i --stage=1 --target=arcv2-none-elf32 compiler/rustc
  1. Use the following for the .cargo/config.toml, don't use Xargo or -Z build-std=core. The compiler-builtins-mem thing is explained here.
[unstable]
build-std = [
    "core",
    "compiler_builtins"
]
build-std-features = ["compiler-builtins-mem"]

[build]
target = "arcv2-none-elf32"
  1. Build the code with a simple cargo build. It compiled just fine, although it failed at linking later - but that's another story.
Related