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/ninja_binary_target_writer.h" | 5 #include "tools/gn/ninja_binary_target_writer.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "tools/gn/config_values_extractors.h" | 10 #include "tools/gn/config_values_extractors.h" |
11 #include "tools/gn/err.h" | 11 #include "tools/gn/err.h" |
12 #include "tools/gn/escape.h" | 12 #include "tools/gn/escape.h" |
13 #include "tools/gn/string_utils.h" | 13 #include "tools/gn/string_utils.h" |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 // Returns the proper escape options for writing compiler and linker flags. | 17 // Returns the proper escape options for writing compiler and linker flags. |
18 EscapeOptions GetFlagOptions() { | 18 EscapeOptions GetFlagOptions() { |
19 EscapeOptions opts; | 19 EscapeOptions opts; |
20 opts.mode = ESCAPE_NINJA; | 20 opts.mode = ESCAPE_NINJA_COMMAND; |
21 | 21 |
22 // Some flag strings are actually multiple flags that expect to be just | 22 // Some flag strings are actually multiple flags that expect to be just |
23 // added to the command line. We assume that quoting is done by the | 23 // added to the command line. We assume that quoting is done by the |
24 // buildfiles if it wants such things quoted. | 24 // buildfiles if it wants such things quoted. |
25 opts.inhibit_quoting = true; | 25 opts.inhibit_quoting = true; |
26 | 26 |
27 return opts; | 27 return opts; |
28 } | 28 } |
29 | 29 |
30 struct DefineWriter { | 30 struct DefineWriter { |
31 DefineWriter() { | 31 DefineWriter() { |
32 options.mode = ESCAPE_SHELL; | 32 options.mode = ESCAPE_NINJA_COMMAND; |
33 } | 33 } |
34 | 34 |
35 void operator()(const std::string& s, std::ostream& out) const { | 35 void operator()(const std::string& s, std::ostream& out) const { |
36 out << " -D"; | 36 out << " -D"; |
37 EscapeStringToStream(out, s, options); | 37 EscapeStringToStream(out, s, options); |
38 } | 38 } |
39 | 39 |
40 EscapeOptions options; | 40 EscapeOptions options; |
41 }; | 41 }; |
42 | 42 |
43 struct IncludeWriter { | 43 struct IncludeWriter { |
44 IncludeWriter(PathOutput& path_output, | 44 IncludeWriter(PathOutput& path_output, const NinjaHelper& h) |
45 const NinjaHelper& h) | |
46 : helper(h), | 45 : helper(h), |
47 path_output_(path_output), | 46 path_output_(path_output) { |
48 old_inhibit_quoting_(path_output.inhibit_quoting()) { | |
49 // Inhibit quoting since we'll put quotes around the whole thing ourselves. | |
50 // Since we're writing in NINJA escaping mode, this won't actually do | |
51 // anything, but I think we may need to change to shell-and-then-ninja | |
52 // escaping for this in the future. | |
53 path_output_.set_inhibit_quoting(true); | |
54 } | 47 } |
55 ~IncludeWriter() { | 48 ~IncludeWriter() { |
56 path_output_.set_inhibit_quoting(old_inhibit_quoting_); | |
57 } | 49 } |
58 | 50 |
59 void operator()(const SourceDir& d, std::ostream& out) const { | 51 void operator()(const SourceDir& d, std::ostream& out) const { |
60 out << " \"-I"; | 52 out << " -I"; |
61 // It's important not to include the trailing slash on directories or on | |
62 // Windows it will be a backslash and the compiler might think we're | |
63 // escaping the quote! | |
64 path_output_.WriteDir(out, d, PathOutput::DIR_NO_LAST_SLASH); | 53 path_output_.WriteDir(out, d, PathOutput::DIR_NO_LAST_SLASH); |
65 out << "\""; | |
66 } | 54 } |
67 | 55 |
68 const NinjaHelper& helper; | 56 const NinjaHelper& helper; |
69 PathOutput& path_output_; | 57 PathOutput& path_output_; |
70 bool old_inhibit_quoting_; // So we can put the PathOutput back. | |
71 }; | 58 }; |
72 | 59 |
73 Toolchain::ToolType GetToolTypeForTarget(const Target* target) { | 60 Toolchain::ToolType GetToolTypeForTarget(const Target* target) { |
74 switch (target->output_type()) { | 61 switch (target->output_type()) { |
75 case Target::STATIC_LIBRARY: | 62 case Target::STATIC_LIBRARY: |
76 return Toolchain::TYPE_ALINK; | 63 return Toolchain::TYPE_ALINK; |
77 case Target::SHARED_LIBRARY: | 64 case Target::SHARED_LIBRARY: |
78 return Toolchain::TYPE_SOLINK; | 65 return Toolchain::TYPE_SOLINK; |
79 case Target::EXECUTABLE: | 66 case Target::EXECUTABLE: |
80 return Toolchain::TYPE_LINK; | 67 return Toolchain::TYPE_LINK; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 EscapeOptions flag_options = GetFlagOptions(); | 248 EscapeOptions flag_options = GetFlagOptions(); |
262 RecursiveTargetConfigStringsToStream(target_, &ConfigValues::ldflags, | 249 RecursiveTargetConfigStringsToStream(target_, &ConfigValues::ldflags, |
263 flag_options, out_); | 250 flag_options, out_); |
264 | 251 |
265 // Followed by library search paths that have been recursively pushed | 252 // Followed by library search paths that have been recursively pushed |
266 // through the dependency tree. | 253 // through the dependency tree. |
267 const OrderedSet<SourceDir> all_lib_dirs = target_->all_lib_dirs(); | 254 const OrderedSet<SourceDir> all_lib_dirs = target_->all_lib_dirs(); |
268 if (!all_lib_dirs.empty()) { | 255 if (!all_lib_dirs.empty()) { |
269 // Since we're passing these on the command line to the linker and not | 256 // Since we're passing these on the command line to the linker and not |
270 // to Ninja, we need to do shell escaping. | 257 // to Ninja, we need to do shell escaping. |
271 PathOutput lib_path_output( | 258 PathOutput lib_path_output(path_output_.current_dir(), |
272 path_output_.current_dir(), ESCAPE_NINJA_SHELL, false); | 259 ESCAPE_NINJA_COMMAND); |
273 for (size_t i = 0; i < all_lib_dirs.size(); i++) { | 260 for (size_t i = 0; i < all_lib_dirs.size(); i++) { |
274 out_ << " " << tool.lib_dir_prefix; | 261 out_ << " " << tool.lib_dir_prefix; |
275 lib_path_output.WriteDir(out_, all_lib_dirs[i], | 262 lib_path_output.WriteDir(out_, all_lib_dirs[i], |
276 PathOutput::DIR_NO_LAST_SLASH); | 263 PathOutput::DIR_NO_LAST_SLASH); |
277 } | 264 } |
278 } | 265 } |
279 | 266 |
280 // Append manifest flag on Windows to reference our file. | 267 // Append manifest flag on Windows to reference our file. |
281 // HACK ERASEME BRETTW FIXME | 268 // HACK ERASEME BRETTW FIXME |
282 if (settings_->IsWin()) { | 269 if (settings_->IsWin()) { |
283 out_ << " /MANIFEST /ManifestFile:"; | 270 out_ << " /MANIFEST /ManifestFile:"; |
284 path_output_.WriteFile(out_, windows_manifest); | 271 path_output_.WriteFile(out_, windows_manifest); |
285 } | 272 } |
286 out_ << std::endl; | 273 out_ << std::endl; |
287 } | 274 } |
288 | 275 |
289 void NinjaBinaryTargetWriter::WriteLibs(const Toolchain::Tool& tool) { | 276 void NinjaBinaryTargetWriter::WriteLibs(const Toolchain::Tool& tool) { |
290 out_ << "libs ="; | 277 out_ << "libs ="; |
291 | 278 |
292 // Libraries that have been recursively pushed through the dependency tree. | 279 // Libraries that have been recursively pushed through the dependency tree. |
293 EscapeOptions lib_escape_opts; | 280 EscapeOptions lib_escape_opts; |
294 lib_escape_opts.mode = ESCAPE_NINJA_SHELL; | 281 lib_escape_opts.mode = ESCAPE_NINJA_COMMAND; |
295 const OrderedSet<std::string> all_libs = target_->all_libs(); | 282 const OrderedSet<std::string> all_libs = target_->all_libs(); |
296 const std::string framework_ending(".framework"); | 283 const std::string framework_ending(".framework"); |
297 for (size_t i = 0; i < all_libs.size(); i++) { | 284 for (size_t i = 0; i < all_libs.size(); i++) { |
298 if (settings_->IsMac() && EndsWith(all_libs[i], framework_ending, false)) { | 285 if (settings_->IsMac() && EndsWith(all_libs[i], framework_ending, false)) { |
299 // Special-case libraries ending in ".framework" on Mac. Add the | 286 // Special-case libraries ending in ".framework" on Mac. Add the |
300 // -framework switch and don't add the extension to the output. | 287 // -framework switch and don't add the extension to the output. |
301 out_ << " -framework "; | 288 out_ << " -framework "; |
302 EscapeStringToStream(out_, | 289 EscapeStringToStream(out_, |
303 all_libs[i].substr(0, all_libs[i].size() - framework_ending.size()), | 290 all_libs[i].substr(0, all_libs[i].size() - framework_ending.size()), |
304 lib_escape_opts); | 291 lib_escape_opts); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 } | 458 } |
472 | 459 |
473 // Data files. | 460 // Data files. |
474 const std::vector<SourceFile>& data = target_->data(); | 461 const std::vector<SourceFile>& data = target_->data(); |
475 for (size_t i = 0; i < data.size(); i++) { | 462 for (size_t i = 0; i < data.size(); i++) { |
476 out_ << " "; | 463 out_ << " "; |
477 path_output_.WriteFile(out_, data[i]); | 464 path_output_.WriteFile(out_, data[i]); |
478 } | 465 } |
479 } | 466 } |
480 } | 467 } |
OLD | NEW |