From ede2cf70ac2e294c9f655b04f5e4ed18d43ac34c Mon Sep 17 00:00:00 2001 From: Nick Spinale Date: Wed, 18 Sep 2024 00:53:44 -0700 Subject: [PATCH] nix: Introduce Ferrocene Signed-off-by: Nick Spinale --- hacking/nix/scope/default.nix | 9 +- hacking/nix/scope/ferrocene/.gitignore | 7 + hacking/nix/scope/ferrocene/default.nix | 225 ++++++++++++++++++++++++ 3 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 hacking/nix/scope/ferrocene/.gitignore create mode 100644 hacking/nix/scope/ferrocene/default.nix diff --git a/hacking/nix/scope/default.nix b/hacking/nix/scope/default.nix index 545cb9615..1f79afae0 100644 --- a/hacking/nix/scope/default.nix +++ b/hacking/nix/scope/default.nix @@ -62,7 +62,7 @@ superCallPackage ../rust-utils {} self // sha256 = "sha256-GJR7CjFPMh450uP/EUzXeng15vusV3ktq7Cioop945U="; }; - defaultRustEnvironment = elaborateRustEnvironment (mkDefaultElaborateRustEnvironmentArgs { + upstreamDefaultRustEnvironment = elaborateRustEnvironment (mkDefaultElaborateRustEnvironmentArgs { rustToolchain = defaultRustToolchain; } // { channel = (builtins.fromTOML (builtins.readFile topLevelRustToolchainFile)).toolchain.channel; @@ -79,6 +79,11 @@ superCallPackage ../rust-utils {} self // ]; }); + ferroceneDefaultRustEnvironment = ferrocene.rustEnvironment; + + defaultRustEnvironment = upstreamDefaultRustEnvironment; + # defaultRustEnvironment = ferroceneDefaultRustEnvironment; + mkDefaultElaborateRustEnvironmentArgs = { rustToolchain }: rec { inherit rustToolchain; @@ -192,6 +197,8 @@ superCallPackage ../rust-utils {} self // dafny = callBuildBuildPackage ./dafny {}; + ferrocene = callBuildBuildPackage ./ferrocene {}; + ### local tools mkTool = rootCrate: buildCratesInLayers { diff --git a/hacking/nix/scope/ferrocene/.gitignore b/hacking/nix/scope/ferrocene/.gitignore new file mode 100644 index 000000000..eab687475 --- /dev/null +++ b/hacking/nix/scope/ferrocene/.gitignore @@ -0,0 +1,7 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +/SHA256SUMS diff --git a/hacking/nix/scope/ferrocene/default.nix b/hacking/nix/scope/ferrocene/default.nix new file mode 100644 index 000000000..338086bd4 --- /dev/null +++ b/hacking/nix/scope/ferrocene/default.nix @@ -0,0 +1,225 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ lib +, hostPlatform +, stdenv +, requireFile +, fetchFromGitHub +, zlib + +, fenix +, crateUtils +, elaborateRustEnvironment +, mkDefaultElaborateRustEnvironmentArgs +, mkMkCustomTargetPathForEnvironment +}: + +let + parseHashesFile = fileContents: + let + rawLines = lib.splitString "\n" fileContents; + lines = assert lib.last rawLines == ""; lib.init rawLines; + parseLine = line: + let + parts = builtins.match ''([0-9a-f]{64}) (.*)'' line; + hash = lib.elemAt parts 0; + fname = lib.elemAt parts 1; + in + lib.nameValuePair fname hash; + in + lib.listToAttrs (map parseLine lines); + + mkFiles = versionName: lib.mapAttrs (fname: sha256: requireFile { + name = fname; + url = "https://releases.ferrocene.dev/ferrocene/files/${versionName}/index.html"; + inherit sha256; + }); + + rpath = "${zlib}/lib:$out/lib"; + + mkComponent = { componentName, nameSuffix, src, rustc, libcManifestDir }: stdenv.mkDerivation { + name = "${componentName}${nameSuffix}"; + inherit src; + sourceRoot = "."; + installPhase = '' + cp -r . $out + + rm $out/lib/rustlib/{components,install.log,manifest-*,rust-installer-version,uninstall.sh} || true + + ${lib.optionalString stdenv.isLinux '' + if [ -d $out/bin ]; then + for file in $(find $out/bin -type f); do + if isELF "$file"; then + patchelf \ + --set-interpreter ${stdenv.cc.bintools.dynamicLinker} \ + --set-rpath ${rpath} \ + "$file" || true + fi + done + fi + + if [ -d $out/lib ]; then + for file in $(find $out/lib -type f); do + if isELF "$file"; then + patchelf --set-rpath ${rpath} "$file" || true + fi + done + fi + + if [ -d $out/libexec ]; then + for file in $(find $out/libexec -type f); do + if isELF "$file"; then + patchelf \ + --set-interpreter ${stdenv.cc.bintools.dynamicLinker} \ + --set-rpath ${rpath} \ + "$file" || true + fi + done + fi + + ${lib.optionalString (componentName == "rustc") '' + for file in $(find $out/lib/rustlib/*/bin -type f); do + if isELF "$file"; then + patchelf \ + --set-interpreter ${stdenv.cc.bintools.dynamicLinker} \ + --set-rpath ${stdenv.cc.cc.lib}/lib:${rpath} \ + "$file" || true + fi + done + ''} + + ${lib.optionalString (componentName == "llvm-tools") '' + for file in $out/lib/rustlib/*/bin/*; do + patchelf \ + --set-interpreter ${stdenv.cc.bintools.dynamicLinker} \ + --set-rpath $out/lib/rustlib/*/lib \ + "$file" || true + done + ''} + ''} + + ${lib.optionalString (componentName == "rustfmt") '' + ${lib.optionalString stdenv.isLinux '' + patchelf \ + --set-rpath ${rustc}/lib $out/bin/rustfmt || true + ''} + ${lib.optionalString stdenv.isDarwin '' + install_name_tool \ + -add_rpath ${rustc}/lib $out/bin/rustfmt || true + ''} + ''} + + ${lib.optionalString (componentName == "rust-analyzer") '' + ${lib.optionalString stdenv.isLinux '' + patchelf \ + --set-rpath ${rustc}/lib $out/bin/rust-analyzer || true + ''} + ${lib.optionalString stdenv.isDarwin '' + install_name_tool \ + -add_rpath ${rustc}/lib $out/bin/rust-analyzer || true + ''} + ''} + + ${lib.optionalString (componentName == "rust-src") '' + substituteInPlace $out/lib/rustlib/src/rust/library/Cargo.toml \ + --replace ../ferrocene/library/libc ${libcManifestDir} + ''} + ''; + dontStrip = true; + }; + + defaultComponentNames = [ + "rustc" + "rust-src" + "rust-std" + "cargo" + "clippy" + "llvm-tools" + "rustfmt" + ]; + + mkToolchain = { hashesFilePath, arch, versionTag, versionName, libcManifestDir, componentNames ? defaultComponentNames }: + let + files = mkFiles versionName (parseHashesFile (builtins.readFile hashesFilePath)); + byName = lib.fix (self: lib.listToAttrs (lib.forEach componentNames (componentName: + let + nameSuffix = "${ + lib.optionalString (componentName != "rust-src") "-${arch}" + }-${versionTag}"; + fname = "${componentName}${nameSuffix}.tar.xz"; + component = mkComponent { + inherit componentName; + inherit nameSuffix; + src = files.${fname}; + inherit (self) rustc; + inherit libcManifestDir; + }; + in + lib.nameValuePair componentName component + ))); + in + fenix.combine (lib.attrValues byName); +in + +let + # upstreamChannel = "1.79.0"; + upstreamChannel = "beta"; + + # versionTag = "24.08.0"; + versionTag = "6ce9c7ddc"; + versionName = "pre-rolling-2024-09-11"; + + repo = fetchFromGitHub { + owner = "ferrocene"; + repo = "ferrocene"; + rev = "6ce9c7ddc767a9b4cddd4ef8a0d4a317bb63159a"; # branch release/1.82 + hash = "sha256-r1s3ifDA9QF9dCPieChFjJo9cwEY6vi5RMtXWyUiw0g="; + }; + + libcManifestDir = "${repo}/ferrocene/library/libc"; + + # DO NOT CHECK IN THIS FILE + hashesFilePath = ./SHA256SUMS; + + rustToolchain = mkToolchain { + inherit hashesFilePath; + arch = hostPlatform.config; + inherit versionTag versionName; + inherit libcManifestDir; + }; +in + +let + upstreamRustToolchain = fenix.fromToolchainFile { + file = crateUtils.toTOMLFile "rust-toolchain.toml" { + toolchain = { + channel = upstreamChannel; + components = [ "rustc-dev" ]; + }; + }; + sha256 = "sha256-4vvAuAhW4cBwR+g1IrI79X7gKL4VsEYKD05XZL0rLc4="; + }; + + upstreamRustEnvironment = lib.fix (self: elaborateRustEnvironment (mkDefaultElaborateRustEnvironmentArgs { + rustToolchain = upstreamRustToolchain; + } // { + channel = upstreamChannel; + })); + + rustEnvironment = lib.fix (self: elaborateRustEnvironment (mkDefaultElaborateRustEnvironmentArgs { + inherit rustToolchain; + } // { + channel = upstreamChannel; + mkCustomTargetPath = mkMkCustomTargetPathForEnvironment { + rustEnvironment = upstreamRustEnvironment; + }; + })); + +in { + inherit rustEnvironment; + inherit upstreamRustEnvironment; +}