OLD | NEW |
(Empty) | |
| 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 "tools/gn/setup.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/file_util.h" |
| 9 #include "base/files/file_path.h" |
| 10 #include "tools/gn/filesystem_utils.h" |
| 11 #include "tools/gn/input_file.h" |
| 12 #include "tools/gn/parse_tree.h" |
| 13 #include "tools/gn/parser.h" |
| 14 #include "tools/gn/source_dir.h" |
| 15 #include "tools/gn/source_file.h" |
| 16 #include "tools/gn/tokenizer.h" |
| 17 #include "tools/gn/value.h" |
| 18 |
| 19 namespace { |
| 20 |
| 21 // More logging. |
| 22 const char kSwitchVerbose[] = "v"; |
| 23 |
| 24 const char kSwitchRoot[] = "root"; |
| 25 const char kSecondarySource[] = "secondary"; |
| 26 |
| 27 const base::FilePath::CharType kGnFile[] = FILE_PATH_LITERAL(".gn"); |
| 28 |
| 29 base::FilePath FindDotFile(const base::FilePath& current_dir) { |
| 30 base::FilePath try_this_file = current_dir.Append(kGnFile); |
| 31 if (base::PathExists(try_this_file)) |
| 32 return try_this_file; |
| 33 |
| 34 base::FilePath with_no_slash = current_dir.StripTrailingSeparators(); |
| 35 base::FilePath up_one_dir = with_no_slash.DirName(); |
| 36 if (up_one_dir == current_dir) |
| 37 return base::FilePath(); // Got to the top. |
| 38 |
| 39 return FindDotFile(up_one_dir); |
| 40 } |
| 41 |
| 42 } // namespace |
| 43 |
| 44 Setup::Setup() |
| 45 : dotfile_toolchain_(Label()), |
| 46 dotfile_settings_(&dotfile_build_settings_, &dotfile_toolchain_, |
| 47 std::string()), |
| 48 dotfile_scope_(&dotfile_settings_) { |
| 49 } |
| 50 |
| 51 Setup::~Setup() { |
| 52 } |
| 53 |
| 54 bool Setup::DoSetup() { |
| 55 CommandLine* cmdline = CommandLine::ForCurrentProcess(); |
| 56 |
| 57 scheduler_.set_verbose_logging(cmdline->HasSwitch(kSwitchVerbose)); |
| 58 |
| 59 if (!FillSourceDir(*cmdline)) |
| 60 return false; |
| 61 if (!RunConfigFile()) |
| 62 return false; |
| 63 if (!FillOtherConfig(*cmdline)) |
| 64 return false; |
| 65 |
| 66 // FIXME(brettw) get python path! |
| 67 /*#if defined(OS_WIN) |
| 68 build_settings_.set_python_path(base::FilePath( |
| 69 //L"P:\\depot_tools\\python_bin\\python.exe")); |
| 70 L"C:\\apps\\depot_tools\\python_bin\\python.exe")); |
| 71 #else*/ |
| 72 build_settings_.set_python_path(base::FilePath("python")); |
| 73 //#endif |
| 74 |
| 75 build_settings_.SetBuildDir(SourceDir("//out/gn/")); |
| 76 |
| 77 return true; |
| 78 } |
| 79 |
| 80 bool Setup::Run() { |
| 81 // Load the root build file and start runnung. |
| 82 build_settings_.toolchain_manager().StartLoadingUnlocked( |
| 83 SourceFile("//BUILD.gn")); |
| 84 if (!scheduler_.Run()) |
| 85 return false; |
| 86 |
| 87 Err err = build_settings_.item_tree().CheckForBadItems(); |
| 88 if (err.has_error()) { |
| 89 err.PrintToStdout(); |
| 90 return false; |
| 91 } |
| 92 return true; |
| 93 } |
| 94 |
| 95 bool Setup::FillSourceDir(const CommandLine& cmdline) { |
| 96 // Find the .gn file. |
| 97 base::FilePath root_path; |
| 98 |
| 99 // Prefer the command line args to the config file. |
| 100 base::FilePath relative_root_path = cmdline.GetSwitchValuePath(kSwitchRoot); |
| 101 if (!relative_root_path.empty()) { |
| 102 root_path = base::MakeAbsoluteFilePath(relative_root_path); |
| 103 dotfile_name_ = root_path.Append(kGnFile); |
| 104 } else { |
| 105 base::FilePath cur_dir; |
| 106 file_util::GetCurrentDirectory(&cur_dir); |
| 107 dotfile_name_ = FindDotFile(cur_dir); |
| 108 if (dotfile_name_.empty()) { |
| 109 Err(Location(), "Can't find source root.", |
| 110 "I could not find a \".gn\" file in the current directory or any " |
| 111 "parent,\nand the --root command-line argument was not specified.") |
| 112 .PrintToStdout(); |
| 113 return false; |
| 114 } |
| 115 root_path = dotfile_name_.DirName(); |
| 116 } |
| 117 |
| 118 if (scheduler_.verbose_logging()) |
| 119 scheduler_.Log("Using source root", FilePathToUTF8(root_path)); |
| 120 build_settings_.set_root_path(root_path); |
| 121 |
| 122 return true; |
| 123 } |
| 124 |
| 125 bool Setup::RunConfigFile() { |
| 126 if (scheduler_.verbose_logging()) |
| 127 scheduler_.Log("Got dotfile", FilePathToUTF8(dotfile_name_)); |
| 128 |
| 129 dotfile_input_file_.reset(new InputFile(SourceFile("//.gn"))); |
| 130 if (!dotfile_input_file_->Load(dotfile_name_)) { |
| 131 Err(Location(), "Could not load dotfile.", |
| 132 "The file \"" + FilePathToUTF8(dotfile_name_) + "\" cound't be loaded") |
| 133 .PrintToStdout(); |
| 134 return false; |
| 135 } |
| 136 |
| 137 Err err; |
| 138 dotfile_tokens_ = Tokenizer::Tokenize(dotfile_input_file_.get(), &err); |
| 139 if (err.has_error()) { |
| 140 err.PrintToStdout(); |
| 141 return false; |
| 142 } |
| 143 |
| 144 dotfile_root_ = Parser::Parse(dotfile_tokens_, &err); |
| 145 if (err.has_error()) { |
| 146 err.PrintToStdout(); |
| 147 return false; |
| 148 } |
| 149 |
| 150 dotfile_root_->AsBlock()->ExecuteBlockInScope(&dotfile_scope_, &err); |
| 151 if (err.has_error()) { |
| 152 err.PrintToStdout(); |
| 153 return false; |
| 154 } |
| 155 |
| 156 return true; |
| 157 } |
| 158 |
| 159 bool Setup::FillOtherConfig(const CommandLine& cmdline) { |
| 160 Err err; |
| 161 |
| 162 // Secondary source path. |
| 163 SourceDir secondary_source; |
| 164 if (cmdline.HasSwitch(kSecondarySource)) { |
| 165 // Prefer the command line over the config file. |
| 166 secondary_source = |
| 167 SourceDir(cmdline.GetSwitchValueASCII(kSecondarySource)); |
| 168 } else { |
| 169 // Read from the config file if present. |
| 170 const Value* secondary_value = |
| 171 dotfile_scope_.GetValue("secondary_source", true); |
| 172 if (secondary_value) { |
| 173 if (!secondary_value->VerifyTypeIs(Value::STRING, &err)) { |
| 174 err.PrintToStdout(); |
| 175 return false; |
| 176 } |
| 177 build_settings_.SetSecondarySourcePath( |
| 178 SourceDir(secondary_value->string_value())); |
| 179 } |
| 180 } |
| 181 |
| 182 // Build config dir. |
| 183 const Value* build_config_value = |
| 184 dotfile_scope_.GetValue("buildconfig", true); |
| 185 if (!build_config_value) { |
| 186 Err(Location(), "No build config file.", |
| 187 "Your .gn file (\"" + FilePathToUTF8(dotfile_name_) + "\")\n" |
| 188 "didn't specify a \"buildconfig\" value.").PrintToStdout(); |
| 189 return false; |
| 190 } |
| 191 build_settings_.set_build_config_file( |
| 192 SourceFile("//build/config/BUILDCONFIG.gn")); |
| 193 |
| 194 return true; |
| 195 } |
OLD | NEW |