-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmake.py
More file actions
151 lines (127 loc) · 5.23 KB
/
make.py
File metadata and controls
151 lines (127 loc) · 5.23 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
from argparse import ArgumentParser
from os import makedirs, path, walk
from shutil import rmtree
from subprocess import PIPE, run
from sys import argv
AS = "tools\\powerpc-eabi-as.exe"
ASFLAGS = "-mgekko -I include"
CC = "tools\\mwcceppc.exe"
CFLAGS = "-I- -i include -ir include/lib/STL -ir include/loader -ir include/caddie -ir include/lib -proc gekko -RTTI off -Cpp_exceptions off -enum int -O4,s -use_lmw_stmw on -fp hard -rostr -sdata 0 -sdata2 0 -msgstyle gcc"
SRC_DIR = "src/"
BUILD_DIR = "build/"
RIIVO_DIR = "riivo/"
EXTERNALS_DIR = "externals/"
BASEROM_DIR = EXTERNALS_DIR + "baserom/"
LOADER_O_DIR = BUILD_DIR + "loader/"
MODULES_DIR = BUILD_DIR + "modules/"
def getLocalPath(path: str, dir: str) -> str:
idx = path.find(dir)
if (idx == -1):
return path
return path[idx:]
def kamekLink(o_files: list, path: str, kamekArgs: str = "") -> None:
# Create modules directory if necessary
try:
makedirs(MODULES_DIR)
except FileExistsError:
pass
cmd = f"tools\\Kamek.exe {kamekArgs} {' '.join(o_files)} -externals={EXTERNALS_DIR}{args.region}.txt -output-kamek={path} -output-map={path.replace('.bin', '.map')}"
result = run(cmd, shell=True, stdout=PIPE,
stderr=PIPE, universal_newlines=True)
if (result.returncode != 0):
print(result.returncode, result.stdout, result.stderr)
exit()
def compile(path: str) -> None:
# Manipulate filepaths
buildPath = path
if (buildPath.endswith(".cpp")):
buildPath = buildPath[0: len(buildPath) - 4]
if (buildPath.endswith(".c")):
buildPath = buildPath[0: len(buildPath) - 2]
buildPath = buildPath.replace("src/", "build/")
buildPath = ''.join([buildPath, ".o"])
buildPath = buildPath.replace("/", "\\")
path = path.replace("/", "\\")
# Make any required build directories
try:
makedirs(buildPath[0: buildPath.rfind("\\")])
except FileExistsError:
pass
# Compile
cmd = f"{CC} {CFLAGS} -c -o {getLocalPath(buildPath, BUILD_DIR)} {getLocalPath(path, SRC_DIR)}"
result = run(cmd, shell=True, stdout=PIPE,
stderr=PIPE, universal_newlines=True)
if (result.returncode != 0):
print(result.returncode, result.stdout, result.stderr)
exit()
def assemble(path: str) -> None:
# Manipulate filepaths
buildPath = path
if (buildPath.endswith(".s")):
buildPath = buildPath[0: len(buildPath) - 2]
buildPath = buildPath.replace("src/", "build/")
buildPath = ''.join([buildPath, ".o"])
buildPath = buildPath.replace("/", "\\")
path = path.replace("/", "\\")
# Make any required build directories
try:
makedirs(buildPath[0: buildPath.rfind("\\")])
except FileExistsError:
pass
# Compile
cmd = f"{AS} {ASFLAGS} -o {getLocalPath(buildPath, BUILD_DIR)} {getLocalPath(path, SRC_DIR)}"
result = run(cmd, shell=True, stdout=PIPE,
stderr=PIPE, universal_newlines=True)
if (result.returncode != 0):
print(result.returncode, result.stdout, result.stderr)
exit()
if __name__ == "__main__":
# Support "make clean"
if (len(argv) == 2 and argv[1].lower() == "clean"):
rmtree(BUILD_DIR, ignore_errors=True)
exit()
# Parse args
parser = ArgumentParser()
parser.add_argument(
"--region", choices=["NTSC_U", "PAL", "NTSC_J"], required=True, help="Region to build")
parser.add_argument("--define", required=False,
help="Optional user define. Usually NDEBUG")
parser.add_argument("--flags", required=False,
help="Optional extra compiler flags")
args = parser.parse_args(argv[1:])
# Chosen region
CFLAGS = ''.join([CFLAGS, f" -DCADDIE_REGION_{args.region}"])
# User define
if (args.define != None):
CFLAGS = ''.join([CFLAGS, f" -D{args.define}"])
# User args
if (args.flags != None):
CFLAGS = ''.join([CFLAGS, f" {args.flags}"])
# Compile all C/C++ source
print("Compiling source...")
for _path, dir, files in walk(SRC_DIR, topdown=True):
for file in files:
if (file.endswith(".cpp") or file.endswith(".c")):
compile(path.join(_path, file))
if (file.endswith(".s")):
assemble(path.join(_path, file))
# Link Kamek loader (DOL patch)
kamek_o_files = []
for _path, dir, files in walk(LOADER_O_DIR, topdown=True):
for file in files:
if (file.endswith(".o")):
kamek_o_files.append(path.join(_path, file))
if (len(kamek_o_files) > 0):
print("Linking Kamek loader...")
kamekLink(kamek_o_files, f"build/modules/Loader_{args.region}.bin",
kamekArgs=f"-static=0x80001900 -input-dol={BASEROM_DIR}baserom_{args.region}.dol -output-dol={BUILD_DIR}main_{args.region}.dol")
# Link Caddie executable
game_o_files = []
for _path, dir, files in walk(BUILD_DIR, topdown=True):
for file in files:
if (file.endswith(".o") and "build/loader" not in _path):
game_o_files.append(path.join(_path, file))
if (len(game_o_files) > 0):
print("Linking Caddie executable...")
kamekLink(game_o_files, f"build/modules/Caddie_{args.region}.bin")
print("Done!")