• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RunGetLabelInfo(Scope * scope,const FunctionCallNode * function,const std::vector<Value> & args,Err * err)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