diff --git a/tools/configure.py b/tools/configure.py index b1416e0f..c3de9e50 100644 --- a/tools/configure.py +++ b/tools/configure.py @@ -129,9 +129,17 @@ def main(): ) n.newline() + # -MMD excludes all includes instead of just system includes for some reason, so use -MD instead. + mwcc_cmd = f'{WINE} "{mwcc_path}/mwccarm.exe" {CC_FLAGS} {CC_INCLUDES} $cc_flags -d $game_version -MD -c $in -o $basedir' + mwcc_implicit = [] + if system != "windows": + transform_dep = "tools/transform_dep.py" + mwcc_cmd += f" && $python {transform_dep} $basefile.d $basefile.d" + mwcc_implicit.append(transform_dep) n.rule( name="mwcc", - command=f'{WINE} "{mwcc_path}/mwccarm.exe" {CC_FLAGS} {CC_INCLUDES} $cc_flags -d $game_version $in -o $out' + command=mwcc_cmd, + depfile="$basefile.d", ) n.newline() @@ -176,7 +184,7 @@ def main(): 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) + add_mwcc_builds(n, game_version, game_build, mwcc_implicit) add_mwld_and_rom_builds(n, game_build, game_config, game_version) @@ -242,20 +250,23 @@ 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): +def add_mwcc_builds(n: ninja_syntax.Writer, game_version: str, game_build: Path, mwcc_implicit: list[Path]): for source_file in get_c_cpp_files([src_path, libs_path]): - output_file = str(game_build / source_file.with_suffix(".o")) + src_obj_path = 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") n.build( inputs=str(source_file), rule="mwcc", - outputs=output_file, + outputs=str(src_obj_path.with_suffix(".o")), variables={ "game_version": game_version, - "cc_flags": " ".join(cc_flags) - } + "cc_flags": " ".join(cc_flags), + "basedir": os.path.dirname(src_obj_path), + "basefile": str(src_obj_path.with_suffix("")), + }, + implicit=mwcc_implicit, ) n.newline() diff --git a/tools/transform_dep.py b/tools/transform_dep.py new file mode 100644 index 00000000..124de04b --- /dev/null +++ b/tools/transform_dep.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 + +### +# Transforms .d files, converting Windows paths to Unix paths. +# Allows usage of the mwcc -MMD flag on platforms other than Windows. +# +# Usage: +# python3 tools/transform_dep.py build/src/file.d build/src/file.d +# +# If changes are made, please submit a PR to +# https://github.com/encounter/dtk-template +### + +import argparse +import os +from platform import uname + +wineprefix = os.path.join(os.environ["HOME"], ".wine") +if "WINEPREFIX" in os.environ: + wineprefix = os.environ["WINEPREFIX"] +winedevices = os.path.join(wineprefix, "dosdevices") + + +def in_wsl() -> bool: + return "microsoft-standard" in uname().release + + +def import_d_file(in_file: str) -> str: + out_text = "" + + with open(in_file) as file: + for idx, line in enumerate(file): + if idx == 0: + if line.endswith(" \\\n"): + out_text += line[:-3].replace("\\", "/") + " \\\n" + else: + out_text += line.replace("\\", "/") + else: + suffix = "" + if line.endswith(" \\\n"): + suffix = " \\" + path = line.lstrip()[:-3] + else: + path = line.strip() + # lowercase drive letter + path = path[0].lower() + path[1:] + if path[0] == "z": + # shortcut for z: + path = path[2:].replace("\\", "/") + elif in_wsl(): + path = path[0:1] + path[2:] + path = os.path.join("/mnt", path.replace("\\", "/")) + else: + # use $WINEPREFIX/dosdevices to resolve path + path = os.path.realpath( + os.path.join(winedevices, path.replace("\\", "/")) + ) + out_text += "\t" + path + suffix + "\n" + + return out_text + + +def main() -> None: + parser = argparse.ArgumentParser( + description="""Transform a .d file from Wine paths to normal paths""" + ) + parser.add_argument( + "d_file", + help="""Dependency file in""", + ) + parser.add_argument( + "d_file_out", + help="""Dependency file out""", + ) + args = parser.parse_args() + + output = import_d_file(args.d_file) + + with open(args.d_file_out, "w", encoding="UTF-8") as f: + f.write(output) + + +if __name__ == "__main__": + main()