| // Copyright 2014 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "tools/gn/err.h" | |
| #include "tools/gn/filesystem_utils.h" | |
| #include "tools/gn/functions.h" | |
| #include "tools/gn/label.h" | |
| #include "tools/gn/parse_tree.h" | |
| #include "tools/gn/value.h" | |
| namespace functions { | |
| const char kGetLabelInfo[] = "get_label_info"; | |
| const char kGetLabelInfo_HelpShort[] = | |
| "get_label_info: Get an attribute from a target's label."; | |
| const char kGetLabelInfo_Help[] = | |
| R"*(get_label_info: Get an attribute from a target's label. | |
| get_label_info(target_label, what) | |
| Given the label of a target, returns some attribute of that target. The | |
| target need not have been previously defined in the same file, since none of | |
| the attributes depend on the actual target definition, only the label itself. | |
| See also "gn help get_target_outputs". | |
| Possible values for the "what" parameter | |
| "name" | |
| The short name of the target. This will match the value of the | |
| "target_name" variable inside that target's declaration. For the label | |
| "//foo/bar:baz" this will return "baz". | |
| "dir" | |
| The directory containing the target's definition, with no slash at the | |
| end. For the label "//foo/bar:baz" this will return "//foo/bar". | |
| "target_gen_dir" | |
| The generated file directory for the target. This will match the value of | |
| the "target_gen_dir" variable when inside that target's declaration. | |
| "root_gen_dir" | |
| The root of the generated file tree for the target. This will match the | |
| value of the "root_gen_dir" variable when inside that target's | |
| declaration. | |
| "target_out_dir | |
| The output directory for the target. This will match the value of the | |
| "target_out_dir" variable when inside that target's declaration. | |
| "root_out_dir" | |
| The root of the output file tree for the target. This will match the | |
| value of the "root_out_dir" variable when inside that target's | |
| declaration. | |
| "label_no_toolchain" | |
| The fully qualified version of this label, not including the toolchain. | |
| For the input ":bar" it might return "//foo:bar". | |
| "label_with_toolchain" | |
| The fully qualified version of this label, including the toolchain. For | |
| the input ":bar" it might return "//foo:bar(//toolchain:x64)". | |
| "toolchain" | |
| The label of the toolchain. This will match the value of the | |
| "current_toolchain" variable when inside that target's declaration. | |
| Examples | |
| get_label_info(":foo", "name") | |
| # Returns string "foo". | |
| get_label_info("//foo/bar:baz", "target_gen_dir") | |
| # Returns string "//out/Debug/gen/foo/bar". | |
| )*"; | |
| Value RunGetLabelInfo(Scope* scope, | |
| const FunctionCallNode* function, | |
| const std::vector<Value>& args, | |
| Err* err) { | |
| if (args.size() != 2) { | |
| *err = Err(function, "Expected two arguments."); | |
| return Value(); | |
| } | |
| // Resolve the requested label. | |
| Label label = Label::Resolve(scope->GetSourceDir(), | |
| ToolchainLabelForScope(scope), args[0], err); | |
| if (label.is_null()) | |
| return Value(); | |
| // Extract the "what" parameter. | |
| if (!args[1].VerifyTypeIs(Value::STRING, err)) | |
| return Value(); | |
| const std::string& what = args[1].string_value(); | |
| Value result(function, Value::STRING); | |
| if (what == "name") { | |
| result.string_value() = label.name(); | |
| } else if (what == "dir") { | |
| result.string_value() = DirectoryWithNoLastSlash(label.dir()); | |
| } else if (what == "target_gen_dir") { | |
| result.string_value() = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir( | |
| BuildDirContext(scope, label.GetToolchainLabel()), | |
| label.dir(), | |
| BuildDirType::GEN)); | |
| } else if (what == "root_gen_dir") { | |
| result.string_value() = DirectoryWithNoLastSlash(GetBuildDirAsSourceDir( | |
| BuildDirContext(scope, label.GetToolchainLabel()), BuildDirType::GEN)); | |
| } else if (what == "target_out_dir") { | |
| result.string_value() = DirectoryWithNoLastSlash(GetSubBuildDirAsSourceDir( | |
| BuildDirContext(scope, label.GetToolchainLabel()), | |
| label.dir(), | |
| BuildDirType::OBJ)); | |
| } else if (what == "root_out_dir") { | |
| result.string_value() = DirectoryWithNoLastSlash(GetBuildDirAsSourceDir( | |
| BuildDirContext(scope, label.GetToolchainLabel()), | |
| BuildDirType::TOOLCHAIN_ROOT)); | |
| } else if (what == "toolchain") { | |
| result.string_value() = label.GetToolchainLabel().GetUserVisibleName(false); | |
| } else if (what == "label_no_toolchain") { | |
| result.string_value() = | |
| label.GetWithNoToolchain().GetUserVisibleName(false); | |
| } else if (what == "label_with_toolchain") { | |
| result.string_value() = label.GetUserVisibleName(true); | |
| } else { | |
| *err = Err(args[1], "Unknown value for \"what\" parameter."); | |
| return Value(); | |
| } | |
| return result; | |
| } | |
| } // namespace functions |