Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 return; | |
|
scottmg
2014/05/05 16:31:15
these |return|s rather than break are a bit odd
| |
| 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 return; | |
| 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 return; | |
| 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 function | |
|
scottmg
2014/05/05 16:31:15
functions
| |
| OLD | NEW |