From bcb473371cffa8c824922fbc3c65bbe2871da9fb Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Tue, 16 May 2023 14:26:53 +0200 Subject: [PATCH] Symmetry: Accept 'foreign' build artifacts without .ninja_log entry Incl. externally updated 'foreign' build artifacts, newer than the modification timestamp recorded in an existing .ninja_log entry. --- CMakeLists.txt | 1 + src/build_test.cc | 23 +++++++++++++++++++++++ src/graph.cc | 10 ++++++++++ 3 files changed, 34 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70fc5e99f0..cab0e7f5bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ else() add_compile_options(-fdiagnostics-color) endif() endif() +add_compile_definitions(SYMMETRY) # --- optional re2c find_program(RE2C re2c) diff --git a/src/build_test.cc b/src/build_test.cc index e8518b47b4..97ce492697 100644 --- a/src/build_test.cc +++ b/src/build_test.cc @@ -1652,6 +1652,9 @@ TEST_F(BuildWithLogTest, NotInLogButOnDisk) { // Because it's not in the log, it should not be up-to-date until // we build again. EXPECT_TRUE(builder_.AddTarget("out1", &err)); +#ifdef SYMMETRY + EXPECT_TRUE(builder_.AlreadyUpToDate()); +#else EXPECT_FALSE(builder_.AlreadyUpToDate()); command_runner_.commands_ran_.clear(); @@ -1660,6 +1663,7 @@ TEST_F(BuildWithLogTest, NotInLogButOnDisk) { EXPECT_TRUE(builder_.AddTarget("out1", &err)); EXPECT_TRUE(builder_.Build(&err)); EXPECT_TRUE(builder_.AlreadyUpToDate()); +#endif } TEST_F(BuildWithLogTest, RebuildAfterFailure) { @@ -1701,10 +1705,14 @@ TEST_F(BuildWithLogTest, RebuildAfterFailure) { // Run again, should rerun even though the output file is up to date on disk EXPECT_TRUE(builder_.AddTarget("out1", &err)); +#ifdef SYMMETRY + EXPECT_TRUE(builder_.AlreadyUpToDate()); +#else EXPECT_FALSE(builder_.AlreadyUpToDate()); EXPECT_TRUE(builder_.Build(&err)); EXPECT_EQ(1u, command_runner_.commands_ran_.size()); EXPECT_EQ("", err); +#endif } TEST_F(BuildWithLogTest, RebuildWithNoInputs) { @@ -1758,6 +1766,9 @@ TEST_F(BuildWithLogTest, RestatTest) { fs_.Create("in", ""); +#ifdef SYMMETRY + string err; +#else // Do a pre-build so that there's commands in the log for the outputs, // otherwise, the lack of an entry in the build log will cause out3 to rebuild // regardless of restat. @@ -1774,6 +1785,8 @@ TEST_F(BuildWithLogTest, RestatTest) { fs_.Tick(); fs_.Create("in", ""); +#endif + // "cc" touches out1, so we should build out2. But because "true" does not // touch out2, we should cancel the build of out3. EXPECT_TRUE(builder_.AddTarget("out3", &err)); @@ -3001,7 +3014,11 @@ TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) { fs_.Create("header.h", ""); RebuildTarget("out", manifest, "build_log", "ninja_deps"); +#ifdef SYMMETRY + ASSERT_EQ(1u, command_runner_.commands_ran_.size()); +#else ASSERT_EQ(2u, command_runner_.commands_ran_.size()); +#endif // Sanity: this rebuild should be NOOP RebuildTarget("out", manifest, "build_log", "ninja_deps"); @@ -3639,10 +3656,16 @@ TEST_F(BuildWithLogTest, DyndepBuildDiscoverRestat) { ASSERT_EQ("", err); EXPECT_TRUE(builder_.Build(&err)); ASSERT_EQ("", err); +#ifdef SYMMETRY + ASSERT_EQ(2u, command_runner_.commands_ran_.size()); +#else ASSERT_EQ(3u, command_runner_.commands_ran_.size()); +#endif EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]); EXPECT_EQ("true", command_runner_.commands_ran_[1]); +#ifndef SYMMETRY EXPECT_EQ("cat out1 > out2", command_runner_.commands_ran_[2]); +#endif command_runner_.commands_ran_.clear(); state_.Reset(); diff --git a/src/graph.cc b/src/graph.cc index 43ba45ae3d..623455a1d4 100644 --- a/src/graph.cc +++ b/src/graph.cc @@ -342,6 +342,10 @@ bool DependencyScan::RecomputeOutputDirty(const Edge* edge, EXPLAIN("command line changed for %s", output->path().c_str()); return true; } +#ifdef SYMMETRY + // ignore mtime of an existing .ninja_log entry + // (for reggae's --dub-objs-dir and re-using 'foreign' artifacts) +#else if (most_recent_input && entry->mtime < most_recent_input->mtime()) { // May also be dirty due to the mtime in the log being older than the // mtime of the most recent input. This can occur even when the mtime @@ -352,11 +356,17 @@ bool DependencyScan::RecomputeOutputDirty(const Edge* edge, entry->mtime, most_recent_input->mtime()); return true; } +#endif } +#ifdef SYMMETRY + // don't require an existing .ninja_log entry + // (for reggae's --dub-objs-dir and re-using 'foreign' artifacts) +#else if (!entry && !generator) { EXPLAIN("command line not found in log for %s", output->path().c_str()); return true; } +#endif } return false;