109 lines
2.9 KiB
Rust
109 lines
2.9 KiB
Rust
use super::*;
|
|
use crate::parsed_config_processing::*;
|
|
use crate::Args;
|
|
|
|
pub fn gen_ninja_header(config: &ConfigTable, cmdline_args: &Args) -> String {
|
|
let mut ret = "".to_string();
|
|
ret.push_str(&format!(
|
|
"## Generated by ngen
|
|
## Do not modify by hand
|
|
|
|
builddir = {0}
|
|
|
|
rule mkdir
|
|
command = mkdir -p $out
|
|
description = Creating directory $out
|
|
|
|
rule regen_ninjafile
|
|
command = ngen -c $in -o $out
|
|
generator = 1
|
|
description = Regenerating $out
|
|
|
|
",
|
|
config.build_dir
|
|
));
|
|
if config.compile_commands {
|
|
ret.push_str(&format!(
|
|
"\
|
|
rule regen_compile_commands
|
|
command = ngen -c $in --write-compile-commands $out
|
|
description = Regenerating $out
|
|
|
|
build $builddir: mkdir
|
|
|
|
build $builddir/compile_commands.json: regen_compile_commands {1} || $builddir
|
|
pool = console
|
|
|
|
build {0}: regen_ninjafile {1} || $builddir/compile_commands.json
|
|
pool = console
|
|
",
|
|
cmdline_args.output_file, cmdline_args.config_file
|
|
));
|
|
} else {
|
|
ret.push_str(&format!(
|
|
"build {}: regen_ninjafile {}\n pool = console\n",
|
|
cmdline_args.output_file, cmdline_args.config_file
|
|
));
|
|
}
|
|
ret
|
|
}
|
|
|
|
pub fn gen_ninja_target(name: &str, target: &Target) -> Result<String, ContentGenerationError> {
|
|
if target.sources.len() == 0 {
|
|
return Err(ContentGenerationError {
|
|
message: format!("target `{}` has no sources", name),
|
|
});
|
|
}
|
|
|
|
let mut ret = "\n".to_string();
|
|
|
|
let compiler_flags = target.compiler_flags.join(" ");
|
|
let linker_flags = target.linker_flags.join(" ");
|
|
let linker_libs = target.linker_libs.join(" ");
|
|
|
|
ret.push_str(&format!(
|
|
"\
|
|
# BEGIN TARGET {0}
|
|
rule cc_{0}
|
|
deps = gcc
|
|
depfile = $dep
|
|
command = {1} {2} -MD -MF $dep -o $out -c $in
|
|
description = Building $in -> $out
|
|
rule link_{name}
|
|
command = {3} {4} -o $out $in {5}
|
|
description = Linking $out
|
|
|
|
build $builddir/{0}/obj: mkdir
|
|
build $builddir/{0}/dep: mkdir
|
|
|
|
",
|
|
name, target.compiler, compiler_flags, target.linker, linker_flags, linker_libs
|
|
));
|
|
let mut object_list: Vec<String> = Vec::new();
|
|
|
|
for source in &target.sources {
|
|
let new_file = source.replace("/", "-");
|
|
let obj_name = format!("$builddir/{}/obj/{}.o", name, new_file);
|
|
let dep_name = format!("$builddir/{}/dep/{}.o.d", name, new_file);
|
|
ret.push_str(&format!(
|
|
"build {}: cc_{} {}\n dep = {}\n",
|
|
obj_name, name, source, dep_name
|
|
));
|
|
object_list.push(obj_name);
|
|
}
|
|
|
|
ret.push_str(&format!(
|
|
"\nbuild $builddir/{0}/{1}: link_{0} ",
|
|
name, target.outfile
|
|
));
|
|
ret.push_str(&object_list.join(" "));
|
|
ret.push_str(&format!(
|
|
" || $builddir/{0}/obj $builddir/{0}/dep\nbuild {0}: phony $builddir/{0}/{1}\n",
|
|
name, target.outfile
|
|
));
|
|
if target.opts.default {
|
|
ret.push_str(&format!("\ndefault {}\n", name));
|
|
}
|
|
ret.push_str(&format!("# END TARGET {}\n", name));
|
|
Ok(ret)
|
|
}
|