-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathMakefile
233 lines (177 loc) · 7.36 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
BASEROM_SHA1 := 67f8adacff79c15d028fffd90de3a77d9ad0602d
REV1_SHA1 := e0aaca45045e408e7e1072bde5b39278111e1952
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
ifeq (,$(wildcard baserom.gba))
$(error No ROM provided. Please place an unmodified ROM named "baserom.gba" in the root folder)
endif
ifneq ($(shell sha1sum -t baserom.gba), $(BASEROM_SHA1) baserom.gba)
$(error Provided ROM is not correct)
endif
SHELL := /bin/bash
CPP := $(CC) -E
include $(DEVKITARM)/base_rules
CROSS := arm-none-eabi-
OBJCOPY := $(CROSS)objcopy
LD := $(CROSS)gcc
AS := $(CROSS)as
CC1 := tools/agbcc/bin/agbcc
# Verbose toggle
V := @
ifeq (VERBOSE, 1)
V=
endif
# Colors
NO_COL := \033[0m
GREEN := \033[0;32m
BLUE := \033[0;34m
YELLOW := \033[0;33m
# Generic print function for make rules
define print
$(V)echo -e "$(GREEN)$(1) $(YELLOW)$(2)$(GREEN) -> $(BLUE)$(3)$(NO_COL)"
endef
# Whether to build a byte-for-byte matching ROM
NONMATCHING ?= 0
# Revision to build
REV ?= 0
ifeq ($(REV), 0)
TARGET := rhythmtengoku
TARGET_SHA1 := $(BASEROM_SHA1)
else
TARGET := rhythmtengoku_rev1
TARGET_SHA1 := $(REV1_SHA1)
endif
# Preprocessor defines
DEFINES := REV=$(REV)
C_DEFINES := $(foreach d,$(DEFINES),-D$(d))
CFLAGS := -mthumb-interwork -Wparentheses -O2 -fhex-asm
CPPFLAGS := -I tools/agbcc -I tools/agbcc/include -I . -iquote include -nostdinc -undef $(C_DEFINES)
#---------------------------------------------------------------------------------
BUILD := build
SOURCES := src $(shell find src -type d)
ASM := asm
INCLUDES := include
BIN := bin
DATA := data
SCENE_DATA := $(shell find $(DATA)/scenes -type d)
LEVEL_DATA := $(DATA)/levels
GAMES := games
GAME_DATA := $(shell find $(GAMES) -type d)
GRAPHICS := $(shell find graphics -type d) $(shell find $(GAMES) -type d -name "graphics")
AUDIO := audio
MUSIC := $(AUDIO)/sequences
SFX := $(AUDIO)/samples
C_DIRS := $(SOURCES) $(AUDIO) $(GRAPHICS) $(DATA) $(SCENE_DATA) $(LEVEL_DATA) $(GAME_DATA)
C_DIRS := $(sort $(C_DIRS)) # remove duplicates
ASM_DIRS := $(ASM) $(DATA) $(SCENE_DATA) $(LEVEL_DATA)
BS_DIRS := $(GAME_DATA) $(SCENE_DATA)
ALL_DIRS := $(BIN) $(ASM_DIRS) $(C_DIRS) $(MUSIC) $(SFX)
ALL_DIRS := $(sort $(ALL_DIRS)) # remove duplicates
BUILD_DIRS := $(BUILD) $(addprefix $(BUILD)/,$(ALL_DIRS))
ifeq ($(NONMATCHING), 0)
LD_SCRIPT := rt.ld
else
LD_SCRIPT := rt_modern.ld
endif
UNDEFINED_SYMS := undefined_syms.ld
#---------------------------------------------------------------------------------
export OUTPUT := $(BUILD)/$(TARGET)
CFILES := $(foreach dir,$(C_DIRS),$(wildcard $(dir)/*.c))
SFILES := $(foreach dir,$(ASM_DIRS),$(wildcard $(dir)/*.s)) $(foreach dir,$(BS_DIRS),$(wildcard $(dir)/*.bs))
BINFILES := $(foreach dir,$(BIN),$(wildcard $(dir)/*.bin)) $(foreach dir,$(MUSIC),$(wildcard $(dir)/*.mid)) $(foreach dir,$(GRAPHICS),$(wildcard $(dir)/*.bin))
WAVFILES := $(foreach dir,$(SFX),$(wildcard $(dir)/*.wav))
JSONFILES := $(foreach dir,$(AUDIO),$(wildcard $(dir)/*.json))
CFILES := $(filter-out %.inc.c, $(CFILES))
PCMFILES := $(addprefix $(BUILD)/,$(WAVFILES:.wav=.pcm))
OFILES_JSON := $(addprefix $(BUILD)/,$(JSONFILES:.json=.json.c.o))
OFILES_BIN := $(addprefix $(BUILD)/,$(addsuffix .o,$(BINFILES)))
OFILES_SOURCES := $(addprefix $(BUILD)/,$(addsuffix .o,$(SFILES))) $(addprefix $(BUILD)/,$(addsuffix .o,$(CFILES)))
OFILES := $(OFILES_BIN) $(OFILES_SOURCES) $(OFILES_JSON)
INCLUDE := -I $(foreach dir,$(INCLUDES),$(wildcard $(dir)/*.h)) \
-I $(foreach dir,$(LIBDIRS),-I $(dir)/include) \
-I $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
.PHONY: default clean distclean rebuild
.SECONDARY:
#---------------------------------------------------------------------------------
# If nonmatching, print a generic message
# otherwise check if the ROM matches the official ROM
default: $(OUTPUT).gba
$(V)if [ "$(NONMATCHING)" = "1" ]; then \
echo "Build succeeded!"; \
else \
if [ "$(shell sha1sum -t $(OUTPUT).gba)" = "$(TARGET_SHA1) $(OUTPUT).gba" ]; then \
echo "$(TARGET).gba: OK"; \
else \
echo "The build succeeded, but did not match the official ROM."; \
fi; \
fi \
#---------------------------------------------------------------------------------
clean:
$(V)echo clean ...
$(V)rm -fr $(filter-out build/audio, $(wildcard build/*))
$(V)rm -fr $(filter-out build/audio/samples build/audio/sequences, $(wildcard build/audio/*))
distclean:
$(V)echo full clean ...
$(V)rm -fr $(BUILD)
#---------------------------------------------------------------------------------
rebuild: clean default
#---------------------------------------------------------------------------------
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(BUILD_DIRS):
$(V)echo -e "$(GREEN)Creating build directory: $(YELLOW)$@$(NO_COL)"
$(V)mkdir -p $@
$(OUTPUT).gba : $(OUTPUT).elf
$(V)$(OBJCOPY) --pad-to=0x1000000 --gap-fill=0x00 -O binary $< $@
$(V)echo "ROM Assembled!"
$(OUTPUT).elf : $(OFILES)
$(V)echo "Building ROM..."
$(V)$(LD) $(OFILES) tools/agbcc/lib/libgcc.a tools/agbcc/lib/libc.a -T $(LD_SCRIPT) -T $(UNDEFINED_SYMS) -Wl,--no-warn-rwx-segments,-Map $(@:.elf=.map) -nostartfiles -o $@
# Binary data
$(BUILD)/%.bin.o $(BUILD)/%.bin.h : %.bin | $(BUILD_DIRS)
$(call print,Copying binary file:,$<,$@)
$(V)bin2s -a 4 -H $(BUILD)/$<.h $< | $(AS) -o $(BUILD)/$<.o
# MIDI files
$(BUILD)/%.mid.o $(BUILD)/%.mid.h : %.mid | $(BUILD_DIRS)
$(call print,Copying MIDI file:,$<,$@)
$(V)bin2s -a 4 -H $(BUILD)/$<.h $< | $(AS) -o $(BUILD)/$<.o
# WAV files
$(BUILD)/%.pcm : %.wav | $(BUILD_DIRS)
$(call print,Converting WAV file to raw PCM audio:,$<,$@)
$(V)ffmpeg -y -loglevel quiet -i $< -f s8 $@
define build_c_file
$(call print,Compiling:,$<,$@)
$(V)$(CPP) -MMD -MF $(BUILD)/$*.d -MT $@ $(CPPFLAGS) $< -o $(BUILD)/$*.i
$(V)$(CC1) $(CFLAGS) $(BUILD)/$*.i -o $(BUILD)/$*.s
$(V)printf ".text\n\t.align\t2, 0\n" >> $(BUILD)/$*.s
$(V)$(AS) -march=armv4t -o $@ $(BUILD)/$*.s
endef
# Autogenerated C files
$(BUILD)/%.json.c : %.json $(PCMFILES) | $(BUILD_DIRS)
$(call print,Generating data table from JSON:,$<,$@)
$(V)python3 tools/sample_parser.py $< $@
$(OFILES_JSON): $(BUILD)/%.c.o : $(BUILD)/%.c | $(BUILD_DIRS)
$(call build_c_file)
# C files
$(BUILD)/%.c.o : %.c | $(BUILD_DIRS)
$(call build_c_file)
build/src/udivdi3.c.o: CFLAGS := -Wparentheses -O2 -fhex-asm
# ASM files
$(BUILD)/%.s.o : %.s | $(BUILD_DIRS)
$(call print,Assembling:,$<,$@)
$(V)$(CPP) $(CPPFLAGS) -x assembler-with-cpp $< -o $(BUILD)/$*.s
$(V)$(AS) -MD $(BUILD)/$*.d -march=armv4t -o $@ $(BUILD)/$*.s
# Beatscript
$(BUILD)/%.bs.o : %.bs | $(BUILD_DIRS)
$(call print,Assembling Beatscript:,$<,$@)
$(V)$(CPP) $(CPPFLAGS) -x assembler-with-cpp $< -o $(BUILD)/$*.bs
$(V)$(AS) -MD $(BUILD)/$*.d -march=armv4t -o $@ $(BUILD)/$*.bs
-include $(addprefix $(BUILD)/,$(CFILES:.c=.d))
#---------------------------------------------------------------------------------------
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true