From ae2720c82685f71b55907ea1b4c8b65891e2ce45 Mon Sep 17 00:00:00 2001 From: pantonshire Date: Mon, 3 Mar 2025 09:32:58 +0000 Subject: [PATCH] library-ify nasm helper --- buildtools/Cargo.lock | 7 +++ buildtools/Cargo.toml | 6 +++ buildtools/src/lib.rs | 109 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 buildtools/Cargo.lock create mode 100644 buildtools/Cargo.toml create mode 100644 buildtools/src/lib.rs diff --git a/buildtools/Cargo.lock b/buildtools/Cargo.lock new file mode 100644 index 0000000..d3aead2 --- /dev/null +++ b/buildtools/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "buildtools" +version = "0.1.0" diff --git a/buildtools/Cargo.toml b/buildtools/Cargo.toml new file mode 100644 index 0000000..f32a0e9 --- /dev/null +++ b/buildtools/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "buildtools" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/buildtools/src/lib.rs b/buildtools/src/lib.rs new file mode 100644 index 0000000..e3b1241 --- /dev/null +++ b/buildtools/src/lib.rs @@ -0,0 +1,109 @@ +use std::{ffi::OsString, path::{Path, PathBuf}, process::Command}; + +#[derive(Clone)] +pub struct Nasm { + bin_path: PathBuf, + includes: Vec, + warnings: Vec, + werror: bool, + out_format: Option, +} + +impl Nasm { + pub fn new(bin_path: PathBuf) -> Self { + Self { + bin_path, + includes: Vec::new(), + warnings: Vec::new(), + werror: true, + out_format: None, + } + } + + pub fn include(self, paths: I) -> Self + where + PathBuf: From, + I: IntoIterator, + { + Self { + includes: { + let mut updated_includes = self.includes; + updated_includes.extend(paths.into_iter().map(From::from)); + updated_includes + }, + ..self + } + } + + pub fn warnings(self, warnings: I) -> Self + where + String: From, + I: IntoIterator, + { + Self { + warnings: { + let mut updated_warnings = self.warnings; + updated_warnings.extend(warnings.into_iter().map(From::from)); + updated_warnings + }, + ..self + } + } + + pub fn werror(self, enabled: bool) -> Self { + Self { + werror: enabled, + ..self + } + } + + pub fn out_format(self, format: T) -> Self + where + String: From, + { + Self { + out_format: Some(From::from(format)), + ..self + } + } + + // TODO: make this generic over sources & path types + pub fn to_cmd(&self, output: &Path, sources: &[&Path]) -> Command { + let mut cmd = self.to_common_cmd(); + + cmd + .arg("-o") + .arg(output) + .args(sources); + + cmd + } + + fn to_common_cmd(&self) -> Command { + let mut cmd = Command::new(&self.bin_path); + + if let Some(format) = self.out_format.as_ref() { + cmd.arg("-f").arg(format); + } + + for include in self.includes.iter() { + let mut buf = OsString::new(); + buf.push("-I"); + buf.push(include); + cmd.arg(buf); + } + + for warning in self.warnings.iter() { + let mut buf = OsString::new(); + buf.push("-w+"); + buf.push(warning); + cmd.arg(buf); + } + + if self.werror { + cmd.arg("-werror"); + } + + cmd + } +}