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