From f8ea4e0c3dabd9551066bc8e74d225d90f8bf4f6 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Thu, 8 Oct 2020 14:32:49 -0700 Subject: [PATCH 01/19] makeRustPlatform: support custom targets --- pkgs/build-support/rust/default.nix | 35 ++++++++++++---- pkgs/build-support/rust/sysroot/Cargo.lock | 20 +++++++++ pkgs/build-support/rust/sysroot/cargo.py | 44 ++++++++++++++++++++ pkgs/build-support/rust/sysroot/default.nix | 45 +++++++++++++++++++++ 4 files changed, 137 insertions(+), 7 deletions(-) create mode 100644 pkgs/build-support/rust/sysroot/Cargo.lock create mode 100644 pkgs/build-support/rust/sysroot/cargo.py create mode 100644 pkgs/build-support/rust/sysroot/default.nix diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index f6177ce198d..10488f4d372 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -4,6 +4,10 @@ , cargo , diffutils , fetchCargoTarball +, runCommandNoCC +, rustPlatform +, callPackage +, remarshal , git , rust , rustc @@ -26,12 +30,15 @@ , cargoBuildFlags ? [] , buildType ? "release" , meta ? {} -, target ? null +, target ? rust.toRustTarget stdenv.hostPlatform , cargoVendorDir ? null , checkType ? buildType , depsExtraArgs ? {} , cargoParallelTestThreads ? true +# Toggles whether a custom sysroot is created when the target is a .json file. +, __internal_dontAddSysroot ? false + # Needed to `pushd`/`popd` into a subdir of a tarball if this subdir # contains a Cargo.toml, but isn't part of a workspace (which is e.g. the # case for `rustfmt`/etc from the `rust-sources). @@ -68,14 +75,26 @@ let else '' cargoDepsCopy="$sourceRoot/${cargoVendorDir}" ''; + + targetIsJSON = stdenv.lib.hasSuffix ".json" target; - rustTarget = if target == null then rust.toRustTarget stdenv.hostPlatform else target; + # see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168 + # the "${}" is needed to transform the path into a /nix/store path before baseNameOf + shortTarget = if targetIsJSON then + (stdenv.lib.removeSuffix ".json" (builtins.baseNameOf "${target}")) + else target; + + sysroot = (callPackage ./sysroot {}) { + inherit target shortTarget; + RUSTFLAGS = args.RUSTFLAGS or ""; + originalCargoToml = src + /Cargo.toml; # profile info is later extracted + }; ccForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc"; cxxForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++"; ccForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc"; cxxForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++"; - releaseDir = "target/${rustTarget}/${buildType}"; + releaseDir = "target/${shortTarget}/${buildType}"; tmpDir = "${releaseDir}-tmp"; # Specify the stdenv's `diff` by abspath to ensure that the user's build @@ -115,7 +134,7 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { [target."${rust.toRustTarget stdenv.buildPlatform}"] "linker" = "${ccForBuild}" ${stdenv.lib.optionalString (stdenv.buildPlatform.config != stdenv.hostPlatform.config) '' - [target."${rustTarget}"] + [target."${shortTarget}"] "linker" = "${ccForHost}" ${# https://github.com/rust-lang/rust/issues/46651#issuecomment-433611633 stdenv.lib.optionalString (stdenv.hostPlatform.isMusl && stdenv.hostPlatform.isAarch64) '' @@ -183,9 +202,11 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { "CXX_${rust.toRustTarget stdenv.buildPlatform}"="${cxxForBuild}" \ "CC_${rust.toRustTarget stdenv.hostPlatform}"="${ccForHost}" \ "CXX_${rust.toRustTarget stdenv.hostPlatform}"="${cxxForHost}" \ - cargo build -j $NIX_BUILD_CORES \ + ${stdenv.lib.optionalString + (targetIsJSON && !__internal_dontAddSysroot) "RUSTFLAGS=\"--sysroot ${sysroot} $RUSTFLAGS\" " + }cargo build -j $NIX_BUILD_CORES \ ${stdenv.lib.optionalString (buildType == "release") "--release"} \ - --target ${rustTarget} \ + --target ${target} \ --frozen ${concatStringsSep " " cargoBuildFlags} ) @@ -205,7 +226,7 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { ''; checkPhase = args.checkPhase or (let - argstr = "${stdenv.lib.optionalString (checkType == "release") "--release"} --target ${rustTarget} --frozen"; + argstr = "${stdenv.lib.optionalString (checkType == "release") "--release"} --target ${target} --frozen"; threads = if cargoParallelTestThreads then "$NIX_BUILD_CORES" else "1"; in '' ${stdenv.lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"} diff --git a/pkgs/build-support/rust/sysroot/Cargo.lock b/pkgs/build-support/rust/sysroot/Cargo.lock new file mode 100644 index 00000000000..3b576f6657f --- /dev/null +++ b/pkgs/build-support/rust/sysroot/Cargo.lock @@ -0,0 +1,20 @@ +[[package]] +name = "alloc" +version = "0.0.0" +dependencies = ["compiler_builtins", "core"] + +[[package]] +name = "compiler_builtins" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc4ac2c824d2bfc612cba57708198547e9a26943af0632aff033e0693074d5c" +dependencies = ["rustc-std-workspace-core"] + +[[package]] +name = "core" +version = "0.0.0" + +[[package]] +name = "rustc-std-workspace-core" +version = "1.99.0" +dependencies = ["core"] diff --git a/pkgs/build-support/rust/sysroot/cargo.py b/pkgs/build-support/rust/sysroot/cargo.py new file mode 100644 index 00000000000..10ad94e4c54 --- /dev/null +++ b/pkgs/build-support/rust/sysroot/cargo.py @@ -0,0 +1,44 @@ +import os +import toml + +rust_src = os.environ['RUSTC_SRC'] +orig_cargo = os.environ['ORIG_CARGO'] + +base = { + 'package': { + 'name': 'alloc', + 'version': '0.0.0', + 'authors': ['The Rust Project Developers'], + 'edition': '2018', + }, + 'dependencies': { + 'compiler_builtins': { + 'version': '0.1.0', + 'features': ['rustc-dep-of-std', 'mem'], + }, + 'core': { + 'path': os.path.join(rust_src, 'libcore'), + }, + }, + 'lib': { + 'name': 'alloc', + 'path': os.path.join(rust_src, 'liballoc/lib.rs'), + }, + 'patch': { + 'crates-io': { + 'rustc-std-workspace-core': { + 'path': os.path.join(rust_src, 'tools/rustc-std-workspace-core'), + }, + }, + }, +} + +with open(orig_cargo, 'r') as f: + src = toml.loads(f.read()) + if 'profile' in src: + base['profile'] = src['profile'] + +out = toml.dumps(base) + +with open('Cargo.toml', 'x') as f: + f.write(out) diff --git a/pkgs/build-support/rust/sysroot/default.nix b/pkgs/build-support/rust/sysroot/default.nix new file mode 100644 index 00000000000..3bb86e9ad9a --- /dev/null +++ b/pkgs/build-support/rust/sysroot/default.nix @@ -0,0 +1,45 @@ +{ stdenv, rust, rustPlatform, buildPackages }: + +{ shortTarget, originalCargoToml, target, RUSTFLAGS }: + +let rustSrc = stdenv.mkDerivation { + name = "rust-src"; + src = rustPlatform.rust.rustc.src; + preferLocalBuild = true; + phases = [ "unpackPhase" "installPhase" ]; + installPhase = "cp -r src $out"; + }; + cargoSrc = stdenv.mkDerivation { + name = "cargo-src"; + preferLocalBuild = true; + phases = [ "installPhase" ]; + installPhase = '' + RUSTC_SRC=${rustSrc} ORIG_CARGO=${originalCargoToml} \ + ${buildPackages.python3.withPackages (ps: with ps; [ toml ])}/bin/python3 ${./cargo.py} + mkdir -p $out + cp Cargo.toml $out/Cargo.toml + cp ${./Cargo.lock} $out/Cargo.lock + ''; + }; +in rustPlatform.buildRustPackage { + inherit target RUSTFLAGS; + + name = "custom-sysroot"; + src = cargoSrc; + + RUSTC_BOOTSTRAP = 1; + __internal_dontAddSysroot = true; + cargoSha256 = "1snkfsx3jb1p5izwlfwkgp8hxhgpa35nmx939sp5730vf9whqqwg"; + + installPhase = '' + export LIBS_DIR=$out/lib/rustlib/${shortTarget}/lib + mkdir -p $LIBS_DIR + for f in target/${shortTarget}/release/deps/*.{rlib,rmeta}; do + cp $f $LIBS_DIR + done + + export RUST_SYSROOT=$(rustc --print=sysroot) + export HOST=${rust.toRustTarget stdenv.buildPlatform} + cp -r $RUST_SYSROOT/lib/rustlib/$HOST $out + ''; +} From 0fca6ba580107406429821c0cd40c674025096aa Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Mon, 12 Oct 2020 14:48:07 -0700 Subject: [PATCH 02/19] fix compile error --- pkgs/build-support/rust/sysroot/default.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/build-support/rust/sysroot/default.nix b/pkgs/build-support/rust/sysroot/default.nix index 3bb86e9ad9a..8cfe2d55152 100644 --- a/pkgs/build-support/rust/sysroot/default.nix +++ b/pkgs/build-support/rust/sysroot/default.nix @@ -29,7 +29,9 @@ in rustPlatform.buildRustPackage { RUSTC_BOOTSTRAP = 1; __internal_dontAddSysroot = true; - cargoSha256 = "1snkfsx3jb1p5izwlfwkgp8hxhgpa35nmx939sp5730vf9whqqwg"; + cargoSha256 = "1l5z44dw5h7lbwmpjqax2g40cf4h27yai3wlj0p5di5v1xf25rng"; + + doCheck = false; installPhase = '' export LIBS_DIR=$out/lib/rustlib/${shortTarget}/lib From 3f3491d64d24e87534a11d0f78e2ffea13150749 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Mon, 12 Oct 2020 18:41:13 -0700 Subject: [PATCH 03/19] fix some whitespace --- pkgs/build-support/rust/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index 10488f4d372..0f3ff2b70e6 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -75,7 +75,7 @@ let else '' cargoDepsCopy="$sourceRoot/${cargoVendorDir}" ''; - + targetIsJSON = stdenv.lib.hasSuffix ".json" target; # see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168 From c0df12de5d938e1c263c992ebd648c4100e8c0a2 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 14 Oct 2020 03:37:29 +0000 Subject: [PATCH 04/19] rust: Add support for managing target JSON in Nix --- doc/languages-frameworks/rust.section.md | 53 ++++++++++++++++++- .../rust/build-rust-crate/build-crate.nix | 2 +- .../rust/build-rust-crate/configure-crate.nix | 4 +- pkgs/build-support/rust/default.nix | 2 +- pkgs/build-support/rust/sysroot/default.nix | 4 +- pkgs/development/compilers/rust/default.nix | 10 +++- pkgs/development/compilers/rust/rustc.nix | 6 +-- pkgs/development/libraries/relibc/default.nix | 3 +- 8 files changed, 71 insertions(+), 13 deletions(-) diff --git a/doc/languages-frameworks/rust.section.md b/doc/languages-frameworks/rust.section.md index 0e1d59e1a95..0f3cc5d8efb 100644 --- a/doc/languages-frameworks/rust.section.md +++ b/doc/languages-frameworks/rust.section.md @@ -63,9 +63,52 @@ The fetcher will verify that the `Cargo.lock` file is in sync with the `src` attribute, and fail the build if not. It will also will compress the vendor directory into a tar.gz archive. -### Building a crate for a different target +### Cross compilation -To build your crate with a different cargo `--target` simply specify the `target` attribute: +By default, Rust packages are compiled for the host platform, just like any +other package is. The `--target` passed to rust tools is computed from this. +By default, it takes the `stdenv.hostPlatform.config` and replaces components +where they are known to differ. But there are ways to customize the argument: + + - To choose a different target by name, define + `stdenv.hostPlatform.rustc.arch.config` as that name (a string), and that + name will be used instead. + + For example: + ```nix + import { + crossSystem = (import ).systems.examples.armhf-embedded // { + rustc.arch.config = "thumbv7em-none-eabi"; + }; + } + ``` + will result in: + ```shell + --target thumbv7em-none-eabi + ``` + + - To pass a completely custom target, define + `stdenv.hostPlatform.rustc.arch.config` with its name, and + `stdenv.hostPlatform.rustc.arch.custom` with the value. The value will be + serialized to JSON in a file called + `${stdenv.hostPlatform.rustc.arch.config}.json`, and the path of that file + will be used instead. + + For example: + ```nix + import { + crossSystem = (import ).systems.examples.armhf-embedded // { + rustc.arch.config = "thumb-crazy"; + rustc.arch.custom = { foo = ""; bar = ""; }; + }; + } + will result in: + ```shell + --target /nix/store/asdfasdfsadf-thumb-crazy.json # contains {"foo":"","bar":""} + ``` + +Finally, as an ad-hoc escape hatch, a computed target (string or JSON file +path) can be passed directly to `buildRustPackage`: ```nix pkgs.rustPlatform.buildRustPackage { @@ -74,6 +117,12 @@ pkgs.rustPlatform.buildRustPackage { } ``` +This is useful to avoid rebuilding Rust tools, since they are actually target +agnostic and don't need to be rebuilt. But in the future, we should always +build the Rust tools and standard library crates separately so there is no +reason not to take the `stdenv.hostPlatform.rustc`-modifying approach, and the +ad-hoc escape hatch to `buildRustPackage` can be removed. + ### Running package tests When using `buildRustPackage`, the `checkPhase` is enabled by default and runs diff --git a/pkgs/build-support/rust/build-rust-crate/build-crate.nix b/pkgs/build-support/rust/build-rust-crate/build-crate.nix index 142109cef49..84d1b2300f1 100644 --- a/pkgs/build-support/rust/build-rust-crate/build-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/build-crate.nix @@ -15,7 +15,7 @@ ++ [(mkRustcDepArgs dependencies crateRenames)] ++ [(mkRustcFeatureArgs crateFeatures)] ++ extraRustcOpts - ++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTarget stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc" + ++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTargetSpec stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc" # since rustc 1.42 the "proc_macro" crate is part of the default crate prelude # https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022 ++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro" diff --git a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix index 18587f7047c..5ada40b3b9b 100644 --- a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix @@ -135,8 +135,8 @@ in '' export CARGO_MANIFEST_DIR=$(pwd) export DEBUG="${toString (!release)}" export OPT_LEVEL="${toString optLevel}" - export TARGET="${rust.toRustTarget stdenv.hostPlatform}" - export HOST="${rust.toRustTarget stdenv.buildPlatform}" + export TARGET="${rust.toRustTargetSpec stdenv.hostPlatform}" + export HOST="${rust.toRustTargetSpec stdenv.buildPlatform}" export PROFILE=${if release then "release" else "debug"} export OUT_DIR=$(pwd)/target/build/${crateName}.out export CARGO_PKG_VERSION_MAJOR=${lib.elemAt version 0} diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index 0f3ff2b70e6..3f6a84b8aed 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -30,7 +30,7 @@ , cargoBuildFlags ? [] , buildType ? "release" , meta ? {} -, target ? rust.toRustTarget stdenv.hostPlatform +, target ? rust.toRustTargetSpec stdenv.hostPlatform , cargoVendorDir ? null , checkType ? buildType , depsExtraArgs ? {} diff --git a/pkgs/build-support/rust/sysroot/default.nix b/pkgs/build-support/rust/sysroot/default.nix index 8cfe2d55152..2625306b246 100644 --- a/pkgs/build-support/rust/sysroot/default.nix +++ b/pkgs/build-support/rust/sysroot/default.nix @@ -41,7 +41,7 @@ in rustPlatform.buildRustPackage { done export RUST_SYSROOT=$(rustc --print=sysroot) - export HOST=${rust.toRustTarget stdenv.buildPlatform} - cp -r $RUST_SYSROOT/lib/rustlib/$HOST $out + host=${rust.toRustTarget stdenv.buildPlatform} + cp -r $RUST_SYSROOT/lib/rustlib/$host $out ''; } diff --git a/pkgs/development/compilers/rust/default.nix b/pkgs/development/compilers/rust/default.nix index 0fbe5b8c0ed..fc1af5a3f94 100644 --- a/pkgs/development/compilers/rust/default.nix +++ b/pkgs/development/compilers/rust/default.nix @@ -24,7 +24,8 @@ if platform.isDarwin then "macos" else platform.parsed.kernel.name; - # Target triple. Rust has slightly different naming conventions than we use. + # Returns the name of the rust target, even if it is custom. Adjustments are + # because rust has slightly different naming conventions than we do. toRustTarget = platform: with platform.parsed; let cpu_ = platform.rustc.arch or { "armv7a" = "armv7"; @@ -34,6 +35,13 @@ in platform.rustc.config or "${cpu_}-${vendor.name}-${kernel.name}${lib.optionalString (abi.name != "unknown") "-${abi.name}"}"; + # Returns the name of the rust target if it is standard, or the json file + # containing the custom target spec. + toRustTargetSpec = platform: + if (platform.rustc.arch or {}) ? custom + then builtins.toFile (platform.rustc.config + ".json") (builtins.toJSON platform.rustc.arch.custom) + else toRustTarget platform; + # This just contains tools for now. But it would conceivably contain # libraries too, say if we picked some default/recommended versions from # `cratesIO` to build by Hydra and/or try to prefer/bias in Cargo.lock for diff --git a/pkgs/development/compilers/rust/rustc.nix b/pkgs/development/compilers/rust/rustc.nix index 65d8920c4a4..a5a49f8c3c0 100644 --- a/pkgs/development/compilers/rust/rustc.nix +++ b/pkgs/development/compilers/rust/rustc.nix @@ -70,9 +70,9 @@ in stdenv.mkDerivation rec { "--set=build.cargo=${rustPlatform.rust.cargo}/bin/cargo" "--enable-rpath" "--enable-vendor" - "--build=${rust.toRustTarget stdenv.buildPlatform}" - "--host=${rust.toRustTarget stdenv.hostPlatform}" - "--target=${rust.toRustTarget stdenv.targetPlatform}" + "--build=${rust.toRustTargetSpec stdenv.buildPlatform}" + "--host=${rust.toRustTargetSpec stdenv.hostPlatform}" + "--target=${rust.toRustTargetSpec stdenv.targetPlatform}" "${setBuild}.cc=${ccForBuild}" "${setHost}.cc=${ccForHost}" diff --git a/pkgs/development/libraries/relibc/default.nix b/pkgs/development/libraries/relibc/default.nix index 43e02fc8758..24d434bf715 100644 --- a/pkgs/development/libraries/relibc/default.nix +++ b/pkgs/development/libraries/relibc/default.nix @@ -63,7 +63,8 @@ redoxRustPlatform.buildRustPackage rec { DESTDIR=$out make install ''; - TARGET = buildPackages.rust.toRustTarget stdenvNoCC.targetPlatform; + # TODO: should be hostPlatform + TARGET = buildPackages.rust.toRustTargetSpec stdenvNoCC.targetPlatform; cargoSha256 = "1fzz7ba3ga57x1cbdrcfrdwwjr70nh4skrpxp4j2gak2c3scj6rz"; From 015d4e2e98368b44cdf3a6d424ef35f0fed5072e Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Wed, 14 Oct 2020 14:23:37 -0700 Subject: [PATCH 05/19] fix whitespace --- pkgs/development/libraries/relibc/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/libraries/relibc/default.nix b/pkgs/development/libraries/relibc/default.nix index 24d434bf715..808d9154711 100644 --- a/pkgs/development/libraries/relibc/default.nix +++ b/pkgs/development/libraries/relibc/default.nix @@ -7,7 +7,7 @@ let ]; bootstrapCrossRust = stdenvNoCC.mkDerivation { name = "binary-redox-rust"; - + src = fetchTarball { name = "redox-rust-toolchain-bin.tar.gz"; url = "https://www.dropbox.com/s/33r92en0t47l1ei/redox-rust-toolchain-bin.tar.gz?dl=1"; From a153be896f275e5f394c55bdbbd267356d49f7b2 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Wed, 14 Oct 2020 22:54:04 -0700 Subject: [PATCH 06/19] use rustcSrc --- pkgs/build-support/rust/sysroot/default.nix | 28 ++++++++------------ pkgs/development/compilers/rust/rust-src.nix | 2 +- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/pkgs/build-support/rust/sysroot/default.nix b/pkgs/build-support/rust/sysroot/default.nix index 2625306b246..de82f2bf30a 100644 --- a/pkgs/build-support/rust/sysroot/default.nix +++ b/pkgs/build-support/rust/sysroot/default.nix @@ -2,24 +2,18 @@ { shortTarget, originalCargoToml, target, RUSTFLAGS }: -let rustSrc = stdenv.mkDerivation { - name = "rust-src"; - src = rustPlatform.rust.rustc.src; - preferLocalBuild = true; - phases = [ "unpackPhase" "installPhase" ]; - installPhase = "cp -r src $out"; - }; +let cargoSrc = stdenv.mkDerivation { - name = "cargo-src"; - preferLocalBuild = true; - phases = [ "installPhase" ]; - installPhase = '' - RUSTC_SRC=${rustSrc} ORIG_CARGO=${originalCargoToml} \ - ${buildPackages.python3.withPackages (ps: with ps; [ toml ])}/bin/python3 ${./cargo.py} - mkdir -p $out - cp Cargo.toml $out/Cargo.toml - cp ${./Cargo.lock} $out/Cargo.lock - ''; + name = "cargo-src"; + preferLocalBuild = true; + phases = [ "installPhase" ]; + installPhase = '' + RUSTC_SRC=${rustPlatform.rustcSrc} ORIG_CARGO=${originalCargoToml} \ + ${buildPackages.python3.withPackages (ps: with ps; [ toml ])}/bin/python3 ${./cargo.py} + mkdir -p $out + cp Cargo.toml $out/Cargo.toml + cp ${./Cargo.lock} $out/Cargo.lock + ''; }; in rustPlatform.buildRustPackage { inherit target RUSTFLAGS; diff --git a/pkgs/development/compilers/rust/rust-src.nix b/pkgs/development/compilers/rust/rust-src.nix index 8977fb84caf..db48d9a95df 100644 --- a/pkgs/development/compilers/rust/rust-src.nix +++ b/pkgs/development/compilers/rust/rust-src.nix @@ -6,6 +6,6 @@ stdenv.mkDerivation { phases = [ "unpackPhase" "installPhase" ]; installPhase = '' mv src $out - rm -rf $out/{ci,doc,etc,grammar,llvm-project,llvm-emscripten,rtstartup,rustllvm,test,tools,vendor,stdarch} + rm -rf $out/{ci,doc,etc,grammar,llvm-project,llvm-emscripten,rtstartup,rustllvm,test,vendor} ''; } From d906fda8d2b467e16d1b41842bf3b63aee3da449 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Thu, 15 Oct 2020 17:27:51 -0700 Subject: [PATCH 07/19] parameterize rustcSrc --- pkgs/build-support/rust/sysroot/default.nix | 2 +- pkgs/development/compilers/rust/rust-src.nix | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pkgs/build-support/rust/sysroot/default.nix b/pkgs/build-support/rust/sysroot/default.nix index de82f2bf30a..c32b6577e35 100644 --- a/pkgs/build-support/rust/sysroot/default.nix +++ b/pkgs/build-support/rust/sysroot/default.nix @@ -8,7 +8,7 @@ let preferLocalBuild = true; phases = [ "installPhase" ]; installPhase = '' - RUSTC_SRC=${rustPlatform.rustcSrc} ORIG_CARGO=${originalCargoToml} \ + RUSTC_SRC=${rustPlatform.rustcSrc.override { minimalContent = false; }} ORIG_CARGO=${originalCargoToml} \ ${buildPackages.python3.withPackages (ps: with ps; [ toml ])}/bin/python3 ${./cargo.py} mkdir -p $out cp Cargo.toml $out/Cargo.toml diff --git a/pkgs/development/compilers/rust/rust-src.nix b/pkgs/development/compilers/rust/rust-src.nix index db48d9a95df..54691f5fdf0 100644 --- a/pkgs/development/compilers/rust/rust-src.nix +++ b/pkgs/development/compilers/rust/rust-src.nix @@ -1,4 +1,4 @@ -{ stdenv, rustc }: +{ lib, stdenv, rustc, minimalContent ? true }: stdenv.mkDerivation { name = "rust-src"; @@ -6,6 +6,9 @@ stdenv.mkDerivation { phases = [ "unpackPhase" "installPhase" ]; installPhase = '' mv src $out - rm -rf $out/{ci,doc,etc,grammar,llvm-project,llvm-emscripten,rtstartup,rustllvm,test,vendor} + rm -rf $out/{${if minimalContent + then "ci,doc,etc,grammar,llvm-project,llvm-emscripten,rtstartup,rustllvm,test,tools,vendor,stdarch" + else "ci,doc,etc,grammar,llvm-project,llvm-emscripten,rtstartup,rustllvm,test,vendor" + }} ''; } From ccbc9988ce41334495f643fc65596a2ee4c09ecd Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Thu, 15 Oct 2020 17:31:32 -0700 Subject: [PATCH 08/19] remove unused import --- pkgs/development/compilers/rust/rust-src.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/compilers/rust/rust-src.nix b/pkgs/development/compilers/rust/rust-src.nix index 54691f5fdf0..489795ecec4 100644 --- a/pkgs/development/compilers/rust/rust-src.nix +++ b/pkgs/development/compilers/rust/rust-src.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, rustc, minimalContent ? true }: +{ stdenv, rustc, minimalContent ? true }: stdenv.mkDerivation { name = "rust-src"; From e745f9333e8ccd63db4dcb7701ea362b57e410aa Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Thu, 15 Oct 2020 19:03:10 -0700 Subject: [PATCH 09/19] fix whitespace --- pkgs/build-support/rust/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index 3f6a84b8aed..2575c7f3107 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -202,7 +202,7 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { "CXX_${rust.toRustTarget stdenv.buildPlatform}"="${cxxForBuild}" \ "CC_${rust.toRustTarget stdenv.hostPlatform}"="${ccForHost}" \ "CXX_${rust.toRustTarget stdenv.hostPlatform}"="${cxxForHost}" \ - ${stdenv.lib.optionalString + ${stdenv.lib.optionalString (targetIsJSON && !__internal_dontAddSysroot) "RUSTFLAGS=\"--sysroot ${sysroot} $RUSTFLAGS\" " }cargo build -j $NIX_BUILD_CORES \ ${stdenv.lib.optionalString (buildType == "release") "--release"} \ From 116ac11652659c0f896fda4a2477152b92e5326a Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 00:43:33 -0700 Subject: [PATCH 10/19] add test --- pkgs/test/default.nix | 2 ++ pkgs/test/rust-sysroot/default.nix | 41 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 pkgs/test/rust-sysroot/default.nix diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix index 85142090dd4..c0a810fa01a 100644 --- a/pkgs/test/default.nix +++ b/pkgs/test/default.nix @@ -35,6 +35,8 @@ with pkgs; cross = callPackage ./cross {}; + rustCustomSysroot = callPackage ./rust-sysroot {}; + nixos-functions = callPackage ./nixos-functions {}; patch-shebangs = callPackage ./patch-shebangs {}; diff --git a/pkgs/test/rust-sysroot/default.nix b/pkgs/test/rust-sysroot/default.nix new file mode 100644 index 00000000000..c6e9ecb89d9 --- /dev/null +++ b/pkgs/test/rust-sysroot/default.nix @@ -0,0 +1,41 @@ +{ rustPlatform, fetchFromGitHub, writeText }: + +rustPlatform.buildRustPackage rec { + name = "blog_os-sysroot-test"; + + src = fetchFromGitHub { + owner = "phil-opp"; + repo = "blog_os"; + rev = "4e38e7ddf8dd021c3cd7e4609dfa01afb827797b"; + sha256 = "0k9ipm9ddm1bad7bs7368wzzp6xwrhyfzfpckdax54l4ffqwljcg"; + }; + + cargoSha256 = "1cbcplgz28yxshyrp2krp1jphbrcqdw6wxx3rry91p7hiqyibd30"; + + # 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 + target = writeText "x86_64-blog_os.json" '' + { + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "gcc", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" + } + ''; + + RUSTFLAGS = "-C link-arg=-nostartfiles"; + + # Tests don't work for `no_std`. See https://os.phil-opp.com/testing/ + doCheck = false; +} From dec97eb3e99be60cbf865d079e1d3215578bbf73 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 00:45:27 -0700 Subject: [PATCH 11/19] minor clean up --- pkgs/build-support/rust/default.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index 2575c7f3107..e027853255c 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -77,6 +77,7 @@ let ''; targetIsJSON = stdenv.lib.hasSuffix ".json" target; + useSysroot = targetIsJSON && !__internal_dontAddSysroot; # see https://github.com/rust-lang/cargo/blob/964a16a28e234a3d397b2a7031d4ab4a428b1391/src/cargo/core/compiler/compile_kind.rs#L151-L168 # the "${}" is needed to transform the path into a /nix/store path before baseNameOf @@ -202,8 +203,8 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { "CXX_${rust.toRustTarget stdenv.buildPlatform}"="${cxxForBuild}" \ "CC_${rust.toRustTarget stdenv.hostPlatform}"="${ccForHost}" \ "CXX_${rust.toRustTarget stdenv.hostPlatform}"="${cxxForHost}" \ - ${stdenv.lib.optionalString - (targetIsJSON && !__internal_dontAddSysroot) "RUSTFLAGS=\"--sysroot ${sysroot} $RUSTFLAGS\" " + ${stdenv.lib.optionalString useSysroot + "RUSTFLAGS=\"--sysroot ${sysroot} $RUSTFLAGS\" " }cargo build -j $NIX_BUILD_CORES \ ${stdenv.lib.optionalString (buildType == "release") "--release"} \ --target ${target} \ From 7c92361028555ea0fcb0da0a8ce059e52ee4d1a8 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 00:47:14 -0700 Subject: [PATCH 12/19] enforce noCheck when useSysroot --- pkgs/build-support/rust/default.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index e027853255c..ae390816d0a 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -105,6 +105,10 @@ let in +# Tests don't currently work for `no_std`, and all custom sysroots are currently built without `std`. +# See https://os.phil-opp.com/testing/ for more information. +assert useSysroot -> !(args.doCheck or true); + stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { inherit cargoDeps; From 2bccf2e554d8fdb630f44181cf1ef787df6fb6b6 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 00:48:07 -0700 Subject: [PATCH 13/19] add documentation --- doc/languages-frameworks/rust.section.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/languages-frameworks/rust.section.md b/doc/languages-frameworks/rust.section.md index 0f3cc5d8efb..784a4603098 100644 --- a/doc/languages-frameworks/rust.section.md +++ b/doc/languages-frameworks/rust.section.md @@ -123,6 +123,9 @@ build the Rust tools and standard library crates separately so there is no reason not to take the `stdenv.hostPlatform.rustc`-modifying approach, and the ad-hoc escape hatch to `buildRustPackage` can be removed. +Note that currently custom targets aren't compiled with `std`, so `cargo test` +will fail. This can be ignored by adding `doCheck = false;` to your derivation. + ### Running package tests When using `buildRustPackage`, the `checkPhase` is enabled by default and runs From d884b2d877cfda8247a6ee49f5c26ba3133c3889 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 00:48:38 -0700 Subject: [PATCH 14/19] NEEDS REVIEW: enable sysroot differently --- pkgs/build-support/rust/default.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index ae390816d0a..8e47a2b0bf2 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -109,7 +109,9 @@ in # See https://os.phil-opp.com/testing/ for more information. assert useSysroot -> !(args.doCheck or true); -stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { +stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // stdenv.lib.optionalAttrs useSysroot { + RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or ""); +} // { inherit cargoDeps; patchRegistryDeps = ./patch-registry-deps; @@ -207,9 +209,7 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { "CXX_${rust.toRustTarget stdenv.buildPlatform}"="${cxxForBuild}" \ "CC_${rust.toRustTarget stdenv.hostPlatform}"="${ccForHost}" \ "CXX_${rust.toRustTarget stdenv.hostPlatform}"="${cxxForHost}" \ - ${stdenv.lib.optionalString useSysroot - "RUSTFLAGS=\"--sysroot ${sysroot} $RUSTFLAGS\" " - }cargo build -j $NIX_BUILD_CORES \ + cargo build -j $NIX_BUILD_CORES \ ${stdenv.lib.optionalString (buildType == "release") "--release"} \ --target ${target} \ --frozen ${concatStringsSep " " cargoBuildFlags} From 0ac33bf3f89c843803bce45ebe5b5a8865b67948 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 00:58:09 -0700 Subject: [PATCH 15/19] add `meta` to rust-sysroot test --- pkgs/test/rust-sysroot/default.nix | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkgs/test/rust-sysroot/default.nix b/pkgs/test/rust-sysroot/default.nix index c6e9ecb89d9..10b37278af9 100644 --- a/pkgs/test/rust-sysroot/default.nix +++ b/pkgs/test/rust-sysroot/default.nix @@ -1,4 +1,4 @@ -{ rustPlatform, fetchFromGitHub, writeText }: +{ lib, rustPlatform, fetchFromGitHub, writeText }: rustPlatform.buildRustPackage rec { name = "blog_os-sysroot-test"; @@ -38,4 +38,9 @@ rustPlatform.buildRustPackage rec { # Tests don't work for `no_std`. See https://os.phil-opp.com/testing/ doCheck = false; + + meta = with lib; { + description = "Test for using custom sysroots with buildRustPackage."; + maintainers = with maintainers; [ aaronjanse ]; + }; } From 7ebcb6ee483cea2152622b980a0b20fe7a4568cb Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 00:58:27 -0700 Subject: [PATCH 16/19] remove trailing period --- pkgs/test/rust-sysroot/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/test/rust-sysroot/default.nix b/pkgs/test/rust-sysroot/default.nix index 10b37278af9..dd10807e3aa 100644 --- a/pkgs/test/rust-sysroot/default.nix +++ b/pkgs/test/rust-sysroot/default.nix @@ -40,7 +40,7 @@ rustPlatform.buildRustPackage rec { doCheck = false; meta = with lib; { - description = "Test for using custom sysroots with buildRustPackage."; + description = "Test for using custom sysroots with buildRustPackage"; maintainers = with maintainers; [ aaronjanse ]; }; } From 512458c68a18f3910fffb3578dbdf987d0740b64 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 01:34:51 -0700 Subject: [PATCH 17/19] add sysroot lockfile update script then run it --- pkgs/build-support/rust/sysroot/Cargo.lock | 19 ++++++++++++----- pkgs/build-support/rust/sysroot/cargo.py | 11 +++++----- pkgs/build-support/rust/sysroot/default.nix | 2 +- .../rust/sysroot/update-lockfile.sh | 21 +++++++++++++++++++ 4 files changed, 42 insertions(+), 11 deletions(-) create mode 100755 pkgs/build-support/rust/sysroot/update-lockfile.sh diff --git a/pkgs/build-support/rust/sysroot/Cargo.lock b/pkgs/build-support/rust/sysroot/Cargo.lock index 3b576f6657f..61fcef61744 100644 --- a/pkgs/build-support/rust/sysroot/Cargo.lock +++ b/pkgs/build-support/rust/sysroot/Cargo.lock @@ -1,14 +1,21 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "alloc" version = "0.0.0" -dependencies = ["compiler_builtins", "core"] +dependencies = [ + "compiler_builtins", + "core", +] [[package]] name = "compiler_builtins" -version = "0.1.32" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc4ac2c824d2bfc612cba57708198547e9a26943af0632aff033e0693074d5c" -dependencies = ["rustc-std-workspace-core"] +checksum = "7cd0782e0a7da7598164153173e5a5d4d9b1da094473c98dce0ff91406112369" +dependencies = [ + "rustc-std-workspace-core", +] [[package]] name = "core" @@ -17,4 +24,6 @@ version = "0.0.0" [[package]] name = "rustc-std-workspace-core" version = "1.99.0" -dependencies = ["core"] +dependencies = [ + "core", +] diff --git a/pkgs/build-support/rust/sysroot/cargo.py b/pkgs/build-support/rust/sysroot/cargo.py index 10ad94e4c54..09f6fba6d1c 100644 --- a/pkgs/build-support/rust/sysroot/cargo.py +++ b/pkgs/build-support/rust/sysroot/cargo.py @@ -2,7 +2,7 @@ import os import toml rust_src = os.environ['RUSTC_SRC'] -orig_cargo = os.environ['ORIG_CARGO'] +orig_cargo = os.environ['ORIG_CARGO'] if 'ORIG_CARGO' in os.environ else None base = { 'package': { @@ -33,10 +33,11 @@ base = { }, } -with open(orig_cargo, 'r') as f: - src = toml.loads(f.read()) - if 'profile' in src: - base['profile'] = src['profile'] +if orig_cargo is not None: + with open(orig_cargo, 'r') as f: + src = toml.loads(f.read()) + if 'profile' in src: + base['profile'] = src['profile'] out = toml.dumps(base) diff --git a/pkgs/build-support/rust/sysroot/default.nix b/pkgs/build-support/rust/sysroot/default.nix index c32b6577e35..4db7cf0dc39 100644 --- a/pkgs/build-support/rust/sysroot/default.nix +++ b/pkgs/build-support/rust/sysroot/default.nix @@ -23,7 +23,7 @@ in rustPlatform.buildRustPackage { RUSTC_BOOTSTRAP = 1; __internal_dontAddSysroot = true; - cargoSha256 = "1l5z44dw5h7lbwmpjqax2g40cf4h27yai3wlj0p5di5v1xf25rng"; + cargoSha256 = "0y6dqfhsgk00y3fv5bnjzk0s7i30nwqc1rp0xlrk83hkh80x81mw"; doCheck = false; diff --git a/pkgs/build-support/rust/sysroot/update-lockfile.sh b/pkgs/build-support/rust/sysroot/update-lockfile.sh new file mode 100755 index 00000000000..83d29832384 --- /dev/null +++ b/pkgs/build-support/rust/sysroot/update-lockfile.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p python3 python3.pkgs.toml cargo + +set -e + +HERE=$(dirname "${BASH_SOURCE[0]}") +NIXPKGS_ROOT="$HERE/../../../.." + +# https://unix.stackexchange.com/a/84980/390173 +tempdir=$(mktemp -d 2>/dev/null || mktemp -d -t 'update-lockfile') + +cd "$tempdir" +nix-build -E "with import (/. + \"${NIXPKGS_ROOT}\") {}; pkgs.rustPlatform.rustcSrc.override { minimalContent = false; }" +RUSTC_SRC="$(pwd)/result" python3 "$HERE/cargo.py" +RUSTC_BOOTSTRAP=1 cargo build || echo "Build failure is expected. All that's needed is the lockfile." + +cp Cargo.lock "$HERE" + +rm -rf "$tempdir" + + From 29cdd8ae609d107889469610176aa53676382eb1 Mon Sep 17 00:00:00 2001 From: Aaron Janse Date: Sat, 17 Oct 2020 14:38:36 -0700 Subject: [PATCH 18/19] fix whitespace --- pkgs/test/rust-sysroot/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/test/rust-sysroot/default.nix b/pkgs/test/rust-sysroot/default.nix index dd10807e3aa..cd07ef53c32 100644 --- a/pkgs/test/rust-sysroot/default.nix +++ b/pkgs/test/rust-sysroot/default.nix @@ -37,7 +37,7 @@ rustPlatform.buildRustPackage rec { RUSTFLAGS = "-C link-arg=-nostartfiles"; # Tests don't work for `no_std`. See https://os.phil-opp.com/testing/ - doCheck = false; + doCheck = false; meta = with lib; { description = "Test for using custom sysroots with buildRustPackage"; From b7650aaa77634e42d62ed6fc1a9081b10139618b Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 28 Nov 2020 19:32:43 +0000 Subject: [PATCH 19/19] rust: Clean up target configs and test some more See the new docs for details. The difference is vis-a-vis older versions of this PR, not master. --- doc/languages-frameworks/rust.section.md | 14 ++--- pkgs/development/compilers/rust/default.nix | 6 +-- pkgs/test/rust-sysroot/default.nix | 60 +++++++++++++-------- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/doc/languages-frameworks/rust.section.md b/doc/languages-frameworks/rust.section.md index 28e488fe8a6..0230993d3f0 100644 --- a/doc/languages-frameworks/rust.section.md +++ b/doc/languages-frameworks/rust.section.md @@ -71,14 +71,14 @@ By default, it takes the `stdenv.hostPlatform.config` and replaces components where they are known to differ. But there are ways to customize the argument: - To choose a different target by name, define - `stdenv.hostPlatform.rustc.arch.config` as that name (a string), and that + `stdenv.hostPlatform.rustc.config` as that name (a string), and that name will be used instead. For example: ```nix import { crossSystem = (import ).systems.examples.armhf-embedded // { - rustc.arch.config = "thumbv7em-none-eabi"; + rustc.config = "thumbv7em-none-eabi"; }; } ``` @@ -88,18 +88,18 @@ where they are known to differ. But there are ways to customize the argument: ``` - To pass a completely custom target, define - `stdenv.hostPlatform.rustc.arch.config` with its name, and - `stdenv.hostPlatform.rustc.arch.custom` with the value. The value will be + `stdenv.hostPlatform.rustc.config` with its name, and + `stdenv.hostPlatform.rustc.platform` with the value. The value will be serialized to JSON in a file called - `${stdenv.hostPlatform.rustc.arch.config}.json`, and the path of that file + `${stdenv.hostPlatform.rustc.config}.json`, and the path of that file will be used instead. For example: ```nix import { crossSystem = (import ).systems.examples.armhf-embedded // { - rustc.arch.config = "thumb-crazy"; - rustc.arch.custom = { foo = ""; bar = ""; }; + rustc.config = "thumb-crazy"; + rustc.platform = { foo = ""; bar = ""; }; }; } will result in: diff --git a/pkgs/development/compilers/rust/default.nix b/pkgs/development/compilers/rust/default.nix index 95febd8945d..25876cc6380 100644 --- a/pkgs/development/compilers/rust/default.nix +++ b/pkgs/development/compilers/rust/default.nix @@ -27,7 +27,7 @@ # Returns the name of the rust target, even if it is custom. Adjustments are # because rust has slightly different naming conventions than we do. toRustTarget = platform: with platform.parsed; let - cpu_ = platform.rustc.arch or { + cpu_ = platform.rustc.platform.arch or { "armv7a" = "armv7"; "armv7l" = "armv7"; "armv6l" = "arm"; @@ -38,8 +38,8 @@ # Returns the name of the rust target if it is standard, or the json file # containing the custom target spec. toRustTargetSpec = platform: - if (platform.rustc.arch or {}) ? custom - then builtins.toFile (platform.rustc.config + ".json") (builtins.toJSON platform.rustc.arch.custom) + if (platform.rustc or {}) ? platform + then builtins.toFile (toRustTarget platform + ".json") (builtins.toJSON platform.rustc.platform) else toRustTarget platform; # This just contains tools for now. But it would conceivably contain diff --git a/pkgs/test/rust-sysroot/default.nix b/pkgs/test/rust-sysroot/default.nix index cd07ef53c32..3a786ad6f00 100644 --- a/pkgs/test/rust-sysroot/default.nix +++ b/pkgs/test/rust-sysroot/default.nix @@ -1,6 +1,7 @@ -{ lib, rustPlatform, fetchFromGitHub, writeText }: +{ lib, rust, rustPlatform, fetchFromGitHub }: -rustPlatform.buildRustPackage rec { +let + mkBlogOsTest = target: rustPlatform.buildRustPackage rec { name = "blog_os-sysroot-test"; src = fetchFromGitHub { @@ -12,27 +13,7 @@ rustPlatform.buildRustPackage rec { cargoSha256 = "1cbcplgz28yxshyrp2krp1jphbrcqdw6wxx3rry91p7hiqyibd30"; - # 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 - target = writeText "x86_64-blog_os.json" '' - { - "llvm-target": "x86_64-unknown-none", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "arch": "x86_64", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "none", - "executables": true, - "linker-flavor": "gcc", - "panic-strategy": "abort", - "disable-redzone": true, - "features": "-mmx,-sse,+soft-float" - } - ''; + inherit target; RUSTFLAGS = "-C link-arg=-nostartfiles"; @@ -42,5 +23,38 @@ rustPlatform.buildRustPackage rec { meta = with lib; { description = "Test for using custom sysroots with buildRustPackage"; maintainers = with maintainers; [ aaronjanse ]; + platforms = lib.platforms.x86_64; }; + }; + + # 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 + targetContents = { + "llvm-target" = "x86_64-unknown-none"; + "data-layout" = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"; + "arch" = "x86_64"; + "target-endian" = "little"; + "target-pointer-width" = "64"; + "target-c-int-width" = "32"; + "os" = "none"; + "executables" = true; + "linker-flavor" = "gcc"; + "panic-strategy" = "abort"; + "disable-redzone" = true; + "features" = "-mmx,-sse,+soft-float"; + }; + +in { + blogOS-targetByFile = mkBlogOsTest (builtins.toFile "x86_64-blog_os.json" (builtins.toJSON targetContents)); + blogOS-targetByNix = let + plat = lib.systems.elaborate { config = "x86_64-none"; } // { + rustc = { + config = "x86_64-blog_os"; + platform = targetContents; + }; + }; + in mkBlogOsTest (rust.toRustTargetSpec plat); }