Skip to content

Commit 3def540

Browse files
authored
kernel-builder: add variants support (#420)
* kernel-builder: add variants support `list-variants` now lists all supported build variants of a kernel. The `devshell`, `testshell`, and `build` commands now accept the `--variant` option to select a different variant than the default. * kernel-builder: fix `build` subcommand * Better naming
1 parent 694f4c1 commit 3def540

5 files changed

Lines changed: 256 additions & 35 deletions

File tree

kernel-builder/src/build.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ use std::path::PathBuf;
22

33
use eyre::Result;
44

5+
use crate::list_variants::variants;
56
use crate::nix::{Flake, Nix, NixSubcommand};
67
use crate::pyproject::write_card;
78
use crate::util::{check_or_infer_kernel_dir, parse_build};
89

9-
pub fn run_build(
10+
fn prepare_build(
1011
kernel_dir: Option<PathBuf>,
1112
max_jobs: Option<u32>,
1213
cores: Option<u32>,
1314
print_build_logs: bool,
14-
target: &str,
15-
) -> Result<()> {
15+
variant: Option<String>,
16+
) -> Result<(Flake, Option<String>, Nix)> {
1617
let kernel_dir = check_or_infer_kernel_dir(kernel_dir)?;
1718

1819
if let Ok(build) = parse_build(&kernel_dir) {
@@ -23,6 +24,16 @@ pub fn run_build(
2324

2425
let flake = Flake::from_path(kernel_dir)?;
2526

27+
if let Some(ref variant) = variant {
28+
let valid_variants = variants(&flake)?;
29+
if !valid_variants.contains(variant) {
30+
eyre::bail!(
31+
"Unknown variant `{variant}`.\nValid variants are: {}",
32+
valid_variants.join(", ")
33+
);
34+
}
35+
}
36+
2637
let mut nix = Nix::new();
2738
if let Some(jobs) = max_jobs {
2839
nix = nix.max_jobs(jobs);
@@ -32,8 +43,35 @@ pub fn run_build(
3243
}
3344
nix = nix.print_build_logs(print_build_logs);
3445

46+
Ok((flake, variant, nix))
47+
}
48+
49+
pub fn run_build(
50+
kernel_dir: Option<PathBuf>,
51+
max_jobs: Option<u32>,
52+
cores: Option<u32>,
53+
print_build_logs: bool,
54+
variant: Option<String>,
55+
) -> Result<()> {
56+
let (flake, variant, nix) =
57+
prepare_build(kernel_dir, max_jobs, cores, print_build_logs, variant)?;
58+
59+
nix.run(NixSubcommand::Build {
60+
flake: &flake,
61+
attribute: variant.map(|v| format!("redistributable.{v}")),
62+
})
63+
}
64+
65+
pub fn run_build_and_copy(
66+
kernel_dir: Option<PathBuf>,
67+
max_jobs: Option<u32>,
68+
cores: Option<u32>,
69+
print_build_logs: bool,
70+
) -> Result<()> {
71+
let (flake, _, nix) = prepare_build(kernel_dir, max_jobs, cores, print_build_logs, None)?;
72+
3573
nix.run(NixSubcommand::Run {
36-
flake,
37-
attribute: Some(target.to_owned()),
74+
flake: &flake,
75+
attribute: Some("build-and-copy".to_owned()),
3876
})
3977
}

kernel-builder/src/develop.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,44 @@ use std::path::PathBuf;
44

55
use eyre::Result;
66

7+
use crate::list_variants::arch_variants;
78
use crate::nix::{Flake, Nix, NixSubcommand};
89
use crate::util::check_or_infer_kernel_dir;
910

11+
/// Validate a variant against the arch variants list.
12+
fn validate_arch_variant(flake: &Flake, variant: &str) -> Result<()> {
13+
let valid_variants = arch_variants(flake)?;
14+
if !valid_variants.contains(&variant.to_string()) {
15+
eyre::bail!(
16+
"Unknown variant `{variant}`.\nValid variants for this architecture are: {}",
17+
valid_variants.join(", ")
18+
);
19+
}
20+
Ok(())
21+
}
22+
1023
/// Run a Nix development shell.
1124
fn run_develop(
1225
kernel_dir: Option<PathBuf>,
1326
max_jobs: Option<u32>,
1427
cores: Option<u32>,
1528
print_build_logs: bool,
16-
attribute: Option<String>,
29+
variant: Option<String>,
30+
shell_prefix: &str,
31+
default_attribute: Option<String>,
1732
) -> Result<()> {
1833
let kernel_dir = check_or_infer_kernel_dir(kernel_dir)?;
1934
let flake = Flake::from_path(kernel_dir)?;
2035

36+
if let Some(ref variant) = variant {
37+
validate_arch_variant(&flake, variant)?;
38+
}
39+
40+
let attribute = match variant {
41+
Some(ref v) => Some(format!("{shell_prefix}.{v}")),
42+
None => default_attribute,
43+
};
44+
2145
let mut nix = Nix::new();
2246

2347
if let Some(max_jobs) = max_jobs {
@@ -30,7 +54,10 @@ fn run_develop(
3054

3155
nix = nix.print_build_logs(print_build_logs);
3256

33-
nix.run(NixSubcommand::Develop { flake, attribute })
57+
nix.run(NixSubcommand::Develop {
58+
flake: &flake,
59+
attribute,
60+
})
3461
}
3562

3663
/// Run a kernel development shell.
@@ -39,8 +66,17 @@ pub fn devshell(
3966
max_jobs: Option<u32>,
4067
cores: Option<u32>,
4168
print_build_logs: bool,
69+
variant: Option<String>,
4270
) -> Result<()> {
43-
run_develop(kernel_dir, max_jobs, cores, print_build_logs, None)
71+
run_develop(
72+
kernel_dir,
73+
max_jobs,
74+
cores,
75+
print_build_logs,
76+
variant,
77+
"devShells",
78+
None,
79+
)
4480
}
4581

4682
/// Run a kernel test shell.
@@ -49,12 +85,15 @@ pub fn testshell(
4985
max_jobs: Option<u32>,
5086
cores: Option<u32>,
5187
print_build_logs: bool,
88+
variant: Option<String>,
5289
) -> Result<()> {
5390
run_develop(
5491
kernel_dir,
5592
max_jobs,
5693
cores,
5794
print_build_logs,
95+
variant,
96+
"testShells",
5897
Some("test".to_string()),
5998
)
6099
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use std::path::PathBuf;
2+
3+
use eyre::Result;
4+
5+
use crate::nix::{Flake, Nix, NixSubcommand};
6+
use crate::util::check_or_infer_kernel_dir;
7+
8+
/// Get the list of variants for a flake.
9+
pub fn variants(flake: &Flake) -> Result<Vec<String>> {
10+
let nix = Nix::new().json(true);
11+
let output = nix.run_capture_stdout(NixSubcommand::Eval {
12+
flake,
13+
attribute: "variants".to_string(),
14+
})?;
15+
16+
let variants: Vec<String> = serde_json::from_slice(&output)?;
17+
18+
Ok(variants)
19+
}
20+
21+
/// Get the list of architecture-specific variants for a flake.
22+
pub fn arch_variants(flake: &Flake) -> Result<Vec<String>> {
23+
let nix = Nix::new().json(true);
24+
let output = nix.run_capture_stdout(NixSubcommand::Eval {
25+
flake,
26+
attribute: "archVariants".to_string(),
27+
})?;
28+
29+
let variants: Vec<String> = serde_json::from_slice(&output)?;
30+
31+
Ok(variants)
32+
}
33+
34+
pub fn list_variants(kernel_dir: Option<PathBuf>, arch: bool) -> Result<()> {
35+
let kernel_dir = check_or_infer_kernel_dir(kernel_dir)?;
36+
let flake = Flake::from_path(kernel_dir)?;
37+
38+
let variant_list = if arch {
39+
arch_variants(&flake)?
40+
} else {
41+
variants(&flake)?
42+
};
43+
44+
for variant in &variant_list {
45+
println!("{}", variant);
46+
}
47+
48+
Ok(())
49+
}

kernel-builder/src/main.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ mod develop;
1313
use develop::{devshell, testshell};
1414

1515
mod build;
16-
use build::run_build;
16+
use build::{run_build, run_build_and_copy};
1717

1818
mod hf;
1919

2020
mod init;
2121
use init::{run_init, InitArgs};
2222

23+
mod list_variants;
24+
use list_variants::list_variants;
25+
2326
mod upload;
2427
use upload::{run_upload, RepoTypeArg, UploadArgs};
2528

@@ -69,6 +72,10 @@ enum Commands {
6972
#[arg(value_name = "KERNEL_DIR")]
7073
kernel_dir: Option<PathBuf>,
7174

75+
/// Build a specific variant.
76+
#[arg(long)]
77+
variant: Option<String>,
78+
7279
#[command(flatten)]
7380
nix_args: NixArgs,
7481
},
@@ -89,6 +96,10 @@ enum Commands {
8996
#[arg(value_name = "KERNEL_DIR")]
9097
kernel_dir: Option<PathBuf>,
9198

99+
/// Build a specific variant.
100+
#[arg(long)]
101+
variant: Option<String>,
102+
92103
#[command(flatten)]
93104
nix_args: NixArgs,
94105

@@ -137,15 +148,33 @@ enum Commands {
137148
#[arg(name = "KERNEL_DIR")]
138149
kernel_dir: Option<PathBuf>,
139150

151+
/// Use a specific variant.
152+
#[arg(long)]
153+
variant: Option<String>,
154+
140155
#[command(flatten)]
141156
nix_args: NixArgs,
142157
},
143158

159+
/// List build variants.
160+
ListVariants {
161+
#[arg(name = "KERNEL_DIR")]
162+
kernel_dir: Option<PathBuf>,
163+
164+
/// Only list variants for the current architecture.
165+
#[arg(long)]
166+
arch: bool,
167+
},
168+
144169
/// Spawn a kernel test shell.
145170
Testshell {
146171
#[arg(name = "KERNEL_DIR")]
147172
kernel_dir: Option<PathBuf>,
148173

174+
/// Use a specific variant.
175+
#[arg(long)]
176+
variant: Option<String>,
177+
149178
#[command(flatten)]
150179
nix_args: NixArgs,
151180
},
@@ -197,26 +226,28 @@ fn main() -> Result<()> {
197226
Commands::Upload(args) => run_upload(args),
198227
Commands::Build {
199228
kernel_dir,
229+
variant,
200230
nix_args,
201231
} => run_build(
202232
kernel_dir,
203233
nix_args.max_jobs,
204234
nix_args.cores,
205235
nix_args.print_build_logs,
206-
"build",
236+
variant,
207237
),
208238
Commands::BuildAndCopy {
209239
kernel_dir,
210240
nix_args,
211-
} => run_build(
241+
..
242+
} => run_build_and_copy(
212243
kernel_dir,
213244
nix_args.max_jobs,
214245
nix_args.cores,
215246
nix_args.print_build_logs,
216-
"build-and-copy",
217247
),
218248
Commands::BuildAndUpload {
219249
kernel_dir,
250+
variant,
220251
nix_args,
221252
repo_id,
222253
branch,
@@ -228,7 +259,7 @@ fn main() -> Result<()> {
228259
nix_args.max_jobs,
229260
nix_args.cores,
230261
nix_args.print_build_logs,
231-
"build",
262+
variant,
232263
)?;
233264
run_upload(UploadArgs {
234265
kernel_dir,
@@ -246,21 +277,26 @@ fn main() -> Result<()> {
246277
} => create_pyproject(kernel_dir, target_dir, force, ops_id),
247278
Commands::Devshell {
248279
kernel_dir,
280+
variant,
249281
nix_args,
250282
} => devshell(
251283
kernel_dir,
252284
nix_args.max_jobs,
253285
nix_args.cores,
254286
nix_args.print_build_logs,
287+
variant,
255288
),
289+
Commands::ListVariants { kernel_dir, arch } => list_variants(kernel_dir, arch),
256290
Commands::Testshell {
257291
kernel_dir,
292+
variant,
258293
nix_args,
259294
} => testshell(
260295
kernel_dir,
261296
nix_args.max_jobs,
262297
nix_args.cores,
263298
nix_args.print_build_logs,
299+
variant,
264300
),
265301
Commands::UpdateBuild { kernel_dir } => update_build(kernel_dir),
266302
Commands::Validate { kernel_dir } => {

0 commit comments

Comments
 (0)