mirror of
https://github.com/SeekyCt/spm-decomp.git
synced 2024-11-23 13:29:42 +00:00
328 lines
7.7 KiB
Python
328 lines
7.7 KiB
Python
#!/usr/bin/env python3
|
|
|
|
###
|
|
# Generates build files for the project.
|
|
# This file also includes the project configuration,
|
|
# such as compiler flags and the object matching status.
|
|
#
|
|
# Usage:
|
|
# python3 configure.py
|
|
# ninja
|
|
#
|
|
# Append --help to see available options.
|
|
###
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List
|
|
|
|
from tools.project import (
|
|
Object,
|
|
ProjectConfig,
|
|
calculate_progress,
|
|
generate_build,
|
|
is_windows,
|
|
)
|
|
|
|
# Game versions
|
|
DEFAULT_VERSION = 0
|
|
VERSIONS = [
|
|
"EU0", # 0
|
|
]
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"mode",
|
|
choices=["configure", "progress"],
|
|
default="configure",
|
|
help="script mode (default: configure)",
|
|
nargs="?",
|
|
)
|
|
parser.add_argument(
|
|
"-v",
|
|
"--version",
|
|
choices=VERSIONS,
|
|
type=str.upper,
|
|
default=VERSIONS[DEFAULT_VERSION],
|
|
help="version to build",
|
|
)
|
|
parser.add_argument(
|
|
"--build-dir",
|
|
metavar="DIR",
|
|
type=Path,
|
|
default=Path("build"),
|
|
help="base build directory (default: build)",
|
|
)
|
|
parser.add_argument(
|
|
"--binutils",
|
|
metavar="BINARY",
|
|
type=Path,
|
|
help="path to binutils (optional)",
|
|
)
|
|
parser.add_argument(
|
|
"--compilers",
|
|
metavar="DIR",
|
|
type=Path,
|
|
help="path to compilers (optional)",
|
|
)
|
|
parser.add_argument(
|
|
"--map",
|
|
action="store_true",
|
|
help="generate map file(s)",
|
|
)
|
|
parser.add_argument(
|
|
"--debug",
|
|
action="store_true",
|
|
help="build with debug info (non-matching)",
|
|
)
|
|
if not is_windows():
|
|
parser.add_argument(
|
|
"--wrapper",
|
|
metavar="BINARY",
|
|
type=Path,
|
|
help="path to wibo or wine (optional)",
|
|
)
|
|
parser.add_argument(
|
|
"--dtk",
|
|
metavar="BINARY | DIR",
|
|
type=Path,
|
|
help="path to decomp-toolkit binary or source (optional)",
|
|
)
|
|
parser.add_argument(
|
|
"--objdiff",
|
|
metavar="BINARY | DIR",
|
|
type=Path,
|
|
help="path to objdiff-cli binary or source (optional)",
|
|
)
|
|
parser.add_argument(
|
|
"--sjiswrap",
|
|
metavar="EXE",
|
|
type=Path,
|
|
help="path to sjiswrap.exe (optional)",
|
|
)
|
|
parser.add_argument(
|
|
"--verbose",
|
|
action="store_true",
|
|
help="print verbose output",
|
|
)
|
|
parser.add_argument(
|
|
"--non-matching",
|
|
dest="non_matching",
|
|
action="store_true",
|
|
help="builds equivalent (but non-matching) or modded objects",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
config = ProjectConfig()
|
|
config.version = str(args.version)
|
|
version_num = VERSIONS.index(config.version)
|
|
|
|
# Apply arguments
|
|
config.build_dir = args.build_dir
|
|
config.dtk_path = args.dtk
|
|
config.objdiff_path = args.objdiff
|
|
config.binutils_path = args.binutils
|
|
config.compilers_path = args.compilers
|
|
config.debug = args.debug
|
|
config.generate_map = args.map or True
|
|
config.non_matching = args.non_matching
|
|
config.sjiswrap_path = args.sjiswrap
|
|
if not is_windows():
|
|
config.wrapper = args.wrapper
|
|
# Don't build asm unless we're --non-matching
|
|
if not config.non_matching:
|
|
config.asm_dir = None
|
|
|
|
# Tool versions
|
|
config.binutils_tag = "2.42-1"
|
|
config.compilers_tag = "20240706"
|
|
config.dtk_tag = "v0.9.4"
|
|
config.objdiff_tag = "v2.0.0-beta.3"
|
|
config.sjiswrap_tag = "v1.1.1"
|
|
config.wibo_tag = "0.6.11"
|
|
|
|
# Project
|
|
config.config_path = Path("config") / config.version / "config.yml"
|
|
config.check_sha_path = Path("config") / config.version / "build.sha1"
|
|
config.asflags = [
|
|
"-mgekko",
|
|
"--strip-local-absolute",
|
|
"-I include",
|
|
f"-I build/{config.version}/include",
|
|
f"--defsym version={version_num}",
|
|
]
|
|
config.ldflags = [
|
|
"-fp hardware",
|
|
"-nodefaults",
|
|
# "-warn off",
|
|
# "-listclosure", # Uncomment for Wii linkers
|
|
]
|
|
# Use for any additional files that should cause a re-configure when modified
|
|
config.reconfig_deps = []
|
|
|
|
SPM_HEADERS = "spm-headers"
|
|
|
|
# Base flags, common to most GC/Wii games.
|
|
# Generally leave untouched, with overrides added below.
|
|
cflags_base = [
|
|
"-nodefaults",
|
|
"-proc gekko",
|
|
"-align powerpc",
|
|
"-enum int",
|
|
"-fp hardware",
|
|
"-Cpp_exceptions on",
|
|
"-W all,error",
|
|
"-O4,p",
|
|
"-inline auto",
|
|
'-pragma "cats off"',
|
|
'-pragma "warn_notinlined off"',
|
|
"-maxerrors 1",
|
|
"-nosyspath",
|
|
"-RTTI off",
|
|
"-fp_contract on",
|
|
"-str reuse",
|
|
"-enc SJIS",
|
|
"-i include",
|
|
f"-i build/{config.version}/include",
|
|
f"-DVERSION={version_num}",
|
|
|
|
# spm-headers
|
|
"-DDECOMP",
|
|
"-DSKIP_PPCDIS",
|
|
f"-DSPM_{config.version.upper()}",
|
|
f"-i {SPM_HEADERS}/include",
|
|
f"-i {SPM_HEADERS}/decomp",
|
|
]
|
|
|
|
# Debug flags
|
|
if config.debug:
|
|
cflags_base.extend(["-sym on", "-DDEBUG=1"])
|
|
else:
|
|
cflags_base.append("-DNDEBUG=1")
|
|
|
|
# Metrowerks library flags
|
|
cflags_runtime = [
|
|
*cflags_base,
|
|
"-use_lmw_stmw on",
|
|
"-str reuse,pool,readonly",
|
|
"-gccinc",
|
|
"-common off",
|
|
"-inline auto",
|
|
]
|
|
|
|
# SPM dol flags
|
|
cflags_dol = [
|
|
*cflags_base,
|
|
"-use_lmw_stmw on",
|
|
"-lang c++",
|
|
"-fp fmadd", # TODO: needed?
|
|
"-str pool,reuse,readonly",
|
|
"-ipa file",
|
|
"-inline all",
|
|
"-sdata 4",
|
|
"-sdata2 4",
|
|
]
|
|
|
|
# REL flags
|
|
cflags_rel = [
|
|
*cflags_dol,
|
|
"-sdata 0",
|
|
"-sdata2 0",
|
|
]
|
|
|
|
config.linker_version = "GC/3.0a5.2"
|
|
|
|
|
|
# Helper function for Dolphin libraries
|
|
def DolphinLib(lib_name: str, objects: List[Object]) -> Dict[str, Any]:
|
|
return {
|
|
"lib": lib_name,
|
|
"mw_version": "GC/1.2.5n",
|
|
"cflags": cflags_base,
|
|
"host": False,
|
|
"objects": objects,
|
|
}
|
|
|
|
|
|
def Dol(lib_name: str, objects: List[Object]) -> Dict[str, Any]:
|
|
return {
|
|
"lib": lib_name,
|
|
"mw_version": config.linker_version,
|
|
"cflags": cflags_dol,
|
|
"host": False,
|
|
"objects": objects,
|
|
}
|
|
|
|
|
|
# Helper function for REL script objects
|
|
def Rel(lib_name: str, objects: List[Object]) -> Dict[str, Any]:
|
|
return {
|
|
"lib": lib_name,
|
|
"mw_version": config.linker_version,
|
|
"cflags": cflags_rel,
|
|
"host": True,
|
|
"objects": objects,
|
|
}
|
|
|
|
|
|
Matching = True # Object matches and should be linked
|
|
NonMatching = False # Object does not match and should not be linked
|
|
Equivalent = config.non_matching # Object should be linked when configured with --non-matching
|
|
|
|
config.warn_missing_config = True
|
|
config.warn_missing_source = False
|
|
config.libs = [
|
|
Dol(
|
|
"dol",
|
|
[
|
|
Object(Matching, "main.c"),
|
|
Object(Matching, "swdrv.c"),
|
|
Object(NonMatching, "windowdrv.c"),
|
|
Object(Matching, "evtmgr.c"),
|
|
Object(Matching, "evtmgr_cmd.c"),
|
|
Object(NonMatching, "mario_pouch.c"),
|
|
Object(NonMatching, "mario.c"),
|
|
Object(NonMatching, "seq_title.c"),
|
|
Object(Matching, "seqdef.c"),
|
|
Object(Matching, "seqdrv.c"),
|
|
Object(NonMatching, "system.c"),
|
|
Object(Matching, "dvdmgr.c"),
|
|
Object(Matching, "debug.c"),
|
|
Object(NonMatching, "filemgr.c"),
|
|
Object(NonMatching, "memory.c"),
|
|
Object(NonMatching, "spmario.c"),
|
|
Object(NonMatching, "npcdrv.c"),
|
|
Object(NonMatching, "wpadmgr.c"),
|
|
Object(Matching, "relmgr.c"),
|
|
Object(Matching, "nandmgr.c"),
|
|
]
|
|
),
|
|
Rel(
|
|
"rel",
|
|
[
|
|
Object(NonMatching, "rel/dan.c"),
|
|
],
|
|
),
|
|
{
|
|
"lib": "Runtime.PPCEABI.H",
|
|
"mw_version": config.linker_version,
|
|
"cflags": cflags_runtime,
|
|
"host": False,
|
|
"objects": [
|
|
Object(NonMatching, "Runtime.PPCEABI.H/global_destructor_chain.c"),
|
|
Object(NonMatching, "Runtime.PPCEABI.H/__init_cpp_exceptions.cpp"),
|
|
],
|
|
},
|
|
]
|
|
|
|
if args.mode == "configure":
|
|
# Write build.ninja and objdiff.json
|
|
generate_build(config)
|
|
elif args.mode == "progress":
|
|
# Print progress and write progress.json
|
|
config.progress_each_module = args.verbose
|
|
calculate_progress(config)
|
|
else:
|
|
sys.exit("Unknown mode: " + args.mode)
|