• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 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/innerapis_publicinfo_generator.h"
6 
7 #include <fstream>
8 #include <iostream>
9 #include <sys/stat.h>
10 
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/json/json_reader.h"
14 #include "base/values.h"
15 #include "gn/build_settings.h"
16 #include "gn/config.h"
17 #include "gn/filesystem_utils.h"
18 #include "gn/functions.h"
19 #include "gn/ohos_components.h"
20 #include "gn/ohos_components_checker.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 #include "gn/standard_out.h"
27 
28 InnerApiPublicInfoGenerator *InnerApiPublicInfoGenerator::instance_ = nullptr;
29 
StartWith(const std::string & str,const std::string & prefix)30 static bool StartWith(const std::string &str, const std::string &prefix)
31 {
32     return (str.rfind(prefix, 0) == 0);
33 }
34 
GetOutName(const Target * target,const std::string & module,const std::string & type,RustValues::CrateType crateType)35 static std::string GetOutName(const Target *target, const std::string &module, const std::string &type, RustValues::CrateType crateType)
36 {
37     std::string output = target->output_name();
38     std::string extension = target->output_extension();
39     if(extension != ""){
40       extension = "." + extension;
41     }else{
42       if (crateType == RustValues::CRATE_AUTO){
43         if (type == "shared_library") {
44           extension = ".z.so";
45         } else if (type == "static_library") {
46           extension = ".a";
47         }
48       }else{
49         if(crateType == RustValues::CRATE_RLIB){
50           extension = ".rlib";
51         }else if(crateType == RustValues::CRATE_DYLIB || crateType == RustValues::CRATE_PROC_MACRO){
52           extension = ".dylib.so";
53         } else if(crateType == RustValues::CRATE_STATICLIB){
54           extension = ".a";
55         } else if(crateType == RustValues::CRATE_CDYLIB){
56           extension = ".z.so";
57         }
58       }
59     }
60     if (output  == "") {
61       output  = module;
62     }
63     if (!StartWith(output , "lib") && crateType != RustValues::CRATE_BIN && type != "executable"){
64       output  = "lib" + output ;
65     }
66     return output  + extension;
67 }
68 
GetRustCrateInfo(const Target * target,const Label & toolchain_label)69 static std::string GetRustCrateInfo(const Target* target, const Label& toolchain_label)
70 {
71     std::string info = "";
72     if (target->has_rust_values()) {
73         info += ",\n  \"rust_crate_name\": \"" + target->rust_values().crate_name() + "\",";
74         info += "\n  \"rust_crate_type\": \"" + RustValues::GetCrateTypeStr(RustValues::InferredCrateType(target)) + "\"";
75         auto private_deps = target->private_deps();
76         if (private_deps.size() > 0) {
77             info += ",\n  \"rust_deps\": [\n    ";
78             bool first = true;
79             for (const auto& dep : private_deps) {
80                 std::string dep_str = dep.label.GetUserVisibleName(toolchain_label);
81                 if (dep_str.find("__check") != std::string::npos ||
82                     dep_str.find("__info") != std::string::npos ||
83                     dep_str.find("__notice") != std::string::npos ||
84                     dep_str.find("__collect") != std::string::npos) {
85                     continue;
86                 }
87                 if (!first) {
88                     info += ",\n    ";
89                 }
90                 first = false;
91                 info += "\"" + dep_str + "\"";
92             }
93             info += "\n  ]";
94         }
95     }
96     return info;
97 }
98 
TraverIncludeDirs(const Target * target,const OhosComponentChecker * checker,const std::string & label,Err * err)99 static bool TraverIncludeDirs(const Target *target, const OhosComponentChecker *checker,
100     const std::string &label, Err *err)
101 {
102     if (checker == nullptr) {
103         return true;
104     }
105 
106     std::vector<SourceDir> dirs = target->include_dirs();
107     for (const SourceDir &dir : dirs) {
108         if (!checker->CheckIncludesAbsoluteDepsOther(target, label, dir.value(), err)) {
109             return false;
110         }
111     }
112     return true;
113 }
114 
CheckIncludes(const Target * target,const OhosComponentChecker * checker,const std::string & dir,Err * err,bool isPublic)115 static bool CheckIncludes(const Target *target, const OhosComponentChecker *checker,
116     const std::string &dir, Err *err, bool isPublic)
117 {
118     std::string label = target->label().GetUserVisibleName(false);
119     if (isPublic) {
120         if (checker != nullptr) {
121             if (!checker->CheckInnerApiIncludesOverRange(target, label, dir, err)) {
122                 return false;
123             }
124         }
125     }
126     if (checker != nullptr) {
127         if (!checker->CheckIncludesAbsoluteDepsOther(target, label, dir, err)) {
128             return false;
129         }
130     }
131     return true;
132 }
133 
ReplaceDoubleQuotes(const std::string & input)134 static std::string ReplaceDoubleQuotes(const std::string &input) {
135     std::string result;
136     for (char c : input) {
137         if (c == '"') {
138             result += "\\\"";
139         } else {
140             result += c;
141         }
142     }
143     return result;
144 }
145 
GetSingleFlagInfo(const std::string & name,const std::vector<std::string> & flags)146 static std::string GetSingleFlagInfo(const std::string &name, const std::vector<std::string> &flags)
147 {
148     std::string info;
149     if (!flags.empty()) {
150         info +=",\n    \"";
151         info += name;
152         info += "\": [\n      ";
153         bool first = true;
154         for (const std::string &flag : flags) {
155             if (!first) {
156                 info += ",\n      ";
157             }
158             first = false;
159             std::string str = ReplaceDoubleQuotes(flag);
160             info += "\"" + str + "\"";
161         }
162         info += "\n    ]";
163     }
164     return info;
165 }
166 
GetFlagsInfo(const Config * config)167 static std::string GetFlagsInfo(const Config *config)
168 {
169     std::string info;
170     info += GetSingleFlagInfo("arflags", config->own_values().arflags());
171     info += GetSingleFlagInfo("asmflags", config->own_values().asmflags());
172     info += GetSingleFlagInfo("cflags", config->own_values().cflags());
173     info += GetSingleFlagInfo("cflags_c", config->own_values().cflags_c());
174     info += GetSingleFlagInfo("cflags_cc", config->own_values().cflags_cc());
175     info += GetSingleFlagInfo("cflags_objc", config->own_values().cflags_objc());
176     info += GetSingleFlagInfo("cflags_objcc", config->own_values().cflags_objcc());
177     info += GetSingleFlagInfo("defines", config->own_values().defines());
178     info += GetSingleFlagInfo("frameworks", config->own_values().frameworks());
179     info += GetSingleFlagInfo("weak_frameworks", config->own_values().weak_frameworks());
180     info += GetSingleFlagInfo("ldflags", config->own_values().ldflags());
181     info += GetSingleFlagInfo("rustflags", config->own_values().rustflags());
182     info += GetSingleFlagInfo("rustenv", config->own_values().rustenv());
183     info += GetSingleFlagInfo("swiftflags", config->own_values().swiftflags());
184     info += "\n";
185     return info;
186 }
187 
TraverLibDirs(const Target * target,const OhosComponentChecker * checker,const std::vector<SourceDir> & dirs,Err * err)188 static bool TraverLibDirs(const Target *target, const OhosComponentChecker *checker,
189     const std::vector<SourceDir> &dirs, Err *err)
190 {
191     if (checker == nullptr) {
192         return true;
193     }
194     std::string label = target->label().GetUserVisibleName(false);
195     for (const SourceDir &dir : dirs) {
196         if (!checker->CheckLibDir(target, label, dir.value(), err)) {
197             return false;
198         }
199     }
200     return true;
201 }
202 
GetIncludeDirsInfo(const Target * target,const Config * config,const OhosComponentChecker * checker,Err * err,bool isPublic)203 static std::string GetIncludeDirsInfo(const Target *target, const Config *config,
204     const OhosComponentChecker *checker, Err *err, bool isPublic)
205 {
206     std::string info = ",\n    \"include_dirs\": [\n      ";
207     const std::vector<SourceDir> dirs = config->own_values().include_dirs();
208     bool first = true;
209     for (const SourceDir &dir : dirs) {
210         if (!first) {
211             info += ",\n      ";
212         }
213         first = false;
214         info += "\"" + dir.value() + "\"";
215         if (!CheckIncludes(target, checker, dir.value(), err, isPublic)) {
216             return "";
217         }
218     }
219 
220     info += "\n    ]";
221     return info;
222 }
223 
GetConfigInfo(const Target * target,const UniqueVector<LabelConfigPair> & configs,const OhosComponentChecker * checker,Err * err,bool isPublic)224 static std::string GetConfigInfo(const Target *target, const UniqueVector<LabelConfigPair> &configs,
225     const OhosComponentChecker *checker, Err *err, bool isPublic)
226 {
227     std::string info = "[{";
228     bool first = true;
229     for (const auto &config : configs) {
230         const std::vector<SourceDir> lib_dirs = config.ptr->own_values().lib_dirs();
231         if (!TraverLibDirs(target, checker, lib_dirs, err)) {
232             return "";
233         }
234         std::string label = config.label.GetUserVisibleName(false);
235         if (!first) {
236             info += ", {";
237         }
238         first = false;
239         info += "\n    \"label\": \"" + label + "\"";
240         info += GetIncludeDirsInfo(target, config.ptr, checker, err, isPublic);
241         info += GetFlagsInfo(config.ptr);
242         info += "  }";
243     }
244     info += "]";
245     return info;
246 }
247 
GetPublicConfigsInfo(const Target * target,const OhosComponentChecker * checker,Err * err)248 static std::string GetPublicConfigsInfo(const Target *target, const OhosComponentChecker *checker, Err *err)
249 {
250     std::string info = "";
251     const UniqueVector<LabelConfigPair> configs = target->own_public_configs();
252     if (configs.size() > 0) {
253         info += ",\n  \"public_configs\": ";
254         std::string tmp = GetConfigInfo(target, configs, checker, err, true);
255         if (tmp == "") {
256             return "";
257         }
258         info += tmp;
259     }
260     return info;
261 }
262 
GetAllDependentConfigsInfo(const Target * target,const OhosComponentChecker * checker,Err * err)263 static std::string GetAllDependentConfigsInfo(const Target *target, const OhosComponentChecker *checker, Err *err)
264 {
265     std::string info = "";
266     const UniqueVector<LabelConfigPair> all_configs = target->own_all_dependent_configs();
267     if (all_configs.size() > 0) {
268         info += ",\n  \"all_dependent_configs\": ";
269         std::string tmp = GetConfigInfo(target, all_configs, checker, err, true);
270         if (tmp == "") {
271             return "";
272         }
273         info += tmp;
274         if (checker != nullptr) {
275             if (!checker->CheckAllDepsConfigs(target, target->label().GetUserVisibleName(false), err)) {
276                 return "";
277             }
278         }
279     }
280     return info;
281 }
282 
TraverPrivateConfigsInfo(const Target * target,const OhosComponentChecker * checker,Err * err)283 static void TraverPrivateConfigsInfo(const Target *target, const OhosComponentChecker *checker, Err *err)
284 {
285     const UniqueVector<LabelConfigPair> private_configs = target->own_configs();
286     if (private_configs.size() > 0) {
287         (void)GetConfigInfo(target, private_configs, checker, err, false);
288     }
289 }
290 
GetPublicHeadersInfo(const Target * target)291 static std::string GetPublicHeadersInfo(const Target *target)
292 {
293     std::string info = "";
294     const std::vector<SourceFile> &headers = target->public_headers();
295     if (headers.size() > 0) {
296         info += ",\n  \"public\": [\n    ";
297         bool first = true;
298         for (const auto &header : headers) {
299             if (!first) {
300                 info += ",\n    ";
301             }
302             first = false;
303             info += "\"" + header.value() + "\"";
304         }
305         info += "  ]";
306     }
307     return info;
308 }
309 
GetPublicDepsInfo(const Target * target,const std::string & label,const OhosComponentChecker * checker,Err * err)310 static std::string GetPublicDepsInfo(const Target *target, const std::string &label,
311     const OhosComponentChecker *checker, Err *err)
312 {
313     std::string info = "";
314     const LabelTargetVector deps = target->public_deps();
315     if (deps.size() > 0) {
316         info += ",\n  \"public_deps\": [\n    ";
317         bool first = true;
318         for (const auto &dep : deps) {
319             if (!first) {
320                 info += ",\n    ";
321             }
322             first = false;
323             std::string dep_str = dep.label.GetUserVisibleName(false);
324             info += "\"" + dep_str + "\"";
325             if (checker == nullptr) {
326                 continue;
327             }
328             if (!checker->CheckInnerApiPublicDepsInner(target, label, dep_str, err)) {
329                 return "";
330             }
331             if (!checker->CheckPublicDeps(target, label, dep_str, err)) {
332                 return "";
333             }
334         }
335         info += "\n  ]";
336     }
337     return info;
338 }
339 
GetOutNameAndTypeInfo(const Target * target,const std::string & module)340 static std::string GetOutNameAndTypeInfo(const Target *target, const std::string &module)
341 {
342     std::string type(Target::GetStringForOutputType(target->output_type()));
343     std::string info = "";
344     RustValues::CrateType crate_type = target->has_rust_values() ? target->rust_values().crate_type() : RustValues::CrateType::CRATE_AUTO;
345     const std::string name = GetOutName(target, module, type, crate_type);
346     const std::vector<OutputFile>& outputFiles = target->computed_outputs();
347     if (outputFiles.size() > 0) {
348       info += ",\n  \"outputs\": [\n    ";
349       bool first = true;
350       for (const auto& outputFile : outputFiles) {
351         if (!first) {
352           info += ",\n    ";
353         }
354         first = false;
355         info += "\"" + outputFile.value() + "\"";
356       }
357       info += "\n  ]";
358     }
359     info += ",\n  \"out_name\":\"" + name + "\"";
360     info += ",\n  \"type\":\"" + type + "\"";
361     return info;
362 }
363 
GetComponentInfo(const std::string & subsystem,const std::string & component,const std::string & path)364 static std::string GetComponentInfo(const std::string &subsystem, const std::string &component, const std::string &path)
365 {
366     std::string info = "";
367     info += ",\n  \"subsystem\":\"" + subsystem + "\"";
368     info += ",\n  \"component\":\"" + component + "\"";
369     info += ",\n  \"path\":\"" + path + "\"";
370     return info;
371 }
372 
GetPublicInfo(const Target * target,const std::string & label,const OhosComponentChecker * checker,Err * err)373 static std::string GetPublicInfo(const Target *target, const std::string &label,
374     const OhosComponentChecker *checker, Err *err)
375 {
376     std::string info = GetPublicConfigsInfo(target, checker, err);
377     info += GetAllDependentConfigsInfo(target, checker, err);
378     if (target->all_headers_public()) {
379         info += ",\n  \"public\": [ \"*\" ]";
380     } else {
381         info += GetPublicHeadersInfo(target);
382     }
383     info += GetPublicDepsInfo(target, label, checker, err);
384     info += "\n}\n";
385     return info;
386 }
387 
GetBaseInfo(const Target * target,const std::string & label,const std::string & module,const OhosComponent * component)388 static std::string GetBaseInfo(const Target *target, const std::string &label,
389     const std::string &module, const OhosComponent *component)
390 {
391     std::string info = "{\n";
392     info += "  \"label\": \"" + label + "\"";
393     info += GetOutNameAndTypeInfo(target, module);
394     info += GetRustCrateInfo(target, target->settings()->default_toolchain_label());
395     if (component != nullptr) {
396         info += GetComponentInfo(component->subsystem(), component->name(), component->path());
397     }
398     return info;
399 }
400 
WritePublicInfo(const std::string & build,const std::string & module,const OhosComponent * component,const std::string & info)401 static void WritePublicInfo(const std::string &build, const std::string &module,
402     const OhosComponent *component, const std::string &info)
403 {
404     const std::string dir = build + "/" + component->subsystem() + "/" + component->name() + "/publicinfo";
405     base::FilePath path(dir);
406     base::CreateDirectory(path);
407     std::ofstream file;
408     const std::string json = dir + "/" + module + ".json";
409     file.open(json, std::ios::out);
410     file << info;
411     file.close();
412 }
413 
DoGeneratedInnerapiPublicInfo(const Target * target,const OhosComponentChecker * checker,Err * err)414 void InnerApiPublicInfoGenerator::DoGeneratedInnerapiPublicInfo(const Target *target,
415     const OhosComponentChecker *checker, Err *err)
416 {
417     if (target == nullptr || (ignoreTest_ && target->testonly())) {
418         return;
419     }
420     std::string label = target->label().GetUserVisibleName(false);
421     size_t pos = label.find(":");
422     if (pos == std::string::npos) {
423         return;
424     }
425     std::string module = label.substr(pos + 1, label.length() - 1);
426     const OhosComponent *component = target->ohos_component();
427     std::string info = GetBaseInfo(target, label, module, component);
428     info += GetPublicInfo(target, label, checker, err);
429     const std::vector<SourceDir> &lib_dirs = target->config_values().lib_dirs();
430     if (!TraverLibDirs(target, checker, lib_dirs, err)) {
431         return;
432     }
433     if (!TraverIncludeDirs(target, checker, label, err)) {
434         return;
435     }
436     TraverPrivateConfigsInfo(target, checker, err);
437 
438     if (target->testonly() || component == nullptr || !component->isInnerApi(label)) {
439         return;
440     }
441 
442     WritePublicInfo(build_dir_, module, component, info);
443     return;
444 }
445 
GeneratedInnerapiPublicInfo(const std::vector<const Target * > & items,Err * err)446 bool InnerApiPublicInfoGenerator::GeneratedInnerapiPublicInfo(const std::vector<const Target*>& items, Err *err)
447 {
448     const OhosComponentChecker *checker = OhosComponentChecker::getInstance();
449     for (const Target *item : items) {
450         if (item->ohos_component()) {
451           DoGeneratedInnerapiPublicInfo(item, checker, err);
452           if (err->has_error()) {
453             return false;
454           }
455         }
456     }
457     return true;
458 }