Update To 11.40.268.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/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"
12
13 namespace functions {
14
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";
70
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();
78   }
79
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();
85
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();
94   }
95   for (const auto& item : *collector) {
96     if (item->label() != label)
97       continue;
98
99     const Target* as_target = item->AsTarget();
100     if (!as_target) {
101       *err = Err(function, "Label does not refer to a target.",
102           label.GetUserVisibleName(false) +
103           "\nrefers to a " + item->GetItemTypeName());
104       return Value();
105     }
106     target = as_target;
107     break;
108   }
109
110   if (!target) {
111     *err = Err(function, "Target not found in this context.",
112         label.GetUserVisibleName(false) +
113         "\nwas not found. get_target_outputs() can only be used for targets\n"
114         "previously defined in the current file.");
115     return Value();
116   }
117
118   // Compute the output list.
119   std::vector<SourceFile> files;
120   if (target->output_type() == Target::ACTION ||
121       target->output_type() == Target::COPY_FILES ||
122       target->output_type() == Target::ACTION_FOREACH) {
123     target->action_values().GetOutputsAsSourceFiles(target, &files);
124   } else {
125     // Other types of targets are not supported.
126     *err = Err(args[0], "Target is not an action, action_foreach, or copy.",
127                "Only these target types are supported by get_target_outputs.");
128     return Value();
129   }
130
131   // Convert to Values.
132   Value ret(function, Value::LIST);
133   ret.list_value().reserve(files.size());
134   for (const auto& file : files)
135     ret.list_value().push_back(Value(function, file.value()));
136
137   return ret;
138 }
139
140 }  // namespace functions