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 |