Anki/build/ninja_gen/src/render.rs
Damien Elmes 9701055eb5 Add support for using n2 instead of ninja
Provides better visibility into what the build is currently doing.
Motivated by slow node.js downloads making the build appear stuck.

You can test this out by running ./tools/install-n2 then building
normally. Please report any problems, and 'cargo uninstall n2' to get
back to the old behaviour. It works on Windows, but prints a new line
each second instead of redrawing the same area.

A couple of changes were required for compatibility:

- n2 doesn't resolve $variable names inside other variables, so the
resolution needs to be done by our build generator.
- Our inputs and outputs in build.ninja need to be listed in a deterministic
order to avoid unwanted rebuilds. I've made a few other tweaks so the
build file should now be fully-deterministic.
2023-06-15 17:17:56 +10:00

70 lines
1.8 KiB
Rust

// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use std::fmt::Write;
use anki_io::create_dir_all;
use anki_io::write_file_if_changed;
use anyhow::Result;
use itertools::Itertools;
use crate::archives::with_exe;
use crate::input::space_separated;
use crate::Build;
impl Build {
pub fn render(&self) -> String {
let mut buf = String::new();
writeln!(
&mut buf,
"# This file is automatically generated by configure.rs. Any edits will be lost.\n"
)
.unwrap();
writeln!(
&mut buf,
"runner = $builddir/rust/debug/{}",
with_exe("runner")
)
.unwrap();
for (key, value) in &self.pools {
writeln!(&mut buf, "pool {}\n depth = {}", key, value).unwrap();
}
buf.push('\n');
buf.push_str(&self.output_text);
for (group, targets) in self.groups.iter().sorted() {
let group = group.replace(':', "_");
writeln!(
&mut buf,
"build {group}: phony {}",
space_separated(targets)
)
.unwrap();
buf.push('\n');
}
buf.push_str(&self.trailing_text);
buf = buf.replace("$builddir", self.buildroot.as_str());
for (key, value) in &self.variables {
buf = buf.replace(
&format!("${key}"),
&value.replace("$builddir", self.buildroot.as_str()),
);
}
buf
}
pub fn write_build_file(&self) -> Result<()> {
create_dir_all(&self.buildroot)?;
let path = self.buildroot.join("build.ninja");
let contents = self.render().into_bytes();
write_file_if_changed(path, contents)?;
Ok(())
}
}