Skip to content

Commit

Permalink
Merge branch 'master' into compdb-target
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesWidman committed Sep 20, 2024
2 parents 623e396 + 6a31acc commit 5e21e2d
Show file tree
Hide file tree
Showing 22 changed files with 815 additions and 244 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ add_library(libninja OBJECT
src/deps_log.cc
src/disk_interface.cc
src/edit_distance.cc
src/elide_middle.cc
src/eval_env.cc
src/graph.cc
src/graphviz.cc
Expand Down Expand Up @@ -265,6 +266,7 @@ if(BUILD_TESTING)
src/disk_interface_test.cc
src/dyndep_parser_test.cc
src/edit_distance_test.cc
src/elide_middle_test.cc
src/explanations_test.cc
src/graph_test.cc
src/json_test.cc
Expand Down Expand Up @@ -295,6 +297,7 @@ if(BUILD_TESTING)
canon_perftest
clparser_perftest
depfile_parser_perftest
elide_middle_perftest
hash_collision_bench
manifest_parser_perftest
)
Expand Down
3 changes: 3 additions & 0 deletions configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ def has_re2c() -> bool:
'dyndep',
'dyndep_parser',
'edit_distance',
'elide_middle',
'eval_env',
'graph',
'graphviz',
Expand Down Expand Up @@ -638,6 +639,7 @@ def has_re2c() -> bool:
'disk_interface_test',
'dyndep_parser_test',
'edit_distance_test',
'elide_middle_test',
'explanations_test',
'graph_test',
'json_test',
Expand Down Expand Up @@ -683,6 +685,7 @@ def has_re2c() -> bool:

for name in ['build_log_perftest',
'canon_perftest',
'elide_middle_perftest',
'depfile_parser_perftest',
'hash_collision_bench',
'manifest_parser_perftest',
Expand Down
80 changes: 80 additions & 0 deletions misc/output_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,21 @@ def test_issue_2048(self) -> None:
except subprocess.CalledProcessError as err:
self.fail("non-zero exit code with: " + err.output)

def test_depfile_directory_creation(self) -> None:
b = BuildDir('''\
rule touch
command = touch $out && echo "$out: extra" > $depfile
build somewhere/out: touch
depfile = somewhere_else/out.d
''')
with b:
self.assertEqual(b.run('', pipe=True), dedent('''\
[1/1] touch somewhere/out && echo "somewhere/out: extra" > somewhere_else/out.d
'''))
self.assertTrue(os.path.isfile(os.path.join(b.d.name, "somewhere", "out")))
self.assertTrue(os.path.isfile(os.path.join(b.d.name, "somewhere_else", "out.d")))

def test_status(self) -> None:
self.assertEqual(run(''), 'ninja: no work to do.\n')
self.assertEqual(run('', pipe=True), 'ninja: no work to do.\n')
Expand Down Expand Up @@ -213,6 +228,71 @@ def test_tool_inputs(self) -> None:
out2
''')

self.assertEqual(run(plan, flags='-t inputs --dependency-order out3'),
'''in2
in1
out1
out2
implicit
order_only
''')

# Verify that results are shell-escaped by default, unless --no-shell-escape
# is used. Also verify that phony outputs are never part of the results.
quote = '"' if platform.system() == "Windows" else "'"

plan = '''
rule cat
command = cat $in $out
build out1 : cat in1
build out$ 2 : cat out1
build out$ 3 : phony out$ 2
build all: phony out$ 3
'''

# Quoting changes the order of results when sorting alphabetically.
self.assertEqual(run(plan, flags='-t inputs all'),
f'''{quote}out 2{quote}
in1
out1
''')

self.assertEqual(run(plan, flags='-t inputs --no-shell-escape all'),
'''in1
out 2
out1
''')

# But not when doing dependency order.
self.assertEqual(
run(
plan,
flags='-t inputs --dependency-order all'
),
f'''in1
out1
{quote}out 2{quote}
''')

self.assertEqual(
run(
plan,
flags='-t inputs --dependency-order --no-shell-escape all'
),
f'''in1
out1
out 2
''')

self.assertEqual(
run(
plan,
flags='-t inputs --dependency-order --no-shell-escape --print0 all'
),
f'''in1\0out1\0out 2\0'''
)


def test_explain_output(self):
b = BuildDir('''\
build .FORCE: phony
Expand Down
27 changes: 15 additions & 12 deletions src/build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,10 @@ namespace {

/// A CommandRunner that doesn't actually run the commands.
struct DryRunCommandRunner : public CommandRunner {
virtual ~DryRunCommandRunner() {}

// Overridden from CommandRunner:
virtual size_t CanRunMore() const;
virtual bool StartCommand(Edge* edge);
virtual bool WaitForCommand(Result* result);
size_t CanRunMore() const override;
bool StartCommand(Edge* edge) override;
bool WaitForCommand(Result* result) override;

private:
queue<Edge*> finished_;
Expand Down Expand Up @@ -528,7 +526,7 @@ void Plan::ComputeCriticalPath() {
for (Edge* edge : sorted_edges)
edge->set_critical_path_weight(EdgeWeightHeuristic(edge));

// Second propagate / increment weidghts from
// Second propagate / increment weights from
// children to parents. Scan the list
// in reverse order to do so.
for (auto reverse_it = sorted_edges.rbegin();
Expand Down Expand Up @@ -595,12 +593,11 @@ void Plan::Dump() const {

struct RealCommandRunner : public CommandRunner {
explicit RealCommandRunner(const BuildConfig& config) : config_(config) {}
virtual ~RealCommandRunner() {}
virtual size_t CanRunMore() const;
virtual bool StartCommand(Edge* edge);
virtual bool WaitForCommand(Result* result);
virtual vector<Edge*> GetActiveEdges();
virtual void Abort();
size_t CanRunMore() const override;
bool StartCommand(Edge* edge) override;
bool WaitForCommand(Result* result) override;
vector<Edge*> GetActiveEdges() override;
void Abort() override;

const BuildConfig& config_;
SubprocessSet subprocs_;
Expand Down Expand Up @@ -906,6 +903,12 @@ bool Builder::StartEdge(Edge* edge, string* err) {

edge->command_start_time_ = build_start;

// Create depfile directory if needed.
// XXX: this may also block; do we care?
std::string depfile = edge->GetUnescapedDepfile();
if (!depfile.empty() && !disk_interface_->MakeDirs(depfile))
return false;

// Create response file, if needed
// XXX: this may also block; do we care?
string rspfile = edge->GetUnescapedRspfile();
Expand Down
4 changes: 2 additions & 2 deletions src/build_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1852,7 +1852,7 @@ TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
// out2 and out3 will be built even though "in" is not touched when built.
// Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
// "true" rule should not lead to the "touch" edge writing out2 and out3 being
// cleard.
// cleared.
command_runner_.commands_ran_.clear();
state_.Reset();
EXPECT_TRUE(builder_.AddTarget("out4", &err));
Expand Down Expand Up @@ -3261,7 +3261,7 @@ TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {

// Touch 'header.in', blank dependencies log (create a different one).
// Building header.h triggers 'restat' outputs cleanup.
// Validate that out is rebuilt netherless, as deps are missing.
// Validate that out is rebuilt nevertheless, as deps are missing.
fs_.Tick();
fs_.Create("header.in", "");

Expand Down
Loading

0 comments on commit 5e21e2d

Please sign in to comment.