Assembly modding support & objdiff + decomp.me integration (#15)

* Add initial asm build support

* WIP decomp.me and links
This commit is contained in:
Luke Street
2024-03-03 22:47:05 -07:00
committed by GitHub
parent bf77cea86d
commit 192191ced2
8 changed files with 422 additions and 132 deletions
Executable → Regular
+45 -17
View File
@@ -13,45 +13,50 @@
import argparse
import os
import re
from typing import List, Set
from typing import List
script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = os.path.abspath(os.path.join(script_dir, ".."))
src_dir = os.path.join(root_dir, "src")
include_dir = os.path.join(root_dir, "include")
include_dirs = [
os.path.join(root_dir, "include"),
# Add additional include directories here
]
include_pattern = re.compile(r'^#include\s*[<"](.+?)[>"]$')
guard_pattern = re.compile(r"^#ifndef\s+(.*)$")
defines: Set[str] = set()
defines = set()
def import_h_file(in_file: str, r_path: str) -> str:
def import_h_file(in_file: str, r_path: str, deps: List[str]) -> str:
rel_path = os.path.join(root_dir, r_path, in_file)
inc_path = os.path.join(include_dir, in_file)
if os.path.exists(rel_path):
return import_c_file(rel_path)
elif os.path.exists(inc_path):
return import_c_file(inc_path)
return import_c_file(rel_path, deps)
for include_dir in include_dirs:
inc_path = os.path.join(include_dir, in_file)
if os.path.exists(inc_path):
return import_c_file(inc_path, deps)
else:
print("Failed to locate", in_file)
exit(1)
return ""
def import_c_file(in_file: str) -> str:
def import_c_file(in_file: str, deps: List[str]) -> str:
in_file = os.path.relpath(in_file, root_dir)
deps.append(in_file)
out_text = ""
try:
with open(in_file, encoding="utf-8") as file:
out_text += process_file(in_file, list(file))
out_text += process_file(in_file, list(file), deps)
except Exception:
with open(in_file) as file:
out_text += process_file(in_file, list(file))
out_text += process_file(in_file, list(file), deps)
return out_text
def process_file(in_file: str, lines: List[str]) -> str:
def process_file(in_file: str, lines: List[str], deps: List[str]) -> str:
out_text = ""
for idx, line in enumerate(lines):
guard_match = guard_pattern.match(line.strip())
@@ -64,7 +69,7 @@ def process_file(in_file: str, lines: List[str]) -> str:
include_match = include_pattern.match(line.strip())
if include_match and not include_match[1].endswith(".s"):
out_text += f'/* "{in_file}" line {idx} "{include_match[1]}" */\n'
out_text += import_h_file(include_match[1], os.path.dirname(in_file))
out_text += import_h_file(include_match[1], os.path.dirname(in_file), deps)
out_text += f'/* end "{include_match[1]}" */\n'
else:
out_text += line
@@ -72,7 +77,11 @@ def process_file(in_file: str, lines: List[str]) -> str:
return out_text
def main() -> None:
def sanitize_path(path: str) -> str:
return path.replace("\\", "/").replace(" ", "\\ ")
def main():
parser = argparse.ArgumentParser(
description="""Create a context file which can be used for decomp.me"""
)
@@ -80,13 +89,32 @@ def main() -> None:
"c_file",
help="""File from which to create context""",
)
parser.add_argument(
"-o",
"--output",
help="""Output file""",
default="ctx.c",
)
parser.add_argument(
"-d",
"--depfile",
help="""Dependency file""",
)
args = parser.parse_args()
output = import_c_file(args.c_file)
deps = []
output = import_c_file(args.c_file, deps)
with open(os.path.join(root_dir, "ctx.c"), "w", encoding="utf-8") as f:
with open(os.path.join(root_dir, args.output), "w", encoding="utf-8") as f:
f.write(output)
if args.depfile:
with open(os.path.join(root_dir, args.depfile), "w", encoding="utf-8") as f:
f.write(sanitize_path(args.output) + ":")
for dep in deps:
path = sanitize_path(dep)
f.write(f" \\\n\t{path}")
if __name__ == "__main__":
main()
Executable → Regular
+25 -6
View File
@@ -22,6 +22,24 @@ from typing import Callable, Dict
from pathlib import Path
def binutils_url(tag):
uname = platform.uname()
system = uname.system.lower()
arch = uname.machine.lower()
if system == "darwin":
system = "macos"
arch = "universal"
elif arch == "amd64":
arch = "x86_64"
repo = "https://github.com/encounter/gc-wii-binutils"
return f"{repo}/releases/download/{tag}/{system}-{arch}.zip"
def compilers_url(tag: str) -> str:
return f"https://files.decomp.dev/compilers_{tag}.zip"
def dtk_url(tag: str) -> str:
uname = platform.uname()
suffix = ""
@@ -48,15 +66,12 @@ def wibo_url(tag: str) -> str:
return f"{repo}/releases/download/{tag}/wibo"
def compilers_url(tag: str) -> str:
return f"https://files.decomp.dev/compilers_{tag}.zip"
TOOLS: Dict[str, Callable[[str], str]] = {
"binutils": binutils_url,
"compilers": compilers_url,
"dtk": dtk_url,
"sjiswrap": sjiswrap_url,
"wibo": wibo_url,
"compilers": compilers_url,
}
@@ -77,7 +92,11 @@ def main() -> None:
data = io.BytesIO(response.read())
with zipfile.ZipFile(data) as f:
f.extractall(output)
output.touch(mode=0o755)
# Make all files executable
for root, _, files in os.walk(output):
for name in files:
os.chmod(os.path.join(root, name), 0o755)
output.touch(mode=0o755) # Update dir modtime
else:
with open(output, "wb") as f:
shutil.copyfileobj(response, f)
+310 -98
View File
File diff suppressed because it is too large Load Diff