jdeps.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright 2018 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package java
  15. import (
  16. "encoding/json"
  17. "fmt"
  18. "android/soong/android"
  19. )
  20. // This singleton generates android java dependency into to a json file. It does so for each
  21. // blueprint Android.bp resulting in a java.Module when either make, mm, mma, mmm or mmma is
  22. // called. Dependency info file is generated in $OUT/module_bp_java_depend.json.
  23. func init() {
  24. android.RegisterParallelSingletonType("jdeps_generator", jDepsGeneratorSingleton)
  25. }
  26. func jDepsGeneratorSingleton() android.Singleton {
  27. return &jdepsGeneratorSingleton{}
  28. }
  29. type jdepsGeneratorSingleton struct {
  30. outputPath android.Path
  31. }
  32. var _ android.SingletonMakeVarsProvider = (*jdepsGeneratorSingleton)(nil)
  33. const (
  34. jdepsJsonFileName = "module_bp_java_deps.json"
  35. )
  36. func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  37. // (b/204397180) Generate module_bp_java_deps.json by default.
  38. moduleInfos := make(map[string]android.IdeInfo)
  39. ctx.VisitAllModules(func(module android.Module) {
  40. if !module.Enabled() {
  41. return
  42. }
  43. // Prevent including both prebuilts and matching source modules when one replaces the other.
  44. if !android.IsModulePreferred(module) {
  45. return
  46. }
  47. ideInfoProvider, ok := module.(android.IDEInfo)
  48. if !ok {
  49. return
  50. }
  51. name := ideInfoProvider.BaseModuleName()
  52. ideModuleNameProvider, ok := module.(android.IDECustomizedModuleName)
  53. if ok {
  54. name = ideModuleNameProvider.IDECustomizedModuleName()
  55. }
  56. dpInfo := moduleInfos[name]
  57. ideInfoProvider.IDEInfo(&dpInfo)
  58. dpInfo.Deps = android.FirstUniqueStrings(dpInfo.Deps)
  59. dpInfo.Srcs = android.FirstUniqueStrings(dpInfo.Srcs)
  60. dpInfo.Aidl_include_dirs = android.FirstUniqueStrings(dpInfo.Aidl_include_dirs)
  61. dpInfo.Jarjar_rules = android.FirstUniqueStrings(dpInfo.Jarjar_rules)
  62. dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars)
  63. dpInfo.SrcJars = android.FirstUniqueStrings(dpInfo.SrcJars)
  64. dpInfo.Paths = android.FirstUniqueStrings(dpInfo.Paths)
  65. dpInfo.Static_libs = android.FirstUniqueStrings(dpInfo.Static_libs)
  66. dpInfo.Libs = android.FirstUniqueStrings(dpInfo.Libs)
  67. moduleInfos[name] = dpInfo
  68. mkProvider, ok := module.(android.AndroidMkDataProvider)
  69. if !ok {
  70. return
  71. }
  72. data := mkProvider.AndroidMk()
  73. if data.Class != "" {
  74. dpInfo.Classes = append(dpInfo.Classes, data.Class)
  75. }
  76. if ctx.ModuleHasProvider(module, JavaInfoProvider) {
  77. dep := ctx.ModuleProvider(module, JavaInfoProvider).(JavaInfo)
  78. dpInfo.Installed_paths = append(dpInfo.Installed_paths, dep.ImplementationJars.Strings()...)
  79. }
  80. dpInfo.Classes = android.FirstUniqueStrings(dpInfo.Classes)
  81. dpInfo.Installed_paths = android.FirstUniqueStrings(dpInfo.Installed_paths)
  82. moduleInfos[name] = dpInfo
  83. })
  84. jfpath := android.PathForOutput(ctx, jdepsJsonFileName)
  85. err := createJsonFile(moduleInfos, jfpath)
  86. if err != nil {
  87. ctx.Errorf(err.Error())
  88. }
  89. j.outputPath = jfpath
  90. // This is necessary to satisfy the dangling rules check as this file is written by Soong rather than a rule.
  91. ctx.Build(pctx, android.BuildParams{
  92. Rule: android.Touch,
  93. Output: jfpath,
  94. })
  95. }
  96. func (j *jdepsGeneratorSingleton) MakeVars(ctx android.MakeVarsContext) {
  97. if j.outputPath == nil {
  98. return
  99. }
  100. ctx.DistForGoal("general-tests", j.outputPath)
  101. }
  102. func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error {
  103. buf, err := json.MarshalIndent(moduleInfos, "", "\t")
  104. if err != nil {
  105. return fmt.Errorf("JSON marshal of java deps failed: %s", err)
  106. }
  107. err = android.WriteFileToOutputDir(jfpath, buf, 0666)
  108. if err != nil {
  109. return fmt.Errorf("Writing java deps to %s failed: %s", jfpath.String(), err)
  110. }
  111. return nil
  112. }