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
GetRealImportFile(const BuildSettings * settings,const std::string & path)38 const static std::string GetRealImportFile(const BuildSettings *settings, const std::string &path)
39 {
40 base::FilePath file = base::FilePath(settings->root_path().MaybeAsASCII() + path);
41 if (!base::PathExists(file)) {
42 return "";
43 }
44 return path;
45 }
46
ReadBuildConfigFile(base::FilePath path,std::string & content)47 static bool ReadBuildConfigFile(base::FilePath path, std::string &content)
48 {
49 if (!base::ReadFileToString(path, &content)) {
50 return false;
51 }
52 return true;
53 }
54
LoadGniMappingFileMap(const base::Value & value)55 static void LoadGniMappingFileMap(const base::Value &value)
56 {
57 for (auto info : value.DictItems()) {
58 gni_mapping_file_map_[info.first] = info.second.GetString();
59 }
60 return;
61 }
62
63 static std::map<std::string, std::function<void(const base::Value &value)>> mapping_map_ = {
64 { "gni_mapping_file", LoadGniMappingFileMap }
65 };
66
LoadMappingFile(const std::string & build_dir)67 static void LoadMappingFile(const std::string &build_dir)
68 {
69 std::string mappingContent;
70 if (!ReadBuildConfigFile(base::FilePath(build_dir + "/build_configs/" + MAPPING_FILE_PATH), mappingContent)) {
71 return;
72 }
73 const base::DictionaryValue *mapping_dict;
74 std::unique_ptr<base::Value> mapping = base::JSONReader::ReadAndReturnError(mappingContent,
75 base::JSONParserOptions::JSON_PARSE_RFC, nullptr, nullptr, nullptr, nullptr);
76 if (!mapping) {
77 return;
78 }
79 if (!mapping->GetAsDictionary(&mapping_dict)) {
80 return;
81 }
82 for (const auto kv : mapping_dict->DictItems()) {
83 auto iter = mapping_map_.find(kv.first);
84 if (iter != mapping_map_.end()) {
85 iter->second(kv.second);
86 }
87 }
88 return;
89 }
90
OhosComponentMapping(const std::string & build_dir)91 OhosComponentMapping::OhosComponentMapping(const std::string &build_dir)
92 {
93 build_dir_ = build_dir;
94 LoadMappingFile(build_dir);
95 return;
96 }
97
MappingTargetAbsoluteDpes(const BuildSettings * settings,const std::string & label,const std::string & deps) const98 const std::string OhosComponentMapping::MappingTargetAbsoluteDpes(const BuildSettings *settings,
99 const std::string &label, const std::string &deps) const
100 {
101 if (settings == nullptr || StartWith(deps, "//build/") ||
102 StartWith(deps, "//out/") || StartWith(deps, "//prebuilts/")) {
103 return "";
104 }
105
106 const OhosComponent *component = settings->GetOhosComponent(label);
107 if (component == nullptr) {
108 return "";
109 }
110 if (StartWith(deps, component->path())) {
111 return "";
112 }
113
114 std::string deps_without_tool = deps;
115 size_t tool_sep = deps.find("(");
116 if (tool_sep != std::string::npos) {
117 deps_without_tool = deps.substr(0, tool_sep);
118 }
119 const OhosComponent *deps_component = settings->GetOhosComponent(deps_without_tool);
120 if (deps_component == nullptr) {
121 return "";
122 }
123
124 size_t pos = deps.find(":");
125 if (pos == std::string::npos) {
126 return "";
127 }
128 return deps_component->getInnerApi(deps.substr(pos + 1));
129 }
130
MappingImportOther(const BuildSettings * settings,const std::string & label,const std::string & deps) const131 const std::string OhosComponentMapping::MappingImportOther(const BuildSettings *settings,
132 const std::string &label, const std::string &deps) const
133 {
134 if (settings == nullptr || StartWith(deps, "//build/") ||
135 StartWith(deps, "//out/") || StartWith(deps, "//prebuilts/")) {
136 return "";
137 }
138 const OhosComponent *component = settings->GetOhosComponent(label);
139 if (component == nullptr) {
140 return "";
141 }
142 if (StartWith(deps, component->path())) {
143 return "";
144 }
145 return GetRealImportFile(settings, gni_mapping_file_map_[deps]);
146 }
147