2021-01-01 05:21:00 +03:00
# Modified from: https://github.com/mozilla/nixpkgs-mozilla/blob/8c007b60731c07dd7a052cce508de3bb1ae849b4/rust-overlay.nix
# This file provide a Rust overlay, which provides pre-packaged bleeding edge versions of rustc
# and cargo.
self : super :
let
# Manifest selector.
2021-01-03 16:43:00 +03:00
selectManifest = { channel , date ? null }: let
2021-01-02 15:42:57 +03:00
inherit ( self . rust-bin ) manifests ;
2021-01-03 13:08:57 +03:00
inherit ( builtins ) match elemAt ;
2021-01-01 19:28:12 +03:00
assertWith = cond : msg : body : if cond then body else throw msg ;
2021-01-01 05:21:00 +03:00
2021-01-03 13:08:57 +03:00
asVersion = match " [ 0 - 9 ] + \\ . [ 0 - 9 ] + \\ . [ 0 - 9 ] + " channel ;
asNightlyDate = let m = match " n i g h t l y - ( [ 0 - 9 ] + - [ 0 - 9 ] + - [ 0 - 9 ] + ) " channel ; in
if m == null then null else elemAt m 0 ;
2021-01-05 12:38:46 +03:00
asBetaDate = let m = match " b e t a - ( [ 0 - 9 ] + - [ 0 - 9 ] + - [ 0 - 9 ] + ) " channel ; in
if m == null then null else elemAt m 0 ;
2021-01-03 13:08:57 +03:00
2021-01-03 16:43:00 +03:00
in
2021-01-05 12:38:46 +03:00
# "stable"
2021-01-03 16:43:00 +03:00
if channel == " s t a b l e " then
assertWith ( date == null ) " S t a b l e v e r s i o n w i t h s p e c i f i c d a t e i s n o t s u p p o r t e d "
manifests . stable . latest
2021-01-05 12:38:46 +03:00
# "nightly"
2021-01-03 16:43:00 +03:00
else if channel == " n i g h t l y " then
manifests . nightly . ${ if date != null then date else " l a t e s t " } or ( throw " N i g h t l y ${ date } i s n o t a v a i l a b l e " )
2021-01-05 12:38:46 +03:00
# "beta"
2021-01-03 16:43:00 +03:00
else if channel == " b e t a " then
2021-01-05 12:38:46 +03:00
manifests . beta . ${ if date != null then date else " l a t e s t " } or ( throw " B e t a ${ date } i s n o t a v a i l a b l e " )
# "1.49.0"
2021-01-03 16:43:00 +03:00
else if asVersion != null then
assertWith ( date == null ) " S t a b l e v e r s i o n w i t h s p e c i f i c d a t e i s n o t s u p p o r t e d "
manifests . stable . ${ channel } or ( throw " S t a b l e ${ channel } i s n o t a v a i l a b l e " )
2021-01-05 12:38:46 +03:00
# "beta-2021-01-01"
else if asBetaDate != null then
assertWith ( date == null ) " C a n n o t s p e c i f y d a t e i n b o t h ` c h a n n e l ` a n d ` d a t e ` "
manifests . beta . ${ asBetaDate } or ( throw " B e t a ${ asBetaDate } i s n o t a v a i l a b l e " )
# "nightly-2021-01-01"
2021-01-03 16:43:00 +03:00
else if asNightlyDate != null then
assertWith ( date == null ) " C a n n o t s p e c i f y d a t e i n b o t h ` c h a n n e l ` a n d ` d a t e ` "
manifests . nightly . ${ asNightlyDate } or ( throw " N i g h t l y ${ asNightlyDate } i s n o t a v a i l a b l e " )
2021-01-05 12:38:46 +03:00
# Otherwise
2021-01-03 16:43:00 +03:00
else throw " U n k n o w n c h a n n e l : ${ channel } " ;
2021-01-01 05:21:00 +03:00
2021-01-03 13:08:57 +03:00
# Select a toolchain and aggregate components by rustup's `rust-toolchain` file format.
2021-04-05 12:57:55 +03:00
# See: https://rust-lang.github.io/rustup/concepts/profiles.html
# Or see source: https://github.com/rust-lang/rustup/blob/84974df1387812269c7b29fa5f3bb1c6480a6500/doc/src/overrides.md#the-toolchain-file
2021-04-06 14:35:24 +03:00
fromRustupToolchain = { path ? null , channel ? null , profile ? null , components ? [ ] , targets ? [ ] }:
2021-04-05 12:57:55 +03:00
if path != null then throw " ` p a t h ` i s n o t s u p p o r t e d , p l e a s e d i r e c t l y a d d i t t o y o u r P A T H i n s t e a d "
else if channel == null then throw " ` c h a n n e l ` i s r e q u i r e d "
else
2021-04-06 14:35:24 +03:00
let
toolchain = toolchainFromManifest ( selectManifest { inherit channel ; } ) ;
profile' = if profile == null then " d e f a u l t " else profile ;
pkg =
if toolchain . _profiles != { } then
toolchain . _profiles . ${ profile' } or ( throw ''
Rust $ { toolchain . _version } doesn't have profile ` $ { profile' } ` .
Available profiles are : $ { self . lib . concatStringsSep " , " ( builtins . attrNames toolchain . _profiles ) }
'' )
# Fallback to package `rust` when profiles are not supported and not specified.
else if profile == null then
toolchain . rust
else
throw " C a n n o t s e l e c t p r o f i l e ` ${ profile' } ` s i n c e r u s t ${ toolchain . _version } i s t o o e a r l y t o s u p p o r t p r o f i l e s " ;
in pkg . override {
2021-04-05 12:57:55 +03:00
extensions = components ;
inherit targets ;
} ;
2021-01-03 13:08:57 +03:00
2021-01-03 18:34:51 +03:00
# Same as `fromRustupToolchain` but read from a `rust-toolchain` file (legacy one-line string or in TOML).
fromRustupToolchainFile = path : let
inherit ( builtins ) readFile match fromTOML head ;
content = readFile path ;
legacy = match " ( [ ^ \r \n ] + ) \r ? \n ? " content ;
in if legacy != null
then fromRustupToolchain { channel = head legacy ; }
else fromRustupToolchain ( fromTOML content ) . toolchain ;
2021-01-01 05:21:00 +03:00
getComponentsWithFixedPlatform = pkgs : pkgname : stdenv :
let
pkg = pkgs . ${ pkgname } ;
srcInfo = pkg . target . ${ super . rust . toRustTarget stdenv . targetPlatform } or pkg . target . " * " ;
components = srcInfo . components or [ ] ;
componentNamesList =
builtins . map ( pkg : pkg . pkg ) ( builtins . filter ( pkg : ( pkg . target != " * " ) ) components ) ;
in
componentNamesList ;
getExtensions = pkgs : pkgname : stdenv :
let
inherit ( super . lib ) unique ;
pkg = pkgs . ${ pkgname } ;
rustTarget = super . rust . toRustTarget stdenv . targetPlatform ;
srcInfo = pkg . target . ${ rustTarget } or pkg . target . " * " or ( throw " ${ pkgname } i s n o a v a i l a b l e " ) ;
extensions = srcInfo . extensions or [ ] ;
extensionNamesList = unique ( builtins . map ( pkg : pkg . pkg ) extensions ) ;
in
extensionNamesList ;
hasTarget = pkgs : pkgname : target :
pkgs ? ${ pkgname } . target . ${ target } ;
getTuples = pkgs : name : targets :
builtins . map ( target : { inherit name target ; } ) ( builtins . filter ( target : hasTarget pkgs name target ) targets ) ;
# In the manifest, a package might have different components which are bundled with it, as opposed as the extensions which can be added.
# By default, a package will include the components for the same architecture, and offers them as extensions for other architectures.
#
# This functions returns a list of { name, target } attribute sets, which includes the current system package, and all its components for the selected targets.
# The list contains the package for the pkgTargets as well as the packages for components for all compTargets
getTargetPkgTuples = pkgs : pkgname : pkgTargets : compTargets : stdenv :
let
inherit ( builtins ) elem ;
inherit ( super . lib ) intersectLists ;
components = getComponentsWithFixedPlatform pkgs pkgname stdenv ;
extensions = getExtensions pkgs pkgname stdenv ;
compExtIntersect = intersectLists components extensions ;
tuples = ( getTuples pkgs pkgname pkgTargets ) ++ ( builtins . map ( name : getTuples pkgs name compTargets ) compExtIntersect ) ;
in
tuples ;
getFetchUrl = pkgs : pkgname : target : stdenv : fetchurl :
2021-04-05 12:57:55 +03:00
let
srcInfo = pkgs . ${ pkgname } . target . ${ target } ;
in
mkComponentSrc {
url = srcInfo . xz_url ;
sha256 = srcInfo . xz_hash ;
inherit fetchurl ;
} ;
mkComponentSrc = { url , sha256 , fetchurl }:
2021-01-01 05:21:00 +03:00
let
2021-01-01 17:42:15 +03:00
inherit ( builtins ) match elemAt ;
2021-04-05 12:57:55 +03:00
url' = builtins . replaceStrings [ " " ] [ " % 2 0 " ] url ; # This is required or download will fail.
2021-01-01 17:42:15 +03:00
# Filter names like `llvm-tools-1.34.2 (6c2484dc3 2019-05-13)-aarch64-unknown-linux-gnu.tar.xz`
2021-04-05 12:57:55 +03:00
matchParenPart = match " . * / ( [ ^ / ] * ) [ ( ] [ ^ ) ] * [ ) ] ( . * ) " url ;
2021-01-01 17:42:15 +03:00
name = if matchParenPart == null then " " else ( elemAt matchParenPart 0 ) + ( elemAt matchParenPart 1 ) ;
2021-01-01 05:21:00 +03:00
in
2021-04-05 12:57:55 +03:00
fetchurl { inherit name sha256 ; url = url' ; } ;
2021-01-01 05:21:00 +03:00
checkMissingExtensions = pkgs : pkgname : stdenv : extensions :
let
inherit ( builtins ) head ;
inherit ( super . lib ) concatStringsSep subtractLists ;
availableExtensions = getExtensions pkgs pkgname stdenv ;
missingExtensions = subtractLists availableExtensions extensions ;
extensionsToInstall =
if missingExtensions == [ ] then extensions else throw ''
While compiling $ { pkgname }: the extension $ { head missingExtensions } is not available .
Select extensions from the following list :
$ { concatStringsSep " \n " availableExtensions } '' ;
in
extensionsToInstall ;
getComponents = pkgs : pkgname : targets : extensions : targetExtensions : stdenv : fetchurl :
let
inherit ( builtins ) head map ;
inherit ( super . lib ) flatten remove subtractLists unique ;
targetExtensionsToInstall = checkMissingExtensions pkgs pkgname stdenv targetExtensions ;
extensionsToInstall = checkMissingExtensions pkgs pkgname stdenv extensions ;
hostTargets = [ " * " ( super . rust . toRustTarget stdenv . hostPlatform ) ( super . rust . toRustTarget stdenv . targetPlatform ) ] ;
pkgTuples = flatten ( getTargetPkgTuples pkgs pkgname hostTargets targets stdenv ) ;
extensionTuples = flatten ( map ( name : getTargetPkgTuples pkgs name hostTargets targets stdenv ) extensionsToInstall ) ;
targetExtensionTuples = flatten ( map ( name : getTargetPkgTuples pkgs name targets targets stdenv ) targetExtensionsToInstall ) ;
pkgsTuples = pkgTuples ++ extensionTuples ++ targetExtensionTuples ;
missingTargets = subtractLists ( map ( tuple : tuple . target ) pkgsTuples ) ( remove " * " targets ) ;
pkgsTuplesToInstall =
if missingTargets == [ ] then pkgsTuples else throw ''
While compiling $ { pkgname }: the target $ { head missingTargets } is not available for any package . '' ;
in
map ( tuple : { name = tuple . name ; src = ( getFetchUrl pkgs tuple . name tuple . target stdenv fetchurl ) ; } ) pkgsTuplesToInstall ;
2021-04-05 12:57:55 +03:00
mkComponent = { pname , version , src }:
2021-04-12 17:19:10 +03:00
self . stdenv . mkDerivation {
2021-04-05 12:57:55 +03:00
inherit pname version src ;
2021-01-14 17:46:23 +03:00
# No point copying src to a build server, then copying back the
# entire unpacked contents after just a little twiddling.
preferLocalBuild = true ;
2021-04-12 16:51:22 +03:00
nativeBuildInputs = [ self . cpio ] ;
2021-01-14 17:46:23 +03:00
installPhase = ''
runHook preInstall
2021-04-12 16:51:22 +03:00
installerVersion = $ ( < ./rust-installer-version )
if [ [ " $ i n s t a l l e r V e r s i o n " != 3 ] ] ; then
echo " U n k n o w n i n s t a l l e r v e r s i o n : $ i n s t a l l e r V e r s i o n "
fi
while read - r comp ; do
echo " I n s t a l l i n g c o m p o n e n t $ c o m p "
# Use cpio with file list instead of forking tons of cp.
cut - d : - f2 < " $ c o m p / m a n i f e s t . i n " | cpio - - quiet - pdD " $ c o m p " " $ o u t "
done < ./components
2021-01-14 17:46:23 +03:00
runHook postInstall
'' ;
# (@nbp) TODO: Check on Windows and Mac.
# This code is inspired by patchelf/setup-hook.sh to iterate over all binaries.
preFixup = ''
setInterpreter ( ) {
local dir = " $ 1 "
[ - e " $ d i r " ] || return 0
header " P a t c h i n g i n t e r p r e t e r o f E L F e x e c u t a b l e s a n d l i b r a r i e s i n $ d i r "
local i
while IFS = read - r - d '' $' \ 0 ' i ; d o
if [ [ " $ i " = ~ . build-id ] ] ; then continue ; fi
if ! isELF " $ i " ; then continue ; fi
echo " s e t t i n g i n t e r p r e t e r o f $ i "
if [ [ - x " $ i " ] ] ; then
# Handle executables
patchelf \
- - set-interpreter " $ ( c a t $ N I X _ C C / n i x - s u p p o r t / d y n a m i c - l i n k e r ) " \
- - set-rpath " ${ super . lib . makeLibraryPath [ self . zlib ] } : $ o u t / l i b " \
" $ i " || true
else
# Handle libraries
patchelf \
- - set-rpath " ${ super . lib . makeLibraryPath [ self . zlib ] } : $ o u t / l i b " \
" $ i " || true
2021-01-01 05:21:00 +03:00
fi
2021-01-14 17:46:23 +03:00
done < < ( find " $ d i r " - type f - print0 )
}
setInterpreter $ out
'' ;
2021-01-01 05:21:00 +03:00
2021-01-14 17:46:23 +03:00
postFixup = ''
# Function moves well-known files from etc/
handleEtc ( ) {
2021-04-12 17:19:10 +03:00
if [ [ - d " $ 1 " ] ] ; then
mkdir - p " $ ( d i r n a m e " $ 2 " ) "
mv - T " $ 1 " " $ 2 "
fi
2021-01-14 17:46:23 +03:00
}
2021-04-12 17:19:10 +03:00
if [ [ - e " $ o u t / e t c " ] ] ; then
handleEtc " $ o u t / e t c / b a s h _ c o m p l e t i o n . d " " $ o u t / s h a r e / b a s h - c o m p l e t i o n / c o m p l e t i o n s "
rmdir $ out/etc || { echo " I n s t a l l e r t r i e s t o i n s t a l l t o / e t c : $ ( l s $ o u t / e t c ) " ; exit 1 ; }
2021-01-14 17:46:23 +03:00
fi
'' ;
dontStrip = true ;
2021-04-12 17:19:10 +03:00
} ;
2021-01-14 17:46:23 +03:00
2021-04-05 12:57:55 +03:00
aggregateComponents = { pname , version , components }:
2021-01-14 17:46:23 +03:00
self . pkgs . symlinkJoin {
name = pname + " - " + version ;
inherit pname version ;
2021-04-05 12:57:55 +03:00
paths = components ;
2021-01-14 17:46:23 +03:00
postBuild = ''
# If rustc or rustdoc is in the derivation, we need to copy their
# executable into the final derivation. This is required
# for making them find the correct SYSROOT.
2021-01-15 18:33:54 +03:00
for target in $ out/bin / { rustc , rustdoc , miri } ; do
2021-01-14 17:46:23 +03:00
if [ - e $ target ] ; then
cp - - remove-destination " $ ( r e a l p a t h - e $ t a r g e t ) " $ target
fi
done
2021-01-15 20:14:03 +03:00
if [ - e $ out/bin/cargo-miri ] ; then
cargo_miri = $ ( readlink $ out/bin/cargo-miri )
cp - f $ { ./cargo-miri-wrapper.sh } $ out/bin/cargo-miri
chmod + w $ out/bin/cargo-miri
substituteInPlace $ out/bin/cargo-miri \
- - replace " @ b a s h @ " " ${ self . pkgs . bash } / b i n / b a s h " \
- - replace " @ m i r i @ " " $ c a r g o _ m i r i " \
- - replace " @ o u t @ " " $ o u t "
fi
2021-04-05 17:07:22 +03:00
2021-04-05 21:27:36 +03:00
# `symlinkJoin` (`runCommand`) doesn't handle propagated dependencies.
2021-04-05 17:07:22 +03:00
# Need to do it manually.
mkdir - p " $ o u t / n i x - s u p p o r t "
echo " $ p r o p a g a t e d B u i l d I n p u t s " > " $ o u t / n i x - s u p p o r t / p r o p a g a t e d - b u i l d - i n p u t s "
2021-04-05 21:27:36 +03:00
if [ [ - n " $ d e p s T a r g e t T a r g e t P r o p a g a t e d " ] ] ; then
echo " $ d e p s T a r g e t T a r g e t P r o p a g a t e d " > " $ o u t / n i x - s u p p o r t / p r o p a g a t e d - t a r g e t - t a r g e t - d e p s "
fi
2021-01-14 17:46:23 +03:00
'' ;
2021-04-05 21:27:36 +03:00
# FIXME: If these propagated dependencies go components, darwin build will fail with "`-liconv` not found".
propagatedBuildInputs = [ self . stdenv . cc ] ;
depsTargetTargetPropagated =
self . lib . optional ( self . stdenv . targetPlatform . isDarwin ) self . targetPackages . libiconv ;
2021-01-14 17:46:23 +03:00
meta . platforms = self . lib . platforms . all ;
} ;
2021-01-01 05:21:00 +03:00
2021-04-05 12:57:55 +03:00
# Resolve final components to install from mozilla-overlay style `extensions`, `targets` and `targetExtensions`.
#
# `componentSet` has a layout of `componentSet.<name>.<rust-target> : Derivation`.
# `targetComponentsList` is a list of all component names for target platforms.
# `name` is only used for error message.
#
# Returns a list of component derivations, or throw if failed.
resolveComponents = { name , componentSet , targetComponentsList , extensions , targets , targetExtensions }:
let
inherit ( self . lib ) flatten elem isString filter any remove concatStringsSep concatMapStrings attrNames ;
rustHostPlatform = self . rust . toRustTarget self . stdenv . hostPlatform ;
collectComponentTargets = compName : comp :
# Platform irrelevent components like `rust-src`.
if comp ? " * " then
comp . " * "
# Components for target platform like `rust-std`.
else if elem compName targetComponentsList then
collectTargetComponentTargets compName comp
# Components for host platform like `rustc`.
else
comp . ${ rustHostPlatform } or " H o s t c o m p o n e n t ` ${ compName } ` d o e s n ' t s u p p o r t t a r g e t ` ${ rustHostPlatform } ` " ;
collectTargetComponentTargets = compName : comp :
let selected = remove null ( map ( tgt : comp . ${ tgt } or null ) targets ) ; in
if selected == [ ]
then throw " E x t e n s i o n ` ${ compName } ` d o e s n ' t s u p p o r t a n y o f t a r g e t s : ${ concatStringsSep " , " targets } "
else selected ;
collectComponents = name : collectComponentTargets name ( componentSet . ${ name } or " M i s s i n g e x t e n s i o n ` ${ name } ` " ) ;
collectTargetComponents = name : collectTargetComponentTargets name ( componentSet . ${ name } or " M i s s i n g t a r g e t e x t e n s i o n ` ${ name } ` " ) ;
result =
flatten ( map collectComponents extensions ) ++
flatten ( map collectTargetComponents targetExtensions ) ;
isTargetUnused = target :
! any ( name : componentSet ? ${ name } . ${ target } )
( filter ( name : elem name targetComponentsList ) extensions ++ targetExtensions ) ;
errors = filter isString result ++
map ( tgt : " T a r g e t ` ${ tgt } ` i s n o t s u p p o r t e d b y a n y c o m p o n e n t s o r e x t e n s i o n s " )
( filter isTargetUnused targets ) ;
in
if errors == [ ] then result
else throw ''
Component resolution failed for $ { name }
- note : available extensions are $ { concatStringsSep " , " ( attrNames componentSet ) }
$ { concatMapStrings ( msg : " - ${ msg } \n " ) errors }
'' ;
2021-01-03 16:43:00 +03:00
# Genereate the toolchain set from a parsed manifest.
#
2021-01-01 05:21:00 +03:00
# Manifest files are organized as follow:
# { date = "2017-03-03";
# pkg.cargo.version= "0.18.0-nightly (5db6d64 2017-03-03)";
# pkg.cargo.target.x86_64-unknown-linux-gnu = {
# available = true;
# hash = "abce..."; # sha256
# url = "https://static.rust-lang.org/dist/....tar.gz";
# xz_hash = "abce..."; # sha256
# xz_url = "https://static.rust-lang.org/dist/....tar.xz";
# };
# }
#
# The packages available usually are:
# cargo, rust-analysis, rust-docs, rust-src, rust-std, rustc, and
# rust, which aggregates them in one package.
#
# For each package the following options are available:
# extensions - The extensions that should be installed for the package.
# For example, install the package rust and add the extension rust-src.
# targets - The package will always be installed for the host system, but with this option
# extra targets can be specified, e.g. "mips-unknown-linux-musl". The target
# will only apply to components of the package that support being installed for
# a different architecture. For example, the rust package will install rust-std
# for the host system and the targets.
# targetExtensions - If you want to force extensions to be installed for the given targets, this is your option.
# All extensions in this list will be installed for the target architectures.
# *Attention* If you want to install an extension like rust-src, that has no fixed architecture (arch *),
# you will need to specify this extension in the extensions options or it will not be installed!
2021-04-05 12:57:55 +03:00
toolchainFromManifest = manifest : let
2021-01-03 21:20:36 +03:00
inherit ( builtins ) elemAt ;
inherit ( super ) makeOverridable ;
inherit ( super . lib ) flip mapAttrs ;
2021-04-05 12:57:55 +03:00
inherit ( super . rust ) toRustTarget ;
2021-01-03 21:20:36 +03:00
2021-04-05 12:57:55 +03:00
maybeRename = name : manifest . renames . ${ name } . to or name ;
2021-01-03 21:20:36 +03:00
2021-04-05 12:57:55 +03:00
# For legacy pre-aggregated package `rust`.
2021-01-03 21:20:36 +03:00
mkPackage = name : pkg :
2021-01-03 16:43:00 +03:00
makeOverridable ( { extensions , targets , targetExtensions , stdenv , fetchurl , patchelf }:
2021-01-01 05:21:00 +03:00
let
2021-01-03 21:20:36 +03:00
extensions' = map maybeRename extensions ;
targetExtensions' = map maybeRename targetExtensions ;
2021-04-05 12:57:55 +03:00
namesAndSrcs = getComponents manifest . pkg name targets extensions' targetExtensions' stdenv fetchurl ;
2021-01-01 05:21:00 +03:00
in
2021-01-14 17:46:23 +03:00
aggregateComponents {
2021-01-03 22:11:32 +03:00
pname = name ;
2021-04-05 12:57:55 +03:00
version = manifest . version ;
components = map ( { name , src }: ( mkComponent {
pname = name ;
inherit ( manifest ) version ;
inherit src ;
} ) ) namesAndSrcs ;
2021-01-01 05:21:00 +03:00
}
2021-01-03 16:43:00 +03:00
) {
extensions = [ ] ;
targets = [ ] ;
targetExtensions = [ ] ;
inherit ( self ) stdenv fetchurl patchelf ;
2021-01-03 21:20:36 +03:00
} ;
2021-04-05 12:57:55 +03:00
# componentSet.cargo.x86_64-unknown-linux-gnu = <derivation>;
componentSet = mapAttrs ( name : pkg :
mapAttrs ( target : { xz_hash , xz_url }:
mkComponent {
pname = name ;
inherit ( manifest ) version ;
src = mkComponentSrc {
url = xz_url ;
sha256 = xz_hash ;
fetchurl = self . fetchurl ;
} ;
}
) pkg . target
) ( removeAttrs manifest . pkg [ " r u s t " ] ) //
mapAttrs ( name : { to }: componentSet . ${ to } ) manifest . renames ;
mkProfile = name : componentNames :
makeOverridable ( { extensions , targets , targetExtensions }:
aggregateComponents {
pname = " r u s t - ${ name } " ;
version = manifest . version ;
components = resolveComponents {
name = " r u s t - ${ name } - ${ manifest . version } " ;
inherit componentSet ;
inherit ( manifest ) targetComponentsList ;
extensions = componentNames ++ extensions ;
2021-04-05 21:27:36 +03:00
targets = [
( toRustTarget self . stdenv . hostPlatform ) # Build script requires host std.
( toRustTarget self . stdenv . targetPlatform )
] ++ targets ;
2021-04-05 12:57:55 +03:00
inherit targetExtensions ;
} ;
}
) {
extensions = [ ] ;
targets = [ ] ;
targetExtensions = [ ] ;
} ;
profiles = mapAttrs mkProfile manifest . profiles ;
2021-01-03 21:20:36 +03:00
2021-04-05 12:57:55 +03:00
in
# Components.
mapAttrs ( name : targets : targets . " * " or targets . ${ toRustTarget self . stdenv . hostPlatform } or null ) componentSet //
# Profiles.
profiles //
{
# Legacy support for special pre-aggregated package.
# It has more components than `default` profile but less than `complete` profile.
2021-04-05 20:38:31 +03:00
rust =
let pkg = mkPackage " r u s t " manifest . pkg . rust ; in
2021-04-06 14:23:03 +03:00
if builtins . match " . * [ . ] . * [ . ] . * " != null && profiles != { }
2021-04-05 20:38:31 +03:00
then builtins . trace ''
Rust $ { manifest . version }:
Pre-aggregated package ` rust ` is not encouraged for stable channel since it contains almost all and uncertain components .
Consider use ` default ` profile like ` rust-bin . stable . latest . default ` and override it with extensions you need .
See README for more information .
'' p k g
else pkg ;
2021-04-05 12:57:55 +03:00
# Internal use.
_components = componentSet ;
2021-04-06 14:35:24 +03:00
_profiles = profiles ;
_version = manifest . version ;
2021-04-05 12:57:55 +03:00
} ;
2021-01-01 05:21:00 +03:00
2021-01-03 16:43:00 +03:00
# Same as `toolchainFromManifest` but read from a manifest file.
toolchainFromManifestFile = path : toolchainFromManifest ( builtins . fromTOML ( builtins . readFile path ) ) ;
# Override all pkgs of a toolchain set.
overrideToolchain = attrs : super . lib . mapAttrs ( name : pkg : pkg . override attrs ) ;
2021-01-01 05:21:00 +03:00
2021-01-14 17:46:23 +03:00
# From a git revision of rustc.
# This does the same thing as crate `rustup-toolchain-install-master`.
# But you need to manually provide component hashes.
fromRustcRev = {
# Package name of the derivation.
pname ? " r u s t - c u s t o m " ,
# Git revision of rustc.
rev ,
# Attrset with component name as key and its SRI hash as value.
components ,
# Rust target to download.
target ? super . rust . toRustTarget self . stdenv . targetPlatform
} : let
shortRev = builtins . substring 0 7 rev ;
2021-04-05 19:25:38 +03:00
components' = super . lib . mapAttrsToList ( compName : hash : mkComponent {
pname = compName ;
version = shortRev ;
2021-01-14 17:46:23 +03:00
src = self . fetchurl {
2021-04-05 19:25:38 +03:00
url = if compName == " r u s t - s r c "
then " h t t p s : / / c i - a r t i f a c t s . r u s t - l a n g . o r g / r u s t c - b u i l d s / ${ rev } / ${ compName } - n i g h t l y . t a r . x z "
else " h t t p s : / / c i - a r t i f a c t s . r u s t - l a n g . o r g / r u s t c - b u i l d s / ${ rev } / ${ compName } - n i g h t l y - ${ target } . t a r . x z " ;
2021-01-14 17:46:23 +03:00
inherit hash ;
} ;
} ) components ;
in
aggregateComponents {
2021-04-05 19:25:38 +03:00
inherit pname ;
2021-01-14 17:46:23 +03:00
version = shortRev ;
2021-04-05 19:25:38 +03:00
components = components' ;
2021-01-14 17:46:23 +03:00
} ;
2021-01-03 16:43:00 +03:00
in {
2021-01-02 15:42:57 +03:00
# For each channel:
# rust-bin.stable.latest.cargo
# rust-bin.stable.latest.rust # Aggregate all others. (recommended)
# rust-bin.stable.latest.rustc
# rust-bin.stable.latest.rust-analysis
# rust-bin.stable.latest.rust-docs
# rust-bin.stable.latest.rust-src
# rust-bin.stable.latest.rust-std
#
# For a specific version of stable:
# rust-bin.stable."1.47.0".rust
#
2021-01-05 12:38:46 +03:00
# For a specific date of beta:
# rust-bin.beta."2021-01-01".rust
#
2021-01-02 15:42:57 +03:00
# For a specific date of nightly:
# rust-bin.nightly."2020-01-01".rust
2021-01-03 13:08:57 +03:00
rust-bin = with builtins ;
( super . rust-bin or { } ) //
2021-01-03 16:43:00 +03:00
mapAttrs ( channel : mapAttrs ( version : toolchainFromManifest ) ) super . rust-bin . manifests //
2021-01-03 13:08:57 +03:00
{
2021-01-03 18:34:51 +03:00
inherit fromRustupToolchain fromRustupToolchainFile ;
2021-01-14 17:46:23 +03:00
# Experimental feature.
inherit fromRustcRev ;
2021-01-03 13:08:57 +03:00
} ;
2021-01-02 15:42:57 +03:00
2021-01-03 16:43:00 +03:00
# All attributes below are for compatiblity with mozilla overlay.
lib = ( super . lib or { } ) // {
rustLib = ( super . lib . rustLib or { } ) // {
manifest_v2_url = throw ''
` manifest_v2_url ` is not supported .
Select a toolchain from ` rust-bin ` or using ` rustChannelOf ` instead .
See also README at https://github.com/oxalica/rust-overlay
'' ;
fromManifest = throw ''
` fromManifest ` is not supported due to network access during evaluation .
Select a toolchain from ` rust-bin ` or using ` rustChannelOf ` instead .
See also README at https://github.com/oxalica/rust-overlay
'' ;
fromManifestFile = manifestFilePath : { stdenv , fetchurl , patchelf } @ deps : builtins . trace ''
` fromManifestFile ` is deprecated .
Select a toolchain from ` rust-bin ` or using ` rustChannelOf ` instead .
See also README at https://github.com/oxalica/rust-overlay
'' ( o v e r r i d e T o o l c h a i n d e p s ( t o o l c h a i n F r o m M a n i f e s t F i l e m a n i f e s t F i l e P a t h ) ) ;
2021-01-01 05:21:00 +03:00
} ;
} ;
2021-01-03 16:43:00 +03:00
rustChannelOf = manifestArgs : toolchainFromManifest ( selectManifest manifestArgs ) ;
2021-01-01 05:21:00 +03:00
latest = ( super . latest or { } ) // {
rustChannels = {
2021-01-03 16:43:00 +03:00
stable = self . rust-bin . stable . latest ;
2021-01-05 12:38:46 +03:00
beta = self . rust-bin . beta . latest ;
2021-01-03 16:43:00 +03:00
nightly = self . rust-bin . nightly . latest ;
2021-01-01 05:21:00 +03:00
} ;
} ;
rustChannelOfTargets = channel : date : targets :
2021-01-03 16:43:00 +03:00
( self . rustChannelOf { inherit channel date ; } )
2021-01-01 05:21:00 +03:00
. rust . override { inherit targets ; } ;
2021-01-03 16:43:00 +03:00
rustChannels = self . latest . rustChannels ;
2021-01-01 05:21:00 +03:00
}