-
Notifications
You must be signed in to change notification settings - Fork 146
Expand file tree
/
Copy pathn64.mk
More file actions
236 lines (212 loc) · 10.3 KB
/
n64.mk
File metadata and controls
236 lines (212 loc) · 10.3 KB
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
234
235
236
BUILD_DIR ?= .
SOURCE_DIR ?= .
# Override this if your project uses a different directory for your DFS filesystem root
N64_MKDFS_ROOT ?= filesystem
N64_ROM_TITLE = "Made with libdragon" # Override this with the name of your game or project
N64_ROM_CATEGORY = # Set an N64 Media Category code in the ROM header (N, D, C, E, Z)
N64_ROM_SAVETYPE = # Supported savetypes: none eeprom4k eeprom16 sram256k sram768k sram1m flashram
N64_ROM_RTC = # Set to true to enable the Joybus Real-Time Clock
N64_ROM_REGIONFREE = # Set to true to allow booting on any console region
N64_ROM_REGION = # Set to a region code (emulators will boot on a specific console region)
N64_ROM_ELFCOMPRESS ?= 1 # Set compression level of ELF file in ROM
N64_ROM_DSOCOMPRESS ?= 1 # Set compression level of DSOs file in ROM
N64_ROM_CONTROLLER1 = # Sets the type of Controller 1 in the Advanced Homebrew Header. This could influence emulator behaviour such as Ares'
N64_ROM_CONTROLLER2 = # Sets the type of Controller 2 in the Advanced Homebrew Header. This could influence emulator behaviour such as Ares'
N64_ROM_CONTROLLER3 = # Sets the type of Controller 3 in the Advanced Homebrew Header. This could influence emulator behaviour such as Ares'
N64_ROM_CONTROLLER4 = # Sets the type of Controller 4 in the Advanced Homebrew Header. This could influence emulator behaviour such as Ares'
# Override this to use a different file prefix for the debug symbols. This is
# useful when building multiple projects in the same directory and you can set
# this to the project name to differentiate between similar paths. Example:
# .PHONY: tiny3d
# tiny3d:
# $(MAKE) -C $(T3D_INST) N64_BACKTRACE_FILE_PREFIX=tiny3d
N64_BACKTRACE_FILE_PREFIX=
# Override this to use a toolchain installed separately from libdragon
N64_GCCPREFIX ?= $(N64_INST)
N64_TARGET ?= mips64-elf
N64_ROOTDIR = $(N64_INST)
N64_BINDIR = $(N64_ROOTDIR)/bin
N64_INCLUDEDIR = $(N64_ROOTDIR)/$(N64_TARGET)/include
N64_LIBDIR = $(N64_ROOTDIR)/$(N64_TARGET)/lib
N64_GCCPREFIX_TRIPLET = $(N64_GCCPREFIX)/bin/$(addsuffix -,$(N64_TARGET))
COMMA:=,
N64_CC = $(CCACHE) $(N64_GCCPREFIX_TRIPLET)gcc
N64_CXX = $(CCACHE) $(N64_GCCPREFIX_TRIPLET)g++
N64_AS = $(N64_GCCPREFIX_TRIPLET)as
N64_AR = $(N64_GCCPREFIX_TRIPLET)gcc-ar
N64_LD = $(N64_GCCPREFIX_TRIPLET)ld
N64_OBJCOPY = $(N64_GCCPREFIX_TRIPLET)objcopy
N64_OBJDUMP = $(N64_GCCPREFIX_TRIPLET)objdump
N64_SIZE = $(N64_GCCPREFIX_TRIPLET)size
N64_NM = $(N64_GCCPREFIX_TRIPLET)nm
N64_STRIP = $(N64_GCCPREFIX_TRIPLET)strip
N64_ED64ROMCONFIG = $(N64_BINDIR)/ed64romconfig
N64_MKDFS = $(N64_BINDIR)/mkdfs
N64_TOOL = $(N64_BINDIR)/n64tool
N64_SYM = $(N64_BINDIR)/n64sym
N64_ELFCOMPRESS = $(N64_BINDIR)/n64elfcompress
N64_AUDIOCONV = $(N64_BINDIR)/audioconv64
N64_MKSPRITE = $(N64_BINDIR)/mksprite
N64_MKFONT = $(N64_BINDIR)/mkfont
N64_DSO = $(N64_BINDIR)/n64dso
N64_DSOEXTERN = $(N64_BINDIR)/n64dso-extern
N64_DSOMSYM = $(N64_BINDIR)/n64dso-msym
N64_C_AND_CXX_FLAGS = -march=vr4300 -mtune=vr4300 -mabi=o64 -I$(N64_INCLUDEDIR)
N64_C_AND_CXX_FLAGS += -falign-functions=32 # NOTE: if you change this, also change backtrace() in backtrace.c
N64_C_AND_CXX_FLAGS += -ffunction-sections -fdata-sections -g -ffile-prefix-map="$(CURDIR)"=$(N64_BACKTRACE_FILE_PREFIX)
N64_C_AND_CXX_FLAGS += -ffast-math -ftrapping-math -fno-associative-math
N64_C_AND_CXX_FLAGS += -DN64 -O2 -Wall -Werror -Wno-error=deprecated-declarations -fdiagnostics-color=always
N64_C_AND_CXX_FLAGS += -Wno-error=unused-variable -Wno-error=unused-but-set-variable -Wno-error=unused-function -Wno-error=unused-parameter -Wno-error=unused-but-set-parameter -Wno-error=unused-label -Wno-error=unused-local-typedefs -Wno-error=unused-const-variable
N64_C_AND_CXX_FLAGS += -ftrivial-auto-var-init=pattern
N64_CFLAGS = $(N64_C_AND_CXX_FLAGS) -std=gnu17
N64_CXXFLAGS = $(N64_C_AND_CXX_FLAGS) -std=gnu++17
N64_ASFLAGS = -mtune=vr4300 -march=vr4300 -mabi=o64 -Wa,--fatal-warnings -I$(N64_INCLUDEDIR)
N64_RSPASFLAGS = -march=mips1 -mabi=32 -Wa,--fatal-warnings -I$(N64_INCLUDEDIR)
N64_LDFLAGS = -g -L$(N64_LIBDIR) -ldragon -lm -ldragonsys -Tn64.ld --gc-sections --wrap __do_global_ctors
N64_DSOLDFLAGS = --emit-relocs --unresolved-symbols=ignore-all --nmagic -T$(N64_LIBDIR)/dso.ld
N64_TOOLFLAGS = --title $(N64_ROM_TITLE)
N64_TOOLFLAGS += $(if $(N64_ROM_HEADER),--header $(N64_ROM_HEADER))
N64_TOOLFLAGS += $(if $(N64_ROM_CATEGORY),--category $(N64_ROM_CATEGORY))
N64_TOOLFLAGS += $(if $(N64_ROM_REGION),--region $(N64_ROM_REGION))
N64_ED64ROMCONFIGFLAGS = $(if $(N64_ROM_SAVETYPE),--savetype $(N64_ROM_SAVETYPE))
N64_ED64ROMCONFIGFLAGS += $(if $(N64_ROM_RTC),--rtc)
N64_ED64ROMCONFIGFLAGS += $(if $(N64_ROM_REGIONFREE),--regionfree)
N64_ED64ROMCONFIGFLAGS += $(if $(N64_ROM_CONTROLLER1),--controller1 $(N64_ROM_CONTROLLER1))
N64_ED64ROMCONFIGFLAGS += $(if $(N64_ROM_CONTROLLER2),--controller2 $(N64_ROM_CONTROLLER2))
N64_ED64ROMCONFIGFLAGS += $(if $(N64_ROM_CONTROLLER3),--controller3 $(N64_ROM_CONTROLLER3))
N64_ED64ROMCONFIGFLAGS += $(if $(N64_ROM_CONTROLLER4),--controller4 $(N64_ROM_CONTROLLER4))
ifeq ($(D),1)
CFLAGS+=-g3
CXXFLAGS+=-g3
ASFLAGS+=-g
RSPASFLAGS+=-g
LDFLAGS+=-g
endif
# automatic .d dependency generation
CFLAGS+=-MMD
CXXFLAGS+=-MMD
ASFLAGS+=-MMD
RSPASFLAGS+=-MMD
# Change all the dependency chain of z64 ROMs to use the N64 toolchain.
%.z64: CC=$(N64_CC)
%.z64: CXX=$(N64_CXX)
%.z64: AS=$(N64_AS)
%.z64: LD=$(N64_LD)
%.z64: CFLAGS+=$(N64_CFLAGS)
%.z64: CXXFLAGS+=$(N64_CXXFLAGS)
%.z64: ASFLAGS+=$(N64_ASFLAGS)
%.z64: RSPASFLAGS+=$(N64_RSPASFLAGS)
%.z64: LDFLAGS+=$(N64_LDFLAGS)
%.z64: $(BUILD_DIR)/%.elf
@echo " [Z64] $@"
$(N64_SYM) $< $<.sym
cp $< $<.stripped
$(N64_STRIP) -s $<.stripped
$(N64_ELFCOMPRESS) -o $(dir $<) -c $(N64_ROM_ELFCOMPRESS) $<.stripped
@rm -f $@
DFS_FILE="$(filter %.dfs, $^)"; \
if [ -z "$$DFS_FILE" ]; then \
$(N64_TOOL) $(N64_TOOLFLAGS) --toc --output $@ --align 256 $<.stripped --align 8 $<.sym --align 8; \
else \
MSYM_FILE="$(filter %.msym, $^)"; \
if [ -z "$$MSYM_FILE" ]; then \
$(N64_TOOL) $(N64_TOOLFLAGS) --toc --output $@ --align 256 $<.stripped --align 8 $<.sym --align 16 "$$DFS_FILE"; \
else \
$(N64_TOOL) $(N64_TOOLFLAGS) --toc --output $@ --align 256 $<.stripped --align 8 $<.sym --align 8 "$$MSYM_FILE" --align 16 "$$DFS_FILE"; \
fi \
fi
if [ ! -z "$(strip $(N64_ED64ROMCONFIGFLAGS))" ]; then \
$(N64_ED64ROMCONFIG) $(N64_ED64ROMCONFIGFLAGS) $@; \
fi
%.v64: %.z64
@echo " [V64] $@"
$(N64_OBJCOPY) -I binary -O binary --reverse-bytes=2 $< $@
%.dfs:
@mkdir -p $(dir $@)
@echo " [DFS] $@"
$(N64_MKDFS) $@ "$(N64_MKDFS_ROOT)" >/dev/null
# Assembly rule. We use .S for both RSP and MIPS assembly code, and we differentiate
# using the prefix of the filename: if it starts with "rsp", it is RSP ucode, otherwise
# it's a standard MIPS assembly file.
$(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.S
@mkdir -p $(dir $@)
set -e; \
FILENAME="$(notdir $(basename $@))"; \
if case "$$FILENAME" in "rsp"*) true;; *) false;; esac; then \
SYMPREFIX="$(subst .,_,$(subst /,_,$(basename $@)))"; \
TEXTSECTION="$(basename $@).text"; \
DATASECTION="$(basename $@).data"; \
BINARY="$(basename $@).elf"; \
echo " [RSP] $<"; \
$(N64_CC) $(RSPASFLAGS) -L$(N64_LIBDIR) -nostartfiles -Wl,-Trsp.ld -Wl,--gc-sections -Wl,-Map=$(BUILD_DIR)/$(notdir $(basename $@)).map -o $@ $<; \
mv "$@" $$BINARY; \
$(N64_OBJCOPY) -O binary -j .text $$BINARY $$TEXTSECTION.bin; \
$(N64_OBJCOPY) -O binary -j .data $$BINARY $$DATASECTION.bin; \
$(N64_OBJCOPY) -I binary -O elf32-bigmips -B mips4300 \
--redefine-sym _binary_$${SYMPREFIX}_text_bin_start=$${FILENAME}_text_start \
--redefine-sym _binary_$${SYMPREFIX}_text_bin_end=$${FILENAME}_text_end \
--redefine-sym _binary_$${SYMPREFIX}_text_bin_size=$${FILENAME}_text_size \
--set-section-alignment .data=8 \
--rename-section .text=.data $$TEXTSECTION.bin $$TEXTSECTION.o; \
$(N64_OBJCOPY) -I binary -O elf32-bigmips -B mips4300 \
--redefine-sym _binary_$${SYMPREFIX}_data_bin_start=$${FILENAME}_data_start \
--redefine-sym _binary_$${SYMPREFIX}_data_bin_end=$${FILENAME}_data_end \
--redefine-sym _binary_$${SYMPREFIX}_data_bin_size=$${FILENAME}_data_size \
--set-section-alignment .data=8 \
--rename-section .text=.data $$DATASECTION.bin $$DATASECTION.o; \
$(N64_SIZE) -G $$BINARY; \
$(N64_LD) -relocatable $$TEXTSECTION.o $$DATASECTION.o -o $@; \
rm $$TEXTSECTION.bin $$DATASECTION.bin $$TEXTSECTION.o $$DATASECTION.o; \
else \
echo " [AS] $<"; \
$(CC) -c $(ASFLAGS) -o $@ $<; \
fi
$(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.c
@mkdir -p $(dir $@)
@echo " [CC] $<"
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.cpp
@mkdir -p $(dir $@)
@echo " [CXX] $<"
$(CXX) -c $(CXXFLAGS) -o $@ $<
%.elf: $(N64_LIBDIR)/libdragon.a $(N64_LIBDIR)/libdragonsys.a $(N64_LIBDIR)/n64.ld
@mkdir -p $(dir $@)
@echo " [LD] $@"
# We always use g++ to link except for ucode and DSO files because of the inconsistencies
# between ld when it comes to global ctors dtors. Also see __do_global_ctors
EXTERNS_FILE="$(filter %.externs, $^)"; \
if [ -z "$$EXTERNS_FILE" ]; then \
$(CXX) -o $@ $(filter %.o, $^) $(filter-out $(N64_LIBDIR)/libdragon.a $(N64_LIBDIR)/libdragonsys.a, $(filter %.a, $^)) \
-lc -mabi=o64 $(patsubst %,-Wl$(COMMA)%,$(LDFLAGS)) -Wl,-Map=$(BUILD_DIR)/$(notdir $(basename $@)).map; \
else \
$(CXX) -o $@ $(filter %.o, $^) $(filter-out $(N64_LIBDIR)/libdragon.a $(N64_LIBDIR)/libdragonsys.a, $(filter %.a, $^)) \
-lc -mabi=o64 $(patsubst %,-Wl$(COMMA)%,$(LDFLAGS)) -Wl,-T"$$EXTERNS_FILE" -Wl,-Map=$(BUILD_DIR)/$(notdir $(basename $@)).map; \
fi
$(N64_SIZE) -G $@
# Change all the dependency chain of DSO files to use the N64 toolchain.
%.dso: CC=$(N64_CC)
%.dso: CXX=$(N64_CXX)
%.dso: AS=$(N64_AS)
%.dso: LD=$(N64_LD)
%.dso: CFLAGS+=$(N64_CFLAGS) -mno-gpopt -DN64_DSO $(DSO_CFLAGS)
%.dso: CXXFLAGS+=$(N64_CXXFLAGS) -mno-gpopt -DN64_DSO $(DSO_CXXFLAGS)
%.dso: ASFLAGS+=$(N64_ASFLAGS)
%.dso: RSPASFLAGS+=$(N64_RSPASFLAGS)
%.dso: $(N64_LIBDIR)/dso.ld
$(eval DSO_ELF=$(basename $(BUILD_DIR)/dso_elf/$@).elf)
@mkdir -p $(dir $@)
@mkdir -p $(dir $(DSO_ELF))
@echo " [DSO] $@"
$(N64_LD) $(N64_DSOLDFLAGS) -Map=$(basename $(DSO_ELF)).map -o $(DSO_ELF) $(filter %.o, $^)
$(N64_SIZE) -G $(DSO_ELF)
$(N64_DSO) -o $(dir $@) -c $(N64_ROM_DSOCOMPRESS) $(DSO_ELF)
$(N64_SYM) $(DSO_ELF) $@.sym
%.externs:
@echo " [DSOEXTERN] $@"
$(N64_DSOEXTERN) -o $@ $^
%.msym: %.elf
@echo " [MSYM] $@"
$(N64_DSOMSYM) $< $@
ifneq ($(V),1)
.SILENT:
endif