1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file. 4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/atomicops.h" 6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/bind.h" 7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/command_line.h" 8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/strings/string_number_conversions.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/timer/elapsed_timer.h" 10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/build_settings.h" 11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/commands.h" 12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/ninja_target_writer.h" 13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/ninja_writer.h" 14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h" 15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/setup.h" 16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/standard_out.h" 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tools/gn/target.h" 18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace commands { 20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace { 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Suppress output on success. 24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst char kSwitchQuiet[] = "q"; 25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kSwitchCheck[] = "check"; 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Called on worker thread to write the ninja file. 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BackgroundDoWrite(const Target* target) { 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NinjaTargetWriter::RunAndWriteFile(target); 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) g_scheduler->DecrementWorkCount(); 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Called on the main thread. 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ItemResolvedCallback(base::subtle::Atomic32* write_counter, 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<Builder> builder, 37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const BuilderRecord* record) { 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::subtle::NoBarrier_AtomicIncrement(write_counter, 1); 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const Item* item = record->item(); 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Target* target = item->AsTarget(); 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (target) { 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) g_scheduler->IncrementWorkCount(); 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci g_scheduler->ScheduleWork(base::Bind(&BackgroundDoWrite, target)); 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} // namespace 49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kGen[] = "gen"; 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kGen_HelpShort[] = 52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "gen: Generate ninja files."; 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kGen_Help[] = 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "gn gen: Generate ninja files.\n" 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "\n" 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " gn gen <output_directory>\n" 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "\n" 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " Generates ninja files from the current tree and puts them in the given\n" 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " output directory.\n" 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "\n" 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " The output directory can be a source-repo-absolute path name such as:\n" 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " //out/foo\n" 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " Or it can be a directory relative to the current directory such as:\n" 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) " out/foo\n" 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " See \"gn help\" for the common command-line switches.\n"; 67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int RunGen(const std::vector<std::string>& args) { 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ElapsedTimer timer; 70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (args.size() != 1) { 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Err(Location(), "Need exactly one build directory to generate.", 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "I expected something more like \"gn gen out/foo\"\n" 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "You can also see \"gn help gen\".").PrintToStdout(); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 1; 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Deliberately leaked to avoid expensive process teardown. 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Setup* setup = new Setup(); 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!setup->DoSetup(args[0], true)) 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return 1; 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (CommandLine::ForCurrentProcess()->HasSwitch(kSwitchCheck)) 84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch setup->set_check_public_headers(true); 85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Cause the load to also generate the ninja files for each target. We wrap 87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the writing to maintain a counter. 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::subtle::Atomic32 write_counter = 0; 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) setup->builder()->set_resolved_callback( 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&ItemResolvedCallback, &write_counter, 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<Builder>(setup->builder()))); 92d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Do the actual load. This will also write out the target ninja files. 94d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!setup->Run()) 95d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return 1; 96d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 97d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Write the root ninja files. 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!NinjaWriter::RunAndWriteFiles(&setup->build_settings(), 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) setup->builder())) 100d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return 1; 101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta elapsed_time = timer.Elapsed(); 103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!CommandLine::ForCurrentProcess()->HasSwitch(kSwitchQuiet)) { 105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch OutputString("Done. ", DECORATION_GREEN); 106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string stats = "Wrote " + 108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::IntToString(static_cast<int>(write_counter)) + 109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch " targets from " + 110d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::IntToString( 111d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch setup->scheduler().input_file_manager()->GetInputFileCount()) + 112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch " files in " + 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::IntToString(elapsed_time.InMilliseconds()) + "ms\n"; 114d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch OutputString(stats); 115d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 116d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 117d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return 0; 118d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace commands 121