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
5 #include "gn/ohos_components_mapping.h"
6
7 #include <fstream>
8 #include <functional>
9 #include <iostream>
10 #include <sys/stat.h>
11
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/json/json_reader.h"
15 #include "base/values.h"
16 #include "gn/build_settings.h"
17 #include "gn/config.h"
18 #include "gn/filesystem_utils.h"
19 #include "gn/functions.h"
20 #include "gn/ohos_components.h"
21 #include "gn/parse_tree.h"
22 #include "gn/settings.h"
23 #include "gn/substitution_writer.h"
24 #include "gn/target.h"
25 #include "gn/value.h"
26
27 static const std::string MAPPING_FILE_PATH = "component_mapping.json";
28
29 OhosComponentMapping *OhosComponentMapping::instance_ = nullptr;
30
31 static std::map<std::string, std::string> gni_mapping_file_map_;
32
StartWith(const std::string & str,const std::string prefix)33 static bool StartWith(const std::string &str, const std::string prefix)
34 {
35 return (str.rfind(prefix, 0) == 0);
36 }
37
ReadBuildConfigFile(base::FilePath path,std::string & content)38 static bool ReadBuildConfigFile(base::FilePath path, std::string &content)
39 {
40 if (!base::ReadFileToString(path, &content)) {
41 return false;
42 }
43 return true;
44 }
45
LoadGniMappingFileMap(const base::Value & value)46 static void LoadGniMappingFileMap(const base::Value &value)
47 {
48 for (auto info : value.DictItems()) {
49 gni_mapping_file_map_[info.first] = info.second.GetString();
50 }
51 }
52
53 static std::map<std::string, std::function<void(const base::Value &value)>> mapping_map_ = {
54 { "gni_mapping_file", LoadGniMappingFileMap }
55 };
56
LoadMappingFile(const std::string & build_dir)57 static void LoadMappingFile(const std::string &build_dir)
58 {
59 std::string mappingContent;
60 if (!ReadBuildConfigFile(base::FilePath(build_dir + "/build_configs/" + MAPPING_FILE_PATH), mappingContent)) {
61 return;
62 }
63 const base::DictionaryValue *mapping_dict;
64 std::unique_ptr<base::Value> mapping = base::JSONReader::ReadAndReturnError(mappingContent,
65 base::JSONParserOptions::JSON_PARSE_RFC, nullptr, nullptr, nullptr, nullptr);
66 if (!mapping) {
67 return;
68 }
69 if (!mapping->GetAsDictionary(&mapping_dict)) {
70 return;
71 }
72 for (const auto kv : mapping_dict->DictItems()) {
73 auto iter = mapping_map_.find(kv.first);
74 if (iter != mapping_map_.end()) {
75 iter->second(kv.second);
76 }
77 }
78 return;
79 }
80
OhosComponentMapping(const std::string & build_dir)81 OhosComponentMapping::OhosComponentMapping(const std::string &build_dir)
82 {
83 build_dir_ = build_dir;
84 LoadMappingFile(build_dir);
85 }
86
MappingTargetAbsoluteDpes(const BuildSettings * build_settings,const std::string label,const std::string deps) const87 const std::string OhosComponentMapping::MappingTargetAbsoluteDpes(const BuildSettings* build_settings,
88 const std::string label, const std::string deps) const
89 {
90 if (build_settings == nullptr || StartWith(deps, "//build/") ||
91 StartWith(deps, "//out/") || StartWith(deps, "//prebuilts/")) {
92 return "";
93 }
94
95 const OhosComponent *component = build_settings->GetOhosComponent(label);
96 if (component == nullptr) {
97 return "";
98 }
99 if (StartWith(deps, component->path())) {
100 return "";
101 }
102
103 std::string deps_without_tool = deps;
104 size_t tool_sep = deps.find("(");
105 if (tool_sep != std::string::npos) {
106 deps_without_tool = deps.substr(0, tool_sep);
107 }
108 const OhosComponent *deps_component = build_settings->GetOhosComponent(deps_without_tool);
109 if (deps_component == nullptr) {
110 return "";
111 }
112
113 size_t pos = deps.find(":");
114 if (pos == std::string::npos) {
115 return "";
116 }
117 return deps_component->getInnerApi(deps.substr(pos + 1));
118 }
119
MappingImportOther(const BuildSettings * build_settings,const std::string label,const std::string deps) const120 const std::string OhosComponentMapping::MappingImportOther(const BuildSettings* build_settings,
121 const std::string label, const std::string deps) const
122 {
123 if (build_settings == nullptr || StartWith(deps, "//build/") ||
124 StartWith(deps, "//out/") || StartWith(deps, "//prebuilts/")) {
125 return "";
126 }
127 const OhosComponent *component = build_settings->GetOhosComponent(label);
128 if (component == nullptr) {
129 return "";
130 }
131 if (StartWith(deps, component->path())) {
132 return "";
133 }
134 return gni_mapping_file_map_[deps];
135 }
136