This implements https://github.com/ninja-build/ninja/issues/370.
[Edit: Since this tracks the set of loaded files, I also enhanced it to also implement #2217 (#pragma once
when loading files). The implementation here is better because it takes into account the fact that files can be loaded in two ways (include
and subninja
). It makes it an error to load the same file twice in two different ways. It would be trivial to change the implementation to make it an explicit error to load the same file twice, if this is preferred.]
[Edit 2: Modified implementation so always tries to build each loaded files before the 1st load. This allows an updated generator action to fix a loaded file with errors in it. As a bonus this means no modifications to the base parser, only to the manifest parser (and the main program to match).]
This is a natural extension of the current iterative way that ninja
deals with the main input file. That is, it allows ninja
to update any include
or subninja
file, similarly to how it updates the main input build.ninja
file. Actually, it goes further - it can also create any loaded files if they doesn't exist yet (which obviously is not possible for the main input file).
For example, it allows placing a fixed small build.ninja
file in the root of the working directory, check it in as part of the sources, and keep the sources directory read-only when building:
include build-dir/generated.ninja
# Normal build statement, e.g. w/ dependencies
build build-dir/generated.ninja: generate_ninja
rule generate_ninja
command = create_build_dir_and_generate_ninja_in_it
Running ninja
in a clean top-level directory will generate build-dir/generated.ninja
, then include
it and continue as usual. Currently one needs to run an arbitrary project-specific bootstrap command before running ninja
for the first time.
Regardless of bootstrapping, It is also very convenient to be able to define dependencies for the loaded files, so that ninja
will update them when needed. Specifically, if the generator program depends on some configuration file(s), or is directly modified, then running ninja
will automatically detect this and update the files. Currently this is only true for the main input file, which makes it more difficult to split the generated build files to follow some modular project structure.