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