1{ lib, stdenv
2, fetchurl
3, mrustc
4, mrustc-minicargo
5, llvm_12
6, llvmPackages_12
7, libffi
8, cmake
9, python3
10, zlib
11, libxml2
12, openssl
13, pkg-config
14, curl
15, which
16, time
17}:
18
19let
20 mrustcTargetVersion = "1.54";
21 rustcVersion = "1.54.0";
22 rustcSrc = fetchurl {
23 url = "https://static.rust-lang.org/dist/rustc-${rustcVersion}-src.tar.gz";
24 sha256 = "0xk9dhfff16caambmwij67zgshd8v9djw6ha0fnnanlv7rii31dc";
25 };
26 rustcDir = "rustc-${rustcVersion}-src";
27 outputDir = "output-${rustcVersion}";
28in
29
30stdenv.mkDerivation rec {
31 pname = "mrustc-bootstrap";
32 version = "${mrustc.version}_${rustcVersion}";
33
34 inherit (mrustc) src;
35 postUnpack = "tar -xf ${rustcSrc} -C source/";
36
37 # the rust build system complains that nix alters the checksums
38 dontFixLibtool = true;
39
40 patches = [
41 ./patches/0001-dont-download-rustc.patch
42 ];
43
44 postPatch = ''
45 echo "applying patch ./rustc-${rustcVersion}-src.patch"
46 patch -p0 -d ${rustcDir}/ < rustc-${rustcVersion}-src.patch
47 '';
48
49 # rustc unfortunately needs cmake to compile llvm-rt but doesn't
50 # use it for the normal build. This disables cmake in Nix.
51 dontUseCmakeConfigure = true;
52
53 strictDeps = true;
54 nativeBuildInputs = [
55 cmake
56 mrustc
57 mrustc-minicargo
58 pkg-config
59 python3
60 time
61 which
62 ];
63 buildInputs = [
64 # for rustc
65 llvm_12 libffi zlib libxml2
66 # for cargo
67 openssl
68 (curl.override { inherit openssl; })
69 ];
70
71 makeFlags = [
72 # Use shared mrustc/minicargo/llvm instead of rebuilding them
73 "MRUSTC=${mrustc}/bin/mrustc"
74 #"MINICARGO=${mrustc-minicargo}/bin/minicargo" # FIXME: we need to rebuild minicargo locally so --manifest-overrides is applied
75 "LLVM_CONFIG=${llvm_12.dev}/bin/llvm-config"
76 "RUSTC_TARGET=${stdenv.targetPlatform.rust.rustcTarget}"
77 ];
78
79 buildPhase = ''
80 runHook preBuild
81
82 local flagsArray=(
83 PARLEVEL=$NIX_BUILD_CORES
84 ${toString makeFlags}
85 )
86
87 touch ${rustcDir}/dl-version
88 export OUTDIR_SUF=-${rustcVersion}
89 export RUSTC_VERSION=${rustcVersion}
90 export MRUSTC_TARGET_VER=${mrustcTargetVersion}
91 export MRUSTC_PATH=${mrustc}/bin/mrustc
92
93 echo minicargo.mk: libs
94 make -f minicargo.mk "''${flagsArray[@]}" LIBS
95
96 echo test
97 make "''${flagsArray[@]}" test
98
99 # disabled because it expects ./bin/mrustc
100 #echo local_tests
101 #make "''${flagsArray[@]}" local_tests
102
103 echo minicargo.mk: rustc
104 make -f minicargo.mk "''${flagsArray[@]}" ${outputDir}/rustc
105
106 echo minicargo.mk: cargo
107 make -f minicargo.mk "''${flagsArray[@]}" ${outputDir}/cargo
108
109 echo run_rustc
110 make -C run_rustc "''${flagsArray[@]}"
111
112 unset flagsArray
113
114 runHook postBuild
115 '';
116
117 doCheck = true;
118 checkPhase = ''
119 runHook preCheck
120 run_rustc/${outputDir}/prefix/bin/hello_world | grep "hello, world"
121 runHook postCheck
122 '';
123
124 installPhase = ''
125 runHook preInstall
126 mkdir -p $out/bin/ $out/lib/
127 cp run_rustc/${outputDir}/prefix/bin/cargo $out/bin/cargo
128 cp run_rustc/${outputDir}/prefix/bin/rustc_binary $out/bin/rustc
129
130 cp -r run_rustc/${outputDir}/prefix/lib/* $out/lib/
131 cp $out/lib/rustlib/${stdenv.targetPlatform.rust.rustcTarget}/lib/*.so $out/lib/
132 runHook postInstall
133 '';
134
135 meta = with lib; {
136 inherit (src.meta) homepage;
137 description = "A minimal build of Rust";
138 longDescription = ''
139 A minimal build of Rust, built from source using mrustc.
140 This is useful for bootstrapping the main Rust compiler without
141 an initial binary toolchain download.
142 '';
143 maintainers = with maintainers; [ progval r-burns ];
144 license = with licenses; [ mit asl20 ];
145 platforms = [ "x86_64-linux" ];
146 };
147}