2020-09-11 23:00:17 +00:00
# If COMPARE is 1, check the output md5sum after building
COMPARE ?= 1
# If NON_MATCHING is 1, define the NON_MATCHING C flag when building
NON_MATCHING ?= 0
# If ORIG_COMPILER is 1, compile with QEMU_IRIX and the original compiler
# TODO we do not support static recomp, so force this to 1
2021-02-24 05:50:57 +00:00
ORIG_COMPILER ?= 0
2020-09-11 23:00:17 +00:00
i f e q ( $( NON_MATCHING ) , 1 )
CFLAGS := -DNON_MATCHING
2021-02-24 05:50:57 +00:00
CPPFLAGS := -DNON_MATCHING
2020-09-11 23:00:17 +00:00
COMPARE := 0
e n d i f
2018-10-26 02:29:41 +00:00
2021-02-24 05:50:57 +00:00
i f e q ( $( OS ) , W i n d o w s _ N T )
DETECTED_OS = windows
e l s e
UNAME_S := $( shell uname -s)
ifeq ( $( UNAME_S) ,Linux)
DETECTED_OS = linux
endif
ifeq ( $( UNAME_S) ,Darwin)
DETECTED_OS = macos
MAKE = gmake
CPPFLAGS += -xc++
endif
e n d i f
2020-05-12 21:08:58 +00:00
#### Tools ####
i f e q ( $( shell type mips -linux -gnu -ld >/dev /null 2>/dev /null ; echo $ $ ?) , 0 )
MIPS_BINUTILS_PREFIX := mips-linux-gnu-
e l s e
MIPS_BINUTILS_PREFIX := mips64-elf-
e n d i f
2021-02-24 05:50:57 +00:00
CC := tools/ido_recomp/$( DETECTED_OS) /7.1/cc
CC_OLD := tools/ido_recomp/$( DETECTED_OS) /5.3/cc
2021-03-15 02:12:14 +00:00
GCC := gcc
2020-09-11 23:00:17 +00:00
QEMU_IRIX ?= ./tools/qemu-mips
# if ORIG_COMPILER is 1, check that either QEMU_IRIX is set or qemu-irix package installed
i f e q ( $( ORIG_COMPILER ) , 1 )
ifndef QEMU_IRIX
QEMU_IRIX := $( shell which qemu-irix)
ifeq ( , $( QEMU_IRIX) )
$( error Please install qemu-irix package or set QEMU_IRIX env var to the full qemu-irix binary path)
endif
endif
CC = $( QEMU_IRIX) -L tools/ido7.1_compiler tools/ido7.1_compiler/usr/bin/cc
CC_OLD = $( QEMU_IRIX) -L tools/ido5.3_compiler tools/ido5.3_compiler/usr/bin/cc
e n d i f
2018-10-26 02:29:41 +00:00
2020-09-11 23:00:17 +00:00
AS := $( MIPS_BINUTILS_PREFIX) as
LD := $( MIPS_BINUTILS_PREFIX) ld
OBJCOPY := $( MIPS_BINUTILS_PREFIX) objcopy
OBJDUMP := $( MIPS_BINUTILS_PREFIX) objdump
2018-10-26 02:29:41 +00:00
2020-09-11 23:00:17 +00:00
OPTFLAGS := -O2 -g3
2018-11-14 04:10:59 +00:00
ASFLAGS := -march= vr4300 -32
2018-10-26 02:29:41 +00:00
MIPS_VERSION := -mips2
2020-09-11 23:00:17 +00:00
# we support Microsoft extensions such as anonymous structs, which the compiler does support but warns for their usage. Surpress the warnings with -woff.
CFLAGS += -G 0 -non_shared -Xfullwarn -Xcpluscomm -Iinclude -Isrc -Wab,-r4300_mul -woff 649,838
2018-11-17 08:16:20 +00:00
2020-09-11 23:00:17 +00:00
#### Files ####
2018-10-26 02:29:41 +00:00
2020-09-11 23:00:17 +00:00
# ROM image
2020-09-23 23:47:05 +00:00
MM_BASEROM ?= baserom.z64
MM_ROM_NAME ?= rom
ROM := $( MM_ROM_NAME) .z64
UNCOMPRESSED_ROM := $( MM_ROM_NAME) _uncompressed.z64
ELF := $( MM_ROM_NAME) .elf
2018-11-14 04:10:59 +00:00
2018-10-26 02:29:41 +00:00
BASEROM_FILES := $( wildcard baserom/*)
2019-04-12 02:12:49 +00:00
# Exclude dmadata, it will be generated right before packing the rom
BASEROM_FILES := $( subst baserom/dmadata ,,$( BASEROM_FILES) )
BASEROM_BUILD_FILES := $( BASEROM_FILES:baserom/%= build/baserom/%)
2019-11-13 04:58:52 +00:00
BASE_DECOMP_FILES := $( wildcard decomp/*)
DECOMP_FILES := $( BASE_DECOMP_FILES:decomp/%= build/decomp/%)
2019-11-16 09:28:05 +00:00
COMP_FILES := $( DECOMP_FILES:build/decomp/%= build/comp/%.yaz0)
2019-04-12 02:12:49 +00:00
2020-02-27 22:22:42 +00:00
DMADATA_FILES := $( DECOMP_FILES) $( BASEROM_BUILD_FILES)
# Exclude code files, they will be extracted from the file instead
DMADATA_FILES := $( subst build/baserom/boot ,,$( DMADATA_FILES) )
DMADATA_FILES := $( subst build/decomp/code ,,$( DMADATA_FILES) )
DMADATA_FILES := $( DMADATA_FILES:build/decomp/ovl_%= )
2020-05-01 21:49:27 +00:00
SRC_DIRS := $( shell find src -type d)
2020-08-29 00:55:08 +00:00
# Because we may not have disassembled the code files yet, there might not be any assembly files.
# Instead, generate a list of assembly files based on what's listed in the linker script.
S_FILES := $( shell grep build/asm ./linker_scripts/code_script.txt | sed 's/\s*build\///g; s/\.o(\..*)/\.asm/g' )
2020-05-01 21:49:27 +00:00
C_FILES := $( foreach dir,$( SRC_DIRS) ,$( wildcard $( dir) /*.c) )
2021-03-15 02:12:14 +00:00
C_O_FILES := $( C_FILES:src/%.c= build/src/%.o)
S_O_FILES := $( S_FILES:asm/%.asm= build/asm/%.o)
O_FILES := $( C_O_FILES) $( S_O_FILES)
2019-09-22 08:11:22 +00:00
ROM_FILES := $( shell cat ./tables/makerom_files.txt)
2020-09-11 23:00:17 +00:00
UNCOMPRESSED_ROM_FILES := $( shell cat ./tables/makerom_uncompressed_files.txt)
2018-10-28 08:32:16 +00:00
2020-09-11 23:00:17 +00:00
# create build directories
2021-03-08 00:45:08 +00:00
$( shell mkdir -p build /asm build /asm /boot build /asm /code build /asm /overlays build /baserom build /comp build /decomp $ ( foreach dir ,$ ( SRC_DIRS ) ,$ ( shell mkdir -p build /$ ( dir ) ) ) )
2018-10-28 08:32:16 +00:00
2020-09-11 23:00:17 +00:00
build/src/libultra/os/% : OPTFLAGS := -O 1
2021-03-27 21:17:41 +00:00
build/src/libultra/voice/% : OPTFLAGS := -O 2
2020-09-11 23:00:17 +00:00
build/src/libultra/io/% : OPTFLAGS := -O 2
build/src/libultra/libc/% : OPTFLAGS := -O 2
build/src/libultra/libc/ll% : OPTFLAGS := -O 1
build/src/libultra/libc/ll% : MIPS_VERSION := -mips 3 -32
build/src/libultra/gu/% : OPTFLAGS := -O 2
build/src/libultra/rmon/% : OPTFLAGS := -O 2
build/src/boot_O1/% : OPTFLAGS := -O 1
build/src/boot_O2/% : OPTFLAGS := -O 2
build/src/boot_O2_g3/% : OPTFLAGS := -O 2 -g 3
build/src/boot_O2_g3_trapuv/% : OPTFLAGS := -O 2 -g 3
build/src/boot_O2_g3_trapuv/% : CFLAGS := $( CFLAGS ) -trapuv
2018-10-26 02:29:41 +00:00
2020-09-11 23:00:17 +00:00
build/src/libultra/% : CC := $( CC_OLD )
2021-03-27 21:17:41 +00:00
build/src/libultra/io/% : CC := ./tools /preprocess .py $( CC_OLD ) -- $( AS ) $( ASFLAGS ) --
build/src/libultra/voice/% : CC := ./tools /preprocess .py $( CC_OLD ) -- $( AS ) $( ASFLAGS ) --
2019-12-28 02:55:17 +00:00
2020-09-11 23:00:17 +00:00
CC := ./tools/preprocess.py $( CC) -- $( AS) $( ASFLAGS) --
2018-10-26 02:29:41 +00:00
2020-09-11 23:00:17 +00:00
.PHONY : all clean setup diff -init init
2020-08-29 00:55:08 +00:00
# disasm is not a file so we must tell make not to check it when evaluating timestamps
.INTERMEDIATE : disasm
2021-03-15 02:12:14 +00:00
# make will delete any generated assembly files that are not a prerequisite for anything, so keep it from doing so
.PRECIOUS : asm /%.asm
2020-08-29 00:55:08 +00:00
2021-02-26 00:12:48 +00:00
$(UNCOMPRESSED_ROM) : $( UNCOMPRESSED_ROM_FILES )
./tools/makerom.py ./tables/dmadata_table.txt $@
i f e q ( $( COMPARE ) , 1 )
@md5sum $( UNCOMPRESSED_ROM)
@md5sum -c checksum_uncompressed.md5
e n d i f
2018-10-28 08:32:16 +00:00
2019-04-11 04:58:55 +00:00
$(ROM) : $( ROM_FILES )
2020-09-11 23:00:17 +00:00
./tools/makerom.py ./tables/dmadata_table.txt $@ -c
i f e q ( $( COMPARE ) , 1 )
@md5sum $( ROM)
@md5sum -c checksum.md5
e n d i f
2018-10-28 08:32:16 +00:00
2021-04-07 22:38:23 +00:00
all : $( UNCOMPRESSED_ROM ) $( ROM ) ;
2019-11-16 09:28:05 +00:00
2020-09-11 23:00:17 +00:00
build/code.elf : $( O_FILES ) linker_scripts /code_script .txt undef .txt linker_scripts /object_script .txt linker_scripts /dmadata_script .txt
2020-03-02 06:21:16 +00:00
$( LD) -T linker_scripts/code_script.txt -T undef.txt -T linker_scripts/object_script.txt -T linker_scripts/dmadata_script.txt --no-check-sections --accept-unknown-input-arch -Map build/mm.map -N -o $@
2019-11-16 09:28:05 +00:00
2020-09-11 23:00:17 +00:00
build/code_pre_dmadata.elf : $( O_FILES ) linker_scripts /code_script .txt undef .txt linker_scripts /object_script .txt
$( LD) -r -T linker_scripts/code_script.txt -T undef.txt -T linker_scripts/object_script.txt --no-check-sections --accept-unknown-input-arch -N -o $@
2020-02-27 22:22:42 +00:00
linker_scripts/dmadata_script.txt : $( DMADATA_FILES ) build /code_pre_dmadata .elf
./tools/dmadata.py ./tables/dmadata_table.txt /dev/null -u -l linker_scripts/dmadata_script.txt -e build/code_pre_dmadata.elf
2018-10-28 08:32:16 +00:00
2020-09-11 23:00:17 +00:00
build/dmadata : $( COMP_FILES ) $( DECOMP_FILES ) $( BASEROM_BUILD_FILES )
2020-02-19 20:08:04 +00:00
./tools/dmadata.py ./tables/dmadata_table.txt $@
2019-04-12 02:12:49 +00:00
2020-09-11 23:00:17 +00:00
build/uncompressed_dmadata : $( DECOMP_FILES ) $( BASEROM_BUILD_FILES )
./tools/dmadata.py ./tables/dmadata_table.txt $@ -u
2021-04-07 22:38:23 +00:00
build/baserom/boot build/decomp/code : build /code .elf
@$( OBJCOPY) --dump-section $( notdir $@ ) = $@ $< /dev/null
2019-11-16 09:28:05 +00:00
2020-02-27 22:22:42 +00:00
build/decomp/ovl_% : build /code .elf
2021-03-15 02:12:14 +00:00
@$( OBJCOPY) --dump-section ovl_$* = $@ $< /dev/null
2019-12-28 08:23:17 +00:00
2021-03-15 02:12:14 +00:00
asm/non_matchings/% : asm /%.asm
@./tools/split_asm.py $< $@
2019-04-12 05:09:21 +00:00
2021-03-15 02:12:14 +00:00
asm/%.asm : disasm ;
2021-03-27 17:44:39 +00:00
disasm : tables /files .txt tables /functions .txt tables /objects .txt tables /variables .txt tables /vrom_variables .txt
./tools/disasm.py -d ./asm -l ./tables/files.txt -f ./tables/functions.txt -o ./tables/objects.txt -v ./tables/variables.txt -v ./tables/vrom_variables.txt
2019-09-21 01:47:01 +00:00
2020-09-11 23:00:17 +00:00
clean :
rm -f $( ROM) $( UNCOMPRESSED_ROM) -r build asm
setup :
git submodule update --init --recursive
python3 -m pip install -r requirements.txt
2020-09-28 22:41:58 +00:00
$( MAKE) -C tools
2020-09-23 23:47:05 +00:00
./tools/extract_rom.py $( MM_BASEROM)
2020-09-11 23:00:17 +00:00
diff-init : all
rm -rf expected/
mkdir -p expected/
cp -r build expected/build
2020-09-17 21:11:59 +00:00
cp $( UNCOMPRESSED_ROM) expected/$( UNCOMPRESSED_ROM)
cp $( ROM) expected/$( ROM)
2020-09-11 23:00:17 +00:00
2020-09-23 23:47:05 +00:00
init :
2021-03-08 00:45:08 +00:00
$( MAKE) clean
2020-09-28 22:41:58 +00:00
$( MAKE) setup
$( MAKE) all
$( MAKE) diff-init
2020-09-11 23:00:17 +00:00
2018-10-26 02:29:41 +00:00
# Recipes
2018-10-28 08:32:16 +00:00
2020-02-27 22:22:42 +00:00
build/baserom/% : baserom /%
2021-03-15 02:12:14 +00:00
@cp $< $@
2018-10-28 08:32:16 +00:00
2021-03-15 02:12:14 +00:00
# FIXME: The process of splitting rodata changes the assembly files, so we must avoid making .o files for them until that is done.
# The simplest way to do that is to give them an order dependency on .c files' .o files
build/asm/%.o : asm /%.asm | $( C_O_FILES )
2021-03-27 19:10:09 +00:00
iconv --from UTF-8 --to EUC-JP $^ | $( AS) $( ASFLAGS) -o $@
2018-10-28 08:32:16 +00:00
2021-03-15 02:12:14 +00:00
build/src/overlays/%.o : src /overlays /%.c
2020-09-11 23:00:17 +00:00
$( CC) -c $( CFLAGS) $( MIPS_VERSION) $( OPTFLAGS) -o $@ $<
2021-03-15 02:12:14 +00:00
@./tools/overlay.py $@ build/src/overlays/$* _overlay.s
@$( AS) $( ASFLAGS) build/src/overlays/$* _overlay.s -o build/src/overlays/$* _overlay.o
2019-12-28 08:23:17 +00:00
2021-03-15 02:12:14 +00:00
build/src/%.o : src /%.c
2020-09-11 23:00:17 +00:00
$( CC) -c $( CFLAGS) $( MIPS_VERSION) $( OPTFLAGS) -o $@ $<
2018-10-28 08:32:16 +00:00
2021-03-15 02:12:14 +00:00
build/src/libultra/libc/ll.o : src /libultra /libc /ll .c
2020-09-11 23:00:17 +00:00
$( CC) -c $( CFLAGS) $( MIPS_VERSION) $( OPTFLAGS) -o $@ $<
2021-03-15 02:12:14 +00:00
@./tools/set_o32abi_bit.py $@
2020-01-21 05:26:49 +00:00
2021-03-15 02:12:14 +00:00
build/src/libultra/libc/llcvt.o : src /libultra /libc /llcvt .c
2020-09-11 23:00:17 +00:00
$( CC) -c $( CFLAGS) $( MIPS_VERSION) $( OPTFLAGS) -o $@ $<
2021-03-15 02:12:14 +00:00
@./tools/set_o32abi_bit.py $@
2020-01-21 05:26:49 +00:00
2020-02-27 22:22:42 +00:00
build/decomp/% : decomp /%
2021-03-15 02:12:14 +00:00
@cp $< $@
2019-11-13 04:58:52 +00:00
build/comp/%.yaz0 : build /decomp /%
2020-09-17 21:11:59 +00:00
./tools/yaz0 $< $@
2019-04-11 04:58:55 +00:00
2021-03-15 02:12:14 +00:00
build/src/%.d : src /%.c
@./tools/depend.py $< $@
@$( GCC) $< -Iinclude -MM -MT 'build/src/$*.o' >> $@
i f n e q ( $( MAKECMDGOALS ) , c l e a n )
2021-03-17 03:48:54 +00:00
-include $(C_FILES : src /%.c =build /src /%.d )
2021-03-15 02:12:14 +00:00
e n d i f