1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gn/ninja_tools.h"
6
7 #include <vector>
8
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "gn/err.h"
13 #include "gn/exec_process.h"
14 #include "gn/filesystem_utils.h"
15
16 namespace {
17
CreateNinjaToolCommandLine(const base::FilePath & ninja_executable,const std::string & tool)18 base::CommandLine CreateNinjaToolCommandLine(
19 const base::FilePath& ninja_executable,
20 const std::string& tool) {
21 base::CommandLine cmdline(ninja_executable);
22 cmdline.SetParseSwitches(false);
23 cmdline.AppendArg("-t");
24 cmdline.AppendArg(tool);
25 return cmdline;
26 }
27
RunNinja(const base::CommandLine & cmdline,const base::FilePath & startup_dir,std::string * output,Err * err)28 bool RunNinja(const base::CommandLine& cmdline,
29 const base::FilePath& startup_dir,
30 std::string* output,
31 Err* err) {
32 std::string stderr_output;
33
34 int exit_code = 0;
35 if (!internal::ExecProcess(cmdline, startup_dir, output, &stderr_output,
36 &exit_code)) {
37 *err = Err(Location(), "Could not execute Ninja.",
38 "I was trying to execute \"" +
39 FilePathToUTF8(cmdline.GetProgram()) + "\".");
40 return false;
41 }
42
43 if (exit_code != 0) {
44 *err = Err(Location(), "Ninja has quit with exit code " +
45 base::IntToString(exit_code) + ".");
46 return false;
47 }
48
49 return true;
50 }
51
52 } // namespace
53
InvokeNinjaRestatTool(const base::FilePath & ninja_executable,const base::FilePath & build_dir,const std::vector<base::FilePath> & files_to_restat,Err * err)54 bool InvokeNinjaRestatTool(const base::FilePath& ninja_executable,
55 const base::FilePath& build_dir,
56 const std::vector<base::FilePath>& files_to_restat,
57 Err* err) {
58 base::CommandLine cmdline =
59 CreateNinjaToolCommandLine(ninja_executable, "restat");
60 for (const base::FilePath& file : files_to_restat) {
61 cmdline.AppendArgPath(file);
62 }
63 std::string output;
64 return RunNinja(cmdline, build_dir, &output, err);
65 }
66
InvokeNinjaCleanDeadTool(const base::FilePath & ninja_executable,const base::FilePath & build_dir,Err * err)67 bool InvokeNinjaCleanDeadTool(const base::FilePath& ninja_executable,
68 const base::FilePath& build_dir,
69 Err* err) {
70 base::CommandLine cmdline =
71 CreateNinjaToolCommandLine(ninja_executable, "cleandead");
72 std::string output;
73 return RunNinja(cmdline, build_dir, &output, err);
74 }
75
InvokeNinjaRecompactTool(const base::FilePath & ninja_executable,const base::FilePath & build_dir,Err * err)76 bool InvokeNinjaRecompactTool(const base::FilePath& ninja_executable,
77 const base::FilePath& build_dir,
78 Err* err) {
79 base::CommandLine cmdline =
80 CreateNinjaToolCommandLine(ninja_executable, "recompact");
81 std::string output;
82 return RunNinja(cmdline, build_dir, &output, err);
83 }
84