custom format strings
This commit is contained in:
parent
9a96f4dfb6
commit
3363b23335
6 changed files with 71 additions and 11 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -86,6 +86,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"clap",
|
||||
"serde",
|
||||
"strfmt",
|
||||
"toml",
|
||||
]
|
||||
|
||||
|
@ -136,6 +137,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strfmt"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.52"
|
||||
|
|
|
@ -8,4 +8,5 @@ edition = "2021"
|
|||
[dependencies]
|
||||
clap = { version = "4.5.1", features = ["derive", "std", "help", "usage"], default-features = false }
|
||||
serde = { version = "1.0.197", features = ["derive"] }
|
||||
strfmt = "0.2.4"
|
||||
toml = "0.8.10"
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::fmt::Display;
|
|||
|
||||
pub enum ErrorKind {
|
||||
NoSources,
|
||||
FormatError,
|
||||
}
|
||||
|
||||
pub struct Error {
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::BufWriter;
|
||||
use std::io::Write;
|
||||
use strfmt::strfmt;
|
||||
|
||||
use super::*;
|
||||
use crate::parse_deser::*;
|
||||
use crate::Args;
|
||||
|
||||
pub fn gen_ninja_header(config: &Config, cmdline_args: &Args) -> Result<String> {
|
||||
fn gen_ninja_header(config: &Config, cmdline_args: &Args) -> Result<String> {
|
||||
let mut ret = "".to_string();
|
||||
ret.push_str(&format!(
|
||||
"## Generated by ngen
|
||||
|
@ -52,7 +54,7 @@ build {0}: regen_ninjafile {1} || $builddir/compile_commands.json
|
|||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn gen_ninja_target(name: &str, target: &Target) -> Result<String> {
|
||||
fn gen_ninja_target(name: &str, target: &Target) -> Result<String> {
|
||||
if target.sources.len() == 0 {
|
||||
return Err(Error {
|
||||
kind: ErrorKind::NoSources,
|
||||
|
@ -66,23 +68,58 @@ pub fn gen_ninja_target(name: &str, target: &Target) -> Result<String> {
|
|||
let linker_flags = target.linker_flags.join(" ");
|
||||
let linker_libs = target.linker_libs.join(" ");
|
||||
|
||||
let mut fmt_args = HashMap::new();
|
||||
fmt_args.insert("outfile".to_string(), "$out");
|
||||
fmt_args.insert("compiler".to_string(), target.compiler);
|
||||
fmt_args.insert("compiler_flags".to_string(), &compiler_flags);
|
||||
fmt_args.insert("linker".to_string(), target.compiler);
|
||||
fmt_args.insert("object".to_string(), "$out");
|
||||
fmt_args.insert("objects".to_string(), "$in");
|
||||
fmt_args.insert("source".to_string(), "$in");
|
||||
fmt_args.insert("depfile".to_string(), "$dep");
|
||||
fmt_args.insert("linker_flags".to_string(), &linker_flags);
|
||||
fmt_args.insert("linker_libs".to_string(), &linker_libs);
|
||||
|
||||
ret.push_str(&format!(
|
||||
"\
|
||||
# BEGIN TARGET {0}
|
||||
rule cc_{0}
|
||||
# BEGIN TARGET {name}
|
||||
rule cc_{name}
|
||||
deps = gcc
|
||||
depfile = $dep
|
||||
command = {1} {2} -MD -MF $dep -o $out -c $in
|
||||
command = "
|
||||
));
|
||||
match strfmt(target.opts.compile_cmd_fmt, &fmt_args) {
|
||||
Ok(v) => ret.push_str(&v),
|
||||
Err(e) => {
|
||||
return Err(Error {
|
||||
kind: ErrorKind::FormatError,
|
||||
message: e.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
ret.push_str(&format!(
|
||||
"
|
||||
description = Building $in -> $out
|
||||
rule link_{name}
|
||||
command = {3} {4} -o $out $in {5}
|
||||
command = "
|
||||
));
|
||||
match strfmt(target.opts.link_cmd_fmt, &fmt_args) {
|
||||
Ok(v) => ret.push_str(&v),
|
||||
Err(e) => {
|
||||
return Err(Error {
|
||||
kind: ErrorKind::FormatError,
|
||||
message: e.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
ret.push_str(&format!(
|
||||
"
|
||||
description = Linking $out
|
||||
|
||||
build $builddir/{0}/obj: mkdir
|
||||
build $builddir/{0}/dep: mkdir
|
||||
build $builddir/{name}/obj: mkdir
|
||||
build $builddir/{name}/dep: mkdir
|
||||
|
||||
",
|
||||
name, target.compiler, compiler_flags, target.linker, linker_flags, linker_libs
|
||||
"
|
||||
));
|
||||
let mut object_list: Vec<String> = Vec::new();
|
||||
|
||||
|
@ -127,7 +164,6 @@ pub fn create_ninja_file_content(
|
|||
Ok(v) => ret.push_str(&v),
|
||||
Err(e) => match e.kind {
|
||||
ErrorKind::NoSources => eprintln!("WARNING: {e}. Skipping `{}`", name),
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => {
|
||||
return Err(e);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ pub struct DeserTargetOptions {
|
|||
pub inherit_from: Option<String>,
|
||||
pub depend_on: Option<Vec<String>>,
|
||||
pub default: Option<bool>,
|
||||
pub compile_cmd_fmt: Option<String>,
|
||||
pub link_cmd_fmt: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
|
|
|
@ -6,6 +6,8 @@ pub struct TargetOptions<'a> {
|
|||
pub inherit_from: &'a str,
|
||||
pub default: bool,
|
||||
pub depend_on: Vec<&'a str>,
|
||||
pub compile_cmd_fmt: &'a str,
|
||||
pub link_cmd_fmt: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a DeserTargetOptions> for TargetOptions<'a> {
|
||||
|
@ -30,6 +32,14 @@ impl<'a> From<&'a DeserTargetOptions> for TargetOptions<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(v) = &value.compile_cmd_fmt {
|
||||
ret.compile_cmd_fmt = v;
|
||||
}
|
||||
|
||||
if let Some(v) = &value.link_cmd_fmt {
|
||||
ret.link_cmd_fmt = v;
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +51,9 @@ impl<'a> TargetOptions<'a> {
|
|||
inherit_from: "main",
|
||||
default: false,
|
||||
depend_on: vec![],
|
||||
compile_cmd_fmt:
|
||||
"{compiler} {compiler_flags} -MD -MF {depfile} -o {object} -c {source}",
|
||||
link_cmd_fmt: "{linker} {linker_flags} -o {outfile} {objects} {linker_libs}",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue