Index: tools/gn/setup.cc |
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f93cd4d31a1ced58ad526b62249ec91e97777db4 |
--- /dev/null |
+++ b/tools/gn/setup.cc |
@@ -0,0 +1,195 @@ |
+// Copyright (c) 2013 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 "tools/gn/setup.h" |
+ |
+#include "base/command_line.h" |
+#include "base/file_util.h" |
+#include "base/files/file_path.h" |
+#include "tools/gn/filesystem_utils.h" |
+#include "tools/gn/input_file.h" |
+#include "tools/gn/parse_tree.h" |
+#include "tools/gn/parser.h" |
+#include "tools/gn/source_dir.h" |
+#include "tools/gn/source_file.h" |
+#include "tools/gn/tokenizer.h" |
+#include "tools/gn/value.h" |
+ |
+namespace { |
+ |
+// More logging. |
+const char kSwitchVerbose[] = "v"; |
+ |
+const char kSwitchRoot[] = "root"; |
+const char kSecondarySource[] = "secondary"; |
+ |
+const base::FilePath::CharType kGnFile[] = FILE_PATH_LITERAL(".gn"); |
+ |
+base::FilePath FindDotFile(const base::FilePath& current_dir) { |
+ base::FilePath try_this_file = current_dir.Append(kGnFile); |
+ if (base::PathExists(try_this_file)) |
+ return try_this_file; |
+ |
+ base::FilePath with_no_slash = current_dir.StripTrailingSeparators(); |
+ base::FilePath up_one_dir = with_no_slash.DirName(); |
+ if (up_one_dir == current_dir) |
+ return base::FilePath(); // Got to the top. |
+ |
+ return FindDotFile(up_one_dir); |
+} |
+ |
+} // namespace |
+ |
+Setup::Setup() |
+ : dotfile_toolchain_(Label()), |
+ dotfile_settings_(&dotfile_build_settings_, &dotfile_toolchain_, |
+ std::string()), |
+ dotfile_scope_(&dotfile_settings_) { |
+} |
+ |
+Setup::~Setup() { |
+} |
+ |
+bool Setup::DoSetup() { |
+ CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
+ |
+ scheduler_.set_verbose_logging(cmdline->HasSwitch(kSwitchVerbose)); |
+ |
+ if (!FillSourceDir(*cmdline)) |
+ return false; |
+ if (!RunConfigFile()) |
+ return false; |
+ if (!FillOtherConfig(*cmdline)) |
+ return false; |
+ |
+ // FIXME(brettw) get python path! |
+/*#if defined(OS_WIN) |
+ build_settings_.set_python_path(base::FilePath( |
+ //L"P:\\depot_tools\\python_bin\\python.exe")); |
+ L"C:\\apps\\depot_tools\\python_bin\\python.exe")); |
+#else*/ |
+ build_settings_.set_python_path(base::FilePath("python")); |
+//#endif |
+ |
+ build_settings_.SetBuildDir(SourceDir("//out/gn/")); |
+ |
+ return true; |
+} |
+ |
+bool Setup::Run() { |
+ // Load the root build file and start runnung. |
+ build_settings_.toolchain_manager().StartLoadingUnlocked( |
+ SourceFile("//BUILD.gn")); |
+ if (!scheduler_.Run()) |
+ return false; |
+ |
+ Err err = build_settings_.item_tree().CheckForBadItems(); |
+ if (err.has_error()) { |
+ err.PrintToStdout(); |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+bool Setup::FillSourceDir(const CommandLine& cmdline) { |
+ // Find the .gn file. |
+ base::FilePath root_path; |
+ |
+ // Prefer the command line args to the config file. |
+ base::FilePath relative_root_path = cmdline.GetSwitchValuePath(kSwitchRoot); |
+ if (!relative_root_path.empty()) { |
+ root_path = base::MakeAbsoluteFilePath(relative_root_path); |
+ dotfile_name_ = root_path.Append(kGnFile); |
+ } else { |
+ base::FilePath cur_dir; |
+ file_util::GetCurrentDirectory(&cur_dir); |
+ dotfile_name_ = FindDotFile(cur_dir); |
+ if (dotfile_name_.empty()) { |
+ Err(Location(), "Can't find source root.", |
+ "I could not find a \".gn\" file in the current directory or any " |
+ "parent,\nand the --root command-line argument was not specified.") |
+ .PrintToStdout(); |
+ return false; |
+ } |
+ root_path = dotfile_name_.DirName(); |
+ } |
+ |
+ if (scheduler_.verbose_logging()) |
+ scheduler_.Log("Using source root", FilePathToUTF8(root_path)); |
+ build_settings_.set_root_path(root_path); |
+ |
+ return true; |
+} |
+ |
+bool Setup::RunConfigFile() { |
+ if (scheduler_.verbose_logging()) |
+ scheduler_.Log("Got dotfile", FilePathToUTF8(dotfile_name_)); |
+ |
+ dotfile_input_file_.reset(new InputFile(SourceFile("//.gn"))); |
+ if (!dotfile_input_file_->Load(dotfile_name_)) { |
+ Err(Location(), "Could not load dotfile.", |
+ "The file \"" + FilePathToUTF8(dotfile_name_) + "\" cound't be loaded") |
+ .PrintToStdout(); |
+ return false; |
+ } |
+ |
+ Err err; |
+ dotfile_tokens_ = Tokenizer::Tokenize(dotfile_input_file_.get(), &err); |
+ if (err.has_error()) { |
+ err.PrintToStdout(); |
+ return false; |
+ } |
+ |
+ dotfile_root_ = Parser::Parse(dotfile_tokens_, &err); |
+ if (err.has_error()) { |
+ err.PrintToStdout(); |
+ return false; |
+ } |
+ |
+ dotfile_root_->AsBlock()->ExecuteBlockInScope(&dotfile_scope_, &err); |
+ if (err.has_error()) { |
+ err.PrintToStdout(); |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+bool Setup::FillOtherConfig(const CommandLine& cmdline) { |
+ Err err; |
+ |
+ // Secondary source path. |
+ SourceDir secondary_source; |
+ if (cmdline.HasSwitch(kSecondarySource)) { |
+ // Prefer the command line over the config file. |
+ secondary_source = |
+ SourceDir(cmdline.GetSwitchValueASCII(kSecondarySource)); |
+ } else { |
+ // Read from the config file if present. |
+ const Value* secondary_value = |
+ dotfile_scope_.GetValue("secondary_source", true); |
+ if (secondary_value) { |
+ if (!secondary_value->VerifyTypeIs(Value::STRING, &err)) { |
+ err.PrintToStdout(); |
+ return false; |
+ } |
+ build_settings_.SetSecondarySourcePath( |
+ SourceDir(secondary_value->string_value())); |
+ } |
+ } |
+ |
+ // Build config dir. |
+ const Value* build_config_value = |
+ dotfile_scope_.GetValue("buildconfig", true); |
+ if (!build_config_value) { |
+ Err(Location(), "No build config file.", |
+ "Your .gn file (\"" + FilePathToUTF8(dotfile_name_) + "\")\n" |
+ "didn't specify a \"buildconfig\" value.").PrintToStdout(); |
+ return false; |
+ } |
+ build_settings_.set_build_config_file( |
+ SourceFile("//build/config/BUILDCONFIG.gn")); |
+ |
+ return true; |
+} |