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

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

Issue 26561005: GYP generator for GN (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 | Annotate | Revision Log
OLDNEW
(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/gyp_binary_target_writer.h"
6
7 #include <set>
8
9 #include "tools/gn/config_values_extractors.h"
10 #include "tools/gn/err.h"
11 #include "tools/gn/escape.h"
12 #include "tools/gn/settings.h"
13 #include "tools/gn/target.h"
14
15 namespace {
16
17 // This functor is used to capture the output of RecursiveTargetConfigToStream
18 // in an vector.
19 struct StringAccumulator {
20 StringAccumulator(std::vector<std::string>* result_in) : result(result_in) {}
21
22 void operator()(const std::string& s, std::ostream&) const {
23 result->push_back(s);
24 }
25
26 std::vector<std::string>* result;
27 };
28
29 // Writes the given array with the given name. The indent should be the
30 // indenting for the name, the values will be indented 2 spaces from there.
31 // Writes nothing if there is nothing in the array.
32 void WriteArray(std::ostream& out,
33 const char* name,
34 const std::vector<std::string>& values,
35 int indent) {
36 if (values.empty())
37 return;
38
39 EscapeOptions options;
40 options.mode = ESCAPE_JSON;
41
42 std::string indent_str(indent, ' ');
43 out << indent_str << "'" << name << "': [";
44 for (size_t i = 0; i < values.size(); i++) {
45 out << " '";
46 EscapeStringToStream(out, values[i], options);
47 out << "',";
48 }
49 out << " ],\n";
50 }
51
52 struct StringWriter {
53 StringWriter() {
54 options.mode = ESCAPE_JSON;
55 }
56
57 void operator()(const std::string& s, std::ostream& out) const {
58 out << " '";
59 EscapeStringToStream(out, s, options);
60 out << "',";
61 }
62
63 EscapeOptions options;
64 };
65
66 struct IncludeWriter {
67 IncludeWriter(const GypHelper& h) : helper(h) {
68 options.mode = ESCAPE_JSON;
69 }
70
71 void operator()(const SourceDir& d, std::ostream& out) const {
72 out << " '";
73 EscapeStringToStream(out, helper.GetDirReference(d, false), options);
74 out << "',";
75 }
76
77 const GypHelper& helper;
78 EscapeOptions options;
79 };
80
81 // Returns the value from the already-filled in cflags_* for the optimization
82 // level to set in the GYP file. Additionally, this removes the flag from the
83 // given vector so we don't get duplicates.
84 std::string GetVCOptimization(std::vector<std::string>* cflags) {
85 // Searches for the "/O?" option and returns the corresponding GYP value.
86 for (size_t i = 0; i < cflags->size(); i++) {
87 const std::string& cur = (*cflags)[i];
88 if (cur.size() == 3 && cur[0] == '/' && cur[1] == 'O') {
89 char level = cur[2];
90 cflags->erase(cflags->begin() + i); // Invalidates |cur|!
91 switch (level) {
92 case 'd': return "'0'";
93 case '1': return "'1'";
94 case '2': return "'2'";
95 case 'x': return "'3'";
96 default: return "'2'";
97 }
98 }
99 }
100 return "'2'"; // Default value.
101 }
102
103 } // namespace
104
105 GypBinaryTargetWriter::GypBinaryTargetWriter(const Target* debug_target,
106 const Target* release_target,
107 std::ostream& out)
108 : GypTargetWriter(debug_target, out),
109 release_target_(release_target) {
110 }
111
112 GypBinaryTargetWriter::~GypBinaryTargetWriter() {
113 }
114
115 void GypBinaryTargetWriter::Run() {
116 out_ << " {\n";
117
118 WriteName();
119 WriteType();
120
121 out_ << " 'configurations': {\n";
122 out_ << " 'Debug': {\n";
123 WriteFlags(target_);
124 out_ << " },\n";
125 out_ << " 'Release': {\n";
126 WriteFlags(release_target_);
127 out_ << " },\n";
128 out_ << " 'Debug_x64': {},\n";
129 out_ << " 'Release_x64': {},\n";
130 out_ << " },\n";
131
132 WriteSources();
133 WriteDeps();
134
135 out_ << " },\n";
136 }
137
138 void GypBinaryTargetWriter::WriteName() {
139 std::string name = helper_.GetNameForTarget(target_);
140 out_ << " 'target_name': '";
141 out_ << name;
142 out_ << "',\n";
143
144 std::string product_name;
145 if (target_->output_name().empty())
146 product_name = target_->label().name();
147 else
148 product_name = name;
149
150 // TODO(brettw) GN knows not to prefix targets starting with "lib" with
151 // another "lib" on Linux, but GYP doesn't. We need to rename applicable
152 // targets here.
153
154 out_ << " 'product_name': '" << product_name << "',\n";
155 }
156
157 void GypBinaryTargetWriter::WriteType() {
158 out_ << " 'type': ";
159 switch (target_->output_type()) {
160 case Target::EXECUTABLE:
161 out_ << "'executable',\n";
162 break;
163 case Target::STATIC_LIBRARY:
164 out_ << "'static_library',\n";
165 break;
166 case Target::SHARED_LIBRARY:
167 out_ << "'shared_library',\n";
168 break;
169 case Target::SOURCE_SET:
170 out_ << "'static_library',\n"; // TODO(brettw) fixme.
171 break;
172 default:
173 NOTREACHED();
174 }
175
176 if (target_->hard_dep())
177 out_ << " 'hard_dependency': 1,\n";
178 }
179
180 void GypBinaryTargetWriter::WriteFlags(const Target* target) {
181 WriteDefines(target);
182 WriteIncludes(target);
183 if (target->settings()->IsWin())
184 WriteVCFlags(target);
185 }
186
187 void GypBinaryTargetWriter::WriteDefines(const Target* target) {
188 out_ << " 'defines': [";
189 RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::defines,
190 StringWriter(), out_);
191 out_ << " ],\n";
192 }
193
194 void GypBinaryTargetWriter::WriteIncludes(const Target* target) {
195 out_ << " 'include_dirs': [";
196 RecursiveTargetConfigToStream<SourceDir>(target, &ConfigValues::include_dirs,
197 IncludeWriter(helper_), out_);
198 out_ << " ],\n";
199 }
200
201 void GypBinaryTargetWriter::WriteVCFlags(const Target* target) {
202 // C flags.
203 out_ << " 'msvs_settings': {\n";
204 out_ << " 'VCCLCompilerTool': {\n";
205
206 std::vector<std::string> cflags;
207 StringAccumulator acc(&cflags);
208 RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::cflags,
209 acc, out_);
210 // GYP always uses the VC optimization flag to add a /O? on Visual Studio.
211 // This can produce duplicate values. So look up the GYP value corresponding
212 // to the flags used, and set the same one.
213 std::string optimization = GetVCOptimization(&cflags);
214 WriteArray(out_, "AdditionalOptions", cflags, 14);
215 // TODO(brettw) cflags_c and cflags_cc!
216 out_ << " 'Optimization': " << optimization << ",\n";
217 out_ << " },\n";
218
219 // Linker tool stuff.
220 out_ << " 'VCLinkerTool': {\n";
221
222 // ...Library dirs.
223 EscapeOptions escape_options;
224 escape_options.mode = ESCAPE_JSON;
225 const OrderedSet<SourceDir> all_lib_dirs = target->all_lib_dirs();
226 if (!all_lib_dirs.empty()) {
227 out_ << " 'AdditionalLibraryDirectories': [";
228 for (size_t i = 0; i < all_lib_dirs.size(); i++) {
229 out_ << " '";
230 EscapeStringToStream(out_,
231 helper_.GetDirReference(all_lib_dirs[i], false),
232 escape_options);
233 out_ << "',";
234 }
235 out_ << " ],\n";
236 }
237
238 // ...Libraries.
239 const OrderedSet<std::string> all_libs = target->all_libs();
240 if (!all_libs.empty()) {
241 out_ << " 'AdditionalDependencies': [";
242 for (size_t i = 0; i < all_libs.size(); i++) {
243 out_ << " '";
244 EscapeStringToStream(out_, all_libs[i], escape_options);
245 out_ << "',";
246 }
247 out_ << " ],\n";
248 }
249
250 // ...LD flags.
251 // TODO(brettw) EnableUAC defaults to on and needs to be set. Also
252 // UACExecutionLevel and UACUIAccess depends on that and defaults to 0/false.
253 std::vector<std::string> ldflags;
254 acc.result = &ldflags;
255 RecursiveTargetConfigToStream<std::string>(target, &ConfigValues::ldflags,
256 acc, out_);
257 WriteArray(out_, "AdditionalOptions", ldflags, 14);
258 out_ << " },\n";
259
260 out_ << " },\n";
261 }
262
263 void GypBinaryTargetWriter::WriteSources() {
264 out_ << " 'sources': [\n";
265
266 const Target::FileList& sources = target_->sources();
267 for (size_t i = 0; i < sources.size(); i++) {
268 const SourceFile& input_file = sources[i];
269 out_ << " '" << helper_.GetFileReference(input_file) << "',\n";
270 }
271
272 out_ << " ],\n";
273 }
274
275 void GypBinaryTargetWriter::WriteDeps() {
276 const std::vector<const Target*>& deps = target_->deps();
277 if (deps.empty())
278 return;
279
280 EscapeOptions escape_options;
281 escape_options.mode = ESCAPE_JSON;
282
283 out_ << " 'dependencies': [\n";
284 for (size_t i = 0; i < deps.size(); i++) {
285 out_ << " '";
286 EscapeStringToStream(out_, helper_.GetFullRefForTarget(deps[i]),
287 escape_options);
288 out_ << "',\n";
289 }
290 out_ << " ],\n";
291 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698