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(const base::FilePath& ninja_executable,
19 const std::string& tool) {
20 base::CommandLine cmdline(ninja_executable);
21 cmdline.SetParseSwitches(false);
22 cmdline.AppendArg("-t");
23 cmdline.AppendArg(tool);
24 return cmdline;
25 }
26
RunNinja(const base::CommandLine & cmdline,const base::FilePath & startup_dir,std::string * output,Err * err)27 bool RunNinja(const base::CommandLine& cmdline,
28 const base::FilePath& startup_dir,
29 std::string* output,
30 Err* err) {
31 std::string stderr_output;
32
33 int exit_code = 0;
34 if (!internal::ExecProcess(cmdline, startup_dir, output, &stderr_output,
35 &exit_code)) {
36 *err = Err(Location(), "Could not execute Ninja.",
37 "I was trying to execute \"" +
38 FilePathToUTF8(cmdline.GetProgram()) + "\".");
39 return false;
40 }
41
42 if (exit_code != 0) {
43 *err = Err(Location(), "Ninja has quit with exit code " +
44 base::IntToString(exit_code) + ".");
45 return false;
46 }
47
48 return true;
49 }
50
51 } // namespace
52
InvokeNinjaRestatTool(const base::FilePath & ninja_executable,const base::FilePath & build_dir,const std::vector<base::FilePath> & files_to_restat,Err * err)53 bool InvokeNinjaRestatTool(const base::FilePath& ninja_executable,
54 const base::FilePath& build_dir,
55 const std::vector<base::FilePath>& files_to_restat,
56 Err* err) {
57 base::CommandLine cmdline =
58 CreateNinjaToolCommandLine(ninja_executable, "restat");
59 for (const base::FilePath& file : files_to_restat) {
60 cmdline.AppendArgPath(file);
61 }
62 std::string output;
63 return RunNinja(cmdline, build_dir, &output, err);
64 }
65
InvokeNinjaCleanDeadTool(const base::FilePath & ninja_executable,const base::FilePath & build_dir,Err * err)66 bool InvokeNinjaCleanDeadTool(const base::FilePath& ninja_executable,
67 const base::FilePath& build_dir,
68 Err* err) {
69 base::CommandLine cmdline =
70 CreateNinjaToolCommandLine(ninja_executable, "cleandead");
71 std::string output;
72 return RunNinja(cmdline, build_dir, &output, err);
73 }
74
InvokeNinjaRecompactTool(const base::FilePath & ninja_executable,const base::FilePath & build_dir,Err * err)75 bool InvokeNinjaRecompactTool(const base::FilePath& ninja_executable,
76 const base::FilePath& build_dir,
77 Err* err) {
78 base::CommandLine cmdline =
79 CreateNinjaToolCommandLine(ninja_executable, "recompact");
80 std::string output;
81 return RunNinja(cmdline, build_dir, &output, err);
82 }
83