Home | History | Annotate | Download | only in gn
      1 // Copyright (c) 2013 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 "base/atomicops.h"
      6 #include "base/bind.h"
      7 #include "base/command_line.h"
      8 #include "base/strings/string_number_conversions.h"
      9 #include "base/time/time.h"
     10 #include "tools/gn/build_settings.h"
     11 #include "tools/gn/commands.h"
     12 #include "tools/gn/ninja_target_writer.h"
     13 #include "tools/gn/ninja_writer.h"
     14 #include "tools/gn/scheduler.h"
     15 #include "tools/gn/setup.h"
     16 #include "tools/gn/standard_out.h"
     17 
     18 namespace commands {
     19 
     20 namespace {
     21 
     22 // Suppress output on success.
     23 const char kSwitchQuiet[] = "q";
     24 
     25 void BackgroundDoWrite(const Target* target, const Toolchain* toolchain) {
     26   NinjaTargetWriter::RunAndWriteFile(target, toolchain);
     27   g_scheduler->DecrementWorkCount();
     28 }
     29 
     30 // Called on the main thread.
     31 void ItemResolvedCallback(base::subtle::Atomic32* write_counter,
     32                           scoped_refptr<Builder> builder,
     33                           const Item* item) {
     34   base::subtle::NoBarrier_AtomicIncrement(write_counter, 1);
     35 
     36   const Target* target = item->AsTarget();
     37   if (target) {
     38     const Toolchain* toolchain =
     39         builder->GetToolchain(target->settings()->toolchain_label());
     40     DCHECK(toolchain);
     41     g_scheduler->IncrementWorkCount();
     42     g_scheduler->ScheduleWork(
     43         base::Bind(&BackgroundDoWrite, target, toolchain));
     44   }
     45 }
     46 
     47 }  // namespace
     48 
     49 const char kGen[] = "gen";
     50 const char kGen_HelpShort[] =
     51     "gen: Generate ninja files.";
     52 const char kGen_Help[] =
     53     "gn gen\n"
     54     "  Generates ninja files from the current tree.\n"
     55     "\n"
     56     "  See \"gn help\" for the common command-line switches.\n";
     57 
     58 // Note: partially duplicated in command_gyp.cc.
     59 int RunGen(const std::vector<std::string>& args) {
     60   base::TimeTicks begin_time = base::TimeTicks::Now();
     61 
     62   // Deliberately leaked to avoid expensive process teardown.
     63   Setup* setup = new Setup;
     64   if (!setup->DoSetup())
     65     return 1;
     66 
     67   // Cause the load to also generate the ninja files for each target. We wrap
     68   // the writing to maintain a counter.
     69   base::subtle::Atomic32 write_counter = 0;
     70   setup->builder()->set_resolved_callback(
     71       base::Bind(&ItemResolvedCallback, &write_counter,
     72                  scoped_refptr<Builder>(setup->builder())));
     73 
     74   // Do the actual load. This will also write out the target ninja files.
     75   if (!setup->Run())
     76     return 1;
     77 
     78   // Write the root ninja files.
     79   if (!NinjaWriter::RunAndWriteFiles(&setup->build_settings(),
     80                                      setup->builder()))
     81     return 1;
     82 
     83   base::TimeTicks end_time = base::TimeTicks::Now();
     84 
     85   if (!CommandLine::ForCurrentProcess()->HasSwitch(kSwitchQuiet)) {
     86     OutputString("Done. ", DECORATION_GREEN);
     87 
     88     std::string stats = "Wrote " +
     89         base::IntToString(static_cast<int>(write_counter)) +
     90         " targets from " +
     91         base::IntToString(
     92             setup->scheduler().input_file_manager()->GetInputFileCount()) +
     93         " files in " +
     94         base::IntToString((end_time - begin_time).InMilliseconds()) + "ms\n";
     95     OutputString(stats);
     96   }
     97 
     98   return 0;
     99 }
    100 
    101 }  // namespace commands
    102