Allow Custom Build Steps/Rules (#27)

This commit is contained in:
NWPlayer123 2024-08-06 21:08:26 -06:00 committed by GitHub
parent 5c333bd399
commit 5e7990495b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 81 additions and 12 deletions

View File

@ -85,15 +85,21 @@ class ProjectConfig:
self.warn_missing_config: bool = False # Warn on missing unit configuration self.warn_missing_config: bool = False # Warn on missing unit configuration
self.warn_missing_source: bool = False # Warn on missing source file self.warn_missing_source: bool = False # Warn on missing source file
self.rel_strip_partial: bool = True # Generate PLFs with -strip_partial self.rel_strip_partial: bool = True # Generate PLFs with -strip_partial
self.rel_empty_file: Optional[ self.rel_empty_file: Optional[str] = (
str None # Object name for generating empty RELs
] = None # Object name for generating empty RELs )
self.shift_jis = ( self.shift_jis = (
True # Convert source files from UTF-8 to Shift JIS automatically True # Convert source files from UTF-8 to Shift JIS automatically
) )
self.reconfig_deps: Optional[List[Path]] = ( self.reconfig_deps: Optional[List[Path]] = (
None # Additional re-configuration dependency files None # Additional re-configuration dependency files
) )
self.custom_build_rules: Optional[List[Dict[str, Any]]] = (
None # Custom ninja build rules
)
self.custom_build_steps: Optional[Dict[str, List[Dict[str, Any]]]] = (
None # Custom build steps, types are ["pre-compile", "post-compile", "post-link", "post-build"]
)
# Progress output and progress.json config # Progress output and progress.json config
self.progress_all: bool = True # Include combined "all" category self.progress_all: bool = True # Include combined "all" category
@ -443,6 +449,48 @@ def generate_build_ninja(
) )
n.newline() n.newline()
n.comment("Custom project build rules (pre/post-processing)")
for rule in config.custom_build_rules or {}:
n.rule(
name=rule.get("name"),
command=rule.get("command"),
description=rule.get("description", None),
depfile=rule.get("depfile", None),
generator=rule.get("generator", False),
pool=rule.get("pool", None),
restat=rule.get("restat", False),
rspfile=rule.get("rspfile", None),
rspfile_content=rule.get("rspfile_content", None),
deps=rule.get("deps", None),
)
n.newline()
def write_custom_step(step: str) -> List[str]:
implicit = []
if config.custom_build_steps and step in config.custom_build_steps:
n.comment(f"Custom build steps ({step})")
for custom_step in config.custom_build_steps[step]:
outputs = custom_step.get("outputs")
if isinstance(outputs, list):
implicit.extend(outputs)
else:
implicit.append(outputs)
n.build(
outputs=outputs,
rule=custom_step.get("rule"),
inputs=custom_step.get("inputs", None),
implicit=custom_step.get("implicit", None),
order_only=custom_step.get("order_only", None),
variables=custom_step.get("variables", None),
implicit_outputs=custom_step.get("implicit_outputs", None),
pool=custom_step.get("pool", None),
dyndep=custom_step.get("dyndep", None),
)
n.newline()
return implicit
n.comment("Host build") n.comment("Host build")
n.variable("host_cflags", "-I include -Wno-trigraphs") n.variable("host_cflags", "-I include -Wno-trigraphs")
n.variable( n.variable(
@ -461,6 +509,9 @@ def generate_build_ninja(
) )
n.newline() n.newline()
# Add all build steps needed before we compile (e.g. processing assets)
precompile_implicit = write_custom_step("pre-compile")
### ###
# Source files # Source files
### ###
@ -511,16 +562,15 @@ def generate_build_ninja(
outputs=elf_path, outputs=elf_path,
rule="link", rule="link",
inputs=self.inputs, inputs=self.inputs,
implicit=[self.ldscript, *mwld_implicit], implicit=[
*precompile_implicit,
self.ldscript,
*mwld_implicit,
*postcompile_implicit,
],
implicit_outputs=elf_map, implicit_outputs=elf_map,
variables={"ldflags": elf_ldflags}, variables={"ldflags": elf_ldflags},
) )
n.build(
outputs=dol_path,
rule="elf2dol",
inputs=elf_path,
implicit=dtk,
)
else: else:
preplf_path = build_path / self.name / f"{self.name}.preplf" preplf_path = build_path / self.name / f"{self.name}.preplf"
plf_path = build_path / self.name / f"{self.name}.plf" plf_path = build_path / self.name / f"{self.name}.plf"
@ -760,6 +810,9 @@ def generate_build_ninja(
if config.compilers_path and not os.path.exists(mw_path): if config.compilers_path and not os.path.exists(mw_path):
sys.exit(f"Linker {mw_path} does not exist") sys.exit(f"Linker {mw_path} does not exist")
# Add all build steps needed before we link and after compiling objects
postcompile_implicit = write_custom_step("post-compile")
### ###
# Link # Link
### ###
@ -768,6 +821,19 @@ def generate_build_ninja(
link_outputs.append(step.output()) link_outputs.append(step.output())
n.newline() n.newline()
# Add all build steps needed after linking and before GC/Wii native format generation
postlink_implicit = write_custom_step("post-link")
###
# Generate DOL
###
n.build(
outputs=link_steps[0].output(),
rule="elf2dol",
inputs=link_steps[0].partial_output(),
implicit=[*postlink_implicit, dtk],
)
### ###
# Generate RELs # Generate RELs
### ###
@ -830,6 +896,9 @@ def generate_build_ninja(
) )
n.newline() n.newline()
# Add all build steps needed post-build (re-building archives and such)
postbuild_implicit = write_custom_step("post-build")
### ###
# Helper rule for building all source files # Helper rule for building all source files
### ###
@ -867,7 +936,7 @@ def generate_build_ninja(
outputs=ok_path, outputs=ok_path,
rule="check", rule="check",
inputs=config.check_sha_path, inputs=config.check_sha_path,
implicit=[dtk, *link_outputs], implicit=[dtk, *link_outputs, *postbuild_implicit],
) )
n.newline() n.newline()
@ -967,7 +1036,7 @@ def generate_build_ninja(
configure_script, configure_script,
python_lib, python_lib,
python_lib_dir / "ninja_syntax.py", python_lib_dir / "ninja_syntax.py",
*(config.reconfig_deps or []) *(config.reconfig_deps or []),
], ],
) )
n.newline() n.newline()