#!/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 sys import argparse from pathlib import Path from tools.project import ( Object, ProjectConfig, calculate_progress, generate_build, is_windows, ) # Game versions DEFAULT_VERSION = 0 VERSIONS = [ "GAMEID", # 0 ] if len(VERSIONS) > 1: versions_str = ", ".join(VERSIONS[:-1]) + f" or {VERSIONS[-1]}" else: versions_str = VERSIONS[0] parser = argparse.ArgumentParser() parser.add_argument( "mode", default="configure", help="configure or progress (default: configure)", nargs="?", ) parser.add_argument( "--version", dest="version", default=VERSIONS[DEFAULT_VERSION], help=f"version to build ({versions_str})", ) parser.add_argument( "--build-dir", dest="build_dir", type=Path, default=Path("build"), help="base build directory (default: build)", ) parser.add_argument( "--compilers", dest="compilers", type=Path, help="path to compilers (optional)", ) parser.add_argument( "--map", dest="map", action="store_true", help="generate map file(s)", ) parser.add_argument( "--debug", dest="debug", action="store_true", help="build with debug info (non-matching)", ) if not is_windows(): parser.add_argument( "--wrapper", dest="wrapper", type=Path, help="path to wibo or wine (optional)", ) parser.add_argument( "--build-dtk", dest="build_dtk", type=Path, help="path to decomp-toolkit source (optional)", ) parser.add_argument( "--sjiswrap", dest="sjiswrap", type=Path, help="path to sjiswrap.exe (optional)", ) parser.add_argument( "--verbose", dest="verbose", action="store_true", help="print verbose output", ) args = parser.parse_args() config = ProjectConfig() config.version = args.version.upper() if config.version not in VERSIONS: sys.exit(f"Invalid version '{config.version}', expected {versions_str}") version_num = VERSIONS.index(config.version) # Apply arguments config.build_dir = args.build_dir config.build_dtk_path = args.build_dtk config.compilers_path = args.compilers config.debug = args.debug config.generate_map = args.map config.sjiswrap_path = args.sjiswrap if not is_windows(): config.wrapper = args.wrapper # Tool versions config.compilers_tag = "20231018" config.dtk_tag = "v0.6.2" config.sjiswrap_tag = "v1.1.1" config.wibo_tag = "0.6.9" # Project config.config_path = Path("config") / config.version / "config.yml" config.check_sha_path = Path("config") / config.version / "build.sha1" config.ldflags = [ "-fp hardware", "-nodefaults", # "-listclosure", # Uncomment for Wii linkers ] # 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 off", # "-W all", "-O4,p", "-inline auto", '-pragma "cats off"', '-pragma "warn_notinlined off"', "-maxerrors 1", "-nosyspath", "-RTTI off", "-fp_contract on", "-str reuse", "-multibyte", # For Wii compilers, replace with `-enc SJIS` "-i include", f"-i build/{config.version}/include", f"-DVERSION={version_num}", ] # 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", ] # REL flags cflags_rel = [ *cflags_base, "-sdata 0", "-sdata2 0", ] config.linker_version = "GC/1.3.2" # Helper function for Dolphin libraries def DolphinLib(lib_name, objects): return { "lib": lib_name, "mw_version": "GC/1.2.5n", "cflags": cflags_base, "host": False, "objects": objects, } # Helper function for REL script objects def Rel(lib_name, objects): return { "lib": lib_name, "mw_version": "GC/1.3.2", "cflags": cflags_rel, "host": True, "objects": objects, } Matching = True NonMatching = False config.warn_missing_config = True config.warn_missing_source = False config.libs = [ { "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)