From 655d70a5b999c89e9ce391a849b3d8bf7b0a8e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20de=20Kok?= Date: Sat, 21 Mar 2026 09:21:39 +0000 Subject: [PATCH 1/2] Move `{create,clean}_pyproject` to the pyproject module --- kernel-builder/src/main.rs | 190 ++-------------------------- kernel-builder/src/pyproject/mod.rs | 133 ++++++++++++++++++- kernel-builder/src/util.rs | 66 ++++++++++ 3 files changed, 203 insertions(+), 186 deletions(-) create mode 100644 kernel-builder/src/util.rs diff --git a/kernel-builder/src/main.rs b/kernel-builder/src/main.rs index 08bbea91..69560e71 100644 --- a/kernel-builder/src/main.rs +++ b/kernel-builder/src/main.rs @@ -1,18 +1,19 @@ -use std::{ - fs::{self, File}, - io::{BufWriter, Read, Write}, - path::{Path, PathBuf}, -}; +use std::fs::File; +use std::io::{BufWriter, Write}; +use std::path::PathBuf; use clap::{Parser, Subcommand}; -use eyre::{bail, ensure, Context, Result}; +use eyre::{Context, Result}; mod pyproject; -use pyproject::create_pyproject_file_set; +use pyproject::{clean_pyproject, create_pyproject}; mod config; use config::{v3, Build, BuildCompat}; +mod util; +use util::parse_and_validate; + mod version; #[derive(Parser, Debug)] @@ -104,36 +105,6 @@ fn main() -> Result<()> { } } -fn parse_build(build_toml: impl AsRef) -> Result { - let build_compat = parse_and_validate(build_toml)?; - - if matches!(build_compat, BuildCompat::V1(_) | BuildCompat::V2(_)) { - eprintln!( - "build.toml is in the deprecated V1 or V2 format, use `kernel-builder update-build` to update." - ) - } - - let build: Build = build_compat - .try_into() - .context("Cannot update build configuration")?; - - Ok(build) -} - -fn create_pyproject( - build_toml: PathBuf, - target_dir: Option, - force: bool, - ops_id: Option, -) -> Result<()> { - let target_dir = check_or_infer_target_dir(&build_toml, target_dir)?; - let build = parse_build(&build_toml)?; - let file_set = create_pyproject_file_set(build, &target_dir, ops_id)?; - file_set.write(&target_dir, force)?; - - Ok(()) -} - fn update_build(build_toml: PathBuf) -> Result<()> { let build_compat: BuildCompat = parse_and_validate(&build_toml)?; @@ -157,148 +128,3 @@ fn update_build(build_toml: PathBuf) -> Result<()> { Ok(()) } - -fn check_or_infer_target_dir( - build_toml: impl AsRef, - target_dir: Option, -) -> Result { - let build_toml = build_toml.as_ref(); - match target_dir { - Some(target_dir) => { - ensure!( - target_dir.is_dir(), - "`{}` is not a directory", - target_dir.to_string_lossy() - ); - Ok(target_dir) - } - None => { - let absolute = std::path::absolute(build_toml)?; - match absolute.parent() { - Some(parent) => Ok(parent.to_owned()), - None => bail!( - "Cannot get parent path of `{}`", - build_toml.to_string_lossy() - ), - } - } - } -} - -fn parse_and_validate(build_toml: impl AsRef) -> Result { - let build_toml = build_toml.as_ref(); - let mut toml_data = String::new(); - File::open(build_toml) - .wrap_err_with(|| format!("Cannot open {} for reading", build_toml.to_string_lossy()))? - .read_to_string(&mut toml_data) - .wrap_err_with(|| format!("Cannot read from {}", build_toml.to_string_lossy()))?; - - let build_compat: BuildCompat = toml::from_str(&toml_data) - .wrap_err_with(|| format!("Cannot parse TOML in {}", build_toml.to_string_lossy()))?; - - Ok(build_compat) -} - -fn clean_pyproject( - build_toml: PathBuf, - target_dir: Option, - dry_run: bool, - force: bool, - ops_id: Option, -) -> Result<()> { - let target_dir = check_or_infer_target_dir(&build_toml, target_dir)?; - - let build = parse_build(&build_toml)?; - let generated_files = - create_pyproject_file_set(build, target_dir.clone(), ops_id)?.into_names(); - - if generated_files.is_empty() { - eprintln!("No generated artifacts found to clean."); - return Ok(()); - } - - if dry_run { - println!("Files that would be deleted:"); - for file in &generated_files { - if file.exists() { - println!(" {}", file.to_string_lossy()); - } - } - return Ok(()); - } - - let existing_files: Vec<_> = generated_files.iter().filter(|f| f.exists()).collect(); - - if existing_files.is_empty() { - eprintln!("No generated artifacts found to clean."); - return Ok(()); - } - - if !force { - println!("Files to be deleted:"); - for file in &existing_files { - println!(" {}", file.to_string_lossy()); - } - print!("Continue? [y/N] "); - std::io::stdout().flush()?; - - let mut response = String::new(); - std::io::stdin().read_line(&mut response)?; - let response = response.trim().to_lowercase(); - - if response != "y" && response != "yes" { - eprintln!("Aborted."); - return Ok(()); - } - } - - let mut deleted_count = 0; - let mut errors = Vec::new(); - - for file in existing_files { - match fs::remove_file(file) { - Ok(_) => { - deleted_count += 1; - println!("Deleted: {}", file.to_string_lossy()); - } - Err(e) => { - errors.push(format!( - "Failed to delete {}: {}", - file.to_string_lossy(), - e - )); - } - } - } - - // Clean up empty directories - let dirs_to_check = [target_dir.join("cmake")]; - - for dir in dirs_to_check { - if dir.exists() && is_empty_dir(&dir)? { - match fs::remove_dir(&dir) { - Ok(_) => println!("Removed empty directory: {}", dir.to_string_lossy()), - Err(e) => eyre::bail!("Failed to remove directory `{}`: {e:?}", dir.display()), - } - } - } - - if !errors.is_empty() { - for error in errors { - eprintln!("Error: {error}"); - } - bail!("Some files could not be deleted"); - } - - println!("Cleaned {deleted_count} generated artifacts."); - Ok(()) -} - -fn is_empty_dir(dir: &Path) -> Result { - if !dir.is_dir() { - return Ok(false); - } - - let mut entries = fs::read_dir(dir)?; - Ok(entries.next().is_none()) -} diff --git a/kernel-builder/src/pyproject/mod.rs b/kernel-builder/src/pyproject/mod.rs index 5537d4c1..b12ffa16 100644 --- a/kernel-builder/src/pyproject/mod.rs +++ b/kernel-builder/src/pyproject/mod.rs @@ -1,8 +1,15 @@ -use std::path::Path; +use std::{ + fs, + io::Write, + path::{Path, PathBuf}, +}; -use eyre::Result; +use eyre::{bail, Result}; use minijinja::Environment; +use crate::config::{Build, Framework}; +use crate::util::{check_or_infer_target_dir, parse_build}; + pub(crate) mod common; pub mod deps; pub mod fileset; @@ -15,7 +22,7 @@ mod tvm_ffi; pub use fileset::FileSet; pub fn create_pyproject_file_set( - build: crate::config::Build, + build: Build, target_dir: impl AsRef, ops_id: Option, ) -> Result { @@ -23,7 +30,7 @@ pub fn create_pyproject_file_set( env.set_trim_blocks(true); minijinja_embed::load_templates!(&mut env); - let file_set = if matches!(build.framework, crate::config::Framework::TvmFfi(_)) { + let file_set = if matches!(build.framework, Framework::TvmFfi(_)) { tvm_ffi::write_tvm_ffi_ext(&env, &build, target_dir, ops_id)? } else if build.is_noarch() { torch::write_torch_ext_noarch(&env, &build, target_dir, ops_id)? @@ -33,3 +40,121 @@ pub fn create_pyproject_file_set( Ok(file_set) } + +pub fn create_pyproject( + build_toml: PathBuf, + target_dir: Option, + force: bool, + ops_id: Option, +) -> Result<()> { + let target_dir = check_or_infer_target_dir(&build_toml, target_dir)?; + let build = parse_build(&build_toml)?; + let file_set = create_pyproject_file_set(build, &target_dir, ops_id)?; + file_set.write(&target_dir, force)?; + + Ok(()) +} + +pub fn clean_pyproject( + build_toml: PathBuf, + target_dir: Option, + dry_run: bool, + force: bool, + ops_id: Option, +) -> Result<()> { + let target_dir = check_or_infer_target_dir(&build_toml, target_dir)?; + + let build = parse_build(&build_toml)?; + let generated_files = + create_pyproject_file_set(build, target_dir.clone(), ops_id)?.into_names(); + + if generated_files.is_empty() { + eprintln!("No generated artifacts found to clean."); + return Ok(()); + } + + if dry_run { + println!("Files that would be deleted:"); + for file in &generated_files { + if file.exists() { + println!(" {}", file.to_string_lossy()); + } + } + return Ok(()); + } + + let existing_files: Vec<_> = generated_files.iter().filter(|f| f.exists()).collect(); + + if existing_files.is_empty() { + eprintln!("No generated artifacts found to clean."); + return Ok(()); + } + + if !force { + println!("Files to be deleted:"); + for file in &existing_files { + println!(" {}", file.to_string_lossy()); + } + print!("Continue? [y/N] "); + std::io::stdout().flush()?; + + let mut response = String::new(); + std::io::stdin().read_line(&mut response)?; + let response = response.trim().to_lowercase(); + + if response != "y" && response != "yes" { + eprintln!("Aborted."); + return Ok(()); + } + } + + let mut deleted_count = 0; + let mut errors = Vec::new(); + + for file in existing_files { + match fs::remove_file(file) { + Ok(_) => { + deleted_count += 1; + println!("Deleted: {}", file.to_string_lossy()); + } + Err(e) => { + errors.push(format!( + "Failed to delete {}: {}", + file.to_string_lossy(), + e + )); + } + } + } + + // Clean up empty directories + let dirs_to_check = [target_dir.join("cmake")]; + + for dir in dirs_to_check { + if dir.exists() && is_empty_dir(&dir)? { + match fs::remove_dir(&dir) { + Ok(_) => println!("Removed empty directory: {}", dir.to_string_lossy()), + Err(e) => eyre::bail!("Failed to remove directory `{}`: {e:?}", dir.display()), + } + } + } + + if !errors.is_empty() { + for error in errors { + eprintln!("Error: {error}"); + } + bail!("Some files could not be deleted"); + } + + println!("Cleaned {deleted_count} generated artifacts."); + Ok(()) +} + +fn is_empty_dir(dir: &Path) -> Result { + if !dir.is_dir() { + return Ok(false); + } + + let mut entries = fs::read_dir(dir)?; + Ok(entries.next().is_none()) +} diff --git a/kernel-builder/src/util.rs b/kernel-builder/src/util.rs new file mode 100644 index 00000000..b649dc00 --- /dev/null +++ b/kernel-builder/src/util.rs @@ -0,0 +1,66 @@ +use std::{ + fs::File, + io::Read, + path::{Path, PathBuf}, +}; + +use eyre::{bail, ensure, Context, Result}; + +use crate::config::{Build, BuildCompat}; + +pub(crate) fn parse_build(build_toml: impl AsRef) -> Result { + let build_compat = parse_and_validate(build_toml)?; + + if matches!(build_compat, BuildCompat::V1(_) | BuildCompat::V2(_)) { + eprintln!( + "build.toml is in the deprecated V1 or V2 format, use `kernel-builder update-build` to update." + ) + } + + let build: Build = build_compat + .try_into() + .context("Cannot update build configuration")?; + + Ok(build) +} + +pub(crate) fn check_or_infer_target_dir( + build_toml: impl AsRef, + target_dir: Option, +) -> Result { + let build_toml = build_toml.as_ref(); + match target_dir { + Some(target_dir) => { + ensure!( + target_dir.is_dir(), + "`{}` is not a directory", + target_dir.to_string_lossy() + ); + Ok(target_dir) + } + None => { + let absolute = std::path::absolute(build_toml)?; + match absolute.parent() { + Some(parent) => Ok(parent.to_owned()), + None => bail!( + "Cannot get parent path of `{}`", + build_toml.to_string_lossy() + ), + } + } + } +} + +pub(crate) fn parse_and_validate(build_toml: impl AsRef) -> Result { + let build_toml = build_toml.as_ref(); + let mut toml_data = String::new(); + File::open(build_toml) + .wrap_err_with(|| format!("Cannot open {} for reading", build_toml.to_string_lossy()))? + .read_to_string(&mut toml_data) + .wrap_err_with(|| format!("Cannot read from {}", build_toml.to_string_lossy()))?; + + let build_compat: BuildCompat = toml::from_str(&toml_data) + .wrap_err_with(|| format!("Cannot parse TOML in {}", build_toml.to_string_lossy()))?; + + Ok(build_compat) +} From 553b49570dd9cd2133f3c6e5f15fa7e00e55fc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20de=20Kok?= Date: Sat, 21 Mar 2026 10:06:57 +0000 Subject: [PATCH 2/2] Make all `kernel-builder` subcommands take a directory This change makes all `kernel-builder` subcommands take a directory rather than `build.toml`. The argument also becomes optional, the current directory is used when the argument is left out. This aligns the subcommand with the upcoming `kernel-builder init` subcommand. --- docs/source/builder/local-dev.md | 13 ++++-- docs/source/builder/nix.md | 4 +- kernel-builder/src/main.rs | 44 ++++++++++++--------- kernel-builder/src/pyproject/mod.rs | 19 +++++---- kernel-builder/src/util.rs | 42 +++++++++++--------- nix-builder/lib/extension/torch/arch.nix | 2 +- nix-builder/lib/extension/torch/no-arch.nix | 2 +- nix-builder/lib/extension/tvm-ffi/arch.nix | 2 +- nix-builder/scripts/windows/builder.ps1 | 31 +++++---------- 9 files changed, 87 insertions(+), 72 deletions(-) diff --git a/docs/source/builder/local-dev.md b/docs/source/builder/local-dev.md index 9cd574de..515c7f97 100644 --- a/docs/source/builder/local-dev.md +++ b/docs/source/builder/local-dev.md @@ -25,11 +25,12 @@ $ cargo install hf-kernel-builder ## Generating a Python project with `kernel-builder` -`kernel-builder` generates a CMake/Python project from a [`build.toml`](./writing-kernels.md) -file. The invocation is as follows: +`kernel-builder` can create CMake/Python project files for a kernel with +a [`build.toml`](./writing-kernels.md) file. The `create-pyproject` +command will create the files for the kernel in the current directory: ```bash -$ kernel-builder create-pyproject build.toml -f +$ kernel-builder create-pyproject -f ``` The `-f` flag is optional and instructs `kernel-builder` to overwrite @@ -43,6 +44,12 @@ $ pip install wheel # Needed once to enable bdist_wheel. $ pip install --no-build-isolation -e . ``` +You can also create a Python project for a kernel in another directory: + +```bash +$ kernel-builder create-pyproject -f path/to/kernel +``` + **Warnings:** - Kernels built in this way should **not** be published on the Kernel diff --git a/docs/source/builder/nix.md b/docs/source/builder/nix.md index e2b41e95..89daea01 100644 --- a/docs/source/builder/nix.md +++ b/docs/source/builder/nix.md @@ -62,7 +62,7 @@ project files. For example: ```bash $ nix develop -$ kernel-builder create-pyproject build.toml +$ kernel-builder create-pyproject $ cmake -B build-ext $ cmake --build build-ext ``` @@ -74,7 +74,7 @@ Python package in this virtual environment: ```bash $ nix develop -$ kernel-builder create-pyproject build.toml +$ kernel-builder create-pyproject $ pip install --no-build-isolation -e . ``` diff --git a/kernel-builder/src/main.rs b/kernel-builder/src/main.rs index 69560e71..f1c05fd5 100644 --- a/kernel-builder/src/main.rs +++ b/kernel-builder/src/main.rs @@ -12,7 +12,7 @@ mod config; use config::{v3, Build, BuildCompat}; mod util; -use util::parse_and_validate; +use util::{check_or_infer_kernel_dir, parse_and_validate}; mod version; @@ -27,8 +27,8 @@ struct Cli { enum Commands { /// Generate CMake files for a kernel extension build. CreatePyproject { - #[arg(name = "BUILD_TOML")] - build_toml: PathBuf, + #[arg(name = "KERNEL_DIR")] + kernel_dir: Option, /// The directory to write the generated files to /// (directory of `BUILD_TOML` when absent). @@ -47,20 +47,20 @@ enum Commands { /// Update a `build.toml` to the current format. UpdateBuild { - #[arg(name = "BUILD_TOML")] - build_toml: PathBuf, + #[arg(name = "KERNEL_DIR")] + kernel_dir: Option, }, /// Validate the build.toml file. Validate { - #[arg(name = "BUILD_TOML")] - build_toml: PathBuf, + #[arg(name = "KERNEL_DIR")] + kernel_dir: Option, }, /// Clean generated artifacts. CleanPyproject { - #[arg(name = "BUILD_TOML")] - build_toml: PathBuf, + #[arg(name = "KERNEL_DIR")] + kernel_dir: Option, /// The directory to clean from (directory of `BUILD_TOML` when absent). #[arg(name = "TARGET_DIR")] @@ -85,28 +85,35 @@ fn main() -> Result<()> { let args = Cli::parse(); match args.command { Commands::CreatePyproject { - build_toml, + kernel_dir, force, target_dir, ops_id, - } => create_pyproject(build_toml, target_dir, force, ops_id), - Commands::UpdateBuild { build_toml } => update_build(build_toml), - Commands::Validate { build_toml } => { - parse_and_validate(build_toml)?; + } => create_pyproject(kernel_dir, target_dir, force, ops_id), + Commands::UpdateBuild { kernel_dir } => update_build(kernel_dir), + Commands::Validate { kernel_dir } => { + validate(kernel_dir)?; Ok(()) } Commands::CleanPyproject { - build_toml, + kernel_dir, target_dir, dry_run, force, ops_id, - } => clean_pyproject(build_toml, target_dir, dry_run, force, ops_id), + } => clean_pyproject(kernel_dir, target_dir, dry_run, force, ops_id), } } -fn update_build(build_toml: PathBuf) -> Result<()> { - let build_compat: BuildCompat = parse_and_validate(&build_toml)?; +fn validate(kernel_dir: Option) -> Result<()> { + let kernel_dir = check_or_infer_kernel_dir(kernel_dir)?; + parse_and_validate(kernel_dir)?; + Ok(()) +} + +fn update_build(kernel_dir: Option) -> Result<()> { + let kernel_dir = check_or_infer_kernel_dir(kernel_dir)?; + let build_compat: BuildCompat = parse_and_validate(&kernel_dir)?; if matches!(build_compat, BuildCompat::V3(_)) { return Ok(()); @@ -118,6 +125,7 @@ fn update_build(build_toml: PathBuf) -> Result<()> { let v3_build: v3::Build = build.into(); let pretty_toml = toml::to_string_pretty(&v3_build)?; + let build_toml = kernel_dir.join("build.toml"); let mut writer = BufWriter::new(File::create(&build_toml).wrap_err_with(|| { format!("Cannot open {} for writing", build_toml.to_string_lossy()) diff --git a/kernel-builder/src/pyproject/mod.rs b/kernel-builder/src/pyproject/mod.rs index b12ffa16..cd87e6cd 100644 --- a/kernel-builder/src/pyproject/mod.rs +++ b/kernel-builder/src/pyproject/mod.rs @@ -7,8 +7,11 @@ use std::{ use eyre::{bail, Result}; use minijinja::Environment; -use crate::config::{Build, Framework}; use crate::util::{check_or_infer_target_dir, parse_build}; +use crate::{ + config::{Build, Framework}, + util::check_or_infer_kernel_dir, +}; pub(crate) mod common; pub mod deps; @@ -42,13 +45,14 @@ pub fn create_pyproject_file_set( } pub fn create_pyproject( - build_toml: PathBuf, + kernel_dir: Option, target_dir: Option, force: bool, ops_id: Option, ) -> Result<()> { - let target_dir = check_or_infer_target_dir(&build_toml, target_dir)?; - let build = parse_build(&build_toml)?; + let kernel_dir = check_or_infer_kernel_dir(kernel_dir)?; + let target_dir = check_or_infer_target_dir(&kernel_dir, target_dir)?; + let build = parse_build(&kernel_dir)?; let file_set = create_pyproject_file_set(build, &target_dir, ops_id)?; file_set.write(&target_dir, force)?; @@ -56,15 +60,16 @@ pub fn create_pyproject( } pub fn clean_pyproject( - build_toml: PathBuf, + kernel_dir: Option, target_dir: Option, dry_run: bool, force: bool, ops_id: Option, ) -> Result<()> { - let target_dir = check_or_infer_target_dir(&build_toml, target_dir)?; + let kernel_dir = check_or_infer_kernel_dir(kernel_dir)?; + let target_dir = check_or_infer_target_dir(&kernel_dir, target_dir)?; - let build = parse_build(&build_toml)?; + let build = parse_build(&kernel_dir)?; let generated_files = create_pyproject_file_set(build, target_dir.clone(), ops_id)?.into_names(); diff --git a/kernel-builder/src/util.rs b/kernel-builder/src/util.rs index b649dc00..dd13dae6 100644 --- a/kernel-builder/src/util.rs +++ b/kernel-builder/src/util.rs @@ -1,15 +1,16 @@ use std::{ + env::current_dir, fs::File, io::Read, path::{Path, PathBuf}, }; -use eyre::{bail, ensure, Context, Result}; +use eyre::{ensure, Context, Result}; use crate::config::{Build, BuildCompat}; -pub(crate) fn parse_build(build_toml: impl AsRef) -> Result { - let build_compat = parse_and_validate(build_toml)?; +pub(crate) fn parse_build(kernel_dir: impl AsRef) -> Result { + let build_compat = parse_and_validate(kernel_dir)?; if matches!(build_compat, BuildCompat::V1(_) | BuildCompat::V2(_)) { eprintln!( @@ -24,11 +25,25 @@ pub(crate) fn parse_build(build_toml: impl AsRef) -> Result { Ok(build) } +pub(crate) fn check_or_infer_kernel_dir(kernel_dir: Option) -> Result { + match kernel_dir { + Some(kernel_dir) => { + ensure!( + kernel_dir.is_dir(), + "`{}` is not a directory", + kernel_dir.to_string_lossy() + ); + Ok(kernel_dir) + } + None => Ok(current_dir()?), + } +} + pub(crate) fn check_or_infer_target_dir( - build_toml: impl AsRef, + kernel_dir: impl AsRef, target_dir: Option, ) -> Result { - let build_toml = build_toml.as_ref(); + let kernel_dir = kernel_dir.as_ref(); match target_dir { Some(target_dir) => { ensure!( @@ -38,23 +53,14 @@ pub(crate) fn check_or_infer_target_dir( ); Ok(target_dir) } - None => { - let absolute = std::path::absolute(build_toml)?; - match absolute.parent() { - Some(parent) => Ok(parent.to_owned()), - None => bail!( - "Cannot get parent path of `{}`", - build_toml.to_string_lossy() - ), - } - } + None => Ok(std::path::absolute(kernel_dir)?), } } -pub(crate) fn parse_and_validate(build_toml: impl AsRef) -> Result { - let build_toml = build_toml.as_ref(); +pub(crate) fn parse_and_validate(kernel_dir: impl AsRef) -> Result { + let build_toml = kernel_dir.as_ref().join("build.toml"); let mut toml_data = String::new(); - File::open(build_toml) + File::open(&build_toml) .wrap_err_with(|| format!("Cannot open {} for reading", build_toml.to_string_lossy()))? .read_to_string(&mut toml_data) .wrap_err_with(|| format!("Cannot read from {}", build_toml.to_string_lossy()))?; diff --git a/nix-builder/lib/extension/torch/arch.nix b/nix-builder/lib/extension/torch/arch.nix index 2b25ff6d..9e6ea5dc 100644 --- a/nix-builder/lib/extension/torch/arch.nix +++ b/nix-builder/lib/extension/torch/arch.nix @@ -116,7 +116,7 @@ stdenv.mkDerivation (prevAttrs: { mkdir -p $out cp -r --no-preserve=mode ${src}/* $out/ ${pkgs.kernel-builder}/bin/kernel-builder create-pyproject \ - --ops-id ${rev} $out/build.toml + --ops-id ${rev} $out ''; preConfigure = diff --git a/nix-builder/lib/extension/torch/no-arch.nix b/nix-builder/lib/extension/torch/no-arch.nix index 2fb5e8d3..57f68156 100644 --- a/nix-builder/lib/extension/torch/no-arch.nix +++ b/nix-builder/lib/extension/torch/no-arch.nix @@ -66,7 +66,7 @@ stdenv.mkDerivation (prevAttrs: { mkdir -p $out cp -r --no-preserve=mode ${src}/* $out/ ${pkgs.kernel-builder}/bin/kernel-builder create-pyproject \ - --ops-id ${rev} $out/build.toml + --ops-id ${rev} $out ''; framework = "torch"; diff --git a/nix-builder/lib/extension/tvm-ffi/arch.nix b/nix-builder/lib/extension/tvm-ffi/arch.nix index ed84c664..e83e31cd 100644 --- a/nix-builder/lib/extension/tvm-ffi/arch.nix +++ b/nix-builder/lib/extension/tvm-ffi/arch.nix @@ -116,7 +116,7 @@ stdenv.mkDerivation (prevAttrs: { # Generate build files. postPatch = '' kernel-builder create-pyproject \ - --ops-id ${rev} build.toml + --ops-id ${rev} . ''; preConfigure = diff --git a/nix-builder/scripts/windows/builder.ps1 b/nix-builder/scripts/windows/builder.ps1 index 852ae51c..2bd0938d 100644 --- a/nix-builder/scripts/windows/builder.ps1 +++ b/nix-builder/scripts/windows/builder.ps1 @@ -212,17 +212,7 @@ function Find-KernelBuilder { throw "kernel-builder executable not found. Please build it or specify -KernelBuilderPath" } -function Get-BuildTomlPath { - param([string]$Folder) - $buildTomlPath = Join-Path $Folder 'build.toml' - - if (!(Test-Path $buildTomlPath -PathType Leaf)) { - throw "build.toml not found in folder: $Folder" - } - - return $buildTomlPath -} function Invoke-KernelBuilder { param( @@ -326,12 +316,12 @@ function Get-CMakeConfigureArgs { # For XPU backend, use Ninja generator with Intel compilers if ($Backend -and $Backend.ToLower() -eq 'xpu') { Write-Status "Using Ninja generator for XPU backend with Intel SYCL compilers" -Type Info - + $kwargs = @("..", "-G", "Ninja", "-DCMAKE_BUILD_TYPE=Release") - + # Verify Intel compilers are available (CMakeLists.txt will set them correctly) $icx = Get-Command icx -ErrorAction SilentlyContinue - + if ($icx) { Write-Status "Found Intel compiler: $($icx.Source)" -Type Info Write-Status "CMakeLists.txt will configure icx for Windows (MSVC-compatible mode)" -Type Info @@ -470,7 +460,7 @@ function Invoke-Backend { #> param( [string]$KernelBuilderExe, - [string]$BuildToml, + [string]$KernelDir, [string]$Target, [hashtable]$Options, [string]$Backend @@ -479,7 +469,7 @@ function Invoke-Backend { $backendName = if ($Backend -eq 'universal') { 'Universal' } else { $Backend.ToUpper() } Write-Status "Generating $backendName backend..." -Type Info - $kwargs = @('create-pyproject', $BuildToml) + $kwargs = @('create-pyproject', $KernelDir) if ($Target) { $kwargs += $Target } if ($Options.Force) { $kwargs += '--force' } @@ -523,13 +513,12 @@ function Set-BackendArchitecture { try { # Resolve paths $SourceFolder = Resolve-Path $SourceFolder -ErrorAction Stop - $buildTomlPath = Get-BuildTomlPath -Folder $SourceFolder $kernelBuilderExe = Find-KernelBuilder # Validate mode if ($Validate) { - Write-Status "Validating $buildTomlPath..." -Type Info - Invoke-KernelBuilder -KernelBuilderExe $kernelBuilderExe -Arguments @('validate', $buildTomlPath) + Write-Status "Validating $SourceFolder..." -Type Info + Invoke-KernelBuilder -KernelBuilderExe $kernelBuilderExe -Arguments @('validate', $SourceFolder) Write-Status "Validation successful!" -Type Success exit 0 } @@ -538,7 +527,7 @@ try { if ($Clean) { Write-Status "Cleaning generated artifacts..." -Type Warning - $kwargs = @('clean', $buildTomlPath) + $kwargs = @('clean', $SourceFolder) if ($TargetFolder) { $kwargs += $TargetFolder } if ($DryRun) { $kwargs += '--dry-run' } if ($Force) { $kwargs += '--force' } @@ -569,12 +558,12 @@ try { if ($Backend) { # Explicit backend specified $targetPath = if ($TargetFolder) { Resolve-Path $TargetFolder } else { $null } - Invoke-Backend -KernelBuilderExe $kernelBuilderExe -BuildToml $buildTomlPath -Target $targetPath -Options $options -Backend $Backend.ToLower() + Invoke-Backend -KernelBuilderExe $kernelBuilderExe -KernelDir $SourceFolder -Target $targetPath -Options $options -Backend $Backend.ToLower() } else { # Auto-detect backend from build.toml Write-Status "Auto-detecting backend from build.toml..." -Type Info - $kwargs = @('create-pyproject', $buildTomlPath) + $kwargs = @('create-pyproject', $SourceFolder) if ($TargetFolder) { $kwargs += (Resolve-Path $TargetFolder) } if ($Force) { $kwargs += '--force' } if ($OpsId) { $kwargs += '--ops-id', $OpsId }