OLD | NEW |
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/gyp_binary_target_writer.h" | 5 #include "tools/gn/gyp_binary_target_writer.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "tools/gn/builder_record.h" | 10 #include "tools/gn/builder_record.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 struct Accumulator { | 23 struct Accumulator { |
24 Accumulator(std::vector<T>* result_in) : result(result_in) {} | 24 Accumulator(std::vector<T>* result_in) : result(result_in) {} |
25 | 25 |
26 void operator()(const T& s, std::ostream&) const { | 26 void operator()(const T& s, std::ostream&) const { |
27 result->push_back(s); | 27 result->push_back(s); |
28 } | 28 } |
29 | 29 |
30 std::vector<T>* result; | 30 std::vector<T>* result; |
31 }; | 31 }; |
32 | 32 |
33 // Standalone version of GypBinaryTargetWriter::Indent for use by standalone | |
34 // functions. | |
35 std::ostream& Indent(std::ostream& out, int spaces) { | |
36 const char kSpaces[81] = | |
37 " " | |
38 " "; | |
39 CHECK(static_cast<size_t>(spaces) <= arraysize(kSpaces) - 1); | |
40 out.write(kSpaces, spaces); | |
41 return out; | |
42 } | |
43 | |
44 // Writes the given array values. The array should already be declared with the | 33 // Writes the given array values. The array should already be declared with the |
45 // opening "[" written to the output. The function will not write the | 34 // opening "[" written to the output. The function will not write the |
46 // terminating "]" either. | 35 // terminating "]" either. |
47 void WriteArrayValues(std::ostream& out, | 36 void WriteArrayValues(std::ostream& out, |
48 const std::vector<std::string>& values) { | 37 const std::vector<std::string>& values) { |
49 EscapeOptions options; | 38 EscapeOptions options; |
50 options.mode = ESCAPE_JSON; | 39 options.mode = ESCAPE_JSON; |
51 for (size_t i = 0; i < values.size(); i++) { | 40 for (size_t i = 0; i < values.size(); i++) { |
52 out << " '"; | 41 out << " '"; |
53 EscapeStringToStream(out, values[i], options); | 42 EscapeStringToStream(out, values[i], options); |
54 out << "',"; | 43 out << "',"; |
55 } | 44 } |
56 } | 45 } |
57 | 46 |
58 // Writes the given array with the given name. The indent should be the | |
59 // indenting for the name, the values will be indented 2 spaces from there. | |
60 // Writes nothing if there is nothing in the array. | |
61 void WriteNamedArray(std::ostream& out, | |
62 const char* name, | |
63 const std::vector<std::string>& values, | |
64 int indent) { | |
65 if (values.empty()) | |
66 return; | |
67 | |
68 EscapeOptions options; | |
69 options.mode = ESCAPE_JSON; | |
70 | |
71 Indent(out, indent) << "'" << name << "': ["; | |
72 WriteArrayValues(out, values); | |
73 out << " ],\n"; | |
74 } | |
75 | |
76 // Returns the value from the already-filled in cflags_* for the optimization | 47 // Returns the value from the already-filled in cflags_* for the optimization |
77 // level to set in the GYP file. Additionally, this removes the flag from the | 48 // level to set in the GYP file. Additionally, this removes the flag from the |
78 // given vector so we don't get duplicates. | 49 // given vector so we don't get duplicates. |
79 std::string GetVCOptimization(std::vector<std::string>* cflags) { | 50 std::string GetVCOptimization(std::vector<std::string>* cflags) { |
80 // Searches for the "/O?" option and returns the corresponding GYP value. | 51 // Searches for the "/O?" option and returns the corresponding GYP value. |
81 for (size_t i = 0; i < cflags->size(); i++) { | 52 for (size_t i = 0; i < cflags->size(); i++) { |
82 const std::string& cur = (*cflags)[i]; | 53 const std::string& cur = (*cflags)[i]; |
83 if (cur.size() == 3 && cur[0] == '/' && cur[1] == 'O') { | 54 if (cur.size() == 3 && cur[0] == '/' && cur[1] == 'O') { |
84 char level = cur[2]; | 55 char level = cur[2]; |
85 cflags->erase(cflags->begin() + i); // Invalidates |cur|! | 56 cflags->erase(cflags->begin() + i); // Invalidates |cur|! |
(...skipping 17 matching lines...) Expand all Loading... |
103 const std::vector<T>& (ConfigValues::* getter)() const, | 74 const std::vector<T>& (ConfigValues::* getter)() const, |
104 std::vector<T>* result) { | 75 std::vector<T>* result) { |
105 for (size_t config_i = 0; config_i < configs.size(); config_i++) { | 76 for (size_t config_i = 0; config_i < configs.size(); config_i++) { |
106 const std::vector<T>& values = | 77 const std::vector<T>& values = |
107 (configs[config_i].ptr->config_values().*getter)(); | 78 (configs[config_i].ptr->config_values().*getter)(); |
108 for (size_t val_i = 0; val_i < values.size(); val_i++) | 79 for (size_t val_i = 0; val_i < values.size(); val_i++) |
109 result->push_back(values[val_i]); | 80 result->push_back(values[val_i]); |
110 } | 81 } |
111 } | 82 } |
112 | 83 |
113 const int kExtraIndent = 2; | |
114 | |
115 } // namespace | 84 } // namespace |
116 | 85 |
117 GypBinaryTargetWriter::Flags::Flags() {} | 86 GypBinaryTargetWriter::Flags::Flags() {} |
118 GypBinaryTargetWriter::Flags::~Flags() {} | 87 GypBinaryTargetWriter::Flags::~Flags() {} |
119 | 88 |
120 GypBinaryTargetWriter::GypBinaryTargetWriter(const TargetGroup& group, | 89 GypBinaryTargetWriter::GypBinaryTargetWriter(const TargetGroup& group, |
| 90 const SourceDir& gyp_dir, |
121 std::ostream& out) | 91 std::ostream& out) |
122 : GypTargetWriter(group.debug->item()->AsTarget(), out), | 92 : GypTargetWriter(group.debug->item()->AsTarget(), gyp_dir, out), |
123 group_(group) { | 93 group_(group) { |
124 } | 94 } |
125 | 95 |
126 GypBinaryTargetWriter::~GypBinaryTargetWriter() { | 96 GypBinaryTargetWriter::~GypBinaryTargetWriter() { |
127 } | 97 } |
128 | 98 |
129 void GypBinaryTargetWriter::Run() { | 99 void GypBinaryTargetWriter::Run() { |
130 int indent = 4; | 100 int indent = 4; |
131 | 101 |
132 Indent(indent) << "{\n"; | 102 Indent(indent) << "{\n"; |
133 | 103 |
134 WriteName(indent + kExtraIndent); | 104 WriteName(indent + kExtraIndent); |
135 WriteType(indent + kExtraIndent); | 105 WriteType(indent + kExtraIndent); |
136 | 106 |
137 if (target_->settings()->IsLinux()) | 107 if (target_->settings()->IsLinux()) |
138 WriteLinuxConfiguration(indent + kExtraIndent); | 108 WriteLinuxConfiguration(indent + kExtraIndent); |
139 else if (target_->settings()->IsWin()) | 109 else if (target_->settings()->IsWin()) |
140 WriteVCConfiguration(indent + kExtraIndent); | 110 WriteVCConfiguration(indent + kExtraIndent); |
141 else if (target_->settings()->IsMac()) | 111 else if (target_->settings()->IsMac()) |
142 WriteMacConfiguration(indent + kExtraIndent); | 112 WriteMacConfiguration(indent + kExtraIndent); |
143 WriteDirectDependentSettings(indent + kExtraIndent); | 113 WriteDirectDependentSettings(indent + kExtraIndent); |
144 WriteAllDependentSettings(indent + kExtraIndent); | 114 WriteAllDependentSettings(indent + kExtraIndent); |
145 | 115 |
146 Indent(indent) << "},\n"; | 116 Indent(indent) << "},\n"; |
147 } | 117 } |
148 | 118 |
149 std::ostream& GypBinaryTargetWriter::Indent(int spaces) { | |
150 return ::Indent(out_, spaces); | |
151 } | |
152 | |
153 void GypBinaryTargetWriter::WriteName(int indent) { | 119 void GypBinaryTargetWriter::WriteName(int indent) { |
154 std::string name = helper_.GetNameForTarget(target_); | 120 std::string name = helper_.GetNameForTarget(target_); |
155 Indent(indent) << "'target_name': '" << name << "',\n"; | 121 Indent(indent) << "'target_name': '" << name << "',\n"; |
156 | 122 |
157 std::string product_name; | 123 std::string product_name; |
158 if (target_->output_name().empty()) | 124 if (target_->output_name().empty()) |
159 product_name = target_->label().name(); | 125 product_name = target_->label().name(); |
160 else | 126 else |
161 product_name = name; | 127 product_name = name; |
162 | 128 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 Indent(indent + kExtraIndent) << "},\n"; | 240 Indent(indent + kExtraIndent) << "},\n"; |
275 | 241 |
276 Indent(indent) << "},\n"; | 242 Indent(indent) << "},\n"; |
277 | 243 |
278 WriteSources(target_, indent); | 244 WriteSources(target_, indent); |
279 WriteDeps(target_, indent); | 245 WriteDeps(target_, indent); |
280 } | 246 } |
281 | 247 |
282 void GypBinaryTargetWriter::WriteVCFlags(Flags& flags, int indent) { | 248 void GypBinaryTargetWriter::WriteVCFlags(Flags& flags, int indent) { |
283 // Defines and includes go outside of the msvs settings. | 249 // Defines and includes go outside of the msvs settings. |
284 WriteNamedArray(out_, "defines", flags.defines, indent); | 250 WriteNamedArray("defines", flags.defines, indent); |
285 WriteIncludeDirs(flags, indent); | 251 WriteIncludeDirs(flags, indent); |
286 | 252 |
287 // C flags. | 253 // C flags. |
288 Indent(indent) << "'msvs_settings': {\n"; | 254 Indent(indent) << "'msvs_settings': {\n"; |
289 Indent(indent + kExtraIndent) << "'VCCLCompilerTool': {\n"; | 255 Indent(indent + kExtraIndent) << "'VCCLCompilerTool': {\n"; |
290 | 256 |
291 // GYP always uses the VC optimization flag to add a /O? on Visual Studio. | 257 // GYP always uses the VC optimization flag to add a /O? on Visual Studio. |
292 // This can produce duplicate values. So look up the GYP value corresponding | 258 // This can produce duplicate values. So look up the GYP value corresponding |
293 // to the flags used, and set the same one. | 259 // to the flags used, and set the same one. |
294 std::string optimization = GetVCOptimization(&flags.cflags); | 260 std::string optimization = GetVCOptimization(&flags.cflags); |
295 WriteNamedArray(out_, "AdditionalOptions", flags.cflags, | 261 WriteNamedArray("AdditionalOptions", flags.cflags, indent + kExtraIndent * 2); |
296 indent + kExtraIndent * 2); | |
297 // TODO(brettw) cflags_c and cflags_cc! | 262 // TODO(brettw) cflags_c and cflags_cc! |
298 Indent(indent + kExtraIndent * 2) << "'Optimization': " | 263 Indent(indent + kExtraIndent * 2) << "'Optimization': " |
299 << optimization << ",\n"; | 264 << optimization << ",\n"; |
300 Indent(indent + kExtraIndent) << "},\n"; | 265 Indent(indent + kExtraIndent) << "},\n"; |
301 | 266 |
302 // Linker tool stuff. | 267 // Linker tool stuff. |
303 Indent(indent + kExtraIndent) << "'VCLinkerTool': {\n"; | 268 Indent(indent + kExtraIndent) << "'VCLinkerTool': {\n"; |
304 | 269 |
305 // ...Library dirs. | 270 // ...Library dirs. |
306 EscapeOptions escape_options; | 271 EscapeOptions escape_options; |
307 escape_options.mode = ESCAPE_JSON; | 272 escape_options.mode = ESCAPE_JSON; |
308 if (!flags.lib_dirs.empty()) { | 273 if (!flags.lib_dirs.empty()) { |
309 Indent(indent + kExtraIndent * 2) << "'AdditionalLibraryDirectories': ["; | 274 Indent(indent + kExtraIndent * 2) << "'AdditionalLibraryDirectories': ["; |
310 for (size_t i = 0; i < flags.lib_dirs.size(); i++) { | 275 for (size_t i = 0; i < flags.lib_dirs.size(); i++) { |
311 out_ << " '"; | 276 out_ << " '"; |
312 EscapeStringToStream(out_, | 277 EscapeStringToStream(out_, |
313 helper_.GetDirReference(flags.lib_dirs[i], false), | 278 helper_.GetDirReference(flags.lib_dirs[i], false), |
314 escape_options); | 279 escape_options); |
315 out_ << "',"; | 280 out_ << "',"; |
316 } | 281 } |
317 out_ << " ],\n"; | 282 out_ << " ],\n"; |
318 } | 283 } |
319 | 284 |
320 // ...Libraries. | 285 // ...Libraries. |
321 WriteNamedArray(out_, "AdditionalDependencies", flags.libs, | 286 WriteNamedArray("AdditionalDependencies", flags.libs, |
322 indent + kExtraIndent * 2); | 287 indent + kExtraIndent * 2); |
323 | 288 |
324 // ...LD flags. | 289 // ...LD flags. |
325 // TODO(brettw) EnableUAC defaults to on and needs to be set. Also | 290 // TODO(brettw) EnableUAC defaults to on and needs to be set. Also |
326 // UACExecutionLevel and UACUIAccess depends on that and defaults to 0/false. | 291 // UACExecutionLevel and UACUIAccess depends on that and defaults to 0/false. |
327 WriteNamedArray(out_, "AdditionalOptions", flags.ldflags, 14); | 292 WriteNamedArray("AdditionalOptions", flags.ldflags, 14); |
328 Indent(indent + kExtraIndent) << "},\n"; | 293 Indent(indent + kExtraIndent) << "},\n"; |
329 Indent(indent) << "},\n"; | 294 Indent(indent) << "},\n"; |
330 } | 295 } |
331 | 296 |
332 void GypBinaryTargetWriter::WriteMacFlags(Flags& flags, int indent) { | 297 void GypBinaryTargetWriter::WriteMacFlags(Flags& flags, int indent) { |
333 WriteNamedArray(out_, "defines", flags.defines, indent); | 298 WriteNamedArray("defines", flags.defines, indent); |
334 WriteIncludeDirs(flags, indent); | 299 WriteIncludeDirs(flags, indent); |
335 | 300 |
336 // Libraries and library directories. | 301 // Libraries and library directories. |
337 EscapeOptions escape_options; | 302 EscapeOptions escape_options; |
338 escape_options.mode = ESCAPE_JSON; | 303 escape_options.mode = ESCAPE_JSON; |
339 if (!flags.lib_dirs.empty()) { | 304 if (!flags.lib_dirs.empty()) { |
340 Indent(indent + kExtraIndent) << "'library_dirs': ["; | 305 Indent(indent + kExtraIndent) << "'library_dirs': ["; |
341 for (size_t i = 0; i < flags.lib_dirs.size(); i++) { | 306 for (size_t i = 0; i < flags.lib_dirs.size(); i++) { |
342 out_ << " '"; | 307 out_ << " '"; |
343 EscapeStringToStream(out_, | 308 EscapeStringToStream(out_, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 Indent(indent + kExtraIndent) << "'OTHER_CPLUSPLUSFLAGS': ["; | 340 Indent(indent + kExtraIndent) << "'OTHER_CPLUSPLUSFLAGS': ["; |
376 WriteArrayValues(out_, flags.cflags); | 341 WriteArrayValues(out_, flags.cflags); |
377 WriteArrayValues(out_, flags.cflags_cc); | 342 WriteArrayValues(out_, flags.cflags_cc); |
378 WriteArrayValues(out_, flags.cflags_objcc); | 343 WriteArrayValues(out_, flags.cflags_objcc); |
379 out_ << " ],\n"; | 344 out_ << " ],\n"; |
380 } | 345 } |
381 | 346 |
382 // Ld flags. Don't write these for static libraries. Otherwise, they'll be | 347 // Ld flags. Don't write these for static libraries. Otherwise, they'll be |
383 // passed to the library tool which doesn't expect it (the toolchain does | 348 // passed to the library tool which doesn't expect it (the toolchain does |
384 // not use ldflags so these are ignored in the normal build). | 349 // not use ldflags so these are ignored in the normal build). |
385 if (target_->output_type() != Target::STATIC_LIBRARY) { | 350 if (target_->output_type() != Target::STATIC_LIBRARY) |
386 WriteNamedArray(out_, "OTHER_LDFLAGS", flags.ldflags, | 351 WriteNamedArray("OTHER_LDFLAGS", flags.ldflags, indent + kExtraIndent); |
387 indent + kExtraIndent); | |
388 } | |
389 | 352 |
390 base::FilePath clang_path = | 353 base::FilePath clang_path = |
391 target_->settings()->build_settings()->GetFullPath(SourceFile( | 354 target_->settings()->build_settings()->GetFullPath(SourceFile( |
392 "//third_party/llvm-build/Release+Asserts/bin/clang")); | 355 "//third_party/llvm-build/Release+Asserts/bin/clang")); |
393 base::FilePath clang_pp_path = | 356 base::FilePath clang_pp_path = |
394 target_->settings()->build_settings()->GetFullPath(SourceFile( | 357 target_->settings()->build_settings()->GetFullPath(SourceFile( |
395 "//third_party/llvm-build/Release+Asserts/bin/clang++")); | 358 "//third_party/llvm-build/Release+Asserts/bin/clang++")); |
396 | 359 |
397 Indent(indent) << "'CC': '" << FilePathToUTF8(clang_path) << "',\n"; | 360 Indent(indent) << "'CC': '" << FilePathToUTF8(clang_path) << "',\n"; |
398 Indent(indent) << "'LDPLUSPLUS': '" | 361 Indent(indent) << "'LDPLUSPLUS': '" |
399 << FilePathToUTF8(clang_pp_path) << "',\n"; | 362 << FilePathToUTF8(clang_pp_path) << "',\n"; |
400 | 363 |
401 Indent(indent) << "},\n"; | 364 Indent(indent) << "},\n"; |
402 } | 365 } |
403 | 366 |
404 void GypBinaryTargetWriter::WriteLinuxFlagsForTarget(const Target* target, | 367 void GypBinaryTargetWriter::WriteLinuxFlagsForTarget(const Target* target, |
405 int indent) { | 368 int indent) { |
406 Flags flags(FlagsFromTarget(target)); | 369 Flags flags(FlagsFromTarget(target)); |
407 WriteLinuxFlags(flags, indent); | 370 WriteLinuxFlags(flags, indent); |
408 } | 371 } |
409 | 372 |
410 void GypBinaryTargetWriter::WriteLinuxFlags(const Flags& flags, int indent) { | 373 void GypBinaryTargetWriter::WriteLinuxFlags(const Flags& flags, int indent) { |
411 WriteIncludeDirs(flags, indent); | 374 WriteIncludeDirs(flags, indent); |
412 WriteNamedArray(out_, "defines", flags.defines, indent); | 375 WriteNamedArray("defines", flags.defines, indent); |
413 WriteNamedArray(out_, "cflags", flags.cflags, indent); | 376 WriteNamedArray("cflags", flags.cflags, indent); |
414 WriteNamedArray(out_, "cflags_c", flags.cflags_c, indent); | 377 WriteNamedArray("cflags_c", flags.cflags_c, indent); |
415 WriteNamedArray(out_, "cflags_cc", flags.cflags_cc, indent); | 378 WriteNamedArray("cflags_cc", flags.cflags_cc, indent); |
416 WriteNamedArray(out_, "cflags_objc", flags.cflags_objc, indent); | 379 WriteNamedArray("cflags_objc", flags.cflags_objc, indent); |
417 WriteNamedArray(out_, "cflags_objcc", flags.cflags_objcc, indent); | 380 WriteNamedArray("cflags_objcc", flags.cflags_objcc, indent); |
418 | 381 |
419 // Put libraries and library directories in with ldflags. | 382 // Put libraries and library directories in with ldflags. |
420 Indent(indent) << "'ldflags': ["; \ | 383 Indent(indent) << "'ldflags': ["; \ |
421 WriteArrayValues(out_, flags.ldflags); | 384 WriteArrayValues(out_, flags.ldflags); |
422 | 385 |
423 EscapeOptions escape_options; | 386 EscapeOptions escape_options; |
424 escape_options.mode = ESCAPE_JSON; | 387 escape_options.mode = ESCAPE_JSON; |
425 for (size_t i = 0; i < flags.lib_dirs.size(); i++) { | 388 for (size_t i = 0; i < flags.lib_dirs.size(); i++) { |
426 out_ << " '-L"; | 389 out_ << " '-L"; |
427 EscapeStringToStream(out_, | 390 EscapeStringToStream(out_, |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 EXTRACT(std::string, cflags_objc); | 529 EXTRACT(std::string, cflags_objc); |
567 EXTRACT(std::string, cflags_objcc); | 530 EXTRACT(std::string, cflags_objcc); |
568 EXTRACT(std::string, ldflags); | 531 EXTRACT(std::string, ldflags); |
569 EXTRACT(SourceDir, lib_dirs); | 532 EXTRACT(SourceDir, lib_dirs); |
570 EXTRACT(std::string, libs); | 533 EXTRACT(std::string, libs); |
571 | 534 |
572 #undef EXTRACT | 535 #undef EXTRACT |
573 | 536 |
574 return ret; | 537 return ret; |
575 } | 538 } |
| 539 |
| 540 void GypBinaryTargetWriter::WriteNamedArray( |
| 541 const char* name, |
| 542 const std::vector<std::string>& values, |
| 543 int indent) { |
| 544 if (values.empty()) |
| 545 return; |
| 546 |
| 547 EscapeOptions options; |
| 548 options.mode = ESCAPE_JSON; |
| 549 |
| 550 Indent(indent) << "'" << name << "': ["; |
| 551 WriteArrayValues(out_, values); |
| 552 out_ << " ],\n"; |
| 553 } |
| 554 |
OLD | NEW |