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

Side by Side Diff: tools/gn/label.cc

Issue 630223002: gn: Support build directories outside the source tree. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/label.h" 5 #include "tools/gn/label.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "tools/gn/err.h" 8 #include "tools/gn/err.h"
9 #include "tools/gn/parse_tree.h" 9 #include "tools/gn/parse_tree.h"
10 #include "tools/gn/value.h" 10 #include "tools/gn/value.h"
(...skipping 10 matching lines...) Expand all
21 } 21 }
22 22
23 // Given the separate-out input (everything before the colon) in the dep rule, 23 // Given the separate-out input (everything before the colon) in the dep rule,
24 // computes the final build rule. Sets err on failure. On success, 24 // computes the final build rule. Sets err on failure. On success,
25 // |*used_implicit| will be set to whether the implicit current directory was 25 // |*used_implicit| will be set to whether the implicit current directory was
26 // used. The value is used only for generating error messages. 26 // used. The value is used only for generating error messages.
27 bool ComputeBuildLocationFromDep(const Value& input_value, 27 bool ComputeBuildLocationFromDep(const Value& input_value,
28 const SourceDir& current_dir, 28 const SourceDir& current_dir,
29 const base::StringPiece& input, 29 const base::StringPiece& input,
30 SourceDir* result, 30 SourceDir* result,
31 const base::FilePath& source_root,
31 Err* err) { 32 Err* err) {
32 // No rule, use the current locaton. 33 // No rule, use the current locaton.
33 if (input.empty()) { 34 if (input.empty()) {
34 *result = current_dir; 35 *result = current_dir;
35 return true; 36 return true;
36 } 37 }
37 38
38 // Don't allow directories to start with a single slash. All labels must be 39 // Don't allow directories to start with a single slash. All labels must be
39 // in the source root. 40 // in the source root.
40 if (input[0] == '/' && (input.size() == 1 || input[1] != '/')) { 41 if (input[0] == '/' && (input.size() == 1 || input[1] != '/')) {
41 *err = Err(input_value, "Label can't start with a single slash", 42 *err = Err(input_value, "Label can't start with a single slash",
42 "Labels must be either relative (no slash at the beginning) or be " 43 "Labels must be either relative (no slash at the beginning) or be "
43 "absolute\ninside the source root (two slashes at the beginning)."); 44 "absolute\ninside the source root (two slashes at the beginning).");
44 return false; 45 return false;
45 } 46 }
46 47
47 *result = current_dir.ResolveRelativeDir(input); 48 *result = current_dir.ResolveRelativeDir(input, source_root);
48 return true; 49 return true;
49 } 50 }
50 51
51 // Given the separated-out target name (after the colon) computes the final 52 // Given the separated-out target name (after the colon) computes the final
52 // name, using the implicit name from the previously-generated 53 // name, using the implicit name from the previously-generated
53 // computed_location if necessary. The input_value is used only for generating 54 // computed_location if necessary. The input_value is used only for generating
54 // error messages. 55 // error messages.
55 bool ComputeTargetNameFromDep(const Value& input_value, 56 bool ComputeTargetNameFromDep(const Value& input_value,
56 const SourceDir& computed_location, 57 const SourceDir& computed_location,
57 const base::StringPiece& input, 58 const base::StringPiece& input,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // Returns true on success. On failure, the out* variables might be written to 93 // Returns true on success. On failure, the out* variables might be written to
93 // but shouldn't be used. 94 // but shouldn't be used.
94 bool Resolve(const SourceDir& current_dir, 95 bool Resolve(const SourceDir& current_dir,
95 const Label& current_toolchain, 96 const Label& current_toolchain,
96 const Value& original_value, 97 const Value& original_value,
97 const base::StringPiece& input, 98 const base::StringPiece& input,
98 SourceDir* out_dir, 99 SourceDir* out_dir,
99 std::string* out_name, 100 std::string* out_name,
100 SourceDir* out_toolchain_dir, 101 SourceDir* out_toolchain_dir,
101 std::string* out_toolchain_name, 102 std::string* out_toolchain_name,
103 const base::FilePath& source_root,
102 Err* err) { 104 Err* err) {
103 // To workaround the problem that StringPiece operator[] doesn't return a ref. 105 // To workaround the problem that StringPiece operator[] doesn't return a ref.
104 const char* input_str = input.data(); 106 const char* input_str = input.data();
105 107
106 size_t path_separator = input.find_first_of(":("); 108 size_t path_separator = input.find_first_of(":(");
107 base::StringPiece location_piece; 109 base::StringPiece location_piece;
108 base::StringPiece name_piece; 110 base::StringPiece name_piece;
109 base::StringPiece toolchain_piece; 111 base::StringPiece toolchain_piece;
110 if (path_separator == std::string::npos) { 112 if (path_separator == std::string::npos) {
111 location_piece = input; 113 location_piece = input;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // Absolute: "//foo:bar" -> /foo:bar 155 // Absolute: "//foo:bar" -> /foo:bar
154 // Target in current file: ":foo" -> <currentdir>:foo 156 // Target in current file: ":foo" -> <currentdir>:foo
155 // Path with implicit name: "/foo" -> /foo:foo 157 // Path with implicit name: "/foo" -> /foo:foo
156 if (location_piece.empty() && name_piece.empty()) { 158 if (location_piece.empty() && name_piece.empty()) {
157 // Can't use both implicit filename and name (":"). 159 // Can't use both implicit filename and name (":").
158 *err = Err(original_value, "This doesn't specify a dependency."); 160 *err = Err(original_value, "This doesn't specify a dependency.");
159 return false; 161 return false;
160 } 162 }
161 163
162 if (!ComputeBuildLocationFromDep(original_value, current_dir, location_piece, 164 if (!ComputeBuildLocationFromDep(original_value, current_dir, location_piece,
163 out_dir, err)) 165 out_dir, source_root, err))
164 return false; 166 return false;
165 167
166 if (!ComputeTargetNameFromDep(original_value, *out_dir, name_piece, 168 if (!ComputeTargetNameFromDep(original_value, *out_dir, name_piece,
167 out_name, err)) 169 out_name, err))
168 return false; 170 return false;
169 171
170 // Last, do the toolchains. 172 // Last, do the toolchains.
171 if (out_toolchain_dir) { 173 if (out_toolchain_dir) {
172 // Handle empty toolchain strings. We don't allow normal labels to be 174 // Handle empty toolchain strings. We don't allow normal labels to be
173 // empty so we can't allow the recursive call of this function to do this 175 // empty so we can't allow the recursive call of this function to do this
174 // check. 176 // check.
175 if (toolchain_piece.empty()) { 177 if (toolchain_piece.empty()) {
176 *out_toolchain_dir = current_toolchain.dir(); 178 *out_toolchain_dir = current_toolchain.dir();
177 *out_toolchain_name = current_toolchain.name(); 179 *out_toolchain_name = current_toolchain.name();
178 return true; 180 return true;
179 } else { 181 } else {
180 return Resolve(current_dir, current_toolchain, 182 return Resolve(current_dir, current_toolchain,
181 original_value, toolchain_piece, 183 original_value, toolchain_piece,
182 out_toolchain_dir, out_toolchain_name, NULL, NULL, err); 184 out_toolchain_dir, out_toolchain_name, NULL, NULL,
185 source_root, err);
183 } 186 }
184 } 187 }
185 return true; 188 return true;
186 } 189 }
187 190
188 } // namespace 191 } // namespace
189 192
190 Label::Label() { 193 Label::Label() {
191 } 194 }
192 195
(...skipping 12 matching lines...) Expand all
205 name_.assign(name.data(), name.size()); 208 name_.assign(name.data(), name.size());
206 } 209 }
207 210
208 Label::~Label() { 211 Label::~Label() {
209 } 212 }
210 213
211 // static 214 // static
212 Label Label::Resolve(const SourceDir& current_dir, 215 Label Label::Resolve(const SourceDir& current_dir,
213 const Label& current_toolchain, 216 const Label& current_toolchain,
214 const Value& input, 217 const Value& input,
218 const base::FilePath& source_root,
215 Err* err) { 219 Err* err) {
216 Label ret; 220 Label ret;
217 if (input.type() != Value::STRING) { 221 if (input.type() != Value::STRING) {
218 *err = Err(input, "Dependency is not a string."); 222 *err = Err(input, "Dependency is not a string.");
219 return ret; 223 return ret;
220 } 224 }
221 const std::string& input_string = input.string_value(); 225 const std::string& input_string = input.string_value();
222 if (input_string.empty()) { 226 if (input_string.empty()) {
223 *err = Err(input, "Dependency string is empty."); 227 *err = Err(input, "Dependency string is empty.");
224 return ret; 228 return ret;
225 } 229 }
226 230
227 if (!::Resolve(current_dir, current_toolchain, input, input_string, 231 if (!::Resolve(current_dir, current_toolchain, input, input_string,
228 &ret.dir_, &ret.name_, 232 &ret.dir_, &ret.name_,
229 &ret.toolchain_dir_, &ret.toolchain_name_, 233 &ret.toolchain_dir_, &ret.toolchain_name_,
230 err)) 234 source_root, err))
231 return Label(); 235 return Label();
232 return ret; 236 return ret;
233 } 237 }
234 238
235 Label Label::GetToolchainLabel() const { 239 Label Label::GetToolchainLabel() const {
236 return Label(toolchain_dir_, toolchain_name_); 240 return Label(toolchain_dir_, toolchain_name_);
237 } 241 }
238 242
239 Label Label::GetWithNoToolchain() const { 243 Label Label::GetWithNoToolchain() const {
240 return Label(dir_, name_); 244 return Label(dir_, name_);
(...skipping 21 matching lines...) Expand all
262 } 266 }
263 return ret; 267 return ret;
264 } 268 }
265 269
266 std::string Label::GetUserVisibleName(const Label& default_toolchain) const { 270 std::string Label::GetUserVisibleName(const Label& default_toolchain) const {
267 bool include_toolchain = 271 bool include_toolchain =
268 default_toolchain.dir() != toolchain_dir_ || 272 default_toolchain.dir() != toolchain_dir_ ||
269 default_toolchain.name() != toolchain_name_; 273 default_toolchain.name() != toolchain_name_;
270 return GetUserVisibleName(include_toolchain); 274 return GetUserVisibleName(include_toolchain);
271 } 275 }
OLDNEW
« tools/gn/filesystem_utils.cc ('K') | « tools/gn/label.h ('k') | tools/gn/label_pattern.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698