# --- CONFIGURABLE DEFAULTS --- PLATFORM ?= linux BUILD_MODE ?= debug # 'debug' or 'release' # --- DIRECTORIES --- SRC_DIR := src BUILD_DIR := build/$(PLATFORM) ARCH_DIR := $(SRC_DIR)/arch/$(PLATFORM) # --- COMPILERS --- ifeq ($(PLATFORM), emscripten) CC := emcc else CC ?= gcc endif ifeq ($(PLATFORM), emscripten) # --- SHARED FLAGS --- BASE_CFLAGS := -I$(SRC_DIR) # --- CORE-SPECIFIC FLAGS (freestanding, no stdlib) --- CORE_CFLAGS := $(BASE_CFLAGS) # --- PLATFORM-SPECIFIC FLAGS --- PLATFORM_CFLAGS := $(BASE_CFLAGS) else # --- SHARED FLAGS --- BASE_CFLAGS := -I$(SRC_DIR) -Wall -Wextra -Werror -pedantic # --- CORE-SPECIFIC FLAGS (freestanding, no stdlib) --- CORE_CFLAGS := $(BASE_CFLAGS) -std=c89 -ffreestanding -nostdlib -fno-builtin # --- PLATFORM-SPECIFIC FLAGS --- PLATFORM_CFLAGS := $(BASE_CFLAGS) endif # --- MODE & PLATFORM SPECIFIC FLAGS --- ifeq ($(BUILD_MODE), release) CORE_CFLAGS += -O2 -DNDEBUG PLATFORM_CFLAGS += -O2 -DNDEBUG LDFLAGS += -s TARGET_SUFFIX := -release else CORE_CFLAGS += -g -DDEBUG PLATFORM_CFLAGS += -g -DDEBUG TARGET_SUFFIX := -debug endif # --- LINUX-SPECIFIC (SDL, libc) --- ifeq ($(PLATFORM), linux) PLATFORM_CFLAGS += $(shell pkg-config --cflags sdl2 2>/dev/null) LDFLAGS += $(shell pkg-config --libs sdl2 2>/dev/null) -lm TARGET = $(BUILD_DIR)/undar-$(PLATFORM)$(TARGET_SUFFIX) endif # --- EMSCRIPTEN-SPECIFIC --- ifeq ($(PLATFORM), emscripten) LDFLAGS += -s USE_SDL=2 -s WASM=1 \ -s ALLOW_MEMORY_GROWTH=1 \ -s MAX_WEBGL_VERSION=2 \ --preload-file test/paint-bw.rom@paint.rom \ -s INITIAL_MEMORY=16MB # For release: optimize, strip debug, minimize size ifeq ($(BUILD_MODE), release) PLATFORM_CFLAGS += -O2 -flto LDFLAGS += -O2 -flto endif # Output: HTML + JS + WASM TARGET = $(BUILD_DIR)/undar.html endif # --- FALLBACK TARGET (if no platform matched) --- ifndef TARGET TARGET = $(BUILD_DIR)/undar-$(PLATFORM)$(TARGET_SUFFIX) endif # --- VM CORE SOURCES --- VM_SOURCES := \ $(SRC_DIR)/vm/vm.c \ $(SRC_DIR)/vm/device.c \ $(SRC_DIR)/vm/str.c ifeq ($(BUILD_MODE), release) PLATFORM_SOURCE := $(ARCH_DIR)/main.c \ $(ARCH_DIR)/devices.c\ $(SRC_DIR)/tools/parser.c \ $(SRC_DIR)/tools/assembler.c else PLATFORM_SOURCE := $(ARCH_DIR)/main.c \ $(ARCH_DIR)/devices.c \ $(SRC_DIR)/tools/parser.c \ $(SRC_DIR)/tools/assembler.c endif # --- OBJECT FILES --- VM_OBJS := $(VM_SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) PLATFORM_OBJ := $(PLATFORM_SOURCE:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) # --- DEPENDENCIES --- DEPS := $(VM_OBJS:.o=.d) $(PLATFORM_OBJ:.o=.d) .PHONY: all debug release clean clean-all help # Default target all: $(TARGET) # 'debug' target — just set BUILD_MODE and build debug: BUILD_MODE=debug debug: $(TARGET) # 'release' target — just set BUILD_MODE and build release: BUILD_MODE=release release: $(TARGET) # --- COMPILE VM CORE (freestanding) --- $(BUILD_DIR)/vm/%.o: $(SRC_DIR)/vm/%.c @mkdir -p $(dir $@) $(CC) $(CORE_CFLAGS) -MMD -MP -c $< -o $@ # --- COMPILE TOOLS (debug only, uses PLATFORM_CFLAGS) --- $(BUILD_DIR)/tools/%.o: $(SRC_DIR)/tools/%.c @mkdir -p $(dir $@) $(CC) $(PLATFORM_CFLAGS) -MMD -MP -c $< -o $@ # --- COMPILE PLATFORM --- $(BUILD_DIR)/arch/$(PLATFORM)/%.o: $(ARCH_DIR)/%.c @mkdir -p $(dir $@) $(CC) $(PLATFORM_CFLAGS) -MMD -MP -c $< -o $@ # Main build rule $(TARGET): $(VM_OBJS) $(PLATFORM_OBJ) @mkdir -p $(dir $@) $(CC) $(PLATFORM_CFLAGS) $(LDFLAGS) -o $@ $^ @echo "Built: $@" @if [ "$(PLATFORM)" = "emscripten" ]; then \ echo "Open in browser: file://$(shell pwd)/$@"; \ fi # --- AUTO-DEPENDENCIES --- -include $(DEPS) # --- CLEAN --- clean: @echo "Cleaning build artifacts for $(PLATFORM)..." @rm -rf $(BUILD_DIR) @echo "Cleaned." clean-all: @echo "Cleaning ALL build artifacts..." @rm -rf build/ @echo "All cleaned." # --- HELP --- help: @echo "Undar VM" @echo "" @echo "Targets:" @echo " make -> debug build (default: linux)" @echo " make debug -> same as above" @echo " make release -> optimized, stripped build" @echo " make clean -> clean current platform" @echo " make clean-all→ clean all platforms" @echo "" @echo "Platforms:" @echo " make PLATFORM=linux -> GCC + SDL2" @echo " make PLATFORM=emscripten -> Emscripten + SDL2 for Web" @echo " make PLATFORM=avr -> (example) AVR-GCC" @echo "" @echo "Output:" @echo " Linux: build/linux/undar-linux-" @echo " Web: build/emscripten/undar.html (+ .js, .wasm)"