diff --git a/make/iigs.mk b/make/iigs.mk index 7d1fe29..8579d85 100644 --- a/make/iigs.mk +++ b/make/iigs.mk @@ -22,9 +22,14 @@ BINDIR := $(BUILD)/bin OBJDIR := $(BUILD)/obj CLANG := $(LLVM816_ROOT)/tools/llvm-mos-build/bin/clang +LLVM_MC := $(LLVM816_ROOT)/tools/llvm-mos-build/bin/llvm-mc +AR := $(LLVM816_ROOT)/tools/llvm-mos-sdk/bin/llvm-ar +CCWRAP := $(LLVM816_ROOT)/scripts/ccRegallocFallback.sh RT_INC := $(LLVM816_ROOT)/runtime/include CFLAGS := --target=w65816 -O2 -ffreestanding -ffunction-sections INCLUDES := -I$(RT_INC) -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/joey -I$(SRC_CORE) -I$(REPO_DIR)/src/codegen +LIBDIR := $(BUILD)/lib +LIB := $(LIBDIR)/libjoey.a PORT_C_SRCS := $(wildcard $(SRC_DIR)/iigs/*.c) # Hand-rolled asm, migrated to llvm-mc GAS .s. @@ -42,6 +47,11 @@ CODEGEN_SRCS := $(REPO_DIR)/src/codegen/spriteCompile.c $(REPO_DIR)/src/codegen/ LIB_C_SRCS := $(CORE_C_SRCS_IIGS) $(GENERIC_C_SRCS) $(PORT_C_SRCS) $(CODEGEN_SRCS) LIB_SRCS := $(LIB_C_SRCS) $(PORT_ASM_SRCS) +# Library header set for archive rebuild triggering (coarse on purpose: any +# header change forces a full lib recompile -- a needless rebuild is safe, a +# missed one is not). +IIGS_LIB_HDRS := $(wildcard $(INCLUDE_DIR)/joey/*.h) $(wildcard $(SRC_CORE)/*.h) $(wildcard $(REPO_DIR)/src/codegen/*.h) $(wildcard $(SRC_DIR)/iigs/*.h) $(wildcard $(REPO_DIR)/src/m68k/*.h) + # Example sources (single-TU unless noted). PATTERN_SRC := $(EXAMPLES)/pattern/pattern.c DRAW_SRC := $(EXAMPLES)/draw/draw.c @@ -135,17 +145,31 @@ $(NTP_ASM): $(NTP_BIN) $(REPO_DIR)/toolchains/iigs/bin-to-s.sh # Compile-check every library and example translation unit with clang, # and assemble every .s with llvm-mc. This is the canonical "does the # IIgs source still build" gate while the launchable pipeline is wired. -iigs-lib: - @mkdir -p $(OBJDIR) - @set -e; \ +# The real static library: compile every library TU (through the regalloc +# fallback, matching clang-build.sh) + assemble every .s, then archive them +# into libjoey.a. link816 reads the archive natively and --gc-sections selects +# what each example references, so examples link $(LIB) exactly like the other +# ports. `iigs-lib' is kept as the canonical build/compile-check entry point. +$(LIB): $(LIB_SRCS) $(IIGS_LIB_HDRS) + @mkdir -p $(OBJDIR) $(LIBDIR) + @set -e; objs=""; \ for c in $(LIB_C_SRCS); do \ + o=$(OBJDIR)/$$(echo $$c | sed 's#[/.]#_#g').o; \ echo " CC $$c"; \ - $(CLANG) $(CFLAGS) $(INCLUDES) -c $$c -o $(OBJDIR)/$$(echo $$c | sed 's#[/.]#_#g').o; \ + $(CCWRAP) $(CLANG) $(CFLAGS) $(INCLUDES) -c $$c -o $$o; \ + objs="$$objs $$o"; \ done; \ for s in $(PORT_ASM_SRCS); do \ + o=$(OBJDIR)/$$(basename $$s .s).o; \ echo " AS $$s"; \ - $(LLVM816_ROOT)/tools/llvm-mos-build/bin/llvm-mc -arch=w65816 -filetype=obj $$s -o $(OBJDIR)/$$(basename $$s .s).o; \ - done + $(LLVM_MC) -arch=w65816 -filetype=obj $$s -o $$o; \ + objs="$$objs $$o"; \ + done; \ + rm -f $@; \ + echo " AR $@"; \ + $(AR) rcs $@ $$objs + +iigs-lib: $(LIB) # End-to-end smoke test: clang -> llvm-mc -> link816 -> MAME, validating # the ported asm computes correctly on emulated hardware. @@ -158,62 +182,62 @@ iigs-clang-smoke: # multi-segment OMF wiring still in progress. DEP_DIR := $(BUILD)/dep -$(BINDIR)/PATTERN: $(PATTERN_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/PATTERN: $(PATTERN_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/PATTERN.d $(INCLUDES) -o $@ $(PATTERN_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/PATTERN.d $(INCLUDES) -o $@ $(PATTERN_SRC) $(LIB) -$(BINDIR)/DRAW: $(DRAW_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/DRAW: $(DRAW_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/DRAW.d $(INCLUDES) -o $@ $(DRAW_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/DRAW.d $(INCLUDES) -o $@ $(DRAW_SRC) $(LIB) -$(BINDIR)/KEYS: $(KEYS_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/KEYS: $(KEYS_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/KEYS.d $(INCLUDES) -o $@ $(KEYS_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/KEYS.d $(INCLUDES) -o $@ $(KEYS_SRC) $(LIB) -$(BINDIR)/SERIAL: $(SERIAL_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/SERIAL: $(SERIAL_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/SERIAL.d $(INCLUDES) -o $@ $(SERIAL_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/SERIAL.d $(INCLUDES) -o $@ $(SERIAL_SRC) $(LIB) -$(BINDIR)/SAVE: $(SAVE_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/SAVE: $(SAVE_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/SAVE.d $(INCLUDES) -o $@ $(SAVE_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/SAVE.d $(INCLUDES) -o $@ $(SAVE_SRC) $(LIB) -$(BINDIR)/JOY: $(JOY_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/JOY: $(JOY_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/JOY.d $(INCLUDES) -o $@ $(JOY_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/JOY.d $(INCLUDES) -o $@ $(JOY_SRC) $(LIB) -$(BINDIR)/SPRITE: $(SPRITE_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/SPRITE: $(SPRITE_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/SPRITE.d $(INCLUDES) -o $@ $(SPRITE_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/SPRITE.d $(INCLUDES) -o $@ $(SPRITE_SRC) $(LIB) -$(BINDIR)/UBER: $(UBER_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/UBER: $(UBER_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/UBER.d $(INCLUDES) -o $@ $(UBER_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/UBER.d $(INCLUDES) -o $@ $(UBER_SRC) $(LIB) -$(BINDIR)/ADV: $(ADV_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/ADV: $(ADV_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/ADV.d $(INCLUDES) -o $@ $(ADV_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/ADV.d $(INCLUDES) -o $@ $(ADV_SRC) $(LIB) -$(BINDIR)/ADV2: $(ADV2_SRC) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/ADV2: $(ADV2_SRC) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/ADV2.d $(INCLUDES) -o $@ $(ADV2_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/ADV2.d $(INCLUDES) -o $@ $(ADV2_SRC) $(LIB) -$(BINDIR)/AGI: $(AGI_SRCS) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/AGI: $(AGI_SRCS) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/AGI.d $(INCLUDES) -I$(EXAMPLES)/agi -o $@ $(AGI_SRCS) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/AGI.d $(INCLUDES) -I$(EXAMPLES)/agi -o $@ $(AGI_SRCS) $(LIB) -$(BINDIR)/STAXI: $(STAXI_SRCS) $(LIB_SRCS) $(IIGS_CLANG_BUILD) +$(BINDIR)/STAXI: $(STAXI_SRCS) $(LIB) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/STAXI.d $(INCLUDES) -I$(EXAMPLES)/spacetaxi -o $@ $(STAXI_SRCS) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/STAXI.d $(INCLUDES) -I$(EXAMPLES)/spacetaxi -o $@ $(STAXI_SRCS) $(LIB) # AUDIO loads the NTP replayer from disk at runtime: audio_full.c reads # ntpplayer.bin via NTP_PATH instead of baking the 34KB replayer as rodata # (which overflowed bank 0, and clang's IMM16+$BE near form can't reach a far # rodata segment anyway). The binary no longer links $(NTP_ASM); $(NTP_BIN) is # still built so it can be shipped on the application disk next to the binary. -$(BINDIR)/AUDIO: $(AUDIO_SRC) $(LIB_SRCS) $(NTP_BIN) $(IIGS_CLANG_BUILD) +$(BINDIR)/AUDIO: $(AUDIO_SRC) $(LIB) $(NTP_BIN) $(IIGS_CLANG_BUILD) @mkdir -p $(dir $@) $(DEP_DIR) - $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/AUDIO.d $(INCLUDES) -o $@ $(AUDIO_SRC) $(LIB_SRCS) + $(IIGS_CLANG_BUILD) -M $(DEP_DIR)/AUDIO.d $(INCLUDES) -o $@ $(AUDIO_SRC) $(LIB) clean-iigs: rm -rf $(BUILD)