_config_cache = {} def _load(filename, depfiles): from . import load_config if not filename in _config_cache: if filename.exists(): depfiles.add(filename) data = load_config(filename) _config_cache[filename] = data return _config_cache.get(filename, dict()) def _build_config(chain, depfiles): config = {} for d in [_load(c, depfiles) for c in chain]: for k, v in d.items(): if isinstance(v, (list, tuple)): config[k] = config.get(k, list()) + list(v) elif isinstance(v, dict): config[k] = config.get(k, dict()) config[k].update(v) else: config[k] = v return config def _make_ninja_config(outfile, config, files): from os import makedirs from ninja.ninja_syntax import Writer makedirs(outfile.parent, exist_ok=True) with open(outfile, "w") as buildfile: build = Writer(buildfile) build.comment("This file is automatically generated by bonnibel") build.comment("Source config files:") for f in files: build.comment(f" - {f}") build.newline() for k, v in config.items(): build.variable(k, v) def generate_configs(root, output, buildconfig, arch, targets, kinds): assets = root / "assets" / "build" / arch base = ["global.yaml", f"config.{buildconfig}.yaml"] depfiles = set() for target in targets: chain = base + [f"target.{target}.yaml"] files = [assets / f for f in chain] config = _build_config(files, depfiles) outfile = output / target / f"config.ninja" _make_ninja_config(outfile, config, files) for kind in kinds: custom = [f"kind.{kind}.yaml", f"target.{target}.{kind}.yaml"] files = [assets / f for f in chain + custom] config = _build_config(files, depfiles) outfile = output / target / f"config.{kind}.ninja" _make_ninja_config(outfile, config, files) return depfiles