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