import sys import os import subprocess from io import StringIO from snapshot import create_snapshot from scheduler import build_distcc_hosts from cache import make_build_key, cache_hit, cache_store from compiler_env import build_ccache_env def run_cmd(cmd, cwd, env): p = subprocess.Popen( cmd, shell=True, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True ) log = StringIO() for line in p.stdout: print(line, end="") log.write(line) p.wait() return p.returncode, log.getvalue() def build_target(project, snapshot, target, nodes): env = os.environ.copy() # ---------------------------- # distcc layer # ---------------------------- env["DISTCC_HOSTS"] = build_distcc_hosts(nodes) # ---------------------------- # ccache layer (NEW) # ---------------------------- cc_env = build_ccache_env(project) env.update(cc_env) build_env = project.get("build_env", {}) env.update(build_env) key = make_build_key( snapshot["hash"], target, build_env ) print(f"[FESTER] target={target}") print(f"[FESTER] cache_key={key}") # ---------------------------- # top-level build cache # ---------------------------- if cache_hit(key): print("[FESTER] BUILD CACHE HIT (skipping full compile)") return 0 cmd = project["targets"][target] code, log = run_cmd(cmd, snapshot["path"], env) if code == 0: cache_store(key, log) return code def run_release(project): snapshot = create_snapshot(project["source"]) nodes = project.get("nodes_override", []) or [] results = {} for target in project["targets"]: results[target] = build_target(project, snapshot, target, nodes) return results if __name__ == "__main__": import json with open(sys.argv[1]) as f: project = json.load(f) run_release(project)