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
fromRustupToolchain = { path ? null , channel ? null , components ? [ ] , targets ? [ ] , profile ? " d e f a u l t " }:
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
( toolchainFromManifest ( selectManifest { inherit channel ; } ) ) . _profiles . ${ profile } . override {
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-01-14 17:46:23 +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 ;
nativeBuildInputs = [ self . python3 ] ;
# VERBOSE_INSTALL = 1; # No spam by default.
installPhase = ''
runHook preInstall
python3 $ { ./rust-installer.py }
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 ( ) {
local oldIFS = " $ I F S "
# Directories we are aware of, given as substitution lists
for paths in \
" e t c / b a s h _ c o m p l e t i o n . d " , " 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 " , " e t c / b a s h _ c o m p l e t i o n s . d " , " s h a r e / b a s h _ c o m p l e t i o n s / c o m p l e t i o n s " ;
do
# Some directoties may be missing in some versions. If so we just skip them.
# See https://github.com/mozilla/nixpkgs-mozilla/issues/48 for more infomation.
if [ ! - e $ paths ] ; then continue ; fi
IFS = " , "
set - - $ paths
IFS = " $ o l d I F S "
local orig_path = " $ 1 "
local wanted_path = " $ 2 "
# Rename the files
if [ - d . / " $ o r i g _ p a t h " ] ; then
mkdir - p " $ ( d i r n a m e . / " $ wanted_path " ) "
fi
mv - v . / " $ o r i g _ p a t h " . / " $ w a n t e d _ p a t h "
# Fail explicitly if etc is not empty so we can add it to the list and/or report it upstream
rmdir ./etc || {
echo Installer tries to install to /etc :
find ./etc
exit 1
}
done
}
if [ - d " $ o u t " /etc ] ; then
pushd " $ o u t "
handleEtc
popd
fi
'' ;
dontStrip = true ;
} ;
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
# `symlinkJoin` (`runCommand`) doesn't handle propagatedBuildInputs.
# 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-01-14 17:46:23 +03:00
'' ;
# Add the compiler as part of the propagated build inputs in order
# to run:
#
# $ nix-shell -p rustChannels.stable.rust
#
# And get a fully working Rust compiler, with the stdenv linker.
2021-04-05 17:07:22 +03:00
propagatedBuildInputs =
[ self . stdenv . cc ] ++
self . lib . optional ( self . stdenv . hostPlatform . isDarwin ) self . 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 ;
targets = [ ( toRustTarget self . stdenv . targetPlatform ) ] ++ targets ;
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.
rust = mkPackage " r u s t " manifest . pkg . rust ;
# Internal use.
_components = componentSet ;
_profiles = if profiles == { }
then throw " R u s t ${ manifest . version } d o e s n ' t s u p p o r t p r o f i l e s "
else profiles ;
} ;
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 ;
namesAndSrcs = super . lib . mapAttrsToList ( component : hash : {
name = " ${ component } - ${ shortRev } " ;
src = self . fetchurl {
url = if component == " 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 } / ${ component } - 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 } / ${ component } - n i g h t l y - ${ target } . t a r . x z " ;
inherit hash ;
} ;
} ) components ;
in
aggregateComponents {
version = shortRev ;
inherit pname namesAndSrcs ;
} ;
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
}