forked from mozilla/nixpkgs-mozilla
/
rust-overlay.nix
172 lines (154 loc) · 6.33 KB
/
rust-overlay.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# This file provide a Rust overlay, which provides pre-packaged bleeding edge versions of rustc
# and cargo.
self: super:
let
fromTOML = (import ./lib/parseTOML.nix).fromTOML;
# See https://github.com/rust-lang-nursery/rustup.rs/blob/master/src/rustup-dist/src/dist.rs
defaultDistRoot = "https://static.rust-lang.org";
manifest_v1_url = {
dist_root ? defaultDistRoot + "/dist",
date ? null,
staging ? false,
# A channel can be "nightly", "beta", "stable", "\d{1}.\d{1}.\d{1}", or "\d{1}.\d{2\d{1}".
channel ? "nightly"
}:
if date == null && staging == false
then "${dist_root}/channel-rust-${channel}"
else if date != null && staging == false
then "${dist_root}/${date}/channel-rust-${channel}"
else if date == null && staging == true
then "${dist_root}/staging/channel-rust-${channel}"
else throw "not a real-world case";
manifest_v2_url = args: (manifest_v1_url args) + ".toml";
# Intersection of rustup-dist/src/dist.rs listed platforms and stdenv/default.nix.
hostTripleOf = system: { # switch
"i686-linux" = "i686-unknown-linux-gnu";
"x86_64-linux" = "x86_64-unknown-linux-gnu";
"armv5tel-linux" = "arm-unknown-linux-gnueabi";
"armv6l-linux" = "arm-unknown-linux-gnueabi";
"armv7l-linux" = "armv7-unknown-linux-gnueabihf";
"aarch64-linux" = "aarch64-unknown-linux-gnu";
"mips64el-linux" = "mips64el-unknown-linux-gnuabi64";
"x86_64-darwin" = "x86_64-apple-darwin";
"i686-cygwin" = "i686-pc-windows-gnu"; # or msvc?
"x86_64-cygwin" = "x86_64-pc-windows-gnu"; # or msvc?
"x86_64-freebsd" = "x86_64-unknown-freebsd";
}.${system} or (throw "Rust overlay does not support ${system} yet.");
getExtensions = pkgs: pkgname: stdenv:
let
pkg = pkgs.${pkgname};
srcInfo = pkg.target.${hostTripleOf stdenv.system} or pkg.target."*";
extensions = srcInfo.extensions or [];
extensionNamesList =
builtins.map (pkg: pkg.pkg) (builtins.filter (pkg: (pkg.target == (hostTripleOf stdenv.system)) || (pkg.target == "*")) extensions);
in
extensionNamesList;
getFetchUrl = pkgs: pkgname: stdenv: fetchurl:
let
pkg = pkgs.${pkgname};
srcInfo = pkg.target.${hostTripleOf stdenv.system} or pkg.target."*";
in
(fetchurl { url = srcInfo.url; sha256 = srcInfo.hash; });
getSrcs = pkgs: pkgname: extensions: stdenv: fetchurl:
let
inherit (builtins) head;
inherit (super.lib) subtractLists concatStringsSep;
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}'';
pkgsToInstall = [pkgname] ++ extensionsToInstall;
in
(builtins.map (pkg: (getFetchUrl pkgs pkg stdenv fetchurl)) pkgsToInstall);
# 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";
# };
# }
#
# The packages available usually are:
# cargo, rust-analysis, rust-docs, rust-src, rust-std, rustc, and
# rust, which aggregates them in one package.
fromManifestFile = manifest: { stdenv, fetchurl, patchelf }:
let
inherit (builtins) elemAt;
inherit (super) makeOverridable;
inherit (super.lib) flip mapAttrs;
pkgs = fromTOML (builtins.readFile manifest);
in
flip mapAttrs pkgs.pkg (name: pkg:
makeOverridable ({extensions}:
let
version' = builtins.match "([^ ]*) [(]([^ ]*) ([^ ]*)[)]" pkg.version;
version = "${elemAt version' 0}-${elemAt version' 2}-${elemAt version' 1}";
srcs = getSrcs pkgs.pkg name extensions stdenv fetchurl;
in
stdenv.mkDerivation {
name = name + "-" + version;
inherit srcs;
sourceRoot = ".";
# (@nbp) TODO: Check on Windows and Mac.
# This code is inspired by patchelf/setup-hook.sh to iterate over all binaries.
installPhase = ''
for i in * ; do
if [ -d "$i" ]; then
cd $i
patchShebangs install.sh
CFG_DISABLE_LDCONFIG=1 ./install.sh --prefix=$out --verbose
cd ..
fi
done
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"
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$i" || true
done < <(find "$dir" -type f -print0)
}
setInterpreter $out
'';
}
) { extensions = []; }
);
fromManifest = manifest: { stdenv, fetchurl, patchelf }:
fromManifestFile (builtins.fetchurl manifest) { inherit stdenv fetchurl patchelf; };
in rec
{
lib = super.lib // {
inherit fromTOML;
rustLib = {
inherit fromManifest fromManifestFile manifest_v2_url;
};
};
rustChannelOf = manifest_args: fromManifest
(manifest_v2_url manifest_args)
{ inherit (self) stdenv fetchurl patchelf; }
;
rustChannels = {
nightly = rustChannelOf { channel = "nightly"; };
beta = rustChannelOf { channel = "beta"; };
stable = rustChannelOf { channel = "stable"; };
};
# For each channel:
# rustChannels.nightly.cargo
# rustChannels.nightly.rust # Aggregate all others. (recommended)
# rustChannels.nightly.rustc
# rustChannels.nightly.rust-analysis
# rustChannels.nightly.rust-docs
# rustChannels.nightly.rust-src
# rustChannels.nightly.rust-std
# For a specific date:
# rustChannelOf { date = "2017-06-06"; channel = "beta"; }.rust
}