# --- CONFIGURABLE DEFAULTS --- PLATFORM ?= linux BUILD_MODE ?= debug # 'debug' or 'deploy' # --- DIRECTORIES --- SRC_DIR := src BUILD_DIR := build/$(PLATFORM) ARCH_DIR := $(SRC_DIR)/arch/$(PLATFORM) # --- COMPILERS --- ifeq ($(PLATFORM), emscripten) CC := emcc else CC ?= gcc endif # --- 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) # --- MODE & PLATFORM SPECIFIC FLAGS --- ifeq ($(BUILD_MODE), deploy) 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)/zre-$(PLATFORM)$(TARGET_SUFFIX) endif # --- EMSCRIPTEN-SPECIFIC --- ifeq ($(PLATFORM), emscripten) # Core still compiled freestanding (emcc supports this) # Platform layer gets Emscripten/SDL flags PLATFORM_CFLAGS += -s USE_SDL=2 -s WASM=1 LDFLAGS += -s USE_SDL=2 -s WASM=1 # For deploy: optimize, strip debug, minimize size ifeq ($(BUILD_MODE), deploy) PLATFORM_CFLAGS += -O3 LDFLAGS += -O3 --closure 1 else # For debug: preserve names, generate source maps PLATFORM_CFLAGS += -gsource-map LDFLAGS += -gsource-map --source-map-base . endif # Output: HTML + JS + WASM TARGET = $(BUILD_DIR)/zre.html endif # --- FALLBACK TARGET (if no platform matched) --- ifndef TARGET TARGET = $(BUILD_DIR)/zre-$(PLATFORM)$(TARGET_SUFFIX) endif # --- CORE SOURCES (flat in src/) --- CORE_SOURCES := \ $(SRC_DIR)/str.c \ $(SRC_DIR)/vm.c \ $(SRC_DIR)/device.c \ $(SRC_DIR)/test.c # --- PLATFORM SOURCE --- PLATFORM_SOURCE := $(ARCH_DIR)/main.c \ $(ARCH_DIR)/devices.c # --- OBJECT FILES --- CORE_OBJS := $(CORE_SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) PLATFORM_OBJ := $(PLATFORM_SOURCE:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) # --- DEPENDENCIES --- DEPS := $(CORE_OBJS:.o=.d) $(PLATFORM_OBJ:.o=.d) .PHONY: all debug deploy clean clean-all help # Default target all: $(TARGET) # 'debug' target — just set BUILD_MODE and build debug: BUILD_MODE = debug debug: $(TARGET) # 'deploy' target — just set BUILD_MODE and build deploy: BUILD_MODE = deploy deploy: $(TARGET) # Main build rule $(TARGET): $(CORE_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 # --- COMPILE CORE (freestanding) --- $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c @mkdir -p $(dir $@) $(CC) $(CORE_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 $@ # --- 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 deploy -> 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/zre-linux-" @echo " Web: build/emscripten/zre.html (+ .js, .wasm)"