Skip to content

Commit

Permalink
Refactor component resolution part
Browse files Browse the repository at this point in the history
Pull out component derivations into a separated file, and drop all
legacy resolution code.
  • Loading branch information
oxalica committed Dec 2, 2021
1 parent 0901e38 commit 0623949
Show file tree
Hide file tree
Showing 3 changed files with 281 additions and 336 deletions.
34 changes: 11 additions & 23 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

outputs = { self, nixpkgs, flake-utils }: let
inherit (nixpkgs.lib)
elem filter filterAttrs head mapAttrs' mapAttrsToList optionalAttrs replaceStrings;
elem filter filterAttrs head isDerivation isString mapAttrs' mapAttrsToList optionalAttrs replaceStrings;

overlay = import ./.;

Expand Down Expand Up @@ -43,33 +43,18 @@
defaultPackage = packages.rust;

packages = let
inherit (builtins) tryEval;

defaultPkg = comps:
if comps ? default then
if (tryEval comps.default.drvPath).success then
comps.default
else if (tryEval comps.minimal.drvPath).success then
comps.minimal
else
null
else if (tryEval comps.rust.drvPath).success then
comps.rust
else
null;

result =
mapAttrs' (version: comps: {
name = "rust-${replaceStrings ["."] ["-"] version}";
value = defaultPkg comps;
value = comps.default or null;
}) pkgs.rust-bin.stable //
mapAttrs' (version: comps: {
name = "rust-nightly-${version}";
value = defaultPkg comps;
value = comps.default or null;
}) pkgs.rust-bin.nightly //
mapAttrs' (version: comps: {
name = "rust-beta-${version}";
value = defaultPkg comps;
value = comps.default or null;
}) pkgs.rust-bin.beta //
{
rust = result.rust-latest;
Expand All @@ -92,14 +77,12 @@
srcUrl = head drv.src.urls;
in assertEq srcUrl url;

assertions = {
# Check only tier 1 targets.
assertions = optionalAttrs (elem system [ "aarch64-linux" "x86_64-linux" ]) {
url-no-arch = assertUrl stable."1.48.0".rust-src "https://static.rust-lang.org/dist/2020-11-19/rust-src-1.48.0.tar.xz";
url-kind-nightly = assertUrl nightly."2021-01-01".rustc "https://static.rust-lang.org/dist/2021-01-01/rustc-nightly-${rustTarget}.tar.xz";
url-kind-beta = assertUrl beta."2021-01-01".rustc "https://static.rust-lang.org/dist/2021-01-01/rustc-beta-${rustTarget}.tar.xz";

# Check only tier 1 targets.
} // optionalAttrs (elem system [ "aarch64-linux" "x86_64-linux" ]) {

name-stable = assertEq stable."1.48.0".rustc.name "rustc-1.48.0";
name-beta = assertEq beta."2021-01-01".rustc.name "rustc-1.50.0-beta.2-2021-01-01";
name-nightly = assertEq nightly."2021-01-01".rustc.name "rustc-1.51.0-nightly-2021-01-01";
Expand Down Expand Up @@ -168,6 +151,11 @@

checkDrvs = optionalAttrs (elem system [ "aarch64-linux" "x86_64-linux" ]) {
latest-nightly-default = rust-bin.selectLatestNightlyWith (toolchain: toolchain.default);
} // optionalAttrs (system == "aarch64-darwin") {
aarch64-darwin-use-x86-docs = rust-bin.stable."1.51.0".default.override {
targets = [ "x86_64-apple-darwin" ];
targetExtensions = [ "rust-docs" ];
};
};

failedAssertions =
Expand Down
126 changes: 126 additions & 0 deletions mk-component-set.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Define component derivations and special treatments.
{ lib, stdenv, buildPackages, gnutar, gcc, zlib, libiconv
, toRustTarget, removeNulls
}:
# Release version of the whole set.
{ version
# The host platform of this set.
, platform
# Set of pname -> src
, srcs
# { clippy.to = "clippy-preview"; }
, renames
}:
let
inherit (lib) elem mapAttrs optional optionalString makeLibraryPath;
inherit (stdenv) hostPlatform targetPlatform;

mkComponent = pname: src:
stdenv.mkDerivation {
inherit pname version src;

passthru.platform = platform;

# No point copying src to a build server, then copying back the
# entire unpacked contents after just a little twiddling.
preferLocalBuild = true;

nativeBuildInputs = [ gnutar ];

# Ourselves have offset -1. In order to make these offset -1 dependencies of downstream derivation,
# they are offset 0 propagated.
propagatedBuildInputs =
optional (pname == "rustc") [ stdenv.cc buildPackages.stdenv.cc ];
# This goes downstream packages' buildInputs.
depsTargetTargetPropagated =
optional (pname == "rustc" && targetPlatform.isDarwin) libiconv;

installPhase = ''
runHook preInstall
installerVersion=$(< ./rust-installer-version)
if [[ "$installerVersion" != 3 ]]; then
echo "Unknown installer version: $installerVersion"
fi
mkdir -p "$out"
while read -r comp; do
echo "Installing component $comp"
# We don't want to parse the file and invoking cp in bash due to slow forking.
cut -d: -f2 <"$comp/manifest.in" | tar -cf - -C "$comp" --files-from - | tar -xC "$out"
done <./components
runHook postInstall
'';

# This code is inspired by patchelf/setup-hook.sh to iterate over all binaries.
preFixup =
optionalString hostPlatform.isLinux ''
setInterpreter() {
local dir="$1"
[ -e "$dir" ] || return 0
header "Patching interpreter of ELF executables and libraries in $dir"
local i
while IFS= read -r -d ''$'\0' i; do
if [[ "$i" =~ .build-id ]]; then continue; fi
if ! isELF "$i"; then continue; fi
echo "setting interpreter of $i"
if [[ -x "$i" ]]; then
# Handle executables
patchelf \
--set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
--set-rpath "${makeLibraryPath [ zlib ]}:$out/lib" \
"$i" || true
else
# Handle libraries
patchelf \
--set-rpath "${makeLibraryPath [ zlib ]}:$out/lib" \
"$i" || true
fi
done < <(find "$dir" -type f -print0)
}
setInterpreter $out
'' + optionalString (elem pname ["clippy-preview" "rls-preview" "miri-preview"]) ''
for f in $out/bin/*; do
${optionalString hostPlatform.isLinux ''
patchelf \
--set-rpath "${self.rustc}/lib:${makeLibraryPath [ zlib ]}:$out/lib" \
"$f" || true
''}
${optionalString hostPlatform.isDarwin ''
install_name_tool \
-add_rpath "${self.rustc}/lib" \
"$f" || true
''}
done
'' + optionalString (pname == "llvm-tools-preview" && hostPlatform.isLinux) ''
dir="$out/lib/rustlib/${toRustTarget hostPlatform}"
for f in "$dir"/bin/*; do
patchelf --set-rpath "$dir/lib" "$f" || true
done
'';

# rust-docs only contains tons of html files.
dontFixup = pname == "rust-docs";

postFixup = ''
# Function moves well-known files from etc/
handleEtc() {
if [[ -d "$1" ]]; then
mkdir -p "$(dirname "$2")"
mv -T "$1" "$2"
fi
}
if [[ -e "$out/etc" ]]; then
handleEtc "$out/etc/bash_completion.d" "$out/share/bash-completion/completions"
rmdir $out/etc || { echo "Installer tries to install to /etc: $(ls $out/etc)"; exit 1; }
fi
'';

dontStrip = true;
};

self = mapAttrs mkComponent srcs;

in
removeNulls (
self //
mapAttrs (alias: { to }: self.${to} or null) renames)
Loading

0 comments on commit 0623949

Please sign in to comment.