Scroll-bar browser test.
[chromium-blink-merge.git] / tools / gn / function_get_target_outputs.cc
blobe3a63eeca6b6b45dadc1366fa9d350988169d2cc
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.
5 #include "tools/gn/build_settings.h"
6 #include "tools/gn/functions.h"
7 #include "tools/gn/parse_tree.h"
8 #include "tools/gn/settings.h"
9 #include "tools/gn/substitution_writer.h"
10 #include "tools/gn/target.h"
11 #include "tools/gn/value.h"
13 namespace functions {
15 const char kGetTargetOutputs[] = "get_target_outputs";
16 const char kGetTargetOutputs_HelpShort[] =
17 "get_target_outputs: [file list] Get the list of outputs from a target.";
18 const char kGetTargetOutputs_Help[] =
19 "get_target_outputs: [file list] Get the list of outputs from a target.\n"
20 "\n"
21 " get_target_outputs(target_label)\n"
22 "\n"
23 " Returns a list of output files for the named target. The named target\n"
24 " must have been previously defined in the current file before this\n"
25 " function is called (it can't reference targets in other files because\n"
26 " there isn't a defined execution order, and it obviously can't\n"
27 " reference targets that are defined after the function call).\n"
28 "\n"
29 " Only copy and action targets are supported. The outputs from binary\n"
30 " targets will depend on the toolchain definition which won't\n"
31 " necessarily have been loaded by the time a given line of code has run,\n"
32 " and source sets and groups have no useful output file.\n"
33 "\n"
34 "Return value\n"
35 "\n"
36 " The names in the resulting list will be absolute file paths (normally\n"
37 " like \"//out/Debug/bar.exe\", depending on the build directory).\n"
38 "\n"
39 " action targets: this will just return the files specified in the\n"
40 " \"outputs\" variable of the target.\n"
41 "\n"
42 " action_foreach targets: this will return the result of applying\n"
43 " the output template to the sources (see \"gn help source_expansion\").\n"
44 " This will be the same result (though with guaranteed absolute file\n"
45 " paths), as process_file_template will return for those inputs\n"
46 " (see \"gn help process_file_template\").\n"
47 "\n"
48 " binary targets (executables, libraries): this will return a list\n"
49 " of the resulting binary file(s). The \"main output\" (the actual\n"
50 " binary or library) will always be the 0th element in the result.\n"
51 " Depending on the platform and output type, there may be other output\n"
52 " files as well (like import libraries) which will follow.\n"
53 "\n"
54 " source sets and groups: this will return a list containing the path of\n"
55 " the \"stamp\" file that Ninja will produce once all outputs are\n"
56 " generated. This probably isn't very useful.\n"
57 "\n"
58 "Example\n"
59 "\n"
60 " # Say this action generates a bunch of C source files.\n"
61 " action_foreach(\"my_action\") {\n"
62 " sources = [ ... ]\n"
63 " outputs = [ ... ]\n"
64 " }\n"
65 "\n"
66 " # Compile the resulting source files into a source set.\n"
67 " source_set(\"my_lib\") {\n"
68 " sources = get_target_outputs(\":my_action\")\n"
69 " }\n";
71 Value RunGetTargetOutputs(Scope* scope,
72 const FunctionCallNode* function,
73 const std::vector<Value>& args,
74 Err* err) {
75 if (args.size() != 1) {
76 *err = Err(function, "Expected one argument.");
77 return Value();
80 // Resolve the requested label.
81 Label label = Label::Resolve(scope->GetSourceDir(),
82 ToolchainLabelForScope(scope), args[0], err);
83 if (label.is_null())
84 return Value();
86 // Find the referenced target. The targets previously encountered in this
87 // scope will have been stashed in the item collector (they'll be dispatched
88 // when this file is done running) so we can look through them.
89 const Target* target = NULL;
90 Scope::ItemVector* collector = scope->GetItemCollector();
91 if (!collector) {
92 *err = Err(function, "No targets defined in this context.");
93 return Value();
95 for (size_t i = 0; i < collector->size(); i++) {
96 const Item* item = (*collector)[i]->get();
97 if (item->label() != label)
98 continue;
100 const Target* as_target = item->AsTarget();
101 if (!as_target) {
102 *err = Err(function, "Label does not refer to a target.",
103 label.GetUserVisibleName(false) +
104 "\nrefers to a " + item->GetItemTypeName());
105 return Value();
107 target = as_target;
108 break;
111 if (!target) {
112 *err = Err(function, "Target not found in this context.",
113 label.GetUserVisibleName(false) +
114 "\nwas not found. get_target_outputs() can only be used for targets\n"
115 "previously defined in the current file.");
116 return Value();
119 // Compute the output list.
120 std::vector<SourceFile> files;
121 if (target->output_type() == Target::ACTION ||
122 target->output_type() == Target::COPY_FILES ||
123 target->output_type() == Target::ACTION_FOREACH) {
124 target->action_values().GetOutputsAsSourceFiles(target, &files);
125 } else {
126 // Other types of targets are not supported.
127 *err = Err(args[0], "Target is not an action, action_foreach, or copy.",
128 "Only these target types are supported by get_target_outputs.");
129 return Value();
132 // Convert to Values.
133 Value ret(function, Value::LIST);
134 ret.list_value().reserve(files.size());
135 for (size_t i = 0; i < files.size(); i++)
136 ret.list_value().push_back(Value(function, files[i].value()));
138 return ret;
141 } // namespace functions