1{
2 lib,
3 stdenv,
4 makeWrapper,
5 wrapRustc,
6 bash,
7 curl,
8 zlib,
9 autoPatchelfHook,
10 gcc,
11 version,
12 src,
13 platform,
14 versionType,
15}:
16
17let
18 inherit (lib) optionalString;
19
20 bootstrapping = versionType == "bootstrap";
21
22 installComponents = "rustc,rust-std-${platform}" + (optionalString bootstrapping ",cargo");
23in
24
25rec {
26 rustc-unwrapped = stdenv.mkDerivation {
27 pname = "rustc-${versionType}";
28
29 inherit version;
30 inherit src;
31
32 meta = with lib; {
33 homepage = "https://www.rust-lang.org/";
34 sourceProvenance = with sourceTypes; [ binaryNativeCode ];
35 description = "Safe, concurrent, practical language";
36 mainProgram = "rustc";
37 maintainers = with maintainers; [ qknight ];
38 license = [
39 licenses.mit
40 licenses.asl20
41 ];
42 };
43
44 nativeBuildInputs = lib.optional (!stdenv.hostPlatform.isDarwin) autoPatchelfHook;
45 buildInputs = [
46 bash
47 ]
48 ++ lib.optional (!stdenv.hostPlatform.isDarwin && !stdenv.hostPlatform.isFreeBSD) gcc.cc.lib
49 ++ lib.optional (!stdenv.hostPlatform.isDarwin) zlib;
50
51 postPatch = ''
52 patchShebangs .
53 '';
54
55 installPhase = ''
56 ./install.sh --prefix=$out \
57 --components=${installComponents}
58
59 # Do NOT, I repeat, DO NOT use `wrapProgram` on $out/bin/rustc
60 # (or similar) here. It causes strange effects where rustc loads
61 # the wrong libraries in a bootstrap-build causing failures that
62 # are very hard to track down. For details, see
63 # https://github.com/rust-lang/rust/issues/34722#issuecomment-232164943
64 ''
65 + lib.optionalString stdenv.hostPlatform.isDarwin ''
66 install_name_tool -change "/usr/lib/libcurl.4.dylib" \
67 "${lib.getLib curl}/lib/libcurl.4.dylib" "$out/bin/cargo"
68 '';
69
70 # The strip tool in cctools 973.0.1 and up appears to break rlibs in the
71 # binaries. The lib.rmeta object inside the ar archive should contain an
72 # .rmeta section, but it is removed. Luckily, this doesn't appear to be an
73 # issue for Rust builds produced by Nix.
74 dontStrip = true;
75
76 setupHooks = ./setup-hook.sh;
77
78 passthru = rec {
79 tier1TargetPlatforms = [
80 # Platforms with host tools from
81 # https://doc.rust-lang.org/nightly/rustc/platform-support.html
82 "x86_64-darwin"
83 "aarch64-darwin"
84 "i686-freebsd"
85 "x86_64-freebsd"
86 "x86_64-solaris"
87 "aarch64-linux"
88 "armv6l-linux"
89 "armv7l-linux"
90 "i686-linux"
91 "loongarch64-linux"
92 "powerpc64-linux"
93 "powerpc64le-linux"
94 "riscv64-linux"
95 "s390x-linux"
96 "x86_64-linux"
97 "aarch64-netbsd"
98 "armv7l-netbsd"
99 "i686-netbsd"
100 "powerpc-netbsd"
101 "x86_64-netbsd"
102 "i686-openbsd"
103 "x86_64-openbsd"
104 "i686-windows"
105 "x86_64-windows"
106 ];
107 targetPlatforms = tier1TargetPlatforms ++ [
108 # Platforms without host tools from
109 # https://doc.rust-lang.org/nightly/rustc/platform-support.html
110 "armv5tel-linux"
111 "armv7a-linux"
112 "m68k-linux"
113 "mips-linux"
114 "mips64-linux"
115 "mipsel-linux"
116 "mips64el-linux"
117 "riscv32-linux"
118 "armv6l-netbsd"
119 "mipsel-netbsd"
120 "riscv64-netbsd"
121 "x86_64-redox"
122 "wasm32-wasi"
123 ];
124 badTargetPlatforms = [
125 # Rust is currently unable to target the n32 ABI
126 lib.systems.inspect.patterns.isMips64n32
127 ];
128 };
129 };
130
131 rustc = wrapRustc rustc-unwrapped;
132
133 cargo = stdenv.mkDerivation {
134 pname = "cargo-${versionType}";
135
136 inherit version;
137 inherit src;
138
139 meta = with lib; {
140 homepage = "https://doc.rust-lang.org/cargo/";
141 sourceProvenance = with sourceTypes; [ binaryNativeCode ];
142 description = "Rust package manager";
143 maintainers = with maintainers; [ qknight ];
144 license = [
145 licenses.mit
146 licenses.asl20
147 ];
148 };
149
150 nativeBuildInputs = [
151 makeWrapper
152 ]
153 ++ lib.optional (!stdenv.hostPlatform.isDarwin) autoPatchelfHook;
154 buildInputs = [
155 bash
156 ]
157 ++ lib.optional (!stdenv.hostPlatform.isDarwin && !stdenv.hostPlatform.isFreeBSD) gcc.cc.lib;
158
159 postPatch = ''
160 patchShebangs .
161 '';
162
163 installPhase = ''
164 patchShebangs ./install.sh
165 ./install.sh --prefix=$out \
166 --components=cargo
167 ''
168 + lib.optionalString stdenv.hostPlatform.isDarwin ''
169 install_name_tool -change "/usr/lib/libcurl.4.dylib" \
170 "${lib.getLib curl}/lib/libcurl.4.dylib" "$out/bin/cargo"
171 ''
172 + ''
173 wrapProgram "$out/bin/cargo" \
174 --suffix PATH : "${rustc}/bin"
175 '';
176 };
177}