1{ stdenv, fetchurl, fetchgit, fetchzip, which, file, perl, curl, python27
2, makeWrapper, tzdata, git, valgrind, procps, coreutils
3
4, shortVersion, isRelease
5, srcSha, srcRev ? ""
6, snapshotHashLinux686, snapshotHashLinux64
7, snapshotHashDarwin686, snapshotHashDarwin64
8, snapshotDate, snapshotRev
9, configureFlags ? []
10
11, patches
12}:
13
14assert !stdenv.isFreeBSD;
15
16/* Rust's build process has a few quirks :
17
18- It requires some patched in llvm that haven't landed upstream, so it
19 compiles its own llvm. This might change in the future, so at some
20 point we may be able to switch to nix's llvm.
21
22- The Rust compiler is written is Rust, so it requires a bootstrap
23 compiler, which is downloaded during the build. To make the build
24 pure, we download it ourself before and put it where it is
25 expected. Once the language is stable (1.0) , we might want to
26 switch it to use nix's packaged rust compiler.
27
28NOTE : some derivation depend on rust. When updating this, please make
29sure those derivations still compile. (racer, for example).
30
31*/
32
33assert (if isRelease then srcRev == "" else srcRev != "");
34
35let version = if isRelease then
36 "${shortVersion}"
37 else
38 "${shortVersion}-g${builtins.substring 0 7 srcRev}";
39
40 name = "rustc-${version}";
41
42 platform = if stdenv.system == "i686-linux"
43 then "linux-i386"
44 else if stdenv.system == "x86_64-linux"
45 then "linux-x86_64"
46 else if stdenv.system == "i686-darwin"
47 then "macos-i386"
48 else if stdenv.system == "x86_64-darwin"
49 then "macos-x86_64"
50 else abort "no snapshot to bootstrap for this platform (missing platform url suffix)";
51
52 target = if stdenv.system == "i686-linux"
53 then "i686-unknown-linux-gnu"
54 else if stdenv.system == "x86_64-linux"
55 then "x86_64-unknown-linux-gnu"
56 else if stdenv.system == "i686-darwin"
57 then "i686-apple-darwin"
58 else if stdenv.system == "x86_64-darwin"
59 then "x86_64-apple-darwin"
60 else abort "no snapshot to bootstrap for this platform (missing target triple)";
61
62 meta = with stdenv.lib; {
63 homepage = http://www.rust-lang.org/;
64 description = "A safe, concurrent, practical language";
65 maintainers = with maintainers; [ madjar cstrahan wizeman globin havvy ];
66 license = [ licenses.mit licenses.asl20 ];
67 platforms = platforms.linux;
68 };
69
70 snapshotHash = if stdenv.system == "i686-linux"
71 then snapshotHashLinux686
72 else if stdenv.system == "x86_64-linux"
73 then snapshotHashLinux64
74 else if stdenv.system == "i686-darwin"
75 then snapshotHashDarwin686
76 else if stdenv.system == "x86_64-darwin"
77 then snapshotHashDarwin64
78 else abort "no snapshot for platform ${stdenv.system}";
79 snapshotName = "rust-stage0-${snapshotDate}-${snapshotRev}-${platform}-${snapshotHash}.tar.bz2";
80in
81
82stdenv.mkDerivation {
83 inherit name;
84 inherit version;
85 inherit meta;
86
87 __impureHostDeps = [ "/usr/lib/libedit.3.dylib" ];
88
89 src = if isRelease then
90 fetchzip {
91 url = "http://static.rust-lang.org/dist/rustc-${version}-src.tar.gz";
92 sha256 = srcSha;
93 }
94 else
95 fetchgit {
96 url = https://github.com/rust-lang/rust;
97 rev = srcRev;
98 sha256 = srcSha;
99 };
100
101 # We need rust to build rust. If we don't provide it, configure will try to download it.
102 snapshot = stdenv.mkDerivation {
103 name = "rust-stage0";
104 src = fetchurl {
105 url = "http://static.rust-lang.org/stage0-snapshots/${snapshotName}";
106 sha1 = snapshotHash;
107 };
108 dontStrip = true;
109 installPhase = ''
110 mkdir -p "$out"
111 cp -r bin "$out/bin"
112 '' + stdenv.lib.optionalString stdenv.isLinux ''
113 patchelf --interpreter "${stdenv.glibc}/lib/${stdenv.cc.dynamicLinker}" \
114 --set-rpath "${stdenv.cc.cc}/lib/:${stdenv.cc.cc}/lib64/" \
115 "$out/bin/rustc"
116 '';
117 };
118
119 configureFlags = configureFlags
120 ++ [ "--enable-local-rust" "--local-rust-root=$snapshot" "--enable-rpath" ]
121 # TODO always include starting from 1.3.0, superseeding patch and substituteInPlace below
122 ++ stdenv.lib.optional (!isRelease) [ "--default-linker=${stdenv.cc}/bin/cc" "--default-ar=${stdenv.cc.binutils}/bin/ar" ]
123 ++ stdenv.lib.optional (stdenv.cc.cc ? isClang) "--enable-clang";
124
125 inherit patches;
126
127 postPatch = ''
128 substituteInPlace src/rust-installer/gen-install-script.sh \
129 --replace /bin/echo "${coreutils}/bin/echo"
130 substituteInPlace src/rust-installer/gen-installer.sh \
131 --replace /bin/echo "${coreutils}/bin/echo"
132
133 # Workaround for NixOS/nixpkgs#8676
134 substituteInPlace mk/rustllvm.mk \
135 --replace "\$\$(subst /,//," "\$\$(subst /,/,"
136 '' + stdenv.lib.optionalString (isRelease) ''
137 substituteInPlace src/librustc_back/target/mod.rs \
138 --subst-var-by "ccPath" "${stdenv.cc}/bin/cc" \
139 --subst-var-by "arPath" "${stdenv.cc.binutils}/bin/ar"
140 ''; # TODO remove in 1.3.0, superseeded by configure flags
141
142 buildInputs = [ which file perl curl python27 makeWrapper git ]
143 ++ stdenv.lib.optionals (!stdenv.isDarwin) [ procps valgrind ];
144
145 enableParallelBuilding = true;
146
147 outputs = [ "out" "doc" ];
148
149 preCheck = "export TZDIR=${tzdata}/share/zoneinfo";
150
151 doCheck = true;
152}