summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAetias <aetias@outlook.com>2025-03-09 16:55:31 +0100
committerAetias <aetias@outlook.com>2025-03-09 16:55:31 +0100
commit3439ade1a70491b0bf7661b4f960393175772fcd (patch)
tree8e60fb76e42164e95ccbd6f24174ae31cd024749 /tools
parent989ac3a16ee2d350d2254c51c34e63cc4570ef27 (diff)
ninja: Download objdiff-cli and generate report
Diffstat (limited to 'tools')
-rwxr-xr-xtools/configure.py182
-rw-r--r--tools/download_tool.py4
2 files changed, 135 insertions, 51 deletions
diff --git a/tools/configure.py b/tools/configure.py
index b73207bd..a1996b85 100755
--- a/tools/configure.py
+++ b/tools/configure.py
@@ -23,6 +23,7 @@ args = parser.parse_args()
GAME = "ph"
DSD_VERSION = 'v0.5.0'
WIBO_VERSION = '0.6.16'
+OBJDIFF_VERSION = 'v2.7.1'
MWCC_VERSION = "2.0/sp1p5"
DECOMP_ME_COMPILER = "mwcc_30_131"
CC_FLAGS = " ".join([
@@ -93,17 +94,80 @@ if platform is None:
EXE = platform.exe
WINE = args.wine if platform.system != "windows" else ""
DSD = str(root_path / f"dsd{EXE}")
+OBJDIFF = str(root_path / f"objdiff-cli{EXE}")
CC = str(mwcc_path / "mwccarm.exe")
LD = str(mwcc_path / "mwldarm.exe")
PYTHON = sys.executable
+class Project:
+ def __init__(self, game_version: str):
+ self.game_version = game_version
+ '''Version of the game'''
+ self.game_config = config_path / game_version
+ '''Root directory for dsd configs'''
+
+ if not self.game_config.is_dir():
+ print(f"Version '{game_version}' not recognized")
+ exit(1)
+
+ self.game_build = build_path / game_version
+ '''Path to build directory'''
+ self.game_extract = extract_path / game_version
+ '''Path to extract directory'''
+
+ self.delinks_files = get_config_files(self.game_config, "delinks.txt")
+ '''Paths to every delinks.txt file'''
+ self.relocs_files = get_config_files(self.game_config, "relocs.txt")
+ '''Paths to every relocs.txt file'''
+ self.symbols_files = get_config_files(self.game_config, "symbols.txt")
+ '''Paths to every symbols.txt file'''
+
+ def dsd_configs(self) -> list[str]:
+ return self.delinks_files + self.relocs_files + self.symbols_files
+
+ def arm9_config_yaml(self) -> Path:
+ return self.game_config / "arm9" / "config.yaml"
+
+ def baserom(self) -> Path:
+ return extract_path / f'baserom_{GAME}_{self.game_version}.nds'
+
+ def build_rom(self) -> str:
+ return f"{GAME}_{self.game_version}.nds"
+
+ def baserom_config(self) -> Path:
+ return self.game_extract / 'config.yaml'
+
+ def build_rom_config(self) -> Path:
+ return self.game_build / "build" / "rom_config.yaml"
+
+ def source_object_files(self) -> list[str]:
+ return [
+ str(self.game_build / source_file.with_suffix(".o"))
+ for source_file in get_c_cpp_files([src_path, libs_path])
+ ]
+
+ def arm9_lcf(self) -> Path:
+ return self.game_build / "linker_script.lcf"
+
+ def arm9_objects_txt(self) -> Path:
+ return self.game_build / "objects.txt"
+
+ def arm9_delink_yaml(self) -> Path:
+ return self.game_build / "delinks" / "delink.yaml"
+
+ def arm9_o(self) -> Path:
+ return self.game_build / "arm9.o"
+
+ def arm9_delinks(self) -> Path:
+ return self.game_build / "delinks"
+
+ def objdiff_report(self) -> Path:
+ return self.game_build / "report.json"
+
+
def main():
- game_version: str = args.version
- game_config = config_path / game_version
- if not game_config.is_dir():
- print(f"Version '{game_version}' not recognized")
- return
+ project = Project(args.version)
with build_ninja_path.open("w") as file:
n = ninja_syntax.Writer(file)
@@ -177,6 +241,12 @@ def main():
n.newline()
n.rule(
+ name="objdiff_report",
+ command=f"{OBJDIFF} report generate -o $out"
+ )
+ n.newline()
+
+ n.rule(
name="m2ctx",
command=f"{PYTHON} tools/m2ctx.py -f $out $in"
)
@@ -188,14 +258,12 @@ def main():
)
n.newline()
- game_build = build_path / game_version
- game_extract = extract_path / game_version
-
add_download_tool_builds(n)
- add_extract_build(n, game_extract, game_version)
- add_delink_and_lcf_builds(n, game_config, game_build, game_extract)
- add_mwcc_builds(n, game_version, game_build, mwcc_implicit)
- add_mwld_and_rom_builds(n, game_build, game_config, game_version)
+ add_extract_build(n, project)
+ add_delink_and_lcf_builds(n, project)
+ add_mwcc_builds(n, project, mwcc_implicit)
+ add_mwld_and_rom_builds(n, project)
+ add_objdiff_builds(n, project)
def add_download_tool_builds(n: ninja_syntax.Writer):
@@ -210,6 +278,17 @@ def add_download_tool_builds(n: ninja_syntax.Writer):
)
n.newline()
+ n.build(
+ rule="download_tool",
+ outputs=OBJDIFF,
+ variables={
+ "tool": "objdiff",
+ "tag": OBJDIFF_VERSION,
+ "path": OBJDIFF,
+ }
+ )
+ n.newline()
+
if args.compiler is None:
n.build(
rule="download_tool",
@@ -235,56 +314,50 @@ def add_download_tool_builds(n: ninja_syntax.Writer):
n.newline()
-def add_extract_build(n: ninja_syntax.Writer, game_extract: Path, game_version: str):
- rom_path = extract_path / f'baserom_{GAME}_{game_version}.nds'
- rom_config = game_extract / 'config.yaml'
+def add_extract_build(n: ninja_syntax.Writer, project: Project):
n.build(
- inputs=str(rom_path),
+ inputs=str(project.baserom()),
implicit=DSD,
rule="extract",
- outputs=str(rom_config),
+ outputs=str(project.baserom_config()),
variables={
- "output_path": str(game_extract)
+ "output_path": str(project.game_extract)
}
)
n.newline()
-def add_mwld_and_rom_builds(n: ninja_syntax.Writer, game_build: Path, game_config: Path, game_version: str):
- source_object_files = [
- str(game_build / source_file.with_suffix(".o"))
- for source_file in get_c_cpp_files([src_path, libs_path])
- ]
- lcf_file = str(game_build / "linker_script.lcf")
- objects_file = str(game_build / "objects.txt")
- delink_file = str(game_build / "delinks" / "delink.yaml")
- elf_file = str(game_build / "arm9.o")
+def add_mwld_and_rom_builds(n: ninja_syntax.Writer, project: Project):
+ lcf_file = str(project.arm9_lcf())
+ objects_file = str(project.arm9_objects_txt())
+ delink_file = str(project.arm9_delink_yaml())
+ elf_file = str(project.arm9_o())
n.build(
- inputs=source_object_files + [lcf_file, objects_file, delink_file],
+ inputs=project.source_object_files() + [lcf_file, objects_file, delink_file],
implicit=LD,
rule="mwld",
outputs=elf_file,
variables={
- "target_dir": game_build,
+ "target_dir": project.game_build,
"objects_file": objects_file,
"lcf_file": lcf_file,
}
)
n.newline()
- rom_config_file = str(game_build / "build" / "rom_config.yaml")
+ rom_config_file = str(project.build_rom_config())
n.build(
inputs=elf_file,
implicit=DSD,
rule="rom_config",
outputs=rom_config_file,
variables={
- "config_path": game_config / "arm9" / "config.yaml",
+ "config_path": project.arm9_config_yaml(),
}
)
n.newline()
- rom_file = f"{GAME}_{game_version}.nds"
+ rom_file = project.build_rom()
n.build(
inputs=rom_config_file,
implicit=DSD,
@@ -311,9 +384,9 @@ def add_mwld_and_rom_builds(n: ninja_syntax.Writer, game_build: Path, game_confi
n.newline()
-def add_mwcc_builds(n: ninja_syntax.Writer, game_version: str, game_build: Path, mwcc_implicit: list[Path]):
+def add_mwcc_builds(n: ninja_syntax.Writer, project: Project, mwcc_implicit: list[Path]):
for source_file in get_c_cpp_files([src_path, libs_path]):
- src_obj_path = game_build / source_file
+ src_obj_path = project.game_build / source_file
cc_flags = []
if is_cpp(source_file): cc_flags.append("-lang=c++")
elif is_c(source_file): cc_flags.append("-lang=c")
@@ -323,7 +396,7 @@ def add_mwcc_builds(n: ninja_syntax.Writer, game_version: str, game_build: Path,
rule="mwcc",
outputs=str(src_obj_path.with_suffix(".o")),
variables={
- "game_version": game_version,
+ "game_version": project.game_version,
"cc_flags": " ".join(cc_flags),
"basedir": os.path.dirname(src_obj_path),
"basefile": str(src_obj_path.with_suffix("")),
@@ -332,7 +405,7 @@ def add_mwcc_builds(n: ninja_syntax.Writer, game_version: str, game_build: Path,
n.newline()
extension = source_file.suffix
- ctx_file = str(game_build / source_file.with_suffix(f".ctx{extension}"))
+ ctx_file = str(project.game_build / source_file.with_suffix(f".ctx{extension}"))
n.build(
inputs=str(source_file),
rule="m2ctx",
@@ -358,20 +431,17 @@ def is_c(name: str):
return Path(name).suffix in [".c"]
-def add_delink_and_lcf_builds(n: ninja_syntax.Writer, game_config: Path, game_build: Path, game_extract: Path):
+def add_delink_and_lcf_builds(n: ninja_syntax.Writer, project: Project):
n.comment("Delink ELF binaries when any delinks.txt file is modified")
- delinks_files = get_config_files(game_config, "delinks.txt")
- relocs_files = get_config_files(game_config, "relocs.txt")
- symbols_files = get_config_files(game_config, "symbols.txt")
- rom_config = str(game_extract / 'config.yaml')
- delinks_path = game_build / "delinks"
+ rom_config = str(project.baserom_config())
+ delinks_path = project.arm9_delinks()
n.build(
- inputs=delinks_files + relocs_files + symbols_files + [rom_config],
+ inputs=project.dsd_configs() + [rom_config],
implicit=DSD,
rule="delink",
outputs=str(delinks_path / "delink.yaml"),
variables={
- "config_path": game_config / "arm9" / "config.yaml",
+ "config_path": project.arm9_config_yaml(),
}
)
n.newline()
@@ -383,28 +453,30 @@ def add_delink_and_lcf_builds(n: ninja_syntax.Writer, game_config: Path, game_bu
)
n.newline()
- lcf_file = game_build / "linker_script.lcf"
- objects_file = game_build / "objects.txt"
+ lcf_file = project.arm9_lcf()
+ objects_file = project.arm9_objects_txt()
n.build(
- inputs=delinks_files + [str(rom_config)],
+ inputs=project.delinks_files + [str(rom_config)],
implicit=DSD,
rule="lcf",
outputs=[str(lcf_file), str(objects_file)],
variables={
- "config_path": game_config / "arm9" / "config.yaml",
+ "config_path": project.arm9_config_yaml(),
"lcf_file": lcf_file,
"objects_file": objects_file,
}
)
n.newline()
+
+def add_objdiff_builds(n: ninja_syntax.Writer, project: Project):
n.build(
- inputs=delinks_files + relocs_files + symbols_files,
+ inputs=project.dsd_configs(),
implicit=DSD,
rule="objdiff",
outputs="objdiff.json",
variables={
- "config_path": game_config / "arm9" / "config.yaml",
+ "config_path": project.arm9_config_yaml(),
}
)
n.newline()
@@ -416,8 +488,16 @@ def add_delink_and_lcf_builds(n: ninja_syntax.Writer, game_config: Path, game_bu
)
n.newline()
+ n.build(
+ inputs=["objdiff.json"],
+ implicit=[OBJDIFF] + project.source_object_files(),
+ rule="objdiff_report",
+ outputs=str(project.objdiff_report()),
+ )
+ n.newline()
+
-def get_config_files(game_config: Path, name: str):
+def get_config_files(game_config: Path, name: str) -> list[str]:
return [
f"{root}/{file}"
for root, _, files in os.walk(game_config)
diff --git a/tools/download_tool.py b/tools/download_tool.py
index 183cf66b..755acd8f 100644
--- a/tools/download_tool.py
+++ b/tools/download_tool.py
@@ -29,10 +29,14 @@ def mwccarm_url(tag: str) -> str:
def wibo_url(tag: str) -> str:
return f'https://github.com/decompals/wibo/releases/download/{tag}/wibo'
+def objdiff_url(tag: str) -> str:
+ return f'https://github.com/encounter/objdiff/releases/download/{tag}/objdiff-cli-{platform.system}-{platform.machine}{platform.exe}'
+
TOOLS = {
"dsd": dsd_url,
"mwccarm": mwccarm_url,
"wibo": wibo_url,
+ "objdiff": objdiff_url,
}