# ============================================================================ # Bastion kernel - Top-Level Build System # # Usage: # make ARCH=x86_64 defconfig — Create default .config for x86_64 # make ARCH=aarch64 defconfig — Create default .config for aarch64 # make ARCH=x86_64 build — Build for x86_64 # make ARCH=aarch64 build — Build for aarch64 # make ARCH=x86_64 run — Build + run in QEMU # make ARCH=aarch64 run — Build + run in QEMU # make all — Build both architectures # make clean — Remove build artifacts and objects # make distclean — Remove build + generated config # ============================================================================ VERSION = 0 PATCHLEVEL = 0 SUBLEVEL = 1 NAME = Husky .PHONY: all build clean distclean configure defconfig disk run check-config RESULT_DIR := result CONFIG_FILE := .config CONFIG_H := include/kernel/config.h CONFIG_MK := config_generated.mk CONFIGURE := python3 scripts/configure.py #TODO: change to $(python) -include $(CONFIG_MK) # ── ARCH validation ──────────────────────────────────────────────────────── # Default ARCH if not specified ARCH ?= $(shell uname -m) ifneq ($(ARCH),x86_64) ifneq ($(ARCH),aarch64) $(error ARCH must be x86_64 or aarch64 (got: $(ARCH))) endif endif # Derive EFI binary name from ARCH # TODO: maybe add name of this artifact to config ifeq ($(ARCH),x86_64) EFI_BINARY := BOOTX64.EFI else EFI_BINARY := BOOTAA64.EFI endif ARCH_RESULT_DIR := $(RESULT_DIR)/$(ARCH) # ── Build ────────────────────────────────────────────────────────────────── all build: check-config @echo "══════════════════════════════════════════" @echo " Building Bastion — $(ARCH)" @echo "══════════════════════════════════════════" @echo " v.$(VERSION).$(PATCHLEVEL).$(SUBLEVEL) — $(NAME)" @echo "══════════════════════════════════════════" @echo " Build boot" @echo "══════════════════════════════════════════" $(MAKE) -C boot ARCH=$(ARCH) RESULT_DIR=$(CURDIR)/$(ARCH_RESULT_DIR)/boot @echo "══════════════════════════════════════════" @echo " Build kernel" @echo "══════════════════════════════════════════" $(MAKE) -C kernel ARCH=$(ARCH) RESULT_DIR=$(CURDIR)/$(ARCH_RESULT_DIR)/kernel # ── Configuration ─────────────────────────────────────────────────────────── defconfig: @cp configs/default_$(ARCH) $(CONFIG_FILE) @echo "Created .config from configs/default_$(ARCH)" @$(CONFIGURE) --arch $(ARCH) @echo "" # Regenerate config.h and config_generated.mk from .config configure: $(CONFIG_FILE) @$(CONFIGURE) --arch $(ARCH) # Auto-generate config.h if .config exists but config.h is stale or broken or missing check-config: $(CONFIG_FILE) @if [ ! -f $(CONFIG_H) ] || [ $(CONFIG_FILE) -nt $(CONFIG_H) ] || [ scripts/configure.py -nt $(CONFIG_H) ]; then \ $(CONFIGURE) --arch $(ARCH); \ fi # If .config doesn't exist, tell the user $(CONFIG_FILE): @echo "═══════════════════════════════════════════════════════════" @echo " ERROR: No .config file found." @echo "" @echo " Create one with:" @echo " make defconfig" @echo " make ARCH=x86_64 defconfig" @echo " make ARCH=aarch64 defconfig" @echo "" @echo " Or copy manually:" @echo " cp configs/default_x86_64 .config" @echo "═══════════════════════════════════════════════════════════" @exit 1 # ── Disk images ───────────────────────────────────────────────────────────── disk: build bash scripts/create_disk.sh $(ARCH) \ $(ARCH_RESULT_DIR)/boot/$(EFI_BINARY) \ $(ARCH_RESULT_DIR)/kernel/$(CONFIG_KERNEL_FILE_NAME) \ $(ARCH_RESULT_DIR)/bastion.img # ── QEMU ──────────────────────────────────────────────────────────────────── run: disk @bash scripts/run_qemu.sh $(ARCH) $(ARCH_RESULT_DIR)/bastion.img # ── Clean ─────────────────────────────────────────────────────────────────── clean: rm -rf $(RESULT_DIR) $(MAKE) -C boot ARCH=$(ARCH) clean $(MAKE) -C kernel ARCH=$(ARCH) clean @echo "Clean." # Remove everything including generated config (but not .config itself) distclean: clean rm -f $(CONFIG_H) $(CONFIG_MK) @echo "Distclean."