• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <optional>
6 
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "gn/commands.h"
10 #include "gn/err.h"
11 #include "gn/ninja_tools.h"
12 #include "gn/setup.h"
13 #include "gn/source_dir.h"
14 #include "gn/switches.h"
15 #include "gn/version.h"
16 
17 namespace commands {
18 
19 namespace {
20 
CleanStaleOneDir(const base::FilePath & ninja_executable,const std::string & dir)21 bool CleanStaleOneDir(const base::FilePath& ninja_executable,
22                       const std::string& dir) {
23   // Deliberately leaked to avoid expensive process teardown.
24   Setup* setup = new Setup;
25   if (!setup->DoSetup(dir, false))
26     return false;
27 
28   base::FilePath build_dir(setup->build_settings().GetFullPath(
29       SourceDir(setup->build_settings().build_dir().value())));
30 
31   // The order of operations for these tools is:
32   // 1. cleandead - This eliminates old files from the build directory.
33   // 2. recompact - This prunes old entries from the ninja log and deps files.
34   //
35   // This order is ideal because the files removed by cleandead will no longer
36   // be found during the recompact, so ninja can prune their entries.
37   Err err;
38   if (!InvokeNinjaCleanDeadTool(ninja_executable, build_dir, &err)) {
39     err.PrintToStdout();
40     return false;
41   }
42 
43   if (!InvokeNinjaRecompactTool(ninja_executable, build_dir, &err)) {
44     err.PrintToStdout();
45     return false;
46   }
47   return true;
48 }
49 
50 }  // namespace
51 
52 const char kCleanStale[] = "clean_stale";
53 const char kCleanStale_HelpShort[] =
54     "clean_stale: Cleans the stale output files from the output directory.";
55 const char kCleanStale_Help[] =
56     R"(gn clean_stale [--ninja-executable=...] <out_dir>...
57 
58   Removes the no longer needed output files from the build directory and prunes
59   their records from the ninja build log and dependency database. These are
60   output files that were generated from previous builds, but the current build
61   graph no longer references them.
62 
63   This command requires a ninja executable of at least version 1.10.0. The
64   executable must be provided by the --ninja-executable switch.
65 
66 Options
67 
68   --ninja-executable=<string>
69       Can be used to specify the ninja executable to use.
70 )";
71 
RunCleanStale(const std::vector<std::string> & args)72 int RunCleanStale(const std::vector<std::string>& args) {
73   if (args.empty()) {
74     Err(Location(), "Missing argument.",
75         "Usage: \"gn clean_stale <out_dir>...\"")
76         .PrintToStdout();
77     return 1;
78   }
79 
80   const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
81   base::FilePath ninja_executable = cmdline->GetSwitchValuePath(switches::kNinjaExecutable);
82   if (ninja_executable.empty()) {
83     Err(Location(), "No --ninja-executable provided.",
84         "--clean-stale requires a ninja executable to run. You can "
85         "provide one on the command line via --ninja-executable.")
86         .PrintToStdout();
87     return 1;
88   }
89 
90   for (const std::string& dir : args) {
91     if (!CleanStaleOneDir(ninja_executable, dir))
92       return 1;
93   }
94 
95   return 0;
96 }
97 
98 }  // namespace commands
99