Reordered makefile.

Added some documentation and simplified dependency scanning.
This commit is contained in:
Icedude907 2023-11-12 13:20:09 +13:00
parent 7fa9819d9a
commit 2198ca31c7
2 changed files with 178 additions and 185 deletions

359
Makefile
View file

@ -1,6 +1,22 @@
TOOLCHAIN := $(DEVKITARM) # GBA rom header
COMPARE ?= 0 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)) ifeq (compare,$(MAKECMDGOALS))
COMPARE := 1 COMPARE := 1
endif endif
@ -8,45 +24,29 @@ endif
# Default make rule # Default make rule
all: rom all: rom
# Toolchain selection
TOOLCHAIN := $(DEVKITARM)
# don't use dkP's base_tools anymore # don't use dkP's base_tools anymore
# because the redefinition of $(CC) conflicts # because the redefinition of $(CC) conflicts
# with when we want to use $(CC) to preprocess files # with when we want to use $(CC) to preprocess files
# thus, manually create the variables for the bin # thus, manually create the variables for the bin
# files, or use arm-none-eabi binaries on the system # files, or use arm-none-eabi binaries on the system
# if dkP is not installed on this system # if dkP is not installed on this system
ifneq (,$(TOOLCHAIN)) ifneq (,$(TOOLCHAIN))
ifneq ($(wildcard $(TOOLCHAIN)/bin),) ifneq ($(wildcard $(TOOLCHAIN)/bin),)
export PATH := $(TOOLCHAIN)/bin:$(PATH) export PATH := $(TOOLCHAIN)/bin:$(PATH)
endif endif
endif endif
PREFIX := arm-none-eabi- PREFIX := arm-none-eabi-
OBJCOPY := $(PREFIX)objcopy OBJCOPY := $(PREFIX)objcopy
OBJDUMP := $(PREFIX)objdump OBJDUMP := $(PREFIX)objdump
AS := $(PREFIX)as AS := $(PREFIX)as
LD := $(PREFIX)ld 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 := EXE :=
endif ifeq ($(OS),Windows_NT)
EXE := .exe
TITLE := POKEMON EMER
GAME_CODE := BPEE
MAKER_CODE := 01
REVISION := 0
MODERN ?= 0
ifeq (modern,$(MAKECMDGOALS))
MODERN := 1
endif endif
# use arm-none-eabi-cpp for macOS # use arm-none-eabi-cpp for macOS
@ -66,22 +66,29 @@ else
CPP := $(PREFIX)cpp CPP := $(PREFIX)cpp
endif 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) ELF_NAME := $(ROM_NAME:.gba=.elf)
MAP_NAME := $(ROM_NAME:.gba=.map) 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_ELF_NAME := $(MODERN_ROM_NAME:.gba=.elf)
MODERN_MAP_NAME := $(MODERN_ROM_NAME:.gba=.map) MODERN_MAP_NAME := $(MODERN_ROM_NAME:.gba=.map)
MODERN_OBJ_DIR_NAME := build/modern
SHELL := /bin/bash -o pipefail # Pick our active variables
ifeq ($(MODERN),0)
ELF = $(ROM:.gba=.elf) ROM := $(ROM_NAME)
MAP = $(ROM:.gba=.map) OBJ_DIR := $(OBJ_DIR_NAME)
SYM = $(ROM:.gba=.sym) 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 C_SUBDIR = src
GFLIB_SUBDIR = gflib GFLIB_SUBDIR = gflib
ASM_SUBDIR = asm ASM_SUBDIR = asm
@ -99,34 +106,43 @@ DATA_ASM_BUILDDIR = $(OBJ_DIR)/$(DATA_ASM_SUBDIR)
SONG_BUILDDIR = $(OBJ_DIR)/$(SONG_SUBDIR) SONG_BUILDDIR = $(OBJ_DIR)/$(SONG_SUBDIR)
MID_BUILDDIR = $(OBJ_DIR)/$(MID_SUBDIR) MID_BUILDDIR = $(OBJ_DIR)/$(MID_SUBDIR)
SHELL := /bin/bash -o pipefail
# Set flags for tools
ASFLAGS := -mcpu=arm7tdmi --defsym MODERN=$(MODERN) ASFLAGS := -mcpu=arm7tdmi --defsym MODERN=$(MODERN)
ifeq ($(MODERN),0) INCLUDE_DIRS := include
CC1 := tools/agbcc/bin/agbcc$(EXE) INCLUDE_CPP_ARGS := $(INCLUDE_DIRS:%=-iquote %)
override CFLAGS += -mthumb-interwork -Wimplicit -Wparentheses -Werror -O2 -fhex-asm -g INCLUDE_SCANINC_ARGS := $(INCLUDE_DIRS:%=-I %)
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
CPPFLAGS := -iquote include -iquote $(GFLIB_SUBDIR) -Wno-trigraphs -DMODERN=$(MODERN) O_LEVEL ?= 2
ifneq ($(MODERN),1) CPPFLAGS := $(INCLUDE_CPP_ARGS) -iquote $(GFLIB_SUBDIR) -Wno-trigraphs -DMODERN=$(MODERN)
CPPFLAGS += -I tools/agbcc/include -I tools/agbcc -nostdinc -undef 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 endif
LDFLAGS = -Map ../../$(MAP) LDFLAGS = -Map ../../$(MAP)
# Variable filled out in other make files
AUTO_GEN_TARGETS := AUTO_GEN_TARGETS :=
include make_tools.mk include make_tools.mk
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c # Tool executables
GFX := $(TOOLS_DIR)/gbagfx/gbagfx$(EXE) GFX := $(TOOLS_DIR)/gbagfx/gbagfx$(EXE)
AIF := $(TOOLS_DIR)/aif2pcm/aif2pcm$(EXE) AIF := $(TOOLS_DIR)/aif2pcm/aif2pcm$(EXE)
MID := $(TOOLS_DIR)/mid2agb/mid2agb$(EXE) MID := $(TOOLS_DIR)/mid2agb/mid2agb$(EXE)
@ -138,6 +154,7 @@ MAPJSON := $(TOOLS_DIR)/mapjson/mapjson$(EXE)
JSONPROC := $(TOOLS_DIR)/jsonproc/jsonproc$(EXE) JSONPROC := $(TOOLS_DIR)/jsonproc/jsonproc$(EXE)
PERL := perl PERL := perl
SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c
MAKEFLAGS += --no-print-directory MAKEFLAGS += --no-print-directory
@ -147,39 +164,36 @@ MAKEFLAGS += --no-print-directory
.SECONDARY: .SECONDARY:
# Delete files that weren't built properly # Delete files that weren't built properly
.DELETE_ON_ERROR: .DELETE_ON_ERROR:
# Secondary expansion is required for dependency variables in object rules. # Secondary expansion is required for dependency variables in object rules.
.SECONDEXPANSION: .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)))) infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst __SPACE__, ,$(line))))
# Build tools when building the rom # Check if we need to scan dependencies based on the chosen rule OR user preference
# Disable dependency scanning for clean/tidy/tools NODEP ?= 0
# Use a separate minimal makefile for speed # Check if we need to pre-build tools and generate assets based on the chosen rule.
# Since we don't need to reload most of this makefile SETUP_PREREQS ?= 1
ifeq (,$(filter-out all rom compare modern libagbsyscall syms,$(MAKECMDGOALS))) # Disable dependency scanning for rules that don't need it.
$(call infoshell, $(MAKE) -f make_tools.mk) ifneq (,$(MAKECMDGOALS))
$(call infoshell, $(MAKE) generated) ifeq (,$(filter-out $(RULES_NO_SCAN),$(MAKECMDGOALS)))
else NODEP := 1
NODEP ?= 1 SETUP_PREREQS := 0
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
endif endif
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_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_SRCS := $(foreach src,$(C_SRCS_IN),$(if $(findstring .inc.c,$(src)),,$(src)))
C_OBJS := $(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(C_SRCS)) C_OBJS := $(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(C_SRCS))
@ -187,7 +201,7 @@ C_OBJS := $(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(C_SRCS))
GFLIB_SRCS := $(wildcard $(GFLIB_SUBDIR)/*.c) GFLIB_SRCS := $(wildcard $(GFLIB_SUBDIR)/*.c)
GFLIB_OBJS := $(patsubst $(GFLIB_SUBDIR)/%.c,$(GFLIB_BUILDDIR)/%.o,$(GFLIB_SRCS)) 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)) C_ASM_OBJS := $(patsubst $(C_SUBDIR)/%.s,$(C_BUILDDIR)/%.o,$(C_ASM_SRCS))
ASM_SRCS := $(wildcard $(ASM_SUBDIR)/*.s) ASM_SRCS := $(wildcard $(ASM_SUBDIR)/*.s)
@ -210,29 +224,29 @@ OBJS_REL := $(patsubst $(OBJ_DIR)/%,%,$(OBJS))
SUBDIRS := $(sort $(dir $(OBJS))) SUBDIRS := $(sort $(dir $(OBJS)))
$(shell mkdir -p $(SUBDIRS)) $(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) rom: $(ROM)
ifeq ($(COMPARE),1) ifeq ($(COMPARE),1)
@$(SHA1) rom.sha1 @$(SHA1) rom.sha1
endif endif
# For contributors to make sure a change didn't affect the contents of the ROM. syms: $(SYM)
compare: all
clean: mostlyclean clean-tools clean: tidy clean-tools clean-generated clean-assets
@$(MAKE) clean -C libagbsyscall
mostlyclean: tidynonmodern tidymodern clean-assets:
find sound -iname '*.bin' -exec rm {} +
rm -f $(MID_SUBDIR)/*.s 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)/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 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 {} + 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 tidy: tidynonmodern tidymodern
@ -244,18 +258,13 @@ tidymodern:
rm -f $(MODERN_ROM_NAME) $(MODERN_ELF_NAME) $(MODERN_MAP_NAME) rm -f $(MODERN_ROM_NAME) $(MODERN_ELF_NAME) $(MODERN_MAP_NAME)
rm -rf $(MODERN_OBJ_DIR_NAME) rm -rf $(MODERN_OBJ_DIR_NAME)
ifneq ($(MODERN),0) # Other rules
$(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member
endif
include graphics_file_rules.mk include graphics_file_rules.mk
include map_data_rules.mk include map_data_rules.mk
include spritesheet_rules.mk include spritesheet_rules.mk
include json_data_rules.mk include json_data_rules.mk
include songs.mk include songs.mk
generated: $(AUTO_GEN_TARGETS)
%.s: ; %.s: ;
%.png: ; %.png: ;
%.pal: ; %.pal: ;
@ -271,119 +280,101 @@ generated: $(AUTO_GEN_TARGETS)
$(CRY_SUBDIR)/%.bin: $(CRY_SUBDIR)/%.aif ; $(AIF) $< $@ --compress $(CRY_SUBDIR)/%.bin: $(CRY_SUBDIR)/%.aif ; $(AIF) $< $@ --compress
sound/%.bin: sound/%.aif ; $(AIF) $< $@ 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) ifeq ($(MODERN),0)
$(C_BUILDDIR)/libc.o: CC1 := $(TOOLS_DIR)/agbcc/bin/old_agbcc$(EXE) $(C_BUILDDIR)/libc.o: CC1 := tools/agbcc/bin/old_agbcc$(EXE)
$(C_BUILDDIR)/libc.o: CFLAGS := -O2 $(C_BUILDDIR)/libc.o: CFLAGS := -O2
$(C_BUILDDIR)/siirtc.o: CFLAGS := -mthumb-interwork $(C_BUILDDIR)/siirtc.o: CFLAGS := -mthumb-interwork
$(C_BUILDDIR)/agb_flash.o: CFLAGS := -O -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_1m.o: CFLAGS := -O -mthumb-interwork
$(C_BUILDDIR)/agb_flash_mx.o: CFLAGS := -O -mthumb-interwork $(C_BUILDDIR)/agb_flash_mx.o: CFLAGS := -O -mthumb-interwork
$(C_BUILDDIR)/m4a.o: CC1 := tools/agbcc/bin/old_agbcc$(EXE)
$(C_BUILDDIR)/m4a.o: CC1 := $(TOOLS_DIR)/agbcc/bin/old_agbcc$(EXE)
$(C_BUILDDIR)/record_mixing.o: CFLAGS += -ffreestanding $(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: CC1 := tools/agbcc/bin/agbcc_arm$(EXE)
$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -O2 -mthumb-interwork -quiet $(C_BUILDDIR)/librfu_intr.o: CFLAGS := -O2 -mthumb-interwork -quiet
else 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)/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 endif
ifeq ($(DINFO),1) # Dependency rules (for the *.c & *.s sources to .o files)
override CFLAGS += -g # Have to be explicit or else missing files won't be reported.
endif
# 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. # 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) # For C dependencies.
ifeq ($(NODEP),1) # Args: $1 = Output file without extension (build/assets/src/data), $2 = Input file (src/data.c)
$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.c
ifeq (,$(KEEP_TEMPS))
@echo "$(CC1) <flags> -o $@ $<"
@$(CPP) $(CPPFLAGS) $< | $(PREPROC) $< charmap.txt -i | $(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
define C_DEP define C_DEP
$1: $2 $$(shell $(SCANINC) -I include -I $(TOOLS_DIR)/agbcc/include -I gflib $2) $(call C_DEP_IMPL,$1,$2,$1)
ifeq (,$$(KEEP_TEMPS))
@echo "$$(CC1) <flags> -o $$@ $$<"
@$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) $$< charmap.txt -i | $$(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
endef endef
$(foreach src, $(C_SRCS), $(eval $(call C_DEP,$(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(src)),$(src),$(patsubst $(C_SUBDIR)/%.c,%,$(src))))) # Internal implementation details.
endif # $1: Output file without extension, $2 input file, $3 temp path (if keeping)
define C_DEP_IMPL
ifeq ($(NODEP),1) $1.o: $2
$(GFLIB_BUILDDIR)/%.o: $(GFLIB_SUBDIR)/%.c $$(c_dep)
ifeq (,$(KEEP_TEMPS)) ifeq (,$(KEEP_TEMPS))
@echo "$(CC1) <flags> -o $@ $<"
@$(CPP) $(CPPFLAGS) $< | $(PREPROC) $< charmap.txt -i | $(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 $$@ $$<" @echo "$$(CC1) <flags> -o $$@ $$<"
@$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) $$< charmap.txt -i | $$(CC1) $$(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $$(AS) $$(ASFLAGS) -o $$@ - @$$(CPP) $$(CPPFLAGS) $$< | $$(PREPROC) $$< charmap.txt -i | $$(CC1) $$(CFLAGS) -o - - | cat - <(echo -e ".text\n\t.align\t2, 0") | $$(AS) $$(ASFLAGS) -o $$@ -
else else
@$$(CPP) $$(CPPFLAGS) $$< -o $$(GFLIB_BUILDDIR)/$3.i @$$(CPP) $$(CPPFLAGS) $$< -o $3.i
@$$(PREPROC) $$(GFLIB_BUILDDIR)/$3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $$(GFLIB_BUILDDIR)/$3.s @$$(PREPROC) $3.i charmap.txt | $$(CC1) $$(CFLAGS) -o $3.s
@echo -e ".text\n\t.align\t2, 0\n" >> $$(GFLIB_BUILDDIR)/$3.s @echo -e ".text\n\t.align\t2, 0\n" >> $3.s
$$(AS) $$(ASFLAGS) -o $$@ $$(GFLIB_BUILDDIR)/$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 endif
endef 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 endif
ifeq ($(NODEP),1) # Similar methodology for Assembly files
$(C_BUILDDIR)/%.o: $(C_SUBDIR)/%.s # $1: Output path without extension, $2: Input file (`*.s`)
$(PREPROC) $< charmap.txt | $(CPP) -I include - | $(AS) $(ASFLAGS) -o $@
else
define SRC_ASM_DATA_DEP
$1: $2 $$(shell $(SCANINC) -I include -I "" $2)
$$(PREPROC) $$< charmap.txt | $$(CPP) -I include - | $$(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
define ASM_DEP define ASM_DEP
$1: $2 $$(shell $(SCANINC) -I include -I "" $2) $1.o: $2
$$(AS) $$(ASFLAGS) -o $$@ $$< $$(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) - | $$(AS) $$(ASFLAGS) -o $$@
$(call ASM_SCANINC,$1,$2)
endef 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) ifeq ($(NODEP),1)
$(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s $(eval $(call ASM_DEP,$(ASM_BUILDDIR)/%,$(ASM_SUBDIR)/%.s))
$(PREPROC) $< charmap.txt | $(CPP) -I include - | $(AS) $(ASFLAGS) -o $@ $(eval $(call ASM_DEP_PREPROC,$(C_BUILDDIR)/%,$(C_SUBDIR)/%.s))
$(eval $(call ASM_DEP_PREPROC,$(DATA_ASM_BUILDDIR)/%,$(DATA_ASM_SUBDIR)/%.s))
else else
$(foreach src, $(REGULAR_DATA_ASM_SRCS), $(eval $(call SRC_ASM_DATA_DEP,$(patsubst $(DATA_ASM_SUBDIR)/%.s,$(DATA_ASM_BUILDDIR)/%.o, $(src)),$(src)))) $(foreach src, $(ASM_SRCS), $(eval $(call ASM_DEP,$(src:%.s=$(OBJ_DIR)/%),$(src))))
endif $(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 endif
# Additional rules
$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s $(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s
$(AS) $(ASFLAGS) -I sound -o $@ $< $(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 $(OBJ_DIR)/sym_ewram.ld: sym_ewram.txt
$(RAMSCRGEN) ewram_data $< ENGLISH > $@ $(RAMSCRGEN) ewram_data $< ENGLISH > $@
# Linker script
ifeq ($(MODERN),0) ifeq ($(MODERN),0)
LD_SCRIPT := ld_script.txt LD_SCRIPT := ld_script.txt
LD_SCRIPT_DEPS := $(OBJ_DIR)/sym_bss.ld $(OBJ_DIR)/sym_common.ld $(OBJ_DIR)/sym_ewram.ld LD_SCRIPT_DEPS := $(OBJ_DIR)/sym_bss.ld $(OBJ_DIR)/sym_common.ld $(OBJ_DIR)/sym_ewram.ld
@ -405,25 +397,24 @@ LD_SCRIPT_DEPS :=
endif endif
$(OBJ_DIR)/ld_script.ld: $(LD_SCRIPT) $(LD_SCRIPT_DEPS) $(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
# Final rules
libagbsyscall:
@$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=$(MODERN)
# Elf from object files
$(ELF): $(OBJ_DIR)/ld_script.ld $(OBJS) libagbsyscall $(ELF): $(OBJ_DIR)/ld_script.ld $(OBJS) libagbsyscall
@echo "cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld -o ../../$@ <objects> <lib>" @echo "cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld -o ../../$@ <objects> <lib>"
@cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld -o ../../$@ $(OBJS_REL) $(LIB) @cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ld_script.ld -o ../../$@ $(OBJS_REL) $(LIB)
$(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent
# Builds the rom from the elf file
$(ROM): $(ELF) $(ROM): $(ELF)
$(OBJCOPY) -O binary $< $@ $(OBJCOPY) -O binary $< $@
$(FIX) $@ -p --silent $(FIX) $@ -p --silent
modern: all # Symbol file (`make syms`)
libagbsyscall:
@$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=$(MODERN)
###################
### Symbol file ###
###################
$(SYM): $(ELF) $(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' > $@ $(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)/%) TOOLDIRS := $(TOOL_NAMES:%=$(TOOLS_DIR)/%)
.PHONY: tools check-tools clean-tools $(TOOLDIRS) $(CHECKTOOLDIRS) # Tool making doesnt require a pokeemerald dependency scan.
RULES_NO_SCAN += tools check-tools clean-tools $(TOOLDIRS) $(CHECKTOOLDIRS)
.PHONY: $(RULES_NO_SCAN)
tools: $(TOOLDIRS) tools: $(TOOLDIRS)
check-tools: $(CHECKTOOLDIRS) check-tools: $(CHECKTOOLDIRS)