diff --git a/x.py b/x.py index afa152c..6f2470d 100755 --- a/x.py +++ b/x.py @@ -4,12 +4,13 @@ import sys import subprocess import threading import os +from datetime import datetime __FILENAME = "" -MAX_JOBS = 4 - -CWD = os.curdir +MAX_JOBS = max(1, len(os.sched_getaffinity(0)) - 2) +TS_VRB = 2 +CWD = os.path.dirname(os.path.abspath(__file__)) BUILD_D = f"{CWD}/build" @@ -20,31 +21,45 @@ def shift(arr): return arr.pop(0) +def timestamp(dt=datetime.now(), fmt="hours"): + return f"{dt.hour:0>2}:{dt.minute:0>2}:{dt.second:0>2}" + + def run(*cmds, parallel=False, tag=None, interactive=False): threads = [] def run_single(cmd, tag): - print(f"CMD: {cmd}") + env = os.environ.copy() + env["MAKE_TERMOUT"] = "true" + env["MAKE_TERMERR"] = "true" + start_time = datetime.now() + print(f"{f"{timestamp(start_time)} | " if TS_VRB > 0 else ""}CMD: {cmd}") with subprocess.Popen( cmd, shell=True, stdout=None if interactive else subprocess.PIPE, stderr=None if interactive else subprocess.STDOUT, - text=None if interactive else True, - bufsize=1 + # text=None if interactive else True, ) as proc: if not interactive: for line in proc.stdout: - line = line.rstrip("\n") + dt = datetime.now() if tag: - print(f"stdout ({tag}): {line}", flush=True) + print(f"{f"{timestamp(dt)} | " if TS_VRB > + 0 else ""}stdout ({tag}): ", flush=True, end='') else: - print(f"stdout: {line}", flush=True) + print(f"{f"{timestamp(dt)} | " if TS_VRB > + 0 else ""}stdout: ", flush=True, end='') + sys.stdout.buffer.write(line) + sys.stdout.buffer.flush() proc.wait() if proc.returncode != 0: - raise subprocess.CalledProcessError(proc.returncode, cmd) - + print(f"ERROR: Command '{ + cmd}' exited with code {proc.returncode}") + exit(1) for i, command in enumerate(cmds): - current_tag = f"{tag}-{i}" if tag else None + + current_tag = tag if len(cmds) <= 1 else ( + f"{tag}-{i}" if tag else None) if parallel: t = threading.Thread( target=run_single, args=(command, current_tag)) @@ -57,17 +72,23 @@ def run(*cmds, parallel=False, tag=None, interactive=False): t.join() +def todo(reason): + print(f"ERROR: Unimplemented {reason}") + exit(1) + + def cmd_configure(args): def cmd_help(): print(f"Usage: {__FILENAME} configure [component]") print("Components:") - print(" kernel - The linux kernel") - print(" busybox - Busybox") + print(" help - Show this help") + print(" kernel - The linux kernel") + print(" busybox - Busybox") # $(MAKE) -C $(MAKEFILE_DIR)/kernel O=$(KERNEL_BUILD_DIR) KCONFIG_CONFIG="$(MAKEFILE_DIR)/.kernel-config" menuconfig subc = shift(args) - if not subc: + if not subc or subc == "help": cmd_help() exit(1) elif subc == "kernel": @@ -82,17 +103,91 @@ def cmd_configure(args): exit(1) +def cmd_build(args): + def cmd_help(): + print(f"Usage: {__FILENAME} build [component]") + print("Components:") + print(" help - Show this help") + print(" all - Builds everything") + print(" linux - Everything bellow") + print(" kernel - The linux kernel") + print(" busybox - Busybox") + print(" rust - Builds all of the rust components") + print(" img - Rebuilds the image") + + def build_init(): + run( + f"mkdir -p {BUILD_D}/linux/kernel", + f"mkdir -p {BUILD_D}/linux/busybox", + parallel=True + ) + + def build_kernel(args): + run(f"make -C {CWD}/linux/kernel O={BUILD_D}/linux/kernel KCONFIG_CONFIG='{ + CWD}/linux/.kernel-config' -j{MAX_JOBS}", tag="kernel") + + def build_busybox(args): + run( + f"cp {CWD}/linux/.busybox-config { + BUILD_D}/linux/busybox/.config", + f"make -C {CWD}/linux/busybox O={BUILD_D}/linux/busybox KCONFIG_CONFIG='{ + CWD}/linux/.busybox-config' -j{MAX_JOBS}", + tag="busybox" + ) + + def build_rust(args): + todo("build_rust") + + def build_image(args): + # for the later bootable.img or whatever file + todo("build_image") + + cmd = shift(args) + + if not cmd or cmd == "help": + cmd_help() + exit(1) + elif cmd == "all": + build_init() + build_kernel(args) + build_busybox(args) + build_rust(args) + build_image(args) + elif cmd == "linux": + build_init() + build_kernel(args) + build_busybox(args) + elif cmd == "kernel": + build_init() + build_kernel(args) + elif cmd == "busybox": + build_init() + build_busybox(args) + elif cmd == "rust": + build_init() + build_rust(args) + elif cmd == "img": + build_init() + build_image(args) + else: + print(f"ERROR: Unknown component '{cmd}'") + cmd_help() + exit(1) + + AVAILABLE_SUBCOMMANDS = { "help": help, "configure": cmd_configure, + "build": cmd_build } def help(): print(f"Usage: {__FILENAME} [subcommand]") print("Subcommands:") - print(" help - Show this help") - print(" configure - Configure components") + print(" help - Show this help") + print(" configure - Configure components") + print(" build - Compile/build components") if __name__ == "__main__":