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 15package java 16 17import ( 18 "encoding/json" 19 "fmt" 20 "os" 21 22 "android/soong/android" 23) 24 25// This singleton generates android java dependency into to a json file. It does so for each 26// blueprint Android.bp resulting in a java.Module when either make, mm, mma, mmm or mmma is 27// called. Dependency info file is generated in $OUT/module_bp_java_depend.json. 28 29func init() { 30 android.RegisterSingletonType("jdeps_generator", jDepsGeneratorSingleton) 31} 32 33func jDepsGeneratorSingleton() android.Singleton { 34 return &jdepsGeneratorSingleton{} 35} 36 37type jdepsGeneratorSingleton struct { 38} 39 40const ( 41 // Environment variables used to modify behavior of this singleton. 42 envVariableCollectJavaDeps = "SOONG_COLLECT_JAVA_DEPS" 43 jdepsJsonFileName = "module_bp_java_deps.json" 44) 45 46func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) { 47 if !ctx.Config().IsEnvTrue(envVariableCollectJavaDeps) { 48 return 49 } 50 51 moduleInfos := make(map[string]android.IdeInfo) 52 53 ctx.VisitAllModules(func(module android.Module) { 54 if !module.Enabled() { 55 return 56 } 57 58 ideInfoProvider, ok := module.(android.IDEInfo) 59 if !ok { 60 return 61 } 62 name := ideInfoProvider.BaseModuleName() 63 ideModuleNameProvider, ok := module.(android.IDECustomizedModuleName) 64 if ok { 65 name = ideModuleNameProvider.IDECustomizedModuleName() 66 } 67 68 dpInfo := moduleInfos[name] 69 ideInfoProvider.IDEInfo(&dpInfo) 70 dpInfo.Deps = android.FirstUniqueStrings(dpInfo.Deps) 71 dpInfo.Srcs = android.FirstUniqueStrings(dpInfo.Srcs) 72 dpInfo.Aidl_include_dirs = android.FirstUniqueStrings(dpInfo.Aidl_include_dirs) 73 dpInfo.Jarjar_rules = android.FirstUniqueStrings(dpInfo.Jarjar_rules) 74 dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars) 75 moduleInfos[name] = dpInfo 76 77 mkProvider, ok := module.(android.AndroidMkDataProvider) 78 if !ok { 79 return 80 } 81 data := mkProvider.AndroidMk() 82 if data.Class != "" { 83 dpInfo.Classes = append(dpInfo.Classes, data.Class) 84 } 85 86 if dep, ok := module.(Dependency); ok { 87 dpInfo.Installed_paths = append(dpInfo.Installed_paths, dep.ImplementationJars().Strings()...) 88 } 89 dpInfo.Classes = android.FirstUniqueStrings(dpInfo.Classes) 90 dpInfo.Installed_paths = android.FirstUniqueStrings(dpInfo.Installed_paths) 91 moduleInfos[name] = dpInfo 92 }) 93 94 jfpath := android.PathForOutput(ctx, jdepsJsonFileName).String() 95 err := createJsonFile(moduleInfos, jfpath) 96 if err != nil { 97 ctx.Errorf(err.Error()) 98 } 99} 100 101func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath string) error { 102 file, err := os.Create(jfpath) 103 if err != nil { 104 return fmt.Errorf("Failed to create file: %s, relative: %v", jdepsJsonFileName, err) 105 } 106 defer file.Close() 107 buf, err := json.MarshalIndent(moduleInfos, "", "\t") 108 if err != nil { 109 return fmt.Errorf("Write file failed: %s, relative: %v", jdepsJsonFileName, err) 110 } 111 fmt.Fprintf(file, string(buf)) 112 return nil 113} 114