| // Copyright 2020 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include <optional> | |
| #include "base/command_line.h" | |
| #include "base/files/file_path.h" | |
| #include "gn/commands.h" | |
| #include "gn/err.h" | |
| #include "gn/ninja_tools.h" | |
| #include "gn/setup.h" | |
| #include "gn/source_dir.h" | |
| #include "gn/switches.h" | |
| #include "gn/version.h" | |
| namespace commands { | |
| namespace { | |
| bool CleanStaleOneDir(const base::FilePath& ninja_executable, | |
| const std::string& dir) { | |
| // Deliberately leaked to avoid expensive process teardown. | |
| Setup* setup = new Setup; | |
| if (!setup->DoSetup(dir, false)) | |
| return false; | |
| base::FilePath build_dir(setup->build_settings().GetFullPath( | |
| SourceDir(setup->build_settings().build_dir().value()))); | |
| // The order of operations for these tools is: | |
| // 1. cleandead - This eliminates old files from the build directory. | |
| // 2. recompact - This prunes old entries from the ninja log and deps files. | |
| // | |
| // This order is ideal because the files removed by cleandead will no longer | |
| // be found during the recompact, so ninja can prune their entries. | |
| Err err; | |
| if (!InvokeNinjaCleanDeadTool(ninja_executable, build_dir, &err)) { | |
| err.PrintToStdout(); | |
| return false; | |
| } | |
| if (!InvokeNinjaRecompactTool(ninja_executable, build_dir, &err)) { | |
| err.PrintToStdout(); | |
| return false; | |
| } | |
| return true; | |
| } | |
| } // namespace | |
| const char kCleanStale[] = "clean_stale"; | |
| const char kCleanStale_HelpShort[] = | |
| "clean_stale: Cleans the stale output files from the output directory."; | |
| const char kCleanStale_Help[] = | |
| R"(gn clean_stale [--ninja-executable=...] <out_dir>... | |
| Removes the no longer needed output files from the build directory and prunes | |
| their records from the ninja build log and dependency database. These are | |
| output files that were generated from previous builds, but the current build | |
| graph no longer references them. | |
| This command requires a ninja executable of at least version 1.10.0. The | |
| executable must be provided by the --ninja-executable switch. | |
| Options | |
| --ninja-executable=<string> | |
| Can be used to specify the ninja executable to use. | |
| )"; | |
| int RunCleanStale(const std::vector<std::string>& args) { | |
| if (args.empty()) { | |
| Err(Location(), "Missing argument.", | |
| "Usage: \"gn clean_stale <out_dir>...\"") | |
| .PrintToStdout(); | |
| return 1; | |
| } | |
| const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess(); | |
| base::FilePath ninja_executable = | |
| cmdline->GetSwitchValuePath(switches::kNinjaExecutable); | |
| if (ninja_executable.empty()) { | |
| Err(Location(), "No --ninja-executable provided.", | |
| "--clean-stale requires a ninja executable to run. You can " | |
| "provide one on the command line via --ninja-executable.") | |
| .PrintToStdout(); | |
| return 1; | |
| } | |
| for (const std::string& dir : args) { | |
| if (!CleanStaleOneDir(ninja_executable, dir)) | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| } // namespace commands |