• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2024 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 #include "gn/ohos_components.h"
5 
6 #include <cstring>
7 #include <iostream>
8 #include <map>
9 
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/json/json_reader.h"
13 #include "base/values.h"
14 
15 #include "gn/err.h"
16 #include "gn/filesystem_utils.h"
17 #include "gn/innerapis_publicinfo_generator.h"
18 #include "gn/ohos_components_checker.h"
19 #include "gn/ohos_components_impl.h"
20 #include "gn/ohos_components_mapping.h"
21 
22 /**
23  * Ohos Component API
24  *
25  * Each component belongs to one subsystem.
26  * Each component has a source path.
27  * Each component has zero or more innerapis
28  */
29 
30 static const std::string EMPTY_INNERAPI;
31 
32 static const int PATH_PREFIX_LEN = 2;
33 
34 OhosComponent::OhosComponent() = default;
35 
GetPath(const char * path)36 static std::string GetPath(const char *path)
37 {
38     std::string process_path;
39     if (strncmp(path, "//", PATH_PREFIX_LEN) == 0) {
40         process_path = std::string(path);
41     } else {
42         process_path = "//" + std::string(path);
43     }
44     return process_path;
45 }
46 
OhosComponent(const char * name,const char * subsystem,const char * path,const std::vector<std::string> & modulePath,bool special_parts_switch)47 OhosComponent::OhosComponent(const char *name, const char *subsystem, const char *path,
48     const std::vector<std::string> &modulePath, bool special_parts_switch)
49 {
50     name_ = std::string(name);
51     subsystem_ = std::string(subsystem);
52     path_ = GetPath(path);
53     special_parts_switch_ = special_parts_switch;
54 
55     auto result = std::find(modulePath.begin(), modulePath.end(), std::string(path));
56     if (result == modulePath.end()) {
57         module_path_.push_back(path_);
58     } else {
59         for (const auto &module_path : modulePath) {
60             module_path_.push_back(GetPath(module_path.c_str()));
61         }
62     }
63 }
64 
addInnerApi(const std::string & name,const std::string & label)65 void OhosComponent::addInnerApi(const std::string &name, const std::string &label)
66 {
67     std::string la = label;
68     size_t pos = label.find(":");
69     if (pos != std::string::npos) {
70         if ((label[pos - 1]) == '/') { // some are like this : "//components/foo/libfoo/:libfoo"
71             unsigned long indexToRemove = pos - 1;
72             if (indexToRemove >= 0 && indexToRemove <= la.length()) {
73                 la.erase(la.begin() + indexToRemove);
74             }
75         }
76     }
77     innerapi_names_[name] = la;
78     innerapi_labels_[la] = name;
79 }
80 
81 
getInnerApi(const std::string & innerapi) const82 const std::string &OhosComponent::getInnerApi(const std::string &innerapi) const
83 {
84     if (auto res = innerapi_names_.find(innerapi); res != innerapi_names_.end()) {
85         return res->second;
86     }
87     return EMPTY_INNERAPI;
88 }
89 
isInnerApi(const std::string & label) const90 bool OhosComponent::isInnerApi(const std::string &label) const
91 {
92     if (auto res = innerapi_labels_.find(label); res != innerapi_labels_.end()) {
93         return true;
94     }
95     return false;
96 }
97 
addInnerApiVisibility(const std::string & name,const std::vector<base::Value> & list)98 void OhosComponent::addInnerApiVisibility(const std::string &name, const std::vector<base::Value> &list)
99 {
100     for (const base::Value &visibility : list) {
101         innerapi_visibility_[innerapi_names_[name]].push_back(visibility.GetString());
102     }
103 }
104 
getInnerApiVisibility(const std::string & label) const105 const std::vector<std::string> OhosComponent::getInnerApiVisibility(const std::string &label) const
106 {
107     if (auto res = innerapi_visibility_.find(label); res != innerapi_visibility_.end()) {
108         return res->second;
109     }
110     return {};
111 }
112 
113 /**
114  * Ohos Component Implimentation API
115  */
116 OhosComponentsImpl::OhosComponentsImpl() = default;
117 
ReadBuildConfigFile(const std::string & build_dir,const char * subfile,std::string & content)118 bool OhosComponentsImpl::ReadBuildConfigFile(const std::string &build_dir, const char *subfile, std::string &content)
119 {
120     std::string path = build_dir;
121     path += "/build_configs/";
122     path += subfile;
123     return base::ReadFileToString(base::FilePath(path), &content);
124 }
125 
GetComponentPath(std::string & content)126 static bool GetComponentPath(std::string &content)
127 {
128     std::string whiteListPath = "out/products_ext/component_path_whitelist.json";
129     return base::ReadFileToString(base::FilePath(whiteListPath), &content);
130 }
131 
GetModulePath(const std::string & path,base::ListValue * list)132 static std::vector<std::string> GetModulePath(const std::string &path, base::ListValue *list)
133 {
134     std::vector<std::string> module_path;
135     for (const base::Value &value : list->GetList()) {
136         const base::Value *component_path = value.FindKey("component_path");
137         if (!component_path) {
138             continue;
139         }
140         if (component_path->GetString() == path) {
141             for (const base::Value &item : value.FindKey("module_path")->GetList()) {
142                 module_path.push_back(item.GetString());
143             }
144             return module_path;
145         }
146     }
147     return module_path;
148 }
149 
LoadComponentInfo(const std::string & components_content,bool special_parts_switch,std::string & err_msg_out)150 bool OhosComponentsImpl::LoadComponentInfo(const std::string &components_content, bool special_parts_switch,
151     std::string &err_msg_out)
152 {
153     const base::DictionaryValue *components_dict;
154     std::unique_ptr<base::Value> components_value = base::JSONReader::ReadAndReturnError(components_content,
155         base::JSONParserOptions::JSON_PARSE_RFC, nullptr, &err_msg_out, nullptr, nullptr);
156     if (!components_value) {
157         return false;
158     }
159     if (!components_value->GetAsDictionary(&components_dict)) {
160         return false;
161     }
162 
163     std::string components_path_content;
164     base::ListValue *components_path_list;
165     bool is_read_path = false;
166     std::unique_ptr<base::Value> components_path_value;
167     if (special_parts_switch && GetComponentPath(components_path_content)) {
168         components_path_value = base::JSONReader::ReadAndReturnError(components_path_content,
169             base::JSONParserOptions::JSON_PARSE_RFC, nullptr, &err_msg_out, nullptr, nullptr);
170         if (components_path_value) {
171             is_read_path = components_path_value->GetAsList(&components_path_list);
172         }
173     }
174 
175     for (const auto com : components_dict->DictItems()) {
176         const base::Value *subsystem = com.second.FindKey("subsystem");
177         const base::Value *path = com.second.FindKey("path");
178         if (!subsystem || !path) {
179             continue;
180         }
181 
182         std::vector<std::string> module_path;
183         if (special_parts_switch && is_read_path) {
184             module_path = GetModulePath(path-> GetString(), components_path_list);
185         }
186 
187         components_[com.first] =
188             new OhosComponent(com.first.c_str(), subsystem->GetString().c_str(), path->GetString().c_str(),
189             module_path, special_parts_switch);
190         const base::Value *innerapis = com.second.FindKey("innerapis");
191         if (!innerapis) {
192             continue;
193         }
194         LoadInnerApi(com.first, innerapis->GetList());
195     }
196     setupComponentsTree();
197     return true;
198 }
199 
findChildByPath(const struct OhosComponentTree * current,const char * path,size_t len)200 const struct OhosComponentTree *OhosComponentsImpl::findChildByPath(const struct OhosComponentTree *current,
201     const char *path, size_t len)
202 {
203     if (current->child == nullptr) {
204         return nullptr;
205     }
206     const struct OhosComponentTree *item = current->child;
207     while (item != nullptr) {
208         if (strncmp(item->dirName, path, len) == 0) {
209             // Exactly matching
210             if (item->dirName[len] == '\0') {
211                 return item;
212             }
213         }
214         item = item->next;
215     }
216 
217     return nullptr;
218 }
219 
matchComponentByLabel(const char * label)220 const OhosComponent *OhosComponentsImpl::matchComponentByLabel(const char *label)
221 {
222     const struct OhosComponentTree *child;
223     const struct OhosComponentTree *previous = pathTree;
224     const struct OhosComponentTree *current = pathTree;
225 
226     if (!label) {
227         return nullptr;
228     }
229     // Skip leading //
230     if (strncmp(label, "//", PATH_PREFIX_LEN) == 0) {
231         label += PATH_PREFIX_LEN;
232     }
233 
234     size_t len;
235     const char *sep;
236     while (label[0] != '\0') {
237         // Get next path seperator
238         sep = strchr(label, '/');
239         if (sep) {
240             len = sep - label;
241         } else {
242             // Check if it is a label with target name
243             sep = strchr(label, ':');
244             if (sep) {
245                 len = sep - label;
246             } else {
247                 len = strlen(label);
248             }
249         }
250 
251         // Match with children
252         child = findChildByPath(current, label, len);
253         if (child == nullptr) {
254             if (current->child != nullptr && previous->component != nullptr &&
255                 previous->component->specialPartsSwitch()) {
256                     return previous->component;
257                 } else {
258                     break;
259                 }
260         }
261 
262         // No children, return current matched item
263         if (child->child == nullptr) {
264             return child->component;
265         }
266 
267         label += len;
268         // Finish matching if target name started
269         if (label[0] == ':') {
270             return child->component;
271         }
272 
273         // Save previous part target
274         if (child->component != nullptr) {
275             previous = child;
276         }
277 
278         // Match with child again
279         current = child;
280 
281         // Skip leading seperator
282         if (label[0] == '/') {
283             label += 1;
284         }
285     }
286 
287     return nullptr;
288 }
289 
addComponentToTree(struct OhosComponentTree * current,OhosComponent * component)290 void OhosComponentsImpl::addComponentToTree(struct OhosComponentTree *current, OhosComponent *component)
291 {
292     std::vector<std::string> module_path = component->modulePath();
293     struct OhosComponentTree *origin = current;
294     for (const auto &part_path : module_path) {
295         size_t len;
296         const char *path = part_path.c_str() + PATH_PREFIX_LEN;
297         const char *sep;
298         current = origin;
299 
300         while (path[0] != '\0') {
301             sep = strchr(path, '/');
302             if (sep) {
303                 len = sep - path;
304             } else {
305                 len = strlen(path);
306             }
307 
308             // Check if node already exists
309             struct OhosComponentTree *child = (struct OhosComponentTree *)findChildByPath(current, path, len);
310             if (!child) {
311                 // Add intermediate node
312                 child = new struct OhosComponentTree(path, len, nullptr);
313                 child->next = current->child;
314                 current->child = child;
315             }
316 
317             // End of path detected, setup component pointer
318             path = path + len;
319             if (path[0] == '\0') {
320                 child->component = component;
321                 break;
322             }
323 
324             // Continue to add next part
325             path += 1;
326             current = child;
327         }
328     }
329 }
330 
setupComponentsTree()331 void OhosComponentsImpl::setupComponentsTree()
332 {
333     pathTree = new struct OhosComponentTree("//", nullptr);
334 
335     std::map<std::string, OhosComponent *>::iterator it;
336     for (it = components_.begin(); it != components_.end(); it++) {
337         addComponentToTree(pathTree, it->second);
338     }
339 }
340 
LoadInnerApi(const std::string & component_name,const std::vector<base::Value> & innerapis)341 void OhosComponentsImpl::LoadInnerApi(const std::string &component_name, const std::vector<base::Value> &innerapis)
342 {
343     OhosComponent *component = (OhosComponent *)GetComponentByName(component_name);
344     if (!component) {
345         return;
346     }
347     for (const base::Value &kv : innerapis) {
348         const base::Value *label = kv.FindKey("label");
349         const base::Value *name = kv.FindKey("name");
350 
351         if (!label || !name) {
352             continue;
353         }
354         component->addInnerApi(name->GetString(), label->GetString());
355         const base::Value *visibility = kv.FindKey("visibility");
356         if (!visibility) {
357             continue;
358         }
359         component->addInnerApiVisibility(name->GetString(), visibility->GetList());
360     }
361 }
362 
LoadOverrideMap(const std::string & override_map)363 void OhosComponentsImpl::LoadOverrideMap(const std::string &override_map)
364 {
365     const base::DictionaryValue *override_dict;
366     std::unique_ptr<base::Value> override_value = base::JSONReader::ReadAndReturnError(override_map,
367         base::JSONParserOptions::JSON_PARSE_RFC, nullptr, nullptr, nullptr, nullptr);
368     if (!override_value) {
369         return;
370     }
371     if (!override_value->GetAsDictionary(&override_dict)) {
372         return;
373     }
374 
375     for (const auto com : override_dict->DictItems()) {
376         override_map_[com.first] = com.second.GetString();
377     }
378     return;
379 }
380 
LoadToolchain(const Value * product)381 void OhosComponentsImpl::LoadToolchain(const Value *product)
382 {
383     if (!product) {
384         return;
385     }
386     std::string path = "out/preloader/" + product->string_value() + "/build_config.json";
387     std::string content;
388     if (!base::ReadFileToString(base::FilePath(path), &content)) {
389         return;
390     }
391 
392     const base::DictionaryValue *content_dict;
393     std::unique_ptr<base::Value> content_value = base::JSONReader::ReadAndReturnError(content,
394         base::JSONParserOptions::JSON_PARSE_RFC, nullptr, nullptr, nullptr, nullptr);
395     if (!content_value) {
396         return;
397     }
398     if (!content_value->GetAsDictionary(&content_dict)) {
399         return;
400     }
401 
402     for (const auto com : content_dict->DictItems()) {
403         if (com.first == "product_toolchain_label") {
404             toolchain_ = com.second.GetString();
405             break;
406         }
407     }
408     return;
409 }
410 
LoadOhosComponents(const std::string & build_dir,const Value * enable,const Value * indep,const Value * product,bool special_parts_switch,Err * err)411 bool OhosComponentsImpl::LoadOhosComponents(const std::string &build_dir, const Value *enable,
412     const Value *indep, const Value *product, bool special_parts_switch, Err *err)
413 {
414     const char *components_file = "parts_info/components.json";
415     std::string components_content;
416     if (!ReadBuildConfigFile(build_dir, components_file, components_content)) {
417         *err = Err(*enable, "Your .gn file has enabled \"ohos_components_support\", but "
418             "OpenHarmony build config file (" +
419             std::string(components_file) + ") does not exists.\n");
420         return false;
421     }
422 
423     std::string override_map;
424     if (ReadBuildConfigFile(build_dir, "component_override_map.json", override_map)) {
425         LoadOverrideMap(override_map);
426     }
427 
428     std::string err_msg_out;
429     if (!LoadComponentInfo(components_content, special_parts_switch, err_msg_out)) {
430         *err = Err(*enable, "Your .gn file has enabled \"ohos_components_support\", but "
431             "OpenHarmony build config file parsing failed:\n" +
432             err_msg_out + "\n");
433         return false;
434     }
435     if (indep && indep->boolean_value()) {
436         is_indep_compiler_enable_ = true;
437     }
438     LoadToolchain(product);
439     return true;
440 }
441 
GetComponentByName(const std::string & component_name) const442 const OhosComponent *OhosComponentsImpl::GetComponentByName(const std::string &component_name) const
443 {
444     if (auto res = components_.find(component_name); res != components_.end()) {
445         return res->second;
446     }
447     return nullptr;
448 }
449 
GetWholeArchiveFlag(std::string str_val,int & whole_status)450 static size_t GetWholeArchiveFlag(std::string str_val, int &whole_status)
451 {
452     size_t sep_whole = str_val.find("(--whole-archive)");
453     if (sep_whole != std::string::npos) {
454         whole_status = 1;
455     } else {
456         sep_whole = str_val.find("(--no-whole-archive)");
457         if (sep_whole != std::string::npos) {
458             whole_status = 0;
459         } else {
460             whole_status = -1;
461         }
462     }
463     return sep_whole;
464 }
465 
GetPrivateDepsLabel(const Value & dep,std::string & label,const Label & current_toolchain,int & whole_status,Err * err) const466 bool OhosComponentsImpl::GetPrivateDepsLabel(const Value &dep, std::string &label,
467     const Label& current_toolchain, int &whole_status, Err *err) const
468 {
469     std::string str_val = dep.string_value();
470     size_t sep_whole = GetWholeArchiveFlag(str_val, whole_status);
471 
472     if (sep_whole != std::string::npos) {
473         label = str_val.substr(0, sep_whole);
474     } else {
475         label = str_val;
476     }
477     std::string current_toolchain_str = current_toolchain.GetUserVisibleName(false);
478     size_t tool_sep = label.find("(");
479     if (tool_sep == std::string::npos && GetTargetToolchain() != current_toolchain_str) {
480         label += "(" + current_toolchain_str + ")";
481     }
482     if (label == EMPTY_INNERAPI) {
483         *err = Err(dep,
484             "Deps label: (" + dep.string_value() + ") format error.");
485         return false;
486     }
487     return true;
488 }
489 
GetExternalDepsLabel(const Value & external_dep,std::string & label,const Label & current_toolchain,int & whole_status,Err * err) const490 bool OhosComponentsImpl::GetExternalDepsLabel(const Value &external_dep, std::string &label,
491     const Label& current_toolchain, int &whole_status, Err *err) const
492 {
493     std::string str_val = external_dep.string_value();
494     size_t sep = str_val.find(":");
495     if (sep == std::string::npos) {
496         *err = Err(external_dep, "OHOS component external_deps format error: (" + external_dep.string_value() +
497             "),"
498             "it should be a string like \"component_name:innerapi_name\".");
499         return false;
500     }
501     std::string component_name = str_val.substr(0, sep);
502     for (const auto& pair : override_map_) {
503         if (pair.first == component_name) {
504             component_name = pair.second;
505             break;
506         }
507     }
508     const OhosComponent *component = GetComponentByName(component_name);
509     if (component == nullptr) {
510         *err = Err(external_dep, "OHOS component : (" + component_name + ") not found.");
511         return false;
512     }
513 
514     std::string innerapi_name;
515     std::string tool_chain = "";
516     size_t sep_whole = GetWholeArchiveFlag(str_val, whole_status);
517     if (sep_whole != std::string::npos) {
518         innerapi_name = str_val.substr(sep + 1, sep_whole - sep - 1);
519     } else {
520         innerapi_name = str_val.substr(sep + 1);
521         size_t tool_sep = innerapi_name.find("(");
522         if (tool_sep != std::string::npos) {
523             tool_chain = innerapi_name.substr(tool_sep);
524             innerapi_name = innerapi_name.substr(0, tool_sep);
525         }
526     }
527 
528     std::string current_toolchain_str = current_toolchain.GetUserVisibleName(false);
529     if (tool_chain == "" && GetTargetToolchain() != current_toolchain_str) {
530         tool_chain = "(" + current_toolchain_str + ")";
531     }
532     if (isOhosIndepCompilerEnable()) {
533         label = component->getInnerApi(innerapi_name + tool_chain);
534         if (label == EMPTY_INNERAPI) {
535             label = component->getInnerApi(innerapi_name) + tool_chain;
536         }
537     } else {
538         label = component->getInnerApi(innerapi_name) + tool_chain;
539     }
540 
541     if (label == EMPTY_INNERAPI) {
542         *err = Err(external_dep,
543             "OHOS innerapi: (" + innerapi_name + ") not found for component (" + component_name + ").");
544         return false;
545     }
546     return true;
547 }
548 
GetSubsystemName(const Value & component_name,std::string & subsystem_name,Err * err) const549 bool OhosComponentsImpl::GetSubsystemName(const Value &component_name, std::string &subsystem_name, Err *err) const
550 {
551     const OhosComponent *component = GetComponentByName(component_name.string_value());
552     if (component == nullptr) {
553         *err = Err(component_name, "OHOS component : (" + component_name.string_value() + ") not found.");
554         return false;
555     }
556 
557     subsystem_name = component->subsystem();
558     return true;
559 }
560 
561 /**
562  * Ohos Components Public API
563  */
564 
565 OhosComponents::OhosComponents() = default;
566 
LoadOhosComponents(const std::string & build_dir,const Value * enable,const Value * indep,const Value * product,bool special_parts_switch,Err * err)567 bool OhosComponents::LoadOhosComponents(const std::string &build_dir,
568     const Value *enable, const Value *indep, const Value *product, bool special_parts_switch, Err *err)
569 {
570     if (!enable) {
571         // Not enabled
572         return true;
573     }
574     if (!enable->VerifyTypeIs(Value::BOOLEAN, err)) {
575         return false;
576     }
577 
578     // Disabled
579     if (!enable->boolean_value()) {
580         return true;
581     }
582 
583     mgr = new OhosComponentsImpl();
584 
585     if (!mgr->LoadOhosComponents(build_dir, enable, indep, product, special_parts_switch, err)) {
586         delete mgr;
587         mgr = nullptr;
588         return false;
589     }
590 
591     return true;
592 }
593 
isOhosComponentsLoaded() const594 bool OhosComponents::isOhosComponentsLoaded() const
595 {
596     if (mgr == nullptr) {
597         return false;
598     } else {
599         return true;
600     }
601 }
602 
GetExternalDepsLabel(const Value & external_dep,std::string & label,const Label & current_toolchain,int & whole_status,Err * err) const603 bool OhosComponents::GetExternalDepsLabel(const Value &external_dep, std::string &label,
604     const Label& current_toolchain, int &whole_status, Err *err) const
605 {
606     if (!mgr) {
607         if (err) {
608             *err = Err(external_dep, "You are compiling OpenHarmony components, but \n"
609                 "\"ohos_components_support\" is not enabled or build_configs files are invalid.");
610         }
611         return false;
612     }
613     return mgr->GetExternalDepsLabel(external_dep, label, current_toolchain, whole_status, err);
614 }
615 
GetPrivateDepsLabel(const Value & dep,std::string & label,const Label & current_toolchain,int & whole_status,Err * err) const616 bool OhosComponents::GetPrivateDepsLabel(const Value &dep, std::string &label,
617     const Label& current_toolchain, int &whole_status, Err *err) const
618 {
619     if (!mgr) {
620         if (err) {
621             *err = Err(dep, "You are compiling OpenHarmony components, but \n"
622                 "\"ohos_components_support\" is not enabled or build_configs files are invalid.");
623         }
624         return false;
625     }
626     return mgr->GetPrivateDepsLabel(dep, label, current_toolchain, whole_status, err);
627 }
628 
GetSubsystemName(const Value & part_name,std::string & label,Err * err) const629 bool OhosComponents::GetSubsystemName(const Value &part_name, std::string &label, Err *err) const
630 {
631     if (!mgr) {
632         if (err) {
633             *err = Err(part_name, "You are compiling OpenHarmony components, but \n"
634                 "\"ohos_components_support\" is not enabled or build_configs files are invalid.");
635         }
636         return false;
637     }
638     return mgr->GetSubsystemName(part_name, label, err);
639 }
640 
GetComponentByLabel(const std::string & label) const641 const OhosComponent *OhosComponents::GetComponentByLabel(const std::string &label) const
642 {
643     if (!mgr) {
644         return nullptr;
645     }
646     return mgr->matchComponentByLabel(label.c_str());
647 }
648 
LoadOhosComponentsChecker(const std::string & build_dir,const Value * support,int checkType,unsigned int ruleSwitch)649 void OhosComponents::LoadOhosComponentsChecker(const std::string &build_dir, const Value *support, int checkType,
650     unsigned int ruleSwitch)
651 {
652     if (!support) {
653         return;
654     }
655     if (!support->boolean_value()) {
656         return;
657     }
658     if (checkType > OhosComponentChecker::CheckType::INTERCEPT_ALL ||
659         checkType <= OhosComponentChecker::CheckType::NONE) {
660         InnerApiPublicInfoGenerator::Init(build_dir, 0);
661         return;
662     }
663     OhosComponentChecker::Init(build_dir, checkType, ruleSwitch);
664     InnerApiPublicInfoGenerator::Init(build_dir, checkType);
665     return;
666 }
667 
LoadOhosComponentsMapping(const std::string & build_dir,const Value * support,const Value * independent)668 void OhosComponents::LoadOhosComponentsMapping(const std::string& build_dir,
669     const Value *support, const Value *independent)
670 {
671     if (!support) {
672         return;
673     }
674     if (!support->boolean_value()) {
675         return;
676     }
677 
678     if (!independent || !independent->boolean_value()) {
679         return;
680     }
681 
682     OhosComponentMapping::Init(build_dir);
683     return;
684 }
685 
GetComponentByName(const std::string & component_name)686 const OhosComponent *OhosComponents::GetComponentByName(const std::string &component_name) {
687     if (!mgr) {
688         return nullptr;
689     }
690     return mgr->GetComponentByName(component_name);
691 }
692 
isOhosIndepCompilerEnable()693 bool OhosComponents::isOhosIndepCompilerEnable() {
694     return mgr && mgr->isOhosIndepCompilerEnable();
695 }
696