shuriken: Implement header dependency detection

This commit is contained in:
Lexi / Zoe 2026-05-19 20:08:50 +02:00
parent acd53e17d1
commit 393c6529e2
Signed by: binaryDiv
GPG key ID: F8D4956E224DA232

View file

@ -600,7 +600,25 @@ class NinjaFileGenerator:
config = self.config config = self.config
target = self.target target = self.target
target_config = self.target_config target_config = self.target_config
build_dir = self.config.build_dir build_dir = config.build_dir
ninja_file_path = config.get_ninja_file_path(config.default_target)
cpp_compiler = target_config.cpp_compiler
# Generate list of all source input files to be used as implicit dependencies for the dyndep file
dyndep_file_implicit_inputs = ' '.join(sorted(
t.src for t in self.compile_targets_cpp + self.compile_targets_cppm
))
# Generate list of all .dep files that are generated implicitly during dyndep file generation.
# This is mostly necessary so that Ninja can create the directories for these files beforehand.
dyndep_file_implicit_outputs = ' '.join(sorted(
f'{t.obj}.dep' for t in self.compile_targets_cpp + self.compile_targets_cppm
))
# Generate list of generated source files (currently just the copied std module file)
generated_source_files = ' '.join(sorted(
t.generated_src for t in self.compile_targets_std_module
))
# Generate Ninja file # Generate Ninja file
return f""" return f"""
@ -626,19 +644,21 @@ rule copy
# Rule to compile a .cpp file to a .o file # Rule to compile a .cpp file to a .o file
rule cpp rule cpp
command = {target_config.cpp_compiler} $cpp_flags -c $in -o $out depfile = $out.dep
command = {cpp_compiler} $cpp_flags -MMD -MF $out.dep -c $in -o $out
# Rule to compile a .cppm file (C++20 module) to a .o file ($out) and a .pcm file ($pcm_out) # Rule to compile a .cppm file (C++20 module) to a .o file ($out) and a .pcm file ($pcm_out)
rule cppm rule cppm
command = {target_config.cpp_compiler} $cpp_flags -c $in -o $out -fmodule-output=$pcm_out depfile = $out.dep
command = {cpp_compiler} $cpp_flags -MMD -MF $out.dep -c $in -o $out -fmodule-output=$pcm_out
# Rule to compile a standard library module to a .pcm file (e.g. "import std") # Rule to compile a standard library module to a .pcm file (e.g. "import std")
rule std_module rule std_module
command = {target_config.cpp_compiler} $cpp_std_module_flags --precompile $in -o $out command = {cpp_compiler} $cpp_std_module_flags --precompile $in -o $out
# Rule to link several .o files to an executable # Rule to link several .o files to an executable
rule link rule link
command = {target_config.cpp_compiler} $linker_flags -o $out $in $linker_args command = {cpp_compiler} $linker_flags -o $out $in $linker_args
# Rule to generate a compilation database (JSON file) from the build targets defined in a Ninja file # Rule to generate a compilation database (JSON file) from the build targets defined in a Ninja file
rule generate_compdb rule generate_compdb
@ -652,13 +672,13 @@ rule generate_dyndeps
# -- STATIC BUILD TARGETS # -- STATIC BUILD TARGETS
# Generate compilation database from default target Ninja file # Generate compilation database from default target Ninja file
build $compdb_file: generate_compdb {self.config.get_ninja_file_path(config.default_target)} | generate_source_files build $compdb_file: generate_compdb {ninja_file_path} | generate_source_files
# Shortcut alias to generate compilation database # Shortcut alias to generate compilation database
build compdb: phony $compdb_file build compdb: phony $compdb_file
# Generate Ninja dyndep file from compilation database # Generate Ninja dyndep file from compilation database
build $dyndep_file: generate_dyndeps $compdb_file build $dyndep_file | {dyndep_file_implicit_outputs}: generate_dyndeps $compdb_file | {dyndep_file_implicit_inputs}
# -- GENERATED BUILD TARGETS # -- GENERATED BUILD TARGETS
@ -668,17 +688,13 @@ build $builddir/{target_config.output_file}: link {' '.join(self.link_target_obj
default $builddir/{target_config.output_file} default $builddir/{target_config.output_file}
# Phony target that depends on all generated source files # Phony target that depends on all generated source files
build generate_source_files: phony {self.list_generated_source_files()} build generate_source_files: phony {generated_source_files}
{self.render_compile_targets()} {self.render_compile_targets()}
# End of build.{target}.ninja # End of build.{target}.ninja
""".strip() """.strip()
def list_generated_source_files(self) -> str:
generated_files = [target.generated_src for target in self.compile_targets_std_module]
return ' '.join(generated_files)
def render_compile_targets(self) -> str: def render_compile_targets(self) -> str:
rendered_targets = list(map(self.render_compile_target_std_module, self.compile_targets_std_module)) rendered_targets = list(map(self.render_compile_target_std_module, self.compile_targets_std_module))
rendered_targets += list(map(self.render_compile_target_cpp, self.compile_targets_cpp)) rendered_targets += list(map(self.render_compile_target_cpp, self.compile_targets_cpp))