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

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

Issue 269723006: Add get_target_outputs function to GN (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review comments Created 6 years, 7 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
« no previous file with comments | « tools/gn/file_template_unittest.cc ('k') | tools/gn/function_get_target_outputs_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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/build_settings.h"
6 #include "tools/gn/file_template.h"
7 #include "tools/gn/functions.h"
8 #include "tools/gn/ninja_helper.h"
9 #include "tools/gn/parse_tree.h"
10 #include "tools/gn/settings.h"
11 #include "tools/gn/target.h"
12 #include "tools/gn/value.h"
13
14 namespace functions {
15
16 namespace {
17
18 void GetOutputsForTarget(const BuildSettings* build_settings,
19 const Target* target,
20 std::vector<std::string>* ret) {
21 switch (target->output_type()) {
22 case Target::ACTION:
23 case Target::COPY_FILES: {
24 // Actions and copy targets: return the outputs specified.
25 const std::vector<SourceFile>& outs = target->action_values().outputs();
26 ret->reserve(outs.size());
27 for (size_t i = 0; i < outs.size(); i++)
28 ret->push_back(outs[i].value());
29 break;
30 }
31
32 case Target::ACTION_FOREACH: {
33 // Action_foreach: return the result of the template in the outputs.
34 FileTemplate file_template(target->action_values().outputs());
35 const std::vector<SourceFile>& sources = target->sources();
36 for (size_t i = 0; i < sources.size(); i++)
37 file_template.ApplyString(sources[i].value(), ret);
38 break;
39 }
40
41 case Target::EXECUTABLE:
42 case Target::SHARED_LIBRARY:
43 case Target::STATIC_LIBRARY:
44 // Return the resulting binary file. Currently, fall through to the
45 // Ninja helper below which will compute the main output name.
46 //
47 // TODO(brettw) some targets have secondary files which should go into
48 // the list after the main (like shared libraries on Windows have an
49 // import library).
50 case Target::GROUP:
51 case Target::SOURCE_SET: {
52 // These return the stamp file, which is computed by the NinjaHelper.
53 NinjaHelper helper(build_settings);
54 OutputFile output_file = helper.GetTargetOutputFile(target);
55
56 // The output file is relative to the build dir.
57 std::string absolute_output_file = build_settings->build_dir().value();
58 absolute_output_file.append(output_file.value());
59
60 ret->push_back(absolute_output_file);
61 break;
62 }
63
64 default:
65 NOTREACHED();
66 }
67 }
68
69 } // namespace
70
71 const char kGetTargetOutputs[] = "get_target_outputs";
72 const char kGetTargetOutputs_HelpShort[] =
73 "get_target_outputs: [file list] Get the list of outputs from a target.";
74 const char kGetTargetOutputs_Help[] =
75 "get_target_outputs: [file list] Get the list of outputs from a target.\n"
76 "\n"
77 " get_target_outputs(target_label)\n"
78 "\n"
79 " Returns a list of output files for the named target. The named target\n"
80 " must have been previously defined in the current file before this\n"
81 " function is called (it can't reference targets in other files because\n"
82 " there isn't a defined execution order, and it obviously can't\n"
83 " reference targets that are defined after the function call).\n"
84 "\n"
85 "Return value\n"
86 "\n"
87 " The names in the resulting list will be absolute file paths (normally\n"
88 " like \"//out/Debug/bar.exe\", depending on the build directory).\n"
89 "\n"
90 " action targets: this will just return the files specified in the\n"
91 " \"outputs\" variable of the target.\n"
92 "\n"
93 " action_foreach targets: this will return the result of applying\n"
94 " the output template to the sources (see \"gn help source_expansion\").\n"
95 " This will be the same result (though with guaranteed absolute file\n"
96 " paths), as process_file_template will return for those inputs\n"
97 " (see \"gn help process_file_template\").\n"
98 "\n"
99 " binary targets (executables, libraries): this will return a list\n"
100 " of the resulting binary file(s). The \"main output\" (the actual\n"
101 " binary or library) will always be the 0th element in the result.\n"
102 " Depending on the platform and output type, there may be other output\n"
103 " files as well (like import libraries) which will follow.\n"
104 "\n"
105 " source sets and groups: this will return a list containing the path of\n"
106 " the \"stamp\" file that Ninja will produce once all outputs are\n"
107 " generated. This probably isn't very useful.\n"
108 "\n"
109 "Example\n"
110 "\n"
111 " # Say this action generates a bunch of C source files.\n"
112 " action_foreach(\"my_action\") {\n"
113 " sources = [ ... ]\n"
114 " outputs = [ ... ]\n"
115 " }\n"
116 "\n"
117 " # Compile the resulting source files into a source set.\n"
118 " source_set(\"my_lib\") {\n"
119 " sources = get_target_outputs(\":my_action\")\n"
120 " }\n";
121
122 Value RunGetTargetOutputs(Scope* scope,
123 const FunctionCallNode* function,
124 const std::vector<Value>& args,
125 Err* err) {
126 if (args.size() != 1) {
127 *err = Err(function, "Expected one argument.");
128 return Value();
129 }
130
131 // Resolve the requested label.
132 Label label = Label::Resolve(scope->GetSourceDir(),
133 ToolchainLabelForScope(scope), args[0], err);
134 if (label.is_null())
135 return Value();
136
137 // Find the referenced target. The targets previously encountered in this
138 // scope will have been stashed in the item collector (they'll be dispatched
139 // when this file is done running) so we can look through them.
140 const Target* target = NULL;
141 Scope::ItemVector* collector = scope->GetItemCollector();
142 if (!collector) {
143 *err = Err(function, "No targets defined in this context.");
144 return Value();
145 }
146 for (size_t i = 0; i < collector->size(); i++) {
147 const Item* item = (*collector)[i]->get();
148 if (item->label() != label)
149 continue;
150
151 const Target* as_target = item->AsTarget();
152 if (!as_target) {
153 *err = Err(function, "Label does not refer to a target.",
154 label.GetUserVisibleName(false) +
155 "\nrefers to a " + item->GetItemTypeName());
156 return Value();
157 }
158 target = as_target;
159 break;
160 }
161
162 if (!target) {
163 *err = Err(function, "Target not found in this context.",
164 label.GetUserVisibleName(false) +
165 "\nwas not found. get_target_outputs() can only be used for targets\n"
166 "previously defined in the current file.");
167 return Value();
168 }
169
170 std::vector<std::string> files;
171 GetOutputsForTarget(scope->settings()->build_settings(), target, &files);
172
173 Value ret(function, Value::LIST);
174 ret.list_value().reserve(files.size());
175 for (size_t i = 0; i < files.size(); i++)
176 ret.list_value().push_back(Value(function, files[i]));
177
178 return ret;
179 }
180
181 } // namespace functions
OLDNEW
« no previous file with comments | « tools/gn/file_template_unittest.cc ('k') | tools/gn/function_get_target_outputs_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698