From a3a26df65f3c050798be3e14d972dfe29ceb8bca Mon Sep 17 00:00:00 2001 From: Soispha Date: Mon, 24 Jul 2023 17:11:17 +0200 Subject: [PATCH] Build(flake): Add rustc cranelift codegen to development shell This is executed by running `cargo clif` instead of `cargo`. It _should_ result in decreased compile times (around 30%). --- flake.nix | 311 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 269 insertions(+), 42 deletions(-) diff --git a/flake.nix b/flake.nix index 4a0858f..d35a329 100644 --- a/flake.nix +++ b/flake.nix @@ -29,6 +29,29 @@ flake-utils.follows = "flake-utils"; }; }; + + # cranelift + rustc_cranelift_backend = { + url = "github:bjorn3/rustc_codegen_cranelift/dev"; + flake = false; + }; + rustc_cranelift_backend_src = { + url = "https://github.com/bjorn3/rustc_codegen_cranelift/releases/download/dev/cg_clif-x86_64-unknown-linux-gnu.tar.xz"; + flake = false; + }; + # # dependencies + # rust_regex ={ + # url = "git+https://github.com/rust-lang/regex.git"; + # flake = false; + # }; + # rust_portable_simd = { + # url = "git+https://github.com/rust-lang/portable-simd.git"; + # flake = false; + # }; + # rust_rand = { + # url = "git+https://github.com/rust-random/rand.git"; + # flake = false; + # }; }; outputs = { @@ -37,60 +60,264 @@ crane, flake-utils, rust-overlay, + rustc_cranelift_backend, + rustc_cranelift_backend_src, + # rust_regex, + # rust_portable_simd, + # rust_rand, ... }: flake-utils.lib.eachDefaultSystem (system: let - pkgs = import nixpkgs { - inherit system; - overlays = [(import rust-overlay)]; - }; + rcb_deps = let + c_rust = pkgs.rust-bin.fromRustupToolchainFile "${rustc_cranelift_backend}/rust-toolchain"; + in + pkgs.stdenv.mkDerivation { + pname = "rustc_cranelift_backend_dependencies"; + version = "1.0"; + nativeBuildInputs = with pkgs; [git curl cacert c_rust]; + src = "${rustc_cranelift_backend}"; + # old implementation {{{ + #"${rust_regex}" "${rust_portable_simd}" "${rust_rand}" + #]; + #sourceRoot = "source"; + # preUnpack = '' + # #set -x; + # unpackCmdHooks=(_defaultUnpack); + # checkForHashToName() { + # case "$1" in + # "regex") + # echo source/download/regex + # ;; + # "portable-simd") + # echo source/download/portable-simd + # ;; + # "rand") + # echo source/download/rand + # ;; + # "rustc_codegen_cranelift") + # echo source + # ;; + # *) + # echo "Warning: Unable to turn hash ($1) to name!" 1>&2 + # echo "Using another method" 1>&2 + # echo null; + # ;; + # esac + # } + # fail() { + # echo "$@"; + # exit 1; + # } + # _defaultUnpack(){ + # local fn="$1" + # local destination + # local finalDestination + # + # # extrem hacky solution to turn the nix hash path to useful names: + # destination="$(sed -n '2p' "$fn/Cargo.toml" | sed 's|name = "||' | sed 's|"||')" + # + # finalDestination="$(checkForHashToName "$destination")" + # if [ "$finalDestination" = "null" ]; then + # if grep "Portable SIMD" "$fn"/README.md > /dev/null 2>&1; then + # destination="portable-simd"; + # else + # echo "Can not grep readme directly" + # fi + # fi + # + # finalDestination="$(checkForHashToName "$destination")" + # if [ "$finalDestination" = "null" ]; then + # fail "No idea how to turn your hash to a name, sorry!"; + # fi + # + # echo "Final destination is '$finalDestination'" + # destination="$finalDestination" + # echo "Copying '$fn' to '$destination'" + # + # mkdir --parents "$destination"; + # # We can't preserve hardlinks because they may have been + # # introduced by store optimization, which might break things + # # in the build. + # cp -pr --reflink=auto -- "$fn"/. "$destination" + # chmod -R u+w "$destination" + # } + # ''; + # }}} + buildPhase = '' + bash ./y.sh prepare + ''; + installPhase = '' + install -d $out/ + cp -r ./. $out/ + ''; + fixupPhase = '' + set -x + ''; # skip it + CARGO = "${c_rust}/bin/cargo"; + RUSTC = "${c_rust}/bin/rustc"; + RUSTDOC = "${c_rust}/bin/rustdoc"; + CARGO_HOME = "/build/cargo"; - nightly = true; - rust = - if nightly - then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default) - else pkgs.rust-bin.stable.latest.default; + outputHashAlgo = "sha512"; + outputHashMode = "recursive"; + outputHash = "sha512-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="; + }; + rcb = let + c_rust = pkgs.rust-bin.fromRustupToolchainFile "${rustc_cranelift_backend}/rust-toolchain"; + in + pkgs.stdenv.mkDerivation { + pname = "rustc_cranelift_backend"; + version = "1.0"; + nativeBuildInputs = [c_rust]; + src = "${rcb_deps}"; + buildPhase = '' + bash ./y.sh build + ''; + installPhase = '' + install -d $out/ + cp -r ./dist/. $out/ + ''; + CARGO = "${c_rust}/bin/cargo"; + RUSTC = "${c_rust}/bin/rustc"; + RUSTDOC = "${c_rust}/bin/rustdoc"; + CARGO_HOME = "/build/cargo"; + }; + c_rust = pkgs.rust-bin.fromRustupToolchainFile "${rustc_cranelift_backend}/rust-toolchain"; + rcb_better = pkgs.stdenv.mkDerivation { + pname = "rustc_cranelift_backend"; + version = "1.0"; + buildInputs = [c_rust]; + nativeBuildInputs = with pkgs; [gawk fd]; + srcs = ["${rustc_cranelift_backend_src}" "${c_rust}"]; + sourceRoot = "."; + postUnpack = '' + rust_dir="$(fd . --max-depth 1 | awk '!/source/ && !/env-vars/')" - craneLib = (crane.mkLib pkgs).overrideToolchain rust; + # remove unneeded stuff + rm -r "$rust_dir"/{bin,nix-support,share}; + rm -r "$rust_dir"/lib/rustlib/{etc,src,rustc-src}; - nativeBuildInputs = with pkgs; [ - pkg-config - mold - ]; - buildInputs = with pkgs; [ - openssl - lua54Packages.stdlib - ]; + cp -r "$rust_dir"/. source/extra_dependencies + rm -r "$rust_dir" + cd source + ''; + postPatch = '' + # patch bins + for file in $(fd . --type file);do + file="$(file --mime "$file" | awk 'BEGIN{FS=":"}/application\/x-pie-executable/{print $1}')"; + if [ "$file" ]; then + echo "file: '$file' matches"; + correct_interpreter_path="$(ldd "$file" | tail -n1 | awk 'BEGIN{FS="=> "} {print $2}' | awk 'BEGIN{FS=" "}{print $1}')" + echo "correct interpreter path is: '$correct_interpreter_path'" + patchelf --set-interpreter "$correct_interpreter_path" "$file" - craneBuild = craneLib.buildPackage { - src = craneLib.cleanCargoSource ./.; + if [ "$(patchelf --print-interpreter "$file")" = "$correct_interpreter_path" ];then + echo "Set interpreter"; + else + echo "Failed to set interprter, the interpreter still is $(patchelf --print-interpreter )"; + exit 1 + fi + fi + done - doCheck = true; - inherit nativeBuildInputs buildInputs; - }; - in { - packages.default = craneBuild; + # patch libs + all_files=$(mktemp); + for file in $(fd .);do + canonical_path="$(readlink -f "$file")" + file="$(file --mime "$canonical_path" | awk 'BEGIN{FS=":"}/application\/x-sharedlib/{print $1}')"; + if [ "$file" ]; then + echo "$file" >> $all_files; + fi + done + while read -r file; do + echo "___________________"; + echo "Checking file: '$file'"; + is_missing="$(ldd "$file" | awk 'BEGIN{FS="=>"}{if (/not found/){print $1}}')" + if [ "$is_missing" ];then + echo "Warning: The following things are missing:"; + for line in $is_missing; do + echo " $line"; + done + echo + for line in $is_missing; do + echo "Searching for a substitute for '$line'" + substitute="$(grep "$line" "$all_files" | awk 'BEGIN{FS=" "}{print $1}' | tail -n1)"; + if [ "$substitute" ]; then + echo "Found '$substitute', which can substitute '$line'" + echo "Patching.." + patchelf --replace-needed "$line" "$(readlink -f "$substitute")" "$file"; + else + echo "Error: Failed to find a substitute" + fi + done + else + echo "This file is not missing anything" + fi + done < $all_files + rm $all_files + ''; + installPhase = '' + install -d $out/ + cp -r ./. $out/ + ''; + }; + pkgs = import nixpkgs { + inherit system; + overlays = [(import rust-overlay)]; + }; - app.default = { - type = "app"; - program = "${self.packages.${system}.default}/bin/trinitix"; - }; + nightly = true; + rust = + if nightly + then pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default) + else pkgs.rust-bin.stable.latest.default; - devShells.default = pkgs.mkShell { - packages = with pkgs; [ - nil - alejandra - statix - ltex-ls + craneLib = (crane.mkLib pkgs).overrideToolchain rust; - rust - rust-analyzer - cargo-edit - cargo-expand + nativeBuildInputs = with pkgs; [ + pkg-config + mold + rcb_better + #self.packages."${system}".cranelift-deps ]; - inherit nativeBuildInputs buildInputs; - }; - }); + buildInputs = with pkgs; [ + openssl + ]; + + craneBuild = craneLib.buildPackage { + src = craneLib.cleanCargoSource ./.; + + doCheck = true; + inherit nativeBuildInputs buildInputs; + }; + in { + packages = { + default = craneBuild; + cranelift = rcb_better; + cranelift-deps = c_rust; + }; + + app.default = { + type = "app"; + program = "${self.packages.${system}.default}/bin/trinitix"; + }; + + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + nil + alejandra + statix + ltex-ls + + rust + rust-analyzer + cargo-edit + cargo-expand + ]; + inherit nativeBuildInputs buildInputs; + }; + }); } # vim: ts=2