// 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 { namespace { bool ToolchainIsDefault(const Scope* scope, const Label& toolchain_label) { return scope->settings()->default_toolchain_label() == toolchain_label; } } // namespace 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[] = "get_label_info: Get an attribute from a target's label.\n" "\n" " get_label_info(target_label, what)\n" "\n" " Given the label of a target, returns some attribute of that target.\n" " The target need not have been previously defined in the same file,\n" " since none of the attributes depend on the actual target definition,\n" " only the label itself.\n" "\n" " See also \"gn help get_target_outputs\".\n" "\n" "Possible values for the \"what\" parameter\n" "\n" " \"name\"\n" " The short name of the target. This will match the value of the\n" " \"target_name\" variable inside that target's declaration. For the\n" " label \"//foo/bar:baz\" this will return \"baz\".\n" "\n" " \"dir\"\n" " The directory containing the target's definition, with no slash at\n" " the end. For the label \"//foo/bar:baz\" this will return\n" " \"//foo/bar\".\n" "\n" " \"target_gen_dir\"\n" " The generated file directory for the target. This will match the\n" " value of the \"target_gen_dir\" variable when inside that target's\n" " declaration.\n" "\n" " \"root_gen_dir\"\n" " The root of the generated file tree for the target. This will\n" " match the value of the \"root_gen_dir\" variable when inside that\n" " target's declaration.\n" "\n" " \"target_out_dir\n" " The output directory for the target. This will match the\n" " value of the \"target_out_dir\" variable when inside that target's\n" " declaration.\n" "\n" " \"root_out_dir\"\n" " The root of the output file tree for the target. This will\n" " match the value of the \"root_out_dir\" variable when inside that\n" " target's declaration.\n" "\n" " \"label_no_toolchain\"\n" " The fully qualified version of this label, not including the\n" " toolchain. For the input \":bar\" it might return\n" " \"//foo:bar\".\n" "\n" " \"label_with_toolchain\"\n" " The fully qualified version of this label, including the\n" " toolchain. For the input \":bar\" it might return\n" " \"//foo:bar(//toolchain:x64)\".\n" "\n" " \"toolchain\"\n" " The label of the toolchain. This will match the value of the\n" " \"current_toolchain\" variable when inside that target's\n" " declaration.\n" "\n" "Examples\n" "\n" " get_label_info(\":foo\", \"name\")\n" " # Returns string \"foo\".\n" "\n" " get_label_info(\"//foo/bar:baz\", \"gen_dir\")\n" " # Returns string \"//out/Debug/gen/foo/bar\".\n"; Value RunGetLabelInfo(Scope* scope, const FunctionCallNode* function, const std::vector& 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( GetGenDirForSourceDir(scope->settings(), label.dir())); } else if (what == "root_gen_dir") { Label toolchain_label = label.GetToolchainLabel(); result.string_value() = DirectoryWithNoLastSlash( GetToolchainGenDir(scope->settings()->build_settings(), toolchain_label, ToolchainIsDefault(scope, toolchain_label))); } else if (what == "target_out_dir") { Label toolchain_label = label.GetToolchainLabel(); result.string_value() = DirectoryWithNoLastSlash( GetOutputDirForSourceDir(scope->settings()->build_settings(), label.dir(), toolchain_label, ToolchainIsDefault(scope, toolchain_label))); } else if (what == "root_out_dir") { Label toolchain_label = label.GetToolchainLabel(); result.string_value() = DirectoryWithNoLastSlash( GetToolchainOutputDir(scope->settings()->build_settings(), toolchain_label, ToolchainIsDefault(scope, toolchain_label))); } 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