You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If a target use a custom rule, has restat = 1, does not modify its output, and only has phony target as outputs, then ninja will record a mtime of 0 for that target if it decides to rebuild it as part of an incremental build. From that point, the build will always be considered as dirty because the recorded mtime (0) will always be older than the mtime of the phony target.
Sample reproduction:
$ mkdir repro && cd repro
$ touch a
$ cat > build.ninja <<EOF
rule create_b
command = test -f b || touch b
restat = 1
build s: phony a
build b: create_b | s
EOF
$ ninja b -d explain
ninja explain: output b doesn't exist
[1/1] test -f b || touch b
$ ninja b -d explain
ninja: no work to do.
$ touch a
$ ninja b -d explain
ninja explain: restat of output b older than most recent input s (1711640092851462338 vs 1711640098788860000)
[1/1] test -f b || touch b
$ ninja b -d explain
ninja explain: restat of output b older than most recent input s (0 vs 1711640098788860000)
[1/1] test -f b || touch b
$ cat .ninja_log
# ninja log v5
0 10 1711640092851462338 b 142acf958f60ee36
1 7 0 b 142acf958f60ee36
1 7 0 b 142acf958f60ee36
As can be seen, the mtime for b is stored as 0 after the target is rebuild due to the modification of a.
I think this is because the following code in Builder::FinishCommand(...):
// Restat the edge outputs
TimeStamp output_mtime = 0;
bool restat = edge->GetBindingBool("restat");
if (!config_.dry_run) {
bool node_cleaned = false;
...
if (node_cleaned) {
TimeStamp restat_mtime = 0;
// If any output was cleaned, find the most recent mtime of any
// (existing) non-order-only input or the depfile.
for (vector<Node*>::iterator i = edge->inputs_.begin();
i != edge->inputs_.end() - edge->order_only_deps_; ++i) {
// here (*i)->path() is "s" which does not exist, so
// Stat() returns 0.
TimeStamp input_mtime = disk_interface_->Stat((*i)->path(), err);
...
}
...
output_mtime = restat_mtime;
}
}
The text was updated successfully, but these errors were encountered:
This is a fix for issue ninja-build#2405 where a target with a single phony
input would be considered dirty forever after being built if the
rule was setting `restat = 1` because the code would try to stat
a non-existing file to record the input mtime.
Instead use the mtime recorded in the Node instance (restating it
if necessary) to avoid this issue.
This reverts commit cfddfff.
Reason for revert: this breaks the incremental build of certains
targets of Chromium (i.e. base_unittests for device when the gn
variable `enable_run_ios_unittests_with_xctest = true`). This is
due to ninja-build/ninja#2405 which is
fixed in the development branch but not yet released.
Original change's description:
> [bundle] Use "phony" builtin tool for create_bundle targets
>
> Instead of using the "stamp" tool which creates files (and potentially
> slow down the build since this requires access to the filesystem), use
> the builtin "phony" tool.
>
> Bug: 194
> Change-Id: Ie1af7020af4e7efc6c8848244c21dac549f179aa
> Reviewed-on: https://gn-review.googlesource.com/c/gn/+/16920
> Reviewed-by: David Turner <digit@google.com>
> Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: 194
Change-Id: Id14e5c08e2ca40f6b2fe40d3a526295786f83302
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/16940
Reviewed-by: David Turner <digit@google.com>
Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
This was found when making a change in gn to use phony targets (https://gn-review.git.corp.google.com/c/gn/+/16920) for Chromium.
If a target use a custom rule, has
restat = 1
, does not modify its output, and only has phony target as outputs, then ninja will record a mtime of 0 for that target if it decides to rebuild it as part of an incremental build. From that point, the build will always be considered as dirty because the recorded mtime (0) will always be older than the mtime of the phony target.Sample reproduction:
As can be seen, the mtime for
b
is stored as 0 after the target is rebuild due to the modification ofa
.I think this is because the following code in
Builder::FinishCommand(...)
:The text was updated successfully, but these errors were encountered: