Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Unified Diff: tools/gn/setup.cc

Issue 265693003: Redo GN "args" command (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/gn/setup.cc
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
index d956c0f94ac0339c45941fa0dce63a40dbdfaf96..cb1effaaab1ea3d883c688daaed9f3881af24a76 100644
--- a/tools/gn/setup.cc
+++ b/tools/gn/setup.cc
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <algorithm>
+#include <sstream>
#include "base/bind.h"
#include "base/command_line.h"
@@ -133,6 +134,8 @@ void DecrementWorkCount() {
// CommonSetup -----------------------------------------------------------------
+const char CommonSetup::kBuildArgFileName[] = "args.gn";
+
CommonSetup::CommonSetup()
: build_settings_(),
loader_(new LoaderImpl(&build_settings_)),
@@ -215,7 +218,8 @@ bool CommonSetup::RunPostMessageLoop() {
Setup::Setup()
: CommonSetup(),
empty_settings_(&empty_build_settings_, std::string()),
- dotfile_scope_(&empty_settings_) {
+ dotfile_scope_(&empty_settings_),
+ fill_arguments_(true) {
empty_settings_.set_toolchain_label(Label());
build_settings_.set_item_defined_callback(
base::Bind(&ItemDefinedCallback, scheduler_.main_loop(), builder_));
@@ -236,8 +240,8 @@ bool Setup::DoSetup(const std::string& build_dir) {
cmdline->HasSwitch(kTracelogSwitch))
EnableTracing();
- if (!FillArguments(*cmdline))
- return false;
+ ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "DoSetup");
+
if (!FillSourceDir(*cmdline))
return false;
if (!RunConfigFile())
@@ -246,6 +250,10 @@ bool Setup::DoSetup(const std::string& build_dir) {
return false;
if (!FillBuildDir(build_dir)) // Must be after FillSourceDir to resolve.
return false;
+ if (fill_arguments_) {
+ if (!FillArguments(*cmdline))
+ return false;
+ }
FillPythonPath();
return true;
@@ -262,14 +270,59 @@ Scheduler* Setup::GetScheduler() {
return &scheduler_;
}
+SourceFile Setup::GetBuildArgFile() const {
+ return SourceFile(build_settings_.build_dir().value() + kBuildArgFileName);
+}
+
bool Setup::FillArguments(const CommandLine& cmdline) {
- std::string args = cmdline.GetSwitchValueASCII(kSwitchArgs);
- if (args.empty())
- return true; // Nothing to set.
+ // Add a dependency on the build arguments file. If this changes, we want
+ // to re-generated the build.
+ g_scheduler->AddGenDependency(build_settings_.GetFullPath(GetBuildArgFile()));
+
+ // Use the args on the command line if specified, and save them. Do this even
+ // if the list is empty (this means clear any defaults).
+ if (cmdline.HasSwitch(kSwitchArgs)) {
+ if (!FillArgsFromCommandLine(cmdline.GetSwitchValueASCII(kSwitchArgs)))
+ return false;
+ SaveArgsToFile();
+ return true;
+ }
+
+ // No command line args given, use the arguments from the build dir (if any).
+ return FillArgsFromFile();
+}
+bool Setup::FillArgsFromCommandLine(const std::string& args) {
args_input_file_.reset(new InputFile(SourceFile()));
args_input_file_->SetContents(args);
- args_input_file_->set_friendly_name("the command-line \"--args\" settings");
+ args_input_file_->set_friendly_name("the command-line \"--args\"");
+ return FillArgsFromArgsInputFile();
+}
+
+bool Setup::FillArgsFromFile() {
+ ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Load args file");
+
+ SourceFile build_arg_source_file = GetBuildArgFile();
+ base::FilePath build_arg_file =
+ build_settings_.GetFullPath(build_arg_source_file);
+
+ std::string contents;
+ if (!base::ReadFileToString(build_arg_file, &contents))
+ return true; // File doesn't exist, continue with default args.
+ if (contents.empty())
+ return true; // Empty file, do nothing.
+
+ args_input_file_.reset(new InputFile(build_arg_source_file));
+ args_input_file_->SetContents(contents);
+ args_input_file_->set_friendly_name(
+ "build arg file (use \"gn args <out_dir>\" to edit)");
+
+ setup_trace.Done(); // Only want to count the load as part of the trace.
+ return FillArgsFromArgsInputFile();
+}
+
+bool Setup::FillArgsFromArgsInputFile() {
+ ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Parse args");
Err err;
args_tokens_ = Tokenizer::Tokenize(args_input_file_.get(), &err);
@@ -298,6 +351,42 @@ bool Setup::FillArguments(const CommandLine& cmdline) {
return true;
}
+bool Setup::SaveArgsToFile() {
+ ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Save args file");
+
+ Scope::KeyValueMap args = build_settings_.build_args().GetAllOverrides();
+
+ std::ostringstream stream;
+ for (Scope::KeyValueMap::const_iterator i = args.begin();
+ i != args.end(); ++i) {
+ stream << i->first.as_string() << " = " << i->second.ToString(true);
+ stream << std::endl;
+ }
+
+ // For the first run, the build output dir might not be created yet, so do
+ // that so we can write a file into it. Ignore errors, we'll catch the error
+ // when we try to write a file to it below.
+ base::FilePath build_arg_file =
+ build_settings_.GetFullPath(GetBuildArgFile());
+ base::CreateDirectory(build_arg_file.DirName());
+
+ std::string contents = stream.str();
+#if defined(OS_WIN)
+ // Use Windows lineendings for this file since it will often open in
+ // Notepad which can't handle Unix ones.
+ ReplaceSubstringsAfterOffset(&contents, 0, "\n", "\r\n");
+#endif
+ if (base::WriteFile(build_arg_file, contents.c_str(), contents.size()) ==
+ -1) {
+ Err(Location(), "Args file could not be written.",
+ "The file is \"" + FilePathToUTF8(build_arg_file) +
+ "\"").PrintToStdout();
+ return false;
+ }
+
+ return true;
+}
+
bool Setup::FillSourceDir(const CommandLine& cmdline) {
// Find the .gn file.
base::FilePath root_path;
@@ -369,6 +458,8 @@ bool Setup::FillBuildDir(const std::string& build_dir) {
}
void Setup::FillPythonPath() {
+ // Trace this since it tends to be a bit slow on Windows.
+ ScopedTrace setup_trace(TraceItem::TRACE_SETUP, "Fill Python Path");
#if defined(OS_WIN)
// Find Python on the path so we can use the absolute path in the build.
const base::char16 kGetPython[] =
« tools/gn/command_args.cc ('K') | « tools/gn/setup.h ('k') | tools/gn/trace.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698