1{
2 lib,
3 importCargoLock,
4 fetchCargoVendor,
5 stdenv,
6 cargoBuildHook,
7 cargoCheckHook,
8 cargoInstallHook,
9 cargoNextestHook,
10 cargoSetupHook,
11 cargo,
12 cargo-auditable,
13 buildPackages,
14 rustc,
15 windows,
16}:
17
18lib.extendMkDerivation {
19 constructDrv = stdenv.mkDerivation;
20
21 excludeDrvArgNames = [
22 "depsExtraArgs"
23 "cargoUpdateHook"
24 "cargoLock"
25 "useFetchCargoVendor"
26 ];
27
28 extendDrvArgs =
29 finalAttrs:
30 {
31 name ? "${args.pname}-${args.version}",
32
33 # Name for the vendored dependencies tarball
34 cargoDepsName ? name,
35
36 src ? null,
37 srcs ? null,
38 preUnpack ? null,
39 unpackPhase ? null,
40 postUnpack ? null,
41 cargoPatches ? [ ],
42 patches ? [ ],
43 sourceRoot ? null,
44 cargoRoot ? null,
45 logLevel ? "",
46 buildInputs ? [ ],
47 nativeBuildInputs ? [ ],
48 cargoUpdateHook ? "",
49 cargoDepsHook ? "",
50 buildType ? "release",
51 meta ? { },
52 useFetchCargoVendor ? true,
53 cargoDeps ? null,
54 cargoLock ? null,
55 cargoVendorDir ? null,
56 checkType ? buildType,
57 buildNoDefaultFeatures ? false,
58 checkNoDefaultFeatures ? buildNoDefaultFeatures,
59 buildFeatures ? [ ],
60 checkFeatures ? buildFeatures,
61 useNextest ? false,
62 auditable ? !cargo-auditable.meta.broken,
63
64 depsExtraArgs ? { },
65
66 # Needed to `pushd`/`popd` into a subdir of a tarball if this subdir
67 # contains a Cargo.toml, but isn't part of a workspace (which is e.g. the
68 # case for `rustfmt`/etc from the `rust-sources).
69 # Otherwise, everything from the tarball would've been built/tested.
70 buildAndTestSubdir ? null,
71 ...
72 }@args:
73
74 assert lib.assertMsg useFetchCargoVendor
75 "buildRustPackage: `useFetchCargoVendor` is non‐optional and enabled by default as of 25.05, remove it";
76
77 assert lib.warnIf (args ? useFetchCargoVendor)
78 "buildRustPackage: `useFetchCargoVendor` is non‐optional and enabled by default as of 25.05, remove it"
79 true;
80
81 lib.optionalAttrs (stdenv.hostPlatform.isDarwin && buildType == "debug") {
82 RUSTFLAGS = "-C split-debuginfo=packed " + (args.RUSTFLAGS or "");
83 }
84 // {
85 cargoDeps =
86 if cargoVendorDir != null then
87 null
88 else if cargoDeps != null then
89 cargoDeps
90 else if cargoLock != null then
91 importCargoLock cargoLock
92 else if args.cargoHash or null == null then
93 throw "cargoHash, cargoVendorDir, cargoDeps, or cargoLock must be set"
94 else
95 fetchCargoVendor (
96 {
97 inherit
98 src
99 srcs
100 sourceRoot
101 cargoRoot
102 preUnpack
103 unpackPhase
104 postUnpack
105 ;
106 name = cargoDepsName;
107 patches = cargoPatches;
108 hash = args.cargoHash;
109 }
110 // depsExtraArgs
111 );
112 inherit buildAndTestSubdir;
113
114 cargoBuildType = buildType;
115
116 cargoCheckType = checkType;
117
118 cargoBuildNoDefaultFeatures = buildNoDefaultFeatures;
119
120 cargoCheckNoDefaultFeatures = checkNoDefaultFeatures;
121
122 cargoBuildFeatures = buildFeatures;
123
124 cargoCheckFeatures = checkFeatures;
125
126 nativeBuildInputs =
127 nativeBuildInputs
128 ++ lib.optionals auditable [
129 (buildPackages.cargo-auditable-cargo-wrapper.override {
130 inherit cargo cargo-auditable;
131 })
132 ]
133 ++ [
134 cargoBuildHook
135 (if useNextest then cargoNextestHook else cargoCheckHook)
136 cargoInstallHook
137 cargoSetupHook
138 rustc
139 cargo
140 ];
141
142 buildInputs = buildInputs ++ lib.optionals stdenv.hostPlatform.isMinGW [ windows.pthreads ];
143
144 patches = cargoPatches ++ patches;
145
146 PKG_CONFIG_ALLOW_CROSS = if stdenv.buildPlatform != stdenv.hostPlatform then 1 else 0;
147
148 postUnpack = ''
149 eval "$cargoDepsHook"
150
151 export RUST_LOG=${logLevel}
152 ''
153 + (args.postUnpack or "");
154
155 configurePhase =
156 args.configurePhase or ''
157 runHook preConfigure
158 runHook postConfigure
159 '';
160
161 doCheck = args.doCheck or true;
162
163 strictDeps = true;
164
165 meta = meta // {
166 badPlatforms = meta.badPlatforms or [ ] ++ rustc.badTargetPlatforms;
167 # default to Rust's platforms
168 platforms = lib.intersectLists meta.platforms or lib.platforms.all rustc.targetPlatforms;
169 };
170 };
171}