I am trying to follow A Minimal Rust Kernel | Writing an OS in Rust and build the target using buildRustPackage
. In particular, the code I’m trying to build is this: GitHub - phil-opp/blog_os at post-02
As far as I can tell, this package was part of a NixOS test before, but has been removed because it was broken. I have not figured out what exactly broke: tests.rustCustomSysroot: remove unmaintained and broken by upstream test · NixOS/nixpkgs@c4a06db · GitHub
I am now following the NixOS guide for cross complation. I have tried many different things; from using crossSystem, to rust-overlay, with custom toolchains and without; none seemed to have really worked well.
I am looking for a derivation that spits out my target; I’m not looking to just set up a shell and use rustup - I’m sure that works, but I don’t want that.
I currently have the following flake:
{
outputs = inputs@{ nixpkgs, flake-utils, ...}:
flake-utils.lib.eachDefaultSystem(system:
let
pkgs = import nixpkgs {
inherit system;
};
# The book uses rust-lld for linking, but rust-lld is not currently packaged for NixOS.
# The justification in the book for using rust-lld suggests that gcc can still be used for testing:
# > Instead of using the platform's default linker (which might not support Linux targets),
# > we use the cross platform LLD linker that is shipped with Rust for linking our kernel.
# https://github.com/phil-opp/blog_os/blame/7212ffaa8383122b1eb07fe1854814f99d2e1af4/blog/content/second-edition/posts/02-minimal-rust-kernel/index.md#L157
targetSpec = {
llvm-target = "x86_64-unknown-none";
data-layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128";
arch = "x86_64";
target-endian = "little";
target-pointer-width = "64";
target-c-int-width = "32";
# target-family = ["unix"];
os = "none";
executables = true;
linker-flavor = "gcc"; #linker-flavor = "ld.lld"; #linker = "rust-lld";
panic-strategy = "abort";
disable-redzone = true;
features = "-mmx,-sse,+soft-float";
};
pkgsCross = import nixpkgs {
inherit system;
crossSystem = {
inherit system;
rust.rustcTarget = "x86_64-smolos";
rust.platform = targetSpec;
};
};
kernel = pkgsCross.rustPlatform.buildRustPackage {
name = "smol-kernel";
src = pkgs.fetchFromGitHub {
owner = "phil-opp";
repo = "blog_os";
rev = "post-02";
hash = "sha256-xS6d3DwhUJmbLt4vgb3xoLV7Jpue0M2Zqs5blI4Ud08=";
};
cargoHash = "";
doCheck = false;
};
in {
packages = { inherit kernel; };
}
);
}
Building this derivation fails with the following error:
error: builder for '/nix/store/qi1033fdgibsxhzl5p3x4y64lgp8dy5m-x86_64-unknown-linux-gnu-rustc-1.73.0.drv' failed with exit code 1;
last 10 log lines:
> 100 | for (desc, result, duration, stdout) in std::mem::take(&mut self.results) {
> | ^^^^^^^^^^^^^^
> |
> = help: add `#![feature(restricted_std)]` to the crate attributes to enable
>
> For more information about this error, try `rustc --explain E0658`.
> warning: `test` (lib) generated 1 warning (1 duplicate)
> error: could not compile `test` (lib) due to 11 previous errors; 1 warning emitted
> warning: build failed, waiting for other jobs to finish...
> Build completed unsuccessfully in 0:00:02
For full logs, run 'nix log /nix/store/qi1033fdgibsxhzl5p3x4y64lgp8dy5m-x86_64-unknown-linux-gnu-rustc-1.73.0.drv'.
error: 1 dependencies of derivation '/nix/store/lff1shjxgs9yrp7q5c3h3rnf0slrngw1-smol-kernel-x86_64-unknown-linux-gnu.drv' failed to build
(The full logs here: https://pastebin.com/raw/hpKZuW5S )
I strongly suspect that already setting up rustPlatform with the custom target fails to build - given by the fact that test
is failing to build during building x86_64-unknown-linux-gnu-rustc-1.73.0.drv
and it does not complain that cargoHash
is empty.
I feel like creating a custom target like that should be easily possible; what am I doing wrong?