Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / tools / gn / function_get_target_outputs.cc
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