| // 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 |