#!/usr/bin/env python3 # vim: sw=2 ts=2 ex: import os import glob from .run import run; from .sha256 import sha256, sha256_file; def build(args): os.makedirs(".build-cache/", exist_ok = 1); cc = "gcc"; cppflags = ("-D", "_GNU_SOURCE"); cppflags += ("-I", "."); cflags = (); match args.build_type: case "debug": cppflags += ("-D", "DEBUG_BUILD_TYPE"); cflags += ("-g", ); cflags += ("-Werror", ); cflags += ("-Wall", ); cflags += ("-Wextra", ); cflags += ("-Wconversion", ); cflags += ("-Wsign-conversion", ); cflags += ("-Wfloat-conversion", ); cflags += ("-Warith-conversion", ); cflags += ("-Wno-strict-prototypes", ); cflags += ("-Wfatal-errors", ); cflags += ("-Wno-unused", ); case "release": cppflags += ("-D", "RELEASE_BUILD_TYPE"); cflags += ("-Werror", ); cflags += ("-Wall", ); cflags += ("-Wextra", ); cflags += ("-Wstrict-prototypes", ); cflags += ("-Wconversion", ); cflags += ("-Wsign-conversion", ); cflags += ("-Wfloat-conversion", ); cflags += ("-Warith-conversion", ); cflags += ("-Wstrict-prototypes", ); cflags += ("-Wfatal-errors", ); case _: print("unknown build type {repr(args.build_type)}"); exit(1); objs = []; for src in sorted(glob.glob("**/*.c", recursive = 1)): command = (cc, ) + ("-MM", ) + cppflags + (src, ); shas = (sha256_file(src), ); dep = ".build-cache/" + sha256((command, *shas)) + ".dep"; if not os.path.exists(dep): command += ("-MF", dep); run(command); with open(dep) as stream: for header in stream.read().replace("\\\n", " ").split()[2:]: shas += (sha256_file(header), ); command = (cc, ) + ("-c", ) + cppflags + cflags + (src, ); sha = sha256((command, *shas)); obj = ".build-cache/" + sha + ".o"; if not os.path.exists(obj): print(f"Compiling {src} ..."); command += ("-o", obj); run(command); objs.append(obj); ld = "gcc"; ldflags = (); ldlibs = ("-lm", "-lreadline"); command = (ld, *ldflags, *objs, *ldlibs) exe = ".build-cache/" + sha256((command, )); if not os.path.exists(exe): print(f"Linking ..."); command += ("-o", exe); run(command); return exe;