Merge pull request #1950 from Icedude907/build-makefile-cleanup

[Build System Rewrite] Refactored `Makefile`
This commit is contained in:
GriffinR 2024-08-31 00:36:50 -04:00 committed by GitHub
commit 4d74dd5e33
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 175 additions and 183 deletions

354
Makefile
View file

@ -1,6 +1,22 @@
TOOLCHAIN := $(DEVKITARM)
COMPARE ?= 0
# GBA rom header
TITLE := POKEMON EMER
GAME_CODE := BPEE
MAKER_CODE := 01
REVISION := 0
MODERN ?= 0
# `File name`.gba ('_modern' will be appended to the modern builds)
FILE_NAME := pokeemerald
BUILD_DIR := build
# Builds the ROM using a modern compiler
MODERN ?= 0
# Compares the ROM to a checksum of the original - only makes sense using when non-modern
COMPARE ?= 0
ifeq (modern,$(MAKECMDGOALS))
MODERN := 1
endif
ifeq (compare,$(MAKECMDGOALS))
COMPARE := 1
endif
@ -8,45 +24,29 @@ endif
# Default make rule
all: rom
# Toolchain selection
TOOLCHAIN := $(DEVKITARM)
# don't use dkP's base_tools anymore
# because the redefinition of $(CC) conflicts
# with when we want to use $(CC) to preprocess files
# thus, manually create the variables for the bin
# files, or use arm-none-eabi binaries on the system
# if dkP is not installed on this system
ifneq (,$(TOOLCHAIN))
ifneq ($(wildcard $(TOOLCHAIN)/bin),)
export PATH := $(TOOLCHAIN)/bin:$(PATH)
endif
ifneq ($(wildcard $(TOOLCHAIN)/bin),)
export PATH := $(TOOLCHAIN)/bin:$(PATH)
endif
endif
PREFIX := arm-none-eabi-
OBJCOPY := $(PREFIX)objcopy
OBJDUMP := $(PREFIX)objdump
AS := $(PREFIX)as
LD := $(PREFIX)ld
# note: the makefile must be set up so MODERNCC is never called
# if MODERN=0
MODERNCC := $(PREFIX)gcc
PATH_MODERNCC := PATH="$(PATH)" $(MODERNCC)
ifeq ($(OS),Windows_NT)
EXE := .exe
else
EXE :=
endif
TITLE := POKEMON EMER
GAME_CODE := BPEE
MAKER_CODE := 01
REVISION := 0
MODERN ?= 0
ifeq (modern,$(MAKECMDGOALS))
MODERN := 1
ifeq ($(OS),Windows_NT)
EXE := .exe
endif
# use arm-none-eabi-cpp for macOS
@ -66,22 +66,29 @@ else
CPP := $(PREFIX)cpp
endif
ROM_NAME := pokeemerald.gba
ROM_NAME := $(FILE_NAME).gba
OBJ_DIR_NAME := $(BUILD_DIR)/emerald
MODERN_ROM_NAME := $(FILE_NAME)_modern.gba
MODERN_OBJ_DIR_NAME := $(BUILD_DIR)/modern
ELF_NAME := $(ROM_NAME:.gba=.elf)
MAP_NAME := $(ROM_NAME:.gba=.map)
OBJ_DIR_NAME := build/emerald
MODERN_ROM_NAME := pokeemerald_modern.gba
MODERN_ELF_NAME := $(MODERN_ROM_NAME:.gba=.elf)
MODERN_MAP_NAME := $(MODERN_ROM_NAME:.gba=.map)
MODERN_OBJ_DIR_NAME := build/modern
SHELL := bash -o pipefail
ELF = $(ROM:.gba=.elf)
MAP = $(ROM:.gba=.map)
SYM = $(ROM:.gba=.sym)
# Pick our active variables
ifeq ($(MODERN),0)
ROM := $(ROM_NAME)
OBJ_DIR := $(OBJ_DIR_NAME)
else
ROM := $(MODERN_ROM_NAME)
OBJ_DIR := $(MODERN_OBJ_DIR_NAME)
endif
ELF := $(ROM:.gba=.elf)
MAP := $(ROM:.gba=.map)
SYM := $(ROM:.gba=.sym)
# Commonly used directories
C_SUBDIR = src
GFLIB_SUBDIR = gflib
ASM_SUBDIR = asm
@ -99,34 +106,41 @@ DATA_ASM_BUILDDIR = $(OBJ_DIR)/$(DATA_ASM_SUBDIR)
SONG_BUILDDIR = $(OBJ_DIR)/$(SONG_SUBDIR)
MID_BUILDDIR = $(OBJ_DIR)/$(MID_SUBDIR)
SHELL := bash -o pipefail
# Set flags for tools
ASFLAGS := -mcpu=arm7tdmi --defsym MODERN=$(MODERN)
ifeq ($(MODERN),0)
CC1 := tools/agbcc/bin/agbcc$(EXE)
override CFLAGS += -mthumb-interwork -Wimplicit -Wparentheses -Werror -O2 -fhex-asm -g
ROM := $(ROM_NAME)
OBJ_DIR := $(OBJ_DIR_NAME)
LIBPATH := -L ../../tools/agbcc/lib
LIB := $(LIBPATH) -lgcc -lc -L../../libagbsyscall -lagbsyscall
else
CC1 = $(shell $(PATH_MODERNCC) --print-prog-name=cc1) -quiet
override CFLAGS += -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
ROM := $(MODERN_ROM_NAME)
OBJ_DIR := $(MODERN_OBJ_DIR_NAME)
LIBPATH := -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libgcc.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libnosys.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libc.a))"
LIB := $(LIBPATH) -lc -lnosys -lgcc -L../../libagbsyscall -lagbsyscall
endif
INCLUDE_DIRS := include
INCLUDE_CPP_ARGS := $(INCLUDE_DIRS:%=-iquote %)
INCLUDE_SCANINC_ARGS := $(INCLUDE_DIRS:%=-I %)
CPPFLAGS := -iquote include -iquote $(GFLIB_SUBDIR) -Wno-trigraphs -DMODERN=$(MODERN)
ifneq ($(MODERN),1)
CPPFLAGS += -I tools/agbcc/include -I tools/agbcc -nostdinc -undef
O_LEVEL ?= 2
CPPFLAGS := $(INCLUDE_CPP_ARGS) -iquote $(GFLIB_SUBDIR) -Wno-trigraphs -DMODERN=$(MODERN)
ifeq ($(MODERN),0)
CPPFLAGS += -I tools/agbcc/include -I tools/agbcc -nostdinc -undef
CC1 := tools/agbcc/bin/agbcc$(EXE)
override CFLAGS += -mthumb-interwork -Wimplicit -Wparentheses -Werror -O$(O_LEVEL) -fhex-asm -g
LIBPATH := -L ../../tools/agbcc/lib
LIB := $(LIBPATH) -lgcc -lc -L../../libagbsyscall -lagbsyscall
else
# Note: The makefile must be set up to not call these if modern == 0
MODERNCC := $(PREFIX)gcc
PATH_MODERNCC := PATH="$(PATH)" $(MODERNCC)
CC1 := $(shell $(PATH_MODERNCC) --print-prog-name=cc1) -quiet
override CFLAGS += -mthumb -mthumb-interwork -O$(O_LEVEL) -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
LIBPATH := -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libgcc.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libnosys.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libc.a))"
LIB := $(LIBPATH) -lc -lnosys -lgcc -L../../libagbsyscall -lagbsyscall
endif
# Enable debug info if set
ifeq ($(DINFO),1)
override CFLAGS += -g
endif
# Variable filled out in other make files
AUTO_GEN_TARGETS :=
include make_tools.mk
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c
# Tool executables
GFX := $(TOOLS_DIR)/gbagfx/gbagfx$(EXE)
AIF := $(TOOLS_DIR)/aif2pcm/aif2pcm$(EXE)
MID := $(TOOLS_DIR)/mid2agb/mid2agb$(EXE)
@ -138,6 +152,7 @@ MAPJSON := $(TOOLS_DIR)/mapjson/mapjson$(EXE)
JSONPROC := $(TOOLS_DIR)/jsonproc/jsonproc$(EXE)
PERL := perl
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c
MAKEFLAGS += --no-print-directory
@ -147,39 +162,36 @@ MAKEFLAGS += --no-print-directory
.SECONDARY:
# Delete files that weren't built properly
.DELETE_ON_ERROR:
# Secondary expansion is required for dependency variables in object rules.
.SECONDEXPANSION:
.PHONY: all rom clean compare tidy mostlyclean libagbsyscall modern tidymodern tidynonmodern
RULES_NO_SCAN += libagbsyscall clean clean-assets tidy tidymodern tidynonmodern generated clean-generated
.PHONY: all rom modern compare
.PHONY: $(RULES_NO_SCAN)
infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst __SPACE__, ,$(line))))
# Build tools when building the rom
# Disable dependency scanning for clean/tidy/tools
# Use a separate minimal makefile for speed
# Since we don't need to reload most of this makefile
ifeq (,$(filter-out all rom compare modern libagbsyscall syms,$(MAKECMDGOALS)))
$(call infoshell, $(MAKE) -f make_tools.mk)
$(call infoshell, $(MAKE) generated)
else
NODEP ?= 1
endif
# check if we need to scan dependencies based on the rule
ifeq (,$(MAKECMDGOALS))
SCAN_DEPS ?= 1
else
# clean, tidy, tools, mostlyclean, clean-tools, $(TOOLDIRS), tidymodern, tidynonmodern don't even build the ROM
# libagbsyscall does its own thing
ifeq (,$(filter-out clean tidy tools mostlyclean clean-tools $(TOOLDIRS) tidymodern tidynonmodern libagbsyscall,$(MAKECMDGOALS)))
SCAN_DEPS ?= 0
else
SCAN_DEPS ?= 1
# Check if we need to scan dependencies based on the chosen rule OR user preference
NODEP ?= 0
# Check if we need to pre-build tools and generate assets based on the chosen rule.
SETUP_PREREQS ?= 1
# Disable dependency scanning for rules that don't need it.
ifneq (,$(MAKECMDGOALS))
ifeq (,$(filter-out $(RULES_NO_SCAN),$(MAKECMDGOALS)))
NODEP := 1
SETUP_PREREQS := 0
endif
endif
ifeq ($(SCAN_DEPS),1)
ifeq ($(SETUP_PREREQS),1)
# If set on: Default target or a rule requiring a scan
# Forcibly execute `make tools` since we need them for what we are doing.
$(call infoshell, $(MAKE) -f make_tools.mk)
# Oh and also generate mapjson sources before we use `SCANINC`.
$(call infoshell, $(MAKE) generated)
endif
# Collect sources
C_SRCS_IN := $(wildcard $(C_SUBDIR)/*.c $(C_SUBDIR)/*/*.c $(C_SUBDIR)/*/*/*.c)
C_SRCS := $(foreach src,$(C_SRCS_IN),$(if $(findstring .inc.c,$(src)),,$(src)))
C_OBJS := $(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(C_SRCS))
@ -187,7 +199,7 @@ C_OBJS := $(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(C_SRCS))
GFLIB_SRCS := $(wildcard $(GFLIB_SUBDIR)/*.c)
GFLIB_OBJS := $(patsubst $(GFLIB_SUBDIR)/%.c,$(GFLIB_BUILDDIR)/%.o,$(GFLIB_SRCS))
C_ASM_SRCS += $(wildcard $(C_SUBDIR)/*.s $(C_SUBDIR)/*/*.s $(C_SUBDIR)/*/*/*.s)
C_ASM_SRCS := $(wildcard $(C_SUBDIR)/*.s $(C_SUBDIR)/*/*.s $(C_SUBDIR)/*/*/*.s)
C_ASM_OBJS := $(patsubst $(C_SUBDIR)/%.s,$(C_BUILDDIR)/%.o,$(C_ASM_SRCS))
ASM_SRCS := $(wildcard $(ASM_SUBDIR)/*.s)
@ -210,29 +222,29 @@ OBJS_REL := $(patsubst $(OBJ_DIR)/%,%,$(OBJS))
SUBDIRS := $(sort $(dir $(OBJS)))
$(shell mkdir -p $(SUBDIRS))
endif
syms: $(SYM)
# Pretend rules that are actually flags defer to `make all`
modern: all
compare: all
# Other rules
rom: $(ROM)
ifeq ($(COMPARE),1)
@$(SHA1) rom.sha1
endif
# For contributors to make sure a change didn't affect the contents of the ROM.
compare: all
syms: $(SYM)
clean: mostlyclean clean-tools
clean: tidy clean-tools clean-generated clean-assets
@$(MAKE) clean -C libagbsyscall
mostlyclean: tidynonmodern tidymodern
find sound -iname '*.bin' -exec rm {} +
clean-assets:
rm -f $(MID_SUBDIR)/*.s
find . \( -iname '*.1bpp' -o -iname '*.4bpp' -o -iname '*.8bpp' -o -iname '*.gbapal' -o -iname '*.lz' -o -iname '*.rl' -o -iname '*.latfont' -o -iname '*.hwjpnfont' -o -iname '*.fwjpnfont' \) -exec rm {} +
rm -f $(DATA_ASM_SUBDIR)/layouts/layouts.inc $(DATA_ASM_SUBDIR)/layouts/layouts_table.inc
rm -f $(DATA_ASM_SUBDIR)/maps/connections.inc $(DATA_ASM_SUBDIR)/maps/events.inc $(DATA_ASM_SUBDIR)/maps/groups.inc $(DATA_ASM_SUBDIR)/maps/headers.inc
find sound -iname '*.bin' -exec rm {} +
find . \( -iname '*.1bpp' -o -iname '*.4bpp' -o -iname '*.8bpp' -o -iname '*.gbapal' -o -iname '*.lz' -o -iname '*.rl' -o -iname '*.latfont' -o -iname '*.hwjpnfont' -o -iname '*.fwjpnfont' \) -exec rm {} +
find $(DATA_ASM_SUBDIR)/maps \( -iname 'connections.inc' -o -iname 'events.inc' -o -iname 'header.inc' \) -exec rm {} +
rm -f $(AUTO_GEN_TARGETS)
@$(MAKE) clean -C libagbsyscall
tidy: tidynonmodern tidymodern
@ -244,10 +256,7 @@ tidymodern:
rm -f $(MODERN_ROM_NAME) $(MODERN_ELF_NAME) $(MODERN_MAP_NAME)
rm -rf $(MODERN_OBJ_DIR_NAME)
ifneq ($(MODERN),0)
$(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member
endif
# Other rules
include graphics_file_rules.mk
include map_data_rules.mk
include spritesheet_rules.mk
@ -271,119 +280,101 @@ generated: $(AUTO_GEN_TARGETS)
$(CRY_SUBDIR)/%.bin: $(CRY_SUBDIR)/%.aif ; $(AIF) $< $@ --compress
sound/%.bin: sound/%.aif ; $(AIF) $< $@
# NOTE: Tools must have been built prior (FIXME)
generated: tools $(AUTO_GEN_TARGETS)
clean-generated:
-rm -f $(AUTO_GEN_TARGETS)
ifeq ($(MODERN),0)
$(C_BUILDDIR)/libc.o: CC1 := $(TOOLS_DIR)/agbcc/bin/old_agbcc$(EXE)
$(C_BUILDDIR)/libc.o: CFLAGS := -O2
$(C_BUILDDIR)/siirtc.o: CFLAGS := -mthumb-interwork
$(C_BUILDDIR)/agb_flash.o: CFLAGS := -O -mthumb-interwork
$(C_BUILDDIR)/agb_flash_1m.o: CFLAGS := -O -mthumb-interwork
$(C_BUILDDIR)/agb_flash_mx.o: CFLAGS := -O -mthumb-interwork
$(C_BUILDDIR)/m4a.o: CC1 := $(TOOLS_DIR)/agbcc/bin/old_agbcc$(EXE)
$(C_BUILDDIR)/m4a.o: CC1 := tools/agbcc/bin/old_agbcc$(EXE)
$(C_BUILDDIR)/record_mixing.o: CFLAGS += -ffreestanding
$(C_BUILDDIR)/librfu_intr.o: CC1 := $(TOOLS_DIR)/agbcc/bin/agbcc_arm$(EXE)
$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -O2 -mthumb-interwork -quiet
else
$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
$(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member
endif
ifeq ($(DINFO),1)
override CFLAGS += -g
endif
# Dependency rules (for the *.c & *.s sources to .o files)
# Have to be explicit or else missing files won't be reported.
# The dep rules have to be explicit or else missing files won't be reported.
# As a side effect, they're evaluated immediately instead of when the rule is invoked.
# It doesn't look like $(shell) can be deferred so there might not be a better way.
# It doesn't look like $(shell) can be deferred so there might not be a better way (Icedude_907: there is soon).
ifeq ($(SCAN_DEPS),1)
ifeq ($(NODEP),1)
$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.c
ifeq (,$(KEEP_TEMPS))
@echo "$(CC1) <flags> -o $@ $<"
@$(CPP) $(CPPFLAGS) $< | $(PREPROC) -i $< charmap.txt | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ -
else
@$(CPP) $(CPPFLAGS) $< -o $(C_BUILDDIR)/$*.i
@$(PREPROC) $(C_BUILDDIR)/$*.i charmap.txt | $(CC1) $(CFLAGS) -o $(C_BUILDDIR)/$*.s
@echo -e ".text\n\t.align\t2, 0\n" >> $(C_BUILDDIR)/$*.s
$(AS) $(ASFLAGS) -o $@ $(C_BUILDDIR)/$*.s
endif
else
# For C dependencies.
# Args: $1 = Output file without extension (build/assets/src/data), $2 = Input file (src/data.c)
define C_DEP
$1: $2 $$(shell $(SCANINC) -I include -I $(TOOLS_DIR)/agbcc/include -I gflib $2)
ifeq (,$$(KEEP_TEMPS))
@echo "$$(CC1) <flags> -o $$@ $$<"
@$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) -i $$< charmap.txt | $$(CC1) $$(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $$(AS) $$(ASFLAGS) -o $$@ -
else
@$$(CPP) $$(CPPFLAGS) $$< -o $$(C_BUILDDIR)/$3.i
@$$(PREPROC) $$(C_BUILDDIR)/$3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $$(C_BUILDDIR)/$3.s
@echo -e ".text\n\t.align\t2, 0\n" >> $$(C_BUILDDIR)/$3.s
$$(AS) $$(ASFLAGS) -o $$@ $$(C_BUILDDIR)/$3.s
endif
$(call C_DEP_IMPL,$1,$2,$1)
endef
$(foreach src, $(C_SRCS), $(eval $(call C_DEP,$(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(src)),$(src),$(patsubst $(C_SUBDIR)/%.c,%,$(src)))))
endif
ifeq ($(NODEP),1)
$(GFLIB_BUILDDIR)/%.o: $(GFLIB_SUBDIR)/%.c $$(c_dep)
# Internal implementation details.
# $1: Output file without extension, $2 input file, $3 temp path (if keeping)
define C_DEP_IMPL
$1.o: $2
ifeq (,$(KEEP_TEMPS))
@echo "$(CC1) <flags> -o $@ $<"
@$(CPP) $(CPPFLAGS) $< | $(PREPROC) -i $< charmap.txt | $(CC1) $(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $(AS) $(ASFLAGS) -o $@ -
else
@$(CPP) $(CPPFLAGS) $< -o $(GFLIB_BUILDDIR)/$*.i
@$(PREPROC) $(GFLIB_BUILDDIR)/$*.i charmap.txt | $(CC1) $(CFLAGS) -o $(GFLIB_BUILDDIR)/$*.s
@echo -e ".text\n\t.align\t2, 0\n" >> $(GFLIB_BUILDDIR)/$*.s
$(AS) $(ASFLAGS) -o $@ $(GFLIB_BUILDDIR)/$*.s
endif
else
define GFLIB_DEP
$1: $2 $$(shell $(SCANINC) -I include -I $(TOOLS_DIR)/agbcc/include -I gflib $2)
ifeq (,$$(KEEP_TEMPS))
@echo "$$(CC1) <flags> -o $$@ $$<"
@$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) -i $$< charmap.txt | $$(CC1) $$(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $$(AS) $$(ASFLAGS) -o $$@ -
else
@$$(CPP) $$(CPPFLAGS) $$< -o $$(GFLIB_BUILDDIR)/$3.i
@$$(PREPROC) $$(GFLIB_BUILDDIR)/$3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $$(GFLIB_BUILDDIR)/$3.s
@echo -e ".text\n\t.align\t2, 0\n" >> $$(GFLIB_BUILDDIR)/$3.s
$$(AS) $$(ASFLAGS) -o $$@ $$(GFLIB_BUILDDIR)/$3.s
@$$(CPP) $$(CPPFLAGS) $$< -o $3.i
@$$(PREPROC) $3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $3.s
@echo -e ".text\n\t.align\t2, 0\n" >> $3.s
$$(AS) $$(ASFLAGS) -o $$@ $3.s
endif
$(call C_SCANINC,$1,$2)
endef
# Calls SCANINC to find dependencies
define C_SCANINC
ifneq ($(NODEP),1)
$1.o: $2 $$(shell $(SCANINC) $(INCLUDE_SCANINC_ARGS) -I tools/agbcc/include -I gflib $2)
endif
endef
$(foreach src, $(GFLIB_SRCS), $(eval $(call GFLIB_DEP,$(patsubst $(GFLIB_SUBDIR)/%.c,$(GFLIB_BUILDDIR)/%.o, $(src)),$(src),$(patsubst $(GFLIB_SUBDIR)/%.c,%, $(src)))))
# Create generic rules if no dependency scanning, else create the real rules
ifeq ($(NODEP),1)
$(eval $(call C_DEP,$(C_BUILDDIR)/%,$(C_SUBDIR)/%.c))
$(eval $(call C_DEP,$(GFLIB_BUILDDIR)/%,$(GFLIB_SUBDIR)/%.c))
else
$(foreach src,$(C_SRCS),$(eval $(call C_DEP,$(OBJ_DIR)/$(basename $(src)),$(src))))
$(foreach src,$(GFLIB_SRCS),$(eval $(call C_DEP,$(OBJ_DIR)/$(basename $(src)),$(src))))
endif
ifeq ($(NODEP),1)
$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.s
$(PREPROC) $< charmap.txt | $(CPP) -I include - | $(PREPROC) -i $$< charmap.txt | $(AS) $(ASFLAGS) -o $@
else
define SRC_ASM_DATA_DEP
$1: $2 $$(shell $(SCANINC) -I include -I "" $2)
$$(PREPROC) $$< charmap.txt | $$(CPP) -I include - | $$(PREPROC) -ie $$< charmap.txt | $$(AS) $$(ASFLAGS) -o $$@
endef
$(foreach src, $(C_ASM_SRCS), $(eval $(call SRC_ASM_DATA_DEP,$(patsubst $(C_SUBDIR)/%.s,$(C_BUILDDIR)/%.o, $(src)),$(src))))
endif
ifeq ($(NODEP),1)
$(ASM_BUILDDIR)/%.o: $(ASM_SUBDIR)/%.s
$(AS) $(ASFLAGS) -o $@ $<
else
# Similar methodology for Assembly files
# $1: Output path without extension, $2: Input file (`*.s`)
define ASM_DEP
$1: $2 $$(shell $(SCANINC) -I include -I "" $2)
$1.o: $2
$$(AS) $$(ASFLAGS) -o $$@ $$<
$(call ASM_SCANINC,$1,$2)
endef
# As above but first doing a preprocessor pass
define ASM_DEP_PREPROC
$1.o: $2
$$(PREPROC) $$< charmap.txt | $$(CPP) $(INCLUDE_SCANINC_ARGS) - | $$(PREPROC) -ie $$< charmap.txt | $$(AS) $$(ASFLAGS) -o $$@
$(call ASM_SCANINC,$1,$2)
endef
$(foreach src, $(ASM_SRCS), $(eval $(call ASM_DEP,$(patsubst $(ASM_SUBDIR)/%.s,$(ASM_BUILDDIR)/%.o, $(src)),$(src))))
endif
define ASM_SCANINC
ifneq ($(NODEP),1)
$1.o: $2 $$(shell $(SCANINC) $(INCLUDE_SCANINC_ARGS) -I "" $2)
endif
endef
# Dummy rules or real rules
ifeq ($(NODEP),1)
$(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s
$(PREPROC) $< charmap.txt | $(CPP) -I include - | $(PREPROC) -ie $$< charmap.txt | $(AS) $(ASFLAGS) -o $@
$(eval $(call ASM_DEP,$(ASM_BUILDDIR)/%,$(ASM_SUBDIR)/%.s))
$(eval $(call ASM_DEP_PREPROC,$(C_BUILDDIR)/%,$(C_SUBDIR)/%.s))
$(eval $(call ASM_DEP_PREPROC,$(DATA_ASM_BUILDDIR)/%,$(DATA_ASM_SUBDIR)/%.s))
else
$(foreach src, $(REGULAR_DATA_ASM_SRCS), $(eval $(call SRC_ASM_DATA_DEP,$(patsubst $(DATA_ASM_SUBDIR)/%.s,$(DATA_ASM_BUILDDIR)/%.o, $(src)),$(src))))
endif
$(foreach src, $(ASM_SRCS), $(eval $(call ASM_DEP,$(src:%.s=$(OBJ_DIR)/%),$(src))))
$(foreach src, $(C_ASM_SRCS), $(eval $(call ASM_DEP_PREPROC,$(src:%.s=$(OBJ_DIR)/%),$(src))))
$(foreach src, $(REGULAR_DATA_ASM_SRCS), $(eval $(call ASM_DEP_PREPROC,$(src:%.s=$(OBJ_DIR)/%),$(src))))
endif
# Additional rules
$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s
$(AS) $(ASFLAGS) -I sound -o $@ $<
@ -396,6 +387,7 @@ $(OBJ_DIR)/sym_common.ld: sym_common.txt $(C_OBJS) $(wildcard common_syms/*.txt)
$(OBJ_DIR)/sym_ewram.ld: sym_ewram.txt
$(RAMSCRGEN) ewram_data $< ENGLISH > $@
# Linker script
ifeq ($(MODERN),0)
LD_SCRIPT := ld_script.ld
LD_SCRIPT_DEPS := $(OBJ_DIR)/sym_bss.ld $(OBJ_DIR)/sym_common.ld $(OBJ_DIR)/sym_ewram.ld
@ -405,26 +397,24 @@ LD_SCRIPT_DEPS :=
endif
$(OBJ_DIR)/ld_script.ld: $(LD_SCRIPT) $(LD_SCRIPT_DEPS)
cd $(OBJ_DIR) && sed "s#tools/#../../tools/#g" ../../$(LD_SCRIPT) > ld_script.ld
sed "s#tools/#tools/#g" $(LD_SCRIPT) > $(OBJ_DIR)/ld_script.ld
LDFLAGS = -Map ../../$(MAP)
# Final rules
libagbsyscall:
@$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=$(MODERN)
# Elf from object files
$(ELF): $(OBJ_DIR)/ld_script.ld $(OBJS) libagbsyscall
@echo "cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld -o ../../$@ <objects> <lib>"
@cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld --print-memory-usage -o ../../$@ $(OBJS_REL) $(LIB) | cat
$(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent
# Builds the rom from the elf file
$(ROM): $(ELF)
$(OBJCOPY) -O binary $< $@
$(FIX) $@ -p --silent
modern: all
libagbsyscall:
@$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=$(MODERN)
###################
### Symbol file ###
###################
# Symbol file (`make syms`)
$(SYM): $(ELF)
$(OBJDUMP) -t $< | sort -u | grep -E "^0[2389]" | $(PERL) -p -e 's/^(\w{8}) (\w).{6} \S+\t(\w{8}) (\S+)$$/\1 \2 \3 \4/g' > $@

View file

@ -9,7 +9,9 @@ TOOL_NAMES := aif2pcm bin2c gbafix gbagfx jsonproc mapjson mid2agb preproc ramsc
TOOLDIRS := $(TOOL_NAMES:%=$(TOOLS_DIR)/%)
.PHONY: tools check-tools clean-tools $(TOOLDIRS)
# Tool making doesnt require a pokeemerald dependency scan.
RULES_NO_SCAN += tools check-tools clean-tools $(TOOLDIRS)
.PHONY: $(RULES_NO_SCAN)
tools: $(TOOLDIRS)