Home | History | Annotate | Download | only in gn
      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/err.h"
      6 #include "tools/gn/filesystem_utils.h"
      7 #include "tools/gn/functions.h"
      8 #include "tools/gn/label.h"
      9 #include "tools/gn/parse_tree.h"
     10 #include "tools/gn/value.h"
     11 
     12 namespace functions {
     13 
     14 const char kGetLabelInfo[] = "get_label_info";
     15 const char kGetLabelInfo_HelpShort[] =
     16     "get_label_info: Get an attribute from a target's label.";
     17 const char kGetLabelInfo_Help[] =
     18     "get_label_info: Get an attribute from a target's label.\n"
     19     "\n"
     20     "  get_label_info(target_label, what)\n"
     21     "\n"
     22     "  Given the label of a target, returns some attribute of that target.\n"
     23     "  The target need not have been previously defined in the same file,\n"
     24     "  since none of the attributes depend on the actual target definition,\n"
     25     "  only the label itself.\n"
     26     "\n"
     27     "  See also \"gn help get_target_outputs\".\n"
     28     "\n"
     29     "Possible values for the \"what\" parameter\n"
     30     "\n"
     31     "  \"name\"\n"
     32     "      The short name of the target. This will match the value of the\n"
     33     "      \"target_name\" variable inside that target's declaration. For the\n"
     34     "      label \"//foo/bar:baz\" this will return \"baz\".\n"
     35     "\n"
     36     "  \"dir\"\n"
     37     "      The directory containing the target's definition, with no slash at\n"
     38     "      the end. For the label \"//foo/bar:baz\" this will return\n"
     39     "      \"//foo/bar\".\n"
     40     "\n"
     41     "  \"target_gen_dir\"\n"
     42     "      The generated file directory for the target. This will match the\n"
     43     "      value of the \"target_gen_dir\" variable when inside that target's\n"
     44     "      declaration.\n"
     45     "\n"
     46     "  \"root_gen_dir\"\n"
     47     "      The root of the generated file tree for the target. This will\n"
     48     "      match the value of the \"root_gen_dir\" variable when inside that\n"
     49     "      target's declaration.\n"
     50     "\n"
     51     "  \"target_out_dir\n"
     52     "      The output directory for the target. This will match the\n"
     53     "      value of the \"target_out_dir\" variable when inside that target's\n"
     54     "      declaration.\n"
     55     "\n"
     56     "  \"root_out_dir\"\n"
     57     "      The root of the output file tree for the target. This will\n"
     58     "      match the value of the \"root_gen_dir\" variable when inside that\n"
     59     "      target's declaration.\n"
     60     "\n"
     61     "  \"label_no_toolchain\"\n"
     62     "      The fully qualified version of this label, not including the\n"
     63     "      toolchain. For the input \":bar\" it might return\n"
     64     "      \"//foo:bar\".\n"
     65     "\n"
     66     "  \"label_with_toolchain\"\n"
     67     "      The fully qualified version of this label, including the\n"
     68     "      toolchain. For the input \":bar\" it might return\n"
     69     "      \"//foo:bar(//toolchain:x64)\".\n"
     70     "\n"
     71     "  \"toolchain\"\n"
     72     "      The label of the toolchain. This will match the value of the\n"
     73     "      \"current_toolchain\" variable when inside that target's\n"
     74     "      declaration.\n"
     75     "\n"
     76     "Examples\n"
     77     "\n"
     78     "  get_label_info(\":foo\", \"name\")\n"
     79     "  # Returns string \"foo\".\n"
     80     "\n"
     81     "  get_label_info(\"//foo/bar:baz\", \"gen_dir\")\n"
     82     "  # Returns string \"//out/Debug/gen/foo/bar\".\n";
     83 
     84 Value RunGetLabelInfo(Scope* scope,
     85                       const FunctionCallNode* function,
     86                       const std::vector<Value>& args,
     87                       Err* err) {
     88   if (args.size() != 2) {
     89     *err = Err(function, "Expected two arguments.");
     90     return Value();
     91   }
     92 
     93   // Resolve the requested label.
     94   Label label = Label::Resolve(scope->GetSourceDir(),
     95                                ToolchainLabelForScope(scope), args[0], err);
     96   if (label.is_null())
     97     return Value();
     98 
     99   // Extract the "what" parameter.
    100   if (!args[1].VerifyTypeIs(Value::STRING, err))
    101     return Value();
    102   const std::string& what = args[1].string_value();
    103 
    104   Value result(function, Value::STRING);
    105   if (what == "name") {
    106     result.string_value() = label.name();
    107 
    108   } else if (what == "dir") {
    109     result.string_value() = DirectoryWithNoLastSlash(label.dir());
    110 
    111   } else if (what == "target_gen_dir") {
    112     result.string_value() = DirectoryWithNoLastSlash(
    113         GetGenDirForSourceDir(scope->settings(), label.dir()));
    114 
    115   } else if (what == "root_gen_dir") {
    116     Label toolchain_label = label.GetToolchainLabel();
    117     bool is_default =
    118         scope->settings()->default_toolchain_label() == toolchain_label;
    119     result.string_value() = DirectoryWithNoLastSlash(
    120         GetToolchainGenDir(scope->settings()->build_settings(),
    121                            toolchain_label, is_default));
    122 
    123   } else if (what == "target_out_dir") {
    124     result.string_value() = DirectoryWithNoLastSlash(
    125         GetOutputDirForSourceDir(scope->settings(), label.dir()));
    126 
    127   } else if (what == "root_out_dir") {
    128     Label toolchain_label = label.GetToolchainLabel();
    129     bool is_default =
    130         scope->settings()->default_toolchain_label() == toolchain_label;
    131     result.string_value() = DirectoryWithNoLastSlash(
    132         GetToolchainOutputDir(scope->settings()->build_settings(),
    133                               toolchain_label, is_default));
    134 
    135   } else if (what == "toolchain") {
    136     result.string_value() = label.GetToolchainLabel().GetUserVisibleName(false);
    137 
    138   } else if (what == "label_no_toolchain") {
    139     result.string_value() =
    140         label.GetWithNoToolchain().GetUserVisibleName(false);
    141 
    142   } else if (what == "label_with_toolchain") {
    143     result.string_value() = label.GetUserVisibleName(true);
    144 
    145   } else {
    146     *err = Err(args[1], "Unknown value for \"what\" parameter.");
    147     return Value();
    148   }
    149 
    150   return result;
    151 }
    152 
    153 }  // namespace functions
    154