### Configuration ### BASENAME := banjo VERSION ?= us.v10 ifeq ($(VERSION),us.v10) C_VERSION=0 endif ifeq ($(VERSION),pal) C_VERSION=1 endif ifeq ($(VERSION),us.v11) C_VERSION=2 endif ifeq ($(VERSION),jp) C_VERSION=3 endif IN_CFLAGS ?= -DCODE2_CODE_CRC2=0 -DCODE2_DATA_CRC2=0 ### Tools ### # System tools MKDIR := mkdir CP := cp CD := cd RM := rm CAT := cat DIFF := diff # Build tools CROSS := mips-linux-gnu- CC := ido/ido5.3_recomp/cc CPP := cpp GCC := $(CROSS)gcc AS := $(CROSS)as LD := $(CROSS)ld -b elf32-tradbigmips OBJDUMP := $(CROSS)objdump OBJCOPY := $(CROSS)objcopy PYTHON := python3 GREP := grep -rl SPLAT := $(PYTHON) tools/n64splat/split.py PRINT := printf PATCH_LIB_MATH := tools/patch_libultra_math ASM_PROCESSOR_DIR := tools/asm-processor BK_TOOLS := tools/bk_tools BK_CRC := tools/bk_crc/bk_crc BK_INFLATE := $(BK_TOOLS)/bk_inflate_code BK_DEFLATE := $(BK_TOOLS)/bk_deflate_code BK_ASSET_TOOL := tools/bk_asset_tool/bk_asset_tool ASM_PROCESSOR := $(PYTHON) $(ASM_PROCESSOR_DIR)/asm_processor.py SPLAT_INPUTS := $(PYTHON) tools/splat_inputs.py PROGRESS := $(PYTHON) tools/progress.py PROGRESS_READ := $(PYTHON) tools/progress_read.py ### Files and Directories ### # Inputs OVERLAYS := core1 core2 MM TTC CC BGS FP lair GV CCW RBB MMM SM fight cutscenes # Creates a list of all the source files for the given overlay (e.g. BGS_C_SRCS) # Appends that list to OVERLAY_C_FILES define get_overlay_sources $(1)_C_SRCS := $(filter $(SRC_ROOT)/$(1)/%,$(ALL_C_SRCS)) $(1)_ASM_SRCS := $(filter $(ASM_ROOT)/$(1)/%,$(ALL_ASM_SRCS)) $(1)_BINS := $(filter $(BIN_ROOT)/$(1)/%,$(ALL_BINS)) OVERLAY_C_SRCS += $$($(1)_C_SRCS) OVERLAY_ASM_SRCS += $$($(1)_ASM_SRCS) OVERLAY_BINS += $$($(1)_BINS) # Overlay inputs $(1)_NEW_FILES := $$(filter $(BIN_ROOT)/$(1)/%, $(NEW_BINS)) $$(filter $(SRC_ROOT)/$(1)/%, $(NEW_C_SRCS)) $$(filter $(ASM_ROOT)/$(1)/%, $(NEW_ASM_SRCS)) $$(filter $(ASM_ROOT)/data/$(1)/%, $(NEW_ASM_SRCS)) OVERLAY_NEW_FILES += $$($(1)_NEW_FILES) endef # Source files SRC_ROOT := src ASM_ROOT := asm BIN_ROOT := bin ASSET_ROOT := assets SUBYAML := subyaml NONMATCHINGS := nonmatchings NONMATCHING_DIR := $(ASM_ROOT)/$(NONMATCHINGS) BUILD_ROOT := build BUILD_DIR := $(BUILD_ROOT)/$(VERSION) ALL_ASSET_FILES := $(shell find $(ASSET_ROOT) -type f -iname '*.*' 2> /dev/null) ALL_C_SRCS := $(shell find $(SRC_ROOT) -type f -iname '*.c' 2> /dev/null) ALL_ASM_SRCS := $(filter-out $(ASM_ROOT)/$(NONMATCHINGS), $(shell find $(ASM_ROOT) -name $(NONMATCHINGS) -prune -o -iname '*.s' 2> /dev/null)) ALL_BINS := $(shell find $(BIN_ROOT) -type f -iname '*.bin' 2> /dev/null) # Files referenced in the splat files YAML_CALL := $(SPLAT_INPUTS) $(BASENAME).$(VERSION).yaml $(addprefix $(SUBYAML)/, $(addsuffix .$(VERSION).yaml, $(OVERLAYS))) YAML_SRCS := $(shell $(SPLAT_INPUTS) $(BASENAME).$(VERSION).yaml $(addprefix $(SUBYAML)/, $(addsuffix .$(VERSION).yaml, $(OVERLAYS)))) YAML_C_SRCS := $(filter %.c, $(YAML_SRCS)) YAML_ASM_SRCS := $(filter %.s, $(YAML_SRCS)) YAML_BINS := $(filter %.bin, $(YAML_SRCS)) # Files that need to be extracted NEW_C_SRCS := $(filter-out $(ALL_C_SRCS), $(YAML_C_SRCS)) NEW_ASM_SRCS := $(filter-out $(ALL_ASM_SRCS), $(YAML_ASM_SRCS)) NEW_BINS := $(filter-out $(ALL_BINS), $(YAML_BINS)) NEW_FILES := $(NEW_C_SRCS) $(NEW_ASM_SRCS) $(NEW_BINS) $(foreach overlay,$(OVERLAYS),$(eval $(call get_overlay_sources,$(overlay)))) # Files for the rom itself MAIN_C_SRCS := $(filter-out $(OVERLAY_C_SRCS),$(ALL_C_SRCS)) MAIN_ASM_SRCS := $(filter-out $(OVERLAY_ASM_SRCS),$(ALL_ASM_SRCS)) MAIN_BINS := $(filter-out $(OVERLAY_BINS),$(ALL_BINS)) # Files that need to be extracted for the rom itself MAIN_NEW_FILES := $(filter-out $(OVERLAY_NEW_FILES), $(NEW_FILES)) # Any source files that have GLOBAL_ASM in them or do not exist before splitting GLOBAL_ASM_C_SRCS := $(shell $(GREP) GLOBAL_ASM $(SRC_ROOT) arg2) define print2 @$(PRINT) "$(GREEN)$(1) $(YELLOW)$(2)$(GREEN) -> $(BLUE)$(3)$(NO_COL)\n" endef ### Flags ### # Build tool flags CFLAGS := -c -Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm $(OPT_FLAGS) $(MIPSBIT) -D_FINALROM -DF3DEX_GBI -DVERSION='$(C_VERSION)' CFLAGS += -woff 649,654,838,807 CFLAGS += $(IN_CFLAGS) CPPFLAGS := -D_FINALROM -DN_MICRO INCLUDE_CFLAGS := -I . -I include -I include/2.0L -I include/2.0L/PR OPT_FLAGS := -O2 MIPSBIT := -mips2 ASFLAGS := -EB -mtune=vr4300 -march=vr4300 -mabi=32 -I include GCC_ASFLAGS := -c -x assembler-with-cpp -mabi=32 -ffreestanding -mtune=vr4300 -march=vr4300 -mfix4300 -G 0 -O -mno-shared -fno-PIC -mno-abicalls LDFLAGS_COMMON := -T symbol_addrs.core1.$(VERSION).txt -T symbol_addrs.core2.$(VERSION).txt -T symbol_addrs.global.$(VERSION).txt -T undefined_syms.$(VERSION).txt -T undefined_syms.libultra.txt --no-check-sections --accept-unknown-input-arch LDFLAGS := -T $(LD_SCRIPT) -Map $(ELF:.elf=.map) --no-check-sections --accept-unknown-input-arch -T undefined_syms.libultra.txt BINOFLAGS := -I binary -O elf32-tradbigmips ### Rules ### # Default target, all all: verify # Shows progress for all overlays, boot, and total progress: $(OVERLAY_PROG_CSVS) $(MAIN_PROG_CSV) $(TOTAL_PROG_CSV) @$(foreach overlay,$(OVERLAYS),$(PROGRESS_READ) progress/progress.$(overlay).csv $(VERSION) $(overlay) &&) \ $(PROGRESS_READ) $(MAIN_PROG_CSV) $(VERSION) bk_boot @$(PROGRESS_READ) $(TOTAL_PROG_CSV) $(VERSION) total # Shows progress for a single overlay (e.g. progress-SM) $(addprefix progress-,$(OVERLAYS)) : progress-% : progress/progress.%.csv @$(PROGRESS_READ) $< $(VERSION) $* # Verify that the roms match, also sets up diff_settings verify: $(Z64) @$(DIFF) $(BASEROM) $(Z64) > /dev/null && \ $(PRINT) "$(YELLOW) _\n _( )_\n [ ]_\n ) _ _)\n [_( )_]\n$(BLUE)$(BASENAME).$(VERSION).z64$(NO_COL): $(GREEN)OK$(NO_COL)\n" || \ $(PRINT) "$(BLUE)$(BASEROM) $(RED)differs$(NO_COL)\n" @$(PRINT) "def apply(config, args):\n" > diff_settings.py @$(PRINT) "\tconfig[\"baseimg\"] = \"$(BASEROM)\"\n" >> diff_settings.py @$(PRINT) "\tconfig[\"myimg\"] = \"$(Z64)\"\n" >> diff_settings.py @$(PRINT) "\tconfig[\"mapfile\"] = \"$(Z64:.z64=.map)\"\n" >> diff_settings.py @$(PRINT) "\tconfig[\"source_directories\"] = ['$(SRC_ROOT)', 'include']\n" >> diff_settings.py @$(PRINT) "\tconfig[\"makeflags\"] = ['-s']\n" >> diff_settings.py # Musical note print for individual overlays # Need to figure out how to print this only when building a single overlay # $(YELLOW) ╒════╕\n │ │\n _│ _│\n └─┘ └─┘\n # Verify that any given overlay matches, also sets up diff_settings verify-%: $(BUILD_DIR)/%.rzip.bin $(BIN_ROOT)/%.$(VERSION).rzip.bin $(BUILD_DIR)/%.full progress/progress_%.svg @$(DIFF) $< $(BIN_ROOT)/$*.$(VERSION).rzip.bin > /dev/null && \ $(PRINT) "$(BLUE)%-10s$(NO_COL): $(GREEN)OK$(NO_COL)\n" "$*" || \ $(PRINT) "$(BLUE)$* $(RED)differs$(NO_COL)\n" @$(PRINT) "def apply(config, args):\n" > diff_settings.py @$(PRINT) "\tconfig[\"baseimg\"] = \"$(BUILD_DIR)/$*.$(VERSION).bin\"\n" >> diff_settings.py @$(PRINT) "\tconfig[\"myimg\"] = \"$(BUILD_DIR)/$*.full\"\n" >> diff_settings.py @$(PRINT) "\tconfig[\"mapfile\"] = \"$(BUILD_DIR)/$*.map\"\n" >> diff_settings.py @$(PRINT) "\tconfig[\"source_directories\"] = ['$(SRC_ROOT)/$*', 'include']\n" >> diff_settings.py @$(PRINT) "\tconfig[\"makeflags\"] = ['TARGET=$*','-s']\n" >> diff_settings.py $(OVERLAY_PROG_SVGS) : progress/progress_%.svg: progress/progress.%.csv $(call print1,Creating progress svg for:,$*) @$(PROGRESS_READ) $< $(VERSION) $* $(OVERLAY_PROG_CSVS) : progress/progress.%.csv: $(BUILD_DIR)/%.elf $(call print1,Calculating progress for:,$*) @$(PROGRESS) . $(BUILD_DIR)/$*.elf .$* --version $(VERSION) --subcode $* > $@ $(MAIN_PROG_SVG): $(MAIN_PROG_CSV) $(call print1,Creating progress svg for:,boot) @$(PROGRESS_READ) $< $(VERSION) bk_boot $(MAIN_PROG_CSV): $(ELF) $(call print1,Calculating progress for:,boot) @$(PROGRESS) . $< .boot_bk_boot --version $(VERSION) > $@ $(TOTAL_PROG_SVG): $(TOTAL_PROG_CSV) $(call print0,Creating total progress svg) @$(PROGRESS_READ) $< $(VERSION) total $(TOTAL_PROG_CSV): $(OVERLAY_PROG_CSVS) $(MAIN_PROG_CSV) $(call print0,Calculating total progress) @cat $^ > $@ $(README_MD): $(TOTAL_PROG_SVG) @head -n 21 $< | tail -n 1 | head -c -8 | tail -c +32 | xargs -i sed -i "/# banjo*/c\# banjo ({})" $@ # Verify that each overlay matches verify-each: $(addprefix verify-,$(OVERLAYS)) # per-overlay rules define overlay_rules # .o -> .elf (overlay) $(BUILD_DIR)/$(1).elf : $$($(1)_ALL_OBJS) $(1).ld $(LD) -T $(1).ld -R core2.elf --allow-multiple-definition -Map $(BUILD_DIR)/$(1).map $$(LDFLAGS_COMMON) -T undefined_syms_auto.$(1).$(VERSION).txt -T undefined_funcs_auto.$(1).$(VERSION).txt -o $$@ # split overlay $(BUILD_DIR)/$(1)_SPLAT_TIMESTAMP : $(SUBYAML)/$(1).$(VERSION).yaml $(BUILD_DIR)/$(1).$(VERSION).bin $(SYMBOL_ADDRS) $(call print1,Splitting bin:,$$<) $(SPLAT) $(SUBYAML)/$(1).$(VERSION).yaml @touch $$@ @touch $(1).ld # Dummy target to make sure extraction happens before compilation, mainly for extracted asm $$($(1)_C_SRCS) $$($(1)_ASM_SRCS) $$($(1)_BINS) : | $(BUILD_DIR)/$(1)_SPLAT_TIMESTAMP @: # Dummy target to make sure extraction happens before processing extracted files and linking $$($(1)_NEW_FILES) $(1).ld: $(BUILD_DIR)/$(1)_SPLAT_TIMESTAMP @: endef $(foreach overlay,$(OVERLAYS),$(eval $(call overlay_rules,$(overlay)))) # Additional symbols for core2 $(BUILD_DIR)/core2.elf: LDFLAGS_COMMON = -T symbol_addrs.core1.$(VERSION).txt -T symbol_addrs.core2.$(VERSION).txt -T symbol_addrs.global.$(VERSION).txt -T undefined_syms.$(VERSION).txt -T undefined_syms.libultra.txt --no-check-sections --accept-unknown-input-arch -T level_symbols.$(VERSION).txt $(BUILD_DIR)/core2.temp.elf: LDFLAGS_COMMON = -T symbol_addrs.core1.$(VERSION).txt -T symbol_addrs.core2.$(VERSION).txt -T symbol_addrs.global.$(VERSION).txt -T undefined_syms.$(VERSION).txt -T undefined_syms.libultra.txt --no-check-sections --accept-unknown-input-arch -T level_symbols.$(VERSION).txt # mkdir $(ALL_DIRS) : $(call print1,Making folder:,$@) @$(MKDIR) -p $@ # .s -> .o (assemble with gcc for preprocessor support) $(BUILD_DIR)/%.s.o: %.s | $(ASM_BUILD_DIRS) $(call print2,Assembling:,$<,$@) @$(GCC) $(GCC_ASFLAGS) $(INCLUDE_CFLAGS) -o $@ $< # .bin -> .o $(BIN_OBJS) : $(BUILD_DIR)/%.bin.o : %.bin | $(BIN_BUILD_DIRS) $(call print2,Objcopying:,$<,$@) @$(OBJCOPY) $(BINOFLAGS) $< $@ # .bin -> .o (overlay) $(OVERLAY_RZIP_OBJS) : $(BUILD_DIR)/$(BIN_ROOT)/%.$(VERSION).rzip.bin.o : $(BUILD_DIR)/%.rzip.bin $(call print2,Objcopying:,$<,$@) @$(OBJCOPY) $(BINOFLAGS) $< $@ $(BUILD_DIR)/bk_boot.full: $(BUILD_DIR)/bk_boot.elf @mips-linux-gnu-objcopy -I elf32-tradbigmips -O binary --only-section .boot_bk_boot $(BUILD_DIR)/bk_boot.elf $@ $(BUILD_DIR)/crc.bin : $(BUILD_DIR)/bk_boot.full $(BUILD_DIR)/core1.code $(BUILD_DIR)/core1.data $(BK_CRC) @$(BK_CRC) $(BUILD_DIR)/bk_boot.full > $(BUILD_DIR)/crc.bin @$(BK_CRC) $(BUILD_DIR)/core1.code >> $(BUILD_DIR)/crc.bin @$(BK_CRC) $(BUILD_DIR)/core1.data >> $(BUILD_DIR)/crc.bin # .bin -> .o (overlay crc check) $(CRC_OBJS) : $(BUILD_DIR)/crc.bin $(call print2,Objcopying:,$<,$@) @$(OBJCOPY) $(BINOFLAGS) $< $@ # Creates a dummy crc file of 32 bytes to use in the initial link $(BUILD_DIR)/dummy_crc.bin: $(call print1,Creating dummy crc file:$@) truncate -s 32 $@ # .bin -> .o (dummy crc) $(DUMMY_CRC_OBJ) : $(BUILD_DIR)/dummy_crc.bin $(call print2,Objcopying:,$<,$@) @$(OBJCOPY) $(BINOFLAGS) $< $@ # .c -> .o $(BUILD_DIR)/%.c.o : %.c | $(C_BUILD_DIRS) $(call print2,Compiling:,$<,$@) @$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDE_CFLAGS) $(OPT_FLAGS) $(MIPSBIT) -o $@ $< # .c -> .o (mips3) $(MIPS3_OBJS) : $(BUILD_DIR)/%.c.o : %.c | $(C_BUILD_DIRS) $(call print2,Compiling:,$<,$@) @$(CC) -c -32 $(CFLAGS) $(CPPFLAGS) $(INCLUDE_CFLAGS) $(OPT_FLAGS) $(LOOP_UNROLL) $(MIPSBIT) -o $@ $< @tools/set_o32abi_bit.py $@ # .c -> .o with asm processor $(GLOBAL_ASM_C_OBJS) : $(BUILD_DIR)/%.c.o : %.c | $(C_BUILD_DIRS) $(call print2,Compiling (with ASM Processor):,$<,$@) @$(ASM_PROCESSOR) $(OPT_FLAGS) $< > $(BUILD_DIR)/$< @$(CC) -32 $(CFLAGS) $(CPPFLAGS) $(INCLUDE_CFLAGS) $(OPT_FLAGS) $(MIPSBIT) -o $@ $(BUILD_DIR)/$< @$(ASM_PROCESSOR) $(OPT_FLAGS) $< --post-process $@ \ --assembler "$(AS) $(ASFLAGS)" --asm-prelude include/prelude.s # Split baserom $(BUILD_DIR)/SPLAT_TIMESTAMP: $(BASENAME).$(VERSION).yaml $(SYMBOL_ADDRS) | $(BUILD_DIR) $(call print1,Splitting rom:,$<) @touch $@ @$(SPLAT) $(BASENAME).$(VERSION).yaml @touch $(LD_SCRIPT) # Dummy target to make the LD script and overlay rzips depend on splat being run # without causing it to be rerun once for every overlay # Bin files are also dependent on the splat timestamp since they get overwritten on resplit $(MAIN_NEW_FILES) $(LD_SCRIPT) $(MAIN_BINS) : $(BUILD_DIR)/SPLAT_TIMESTAMP @: # Dummy target to make sure extraction happens before compilation, mainly for extracted asm $(MAIN_C_SRCS) $(MAIN_ASM_SRCS) : | $(BUILD_DIR)/SPLAT_TIMESTAMP @: # .rzip.bin -> .bin $(OVERLAY_BINS) : $(BUILD_DIR)/%.$(VERSION).bin : $(BIN_ROOT)/%.$(VERSION).rzip.bin $(BK_INFLATE) | $(BUILD_DIR) $(call print1,Decompressing rzip:,$<) @$(BK_INFLATE) $< $@ # Special rules to handle core2 code checksumming ifneq ($(CORE2_CODE_CRC_C_OBJS),) CORE2_TEMP_LD := core2.temp.ld CORE2_CODE_CRC_C_TEMP_OBJS := $(CORE2_CODE_CRC_C_OBJS:.c.o=.c.o_) core2_NON_CRC_OBJS := $(filter-out $(CORE2_CODE_CRC_C_OBJS),$(core2_ALL_OBJS)) # core2.ld -> core2.temp.ld $(CORE2_TEMP_LD) : core2.ld $(call print0,Creating linker script for initial core2 linking step) @$(CP) $< $@ $(foreach obj, $(CORE2_CODE_CRC_C_OBJS), sed -i 's:$(obj):$(obj)_:g' $@) # core2 .c -> .o with zero for core2 code CRC $(CORE2_CODE_CRC_C_TEMP_OBJS) : $(BUILD_DIR)/%.c.o_ : %.c | $(C_BUILD_DIRS) $(call print2,Compiling temp file:,$<,$@) @$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDE_CFLAGS) $(OPT_FLAGS) $(MIPSBIT) -o $@ $< # core2 objects with zero for code CRC -> core2.temp.elf $(BUILD_DIR)/core2.temp.elf : $(core2_NON_CRC_OBJS) $(CORE2_TEMP_LD) $(CORE2_CODE_CRC_C_TEMP_OBJS) $(call print1,Linking elf:,$@) @$(LD) -T $(CORE2_TEMP_LD) -Map $(BUILD_DIR)/core2.map $(LDFLAGS_COMMON) -T undefined_syms_auto.core2.$(VERSION).txt -T undefined_funcs_auto.core2.$(VERSION).txt -o $@ $(BUILD_DIR)/core2.temp.full : $(BUILD_DIR)/core2.temp.elf @$(OBJCOPY) -I elf32-tradbigmips -O binary $< $@ # core2.temp.elf -> core2.temp.code $(BUILD_DIR)/core2.temp.code : $(BUILD_DIR)/core2.temp.full $(BUILD_DIR)/core2.temp.elf $(call print2,Converting initial core2 code:,$<,$@) @head -c $(shell {\ text_offset=0x$$(nm $(BUILD_DIR)/core2.temp.elf | grep core2_TEXT_START | head -c 8) ;\ data_offset=0x$$(nm $(BUILD_DIR)/core2.temp.elf | grep core2_DATA_START | head -c 8) ;\ echo $$(($$data_offset - $$text_offset)) ;\ }) $< > $@ # core2 code -> core2 code crc $(BUILD_DIR)/core2.code.crc : $(BUILD_DIR)/core2.temp.code $(BK_CRC) $(call print0,Calculating core2 code CRC) @$(BK_CRC) -D CORE2_CODE $< > $@ # core2 .c -> .o with correct core2 code CRC $(CORE2_CODE_CRC_C_OBJS) : $(BUILD_DIR)/%.c.o : %.c $(BUILD_DIR)/core2.code.crc | $(C_BUILD_DIRS) $(call print2,Compiling:,$<,$@) @$(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDE_CFLAGS) $(OPT_FLAGS) $(MIPSBIT) $(shell cat $(BUILD_DIR)/core2.code.crc) -o $@ $< endif # core2 data -> core2 data CRC $(BUILD_DIR)/core2.data.crc : $(BUILD_DIR)/core2.data $(BK_CRC) $(call print0,Calculating core2 data CRC) @$(BK_CRC) -D CORE2_DATA $< > $@ # core1 .c -> .o with correct core2 data CRC $(CORE2_DATA_CRC_C_OBJS) : $(BUILD_DIR)/%.o : % $(BUILD_DIR)/core2.data.crc | $(C_BUILD_DIRS) $(call print2,Compiling file with core2 data CRC (with ASM Processor):,$<,$@) @$(ASM_PROCESSOR) $(OPT_FLAGS) $< > $(BUILD_DIR)/$< @$(CC) -32 $(CFLAGS) $(CPPFLAGS) $(INCLUDE_CFLAGS) $(OPT_FLAGS) $(MIPSBIT) $(shell cat $(BUILD_DIR)/core2.data.crc) -o $@ $(BUILD_DIR)/$< @$(ASM_PROCESSOR) $(OPT_FLAGS) $< --post-process $@ \ --assembler "$(AS) $(ASFLAGS)" --asm-prelude include/prelude.s # .elf -> .code $(OVERLAY_CODE_BINS) : $(BUILD_DIR)/%.code : $(BUILD_DIR)/%.full $(BUILD_DIR)/%.elf $(call print2,Converting overlay code:,$<,$@) @head -c $(shell {\ text_offset=0x$$(nm $(BUILD_DIR)/$*.elf | grep $*_TEXT_START | head -c 8) ;\ data_offset=0x$$(nm $(BUILD_DIR)/$*.elf | grep $*_DATA_START | sort -r | head -c 8) ;\ echo $$(($$data_offset - $$text_offset)) ;\ }) $< > $@ # @$(OBJCOPY) -I elf32-tradbigmips -O binary --only-section .$*_code --only-section .$*_mips3 $< $@ # .elf -> .data $(OVERLAY_DATA_BINS) : $(BUILD_DIR)/%.data : $(BUILD_DIR)/%.full $(BUILD_DIR)/%.elf $(call print2,Converting overlay data:,$<,$@) @tail -c +$(shell {\ text_offset=0x$$(nm $(BUILD_DIR)/$*.elf | grep $*_TEXT_START | head -c 8) ;\ data_offset=0x$$(nm $(BUILD_DIR)/$*.elf | grep $*_DATA_START | sort -r | head -c 8) ;\ echo $$(($$data_offset - $$text_offset + 1)) ;\ }) $< > $@ # @$(OBJCOPY) -I elf32-tradbigmips -O binary --only-section .$*_data --only-section .*_data_* $< $@ # .elf -> .full $(BUILD_DIR)/%.full : $(BUILD_DIR)/%.elf @$(OBJCOPY) -I elf32-tradbigmips -O binary $< $@ # .data + .code -> .rzip.bin $(BUILD_DIR)/%.rzip.bin : $(BUILD_DIR)/%.code $(BUILD_DIR)/%.data $(BK_DEFLATE) $(call print1,Compressing overlay:,$@) @cd $(BK_TOOLS) && ../../$(BK_DEFLATE) ../../$@ ../../$(BUILD_DIR)/$*.code ../../$(BUILD_DIR)/$*.data # .bin -> .yaml $(ASSET_ROOT)/assets.yaml : $(BIN_ROOT)/assets.bin $(BK_ASSET_TOOL) $(call print1,Extracting Assets:,$@) $(BK_ASSET_TOOL) -e $< $(ASSET_ROOT) # .yaml -> .bin ifneq (,$(shell which cargo)) $(ASSET_BIN): $(ASSET_ROOT)/assets.yaml $(BK_ASSET_TOOL) $(ALL_ASSET_FILES) $(call print2,Constructing Asset Binary:,$<,$@) $(BK_ASSET_TOOL) -c $< $@ else $(ASSET_BIN): $(BIN_ROOT)/assets.bin $(call print2,Copying Asset Binary (install cargo to construct instead):,$<,$@) @$(CP) $< $@ endif # .bin -> .o $(ASSET_OBJS): $(ASSET_BIN) $(call print2,Objcopying:,$<,$@) @$(OBJCOPY) $(BINOFLAGS) $< $@ # .o -> .elf (game) $(ELF): $(MAIN_ALL_OBJS) $(LD_SCRIPT) $(OVERLAY_RZIP_OBJS) $(addprefix $(BUILD_DIR)/, $(addsuffix .full, $(OVERLAYS))) $(ASSET_OBJS) $(call print1,Linking elf:,$@) @$(LD) $(LDFLAGS) -T undefined_syms_auto.$(VERSION).txt -o $@ $(BK_BOOT_LD_SCRIPT): $(LD_SCRIPT) sed 's|$(CRC_OBJS)|$(DUMMY_CRC_OBJ)|' $< > $@ # .o -> .elf (game) $(BUILD_DIR)/bk_boot.elf: $(DUMMY_CRC_OBJ) $(filter-out $(CRC_OBJS),$(MAIN_ALL_OBJS)) $(BK_BOOT_LD_SCRIPT) $(OVERLAY_RZIP_OBJS) $(addprefix $(BUILD_DIR)/, $(addsuffix .full, $(OVERLAYS))) $(call print1,Linking elf:,$@) @$(LD) -T $(BK_BOOT_LD_SCRIPT) -Map $(ELF:.elf=.map) --no-check-sections --accept-unknown-input-arch -T undefined_syms.libultra.txt -T undefined_syms_auto.$(VERSION).txt -o $@ # .elf -> .z64 $(Z64) : $(ELF) $(OVERLAY_PROG_SVGS) $(MAIN_PROG_SVG) $(TOTAL_PROG_SVG) $(README_MD) $(call print1,Creating z64:,$@) @$(OBJCOPY) $< $@ -O binary $(OCOPYFLAGS) $(BK_TOOLS)/gzip-1.2.4/gzip: $(BK_TOOLS)/gzip-1.2.4/Makefile @$(CD) $(BK_TOOLS)/gzip-1.2.4 && $(MAKE) gzip $(BK_TOOLS)/gzip-1.2.4/Makefile: @$(CD) $(BK_TOOLS)/gzip-1.2.4 && ./configure $(BK_ASSET_TOOL): @$(CD) tools/bk_asset_tool && cargo build --release @$(CP) tools/bk_asset_tool/target/release/bk_asset_tool $@ # Build tools $(BK_TOOLS)/%: $(BK_TOOLS)/gzip-1.2.4/gzip $(call print1,Compiling build tool:,$@) @$(CD) $(BK_TOOLS) && $(MAKE) $* $(BK_CRC) : g++ $@.cpp -o $@ # Combined symbol addresses file $(SYMBOL_ADDRS): $(SYMBOL_ADDR_FILES) $(call print0,Combining symbol address files) @$(CAT) symbol_addrs.*.$(VERSION).txt > $@ # Shorthand rules for each overlay (e.g. SM) $(OVERLAYS): %: verify-% clean: $(call print0,Cleaning build artifacts) @$(RM) -rf $(BUILD_ROOT) @$(RM) -rf $(BIN_ROOT) @$(RM) -rf $(NONMATCHING_DIR) @$(RM) -rf $(ASM_ROOT)/*.s @$(RM) -rf $(addprefix $(ASM_ROOT)/,$(filter-out core1,$(OVERLAYS))) @$(RM) -rf $(ASM_ROOT)/core1/*.s @$(RM) -rf $(ASM_ROOT)/core1/os @$(RM) -f undefined_syms_auto* undefined_funcs_auto* @$(RM) -f *.ld @$(RM) -f $(SYMBOL_ADDRS) # Per-file flag definitions build/$(VERSION)/src/core1/io/%.c.o: OPT_FLAGS = -O1 build/$(VERSION)/src/core1/io/pimgr.c.o: OPT_FLAGS = -O1 build/$(VERSION)/src/core1/done/io/%.c.o: OPT_FLAGS = -O1 build/$(VERSION)/src/core1/os/%.c.o: OPT_FLAGS = -O1 build/$(VERSION)/src/core1/code_2D2D0.c.o: OPT_FLAGS = -O1 build/$(VERSION)/src/core1/done/os/%.c.o: OPT_FLAGS = -O1 build/$(VERSION)/src/core1/code_21A10.c.o: INCLUDE_CFLAGS = -I . -I include -I include/2.0L -I include/2.0L/PR build/$(VERSION)/src/core1/code_21A10.c.o: OPT_FLAGS = -O3 build/$(VERSION)/src/core1/done/gu/%.c.o: OPT_FLAGS = -O3 build/$(VERSION)/src/core1/done/gu/%.c.o: INCLUDE_CFLAGS = -I . -I include -I include/2.0L -I include/2.0L/PR build/$(VERSION)/src/core1/gu/mtxutil.c.o: OPT_FLAGS = -O2 build/$(VERSION)/src/core1/gu/rotate.c.o: OPT_FLAGS = -O2 build/$(VERSION)/src/core1/done/audio/%.c.o: INCLUDE_CFLAGS = -I . -I include -I include/2.0L -I include/2.0L/PR build/$(VERSION)/src/core1/done/audio/%.c.o: OPT_FLAGS = -O3 # build/$(VERSION)/src/core1/code_21CB0.c.o: INCLUDE_CFLAGS = -I . -I include -I include/2.0L -I include/2.0L/PR # build/$(VERSION)/src/core1/code_21CB0.c.o: OPT_FLAGS = -O3 build/$(VERSION)/src/core1/done/io/sptask.c.o: OPT_FLAGS = -O1 build/$(VERSION)/src/core1/done/ll.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/core1/done/ll.c.o: MIPSBIT := -mips3 -o32 build/$(VERSION)/src/bk_boot_27F0.c.o: OPT_FLAGS = -O2 build/$(VERSION)/src/done/destroythread.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/pirawdma.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/thread.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/pimgr.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/getthreadid.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/setthreadpri.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/createthread.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/yieldthread.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/setglobalintmask.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/recvmesg.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/startthread.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/devmgr.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/sendmesg.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/pigetstat.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/si.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/resetglobalintmask.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/epirawwrite.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/epirawread.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/createmesgqueue.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/leodiskinit.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/virtualtophysical.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/ll.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/ll.c.o: MIPSBIT := -mips3 -o32 build/$(VERSION)/src/done/sirawwrite.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/sirawread.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/initialize.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/pirawread.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/seteventmesg.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/siacs.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/cartrominit.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/leointerrupt.c.o: OPT_FLAGS := -O1 build/$(VERSION)/src/done/epirawdma.c.o: OPT_FLAGS := -O1 # Disable implicit rules MAKEFLAGS += -r # Disable built-in rules .SUFFIXES: # Phony targets .PHONY: all clean verify $(OVERLAYS) progress $(addprefix progress-,$(OVERLAYS)) # Set up pipefail SHELL = /bin/bash -e -o pipefail # Debug variable print target print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true