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 targetPlatformsWithHostTools = [
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 "powerpc-linux"
93 "powerpc64-linux"
94 "powerpc64le-linux"
95 "riscv64-linux"
96 "s390x-linux"
97 "x86_64-linux"
98 "aarch64-netbsd"
99 "armv7l-netbsd"
100 "i686-netbsd"
101 "powerpc-netbsd"
102 "x86_64-netbsd"
103 "i686-openbsd"
104 "x86_64-openbsd"
105 "i686-windows"
106 "x86_64-windows"
107 ];
108 targetPlatforms = targetPlatformsWithHostTools ++ [
109 # Platforms without host tools from
110 # https://doc.rust-lang.org/nightly/rustc/platform-support.html
111 "armv5tel-linux"
112 "armv7a-linux"
113 "m68k-linux"
114 "mips-linux"
115 "mips64-linux"
116 "mipsel-linux"
117 "mips64el-linux"
118 "riscv32-linux"
119 "armv6l-netbsd"
120 "mipsel-netbsd"
121 "riscv64-netbsd"
122 "x86_64-redox"
123 "wasm32-wasi"
124 ];
125 badTargetPlatforms = [
126 # Rust is currently unable to target the n32 ABI
127 lib.systems.inspect.patterns.isMips64n32
128 ];
129 };
130 };
131
132 rustc = wrapRustc rustc-unwrapped;
133
134 cargo = stdenv.mkDerivation {
135 pname = "cargo-${versionType}";
136
137 inherit version;
138 inherit src;
139
140 meta = with lib; {
141 homepage = "https://doc.rust-lang.org/cargo/";
142 sourceProvenance = with sourceTypes; [ binaryNativeCode ];
143 description = "Rust package manager";
144 maintainers = with maintainers; [ qknight ];
145 license = [
146 licenses.mit
147 licenses.asl20
148 ];
149 };
150
151 nativeBuildInputs = [
152 makeWrapper
153 ]
154 ++ lib.optional (!stdenv.hostPlatform.isDarwin) autoPatchelfHook;
155 buildInputs = [
156 bash
157 ]
158 ++ lib.optional (!stdenv.hostPlatform.isDarwin && !stdenv.hostPlatform.isFreeBSD) gcc.cc.lib;
159
160 postPatch = ''
161 patchShebangs .
162 '';
163
164 installPhase = ''
165 patchShebangs ./install.sh
166 ./install.sh --prefix=$out \
167 --components=cargo
168 ''
169 + lib.optionalString stdenv.hostPlatform.isDarwin ''
170 install_name_tool -change "/usr/lib/libcurl.4.dylib" \
171 "${lib.getLib curl}/lib/libcurl.4.dylib" "$out/bin/cargo"
172 ''
173 + ''
174 wrapProgram "$out/bin/cargo" \
175 --suffix PATH : "${rustc}/bin"
176 '';
177 };
178}