| 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 |