xref: /aosp_15_r20/build/soong/java/device_host_converter.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2019 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	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"io"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
22*333d2b36SAndroid Build Coastguard Worker	"android/soong/dexpreopt"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/depset"
25*333d2b36SAndroid Build Coastguard Worker)
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Workertype DeviceHostConverter struct {
28*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
29*333d2b36SAndroid Build Coastguard Worker	android.DefaultableModuleBase
30*333d2b36SAndroid Build Coastguard Worker
31*333d2b36SAndroid Build Coastguard Worker	properties DeviceHostConverterProperties
32*333d2b36SAndroid Build Coastguard Worker
33*333d2b36SAndroid Build Coastguard Worker	headerJars                    android.Paths
34*333d2b36SAndroid Build Coastguard Worker	implementationJars            android.Paths
35*333d2b36SAndroid Build Coastguard Worker	implementationAndResourceJars android.Paths
36*333d2b36SAndroid Build Coastguard Worker	resourceJars                  android.Paths
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Worker	srcJarArgs []string
39*333d2b36SAndroid Build Coastguard Worker	srcJarDeps android.Paths
40*333d2b36SAndroid Build Coastguard Worker
41*333d2b36SAndroid Build Coastguard Worker	combinedHeaderJar         android.Path
42*333d2b36SAndroid Build Coastguard Worker	combinedImplementationJar android.Path
43*333d2b36SAndroid Build Coastguard Worker}
44*333d2b36SAndroid Build Coastguard Worker
45*333d2b36SAndroid Build Coastguard Workertype DeviceHostConverterProperties struct {
46*333d2b36SAndroid Build Coastguard Worker	// List of modules whose contents will be visible to modules that depend on this module.
47*333d2b36SAndroid Build Coastguard Worker	Libs []string
48*333d2b36SAndroid Build Coastguard Worker}
49*333d2b36SAndroid Build Coastguard Worker
50*333d2b36SAndroid Build Coastguard Workertype DeviceForHost struct {
51*333d2b36SAndroid Build Coastguard Worker	DeviceHostConverter
52*333d2b36SAndroid Build Coastguard Worker}
53*333d2b36SAndroid Build Coastguard Worker
54*333d2b36SAndroid Build Coastguard Worker// java_device_for_host makes the classes.jar output of a device java_library module available to host
55*333d2b36SAndroid Build Coastguard Worker// java_library modules.
56*333d2b36SAndroid Build Coastguard Worker//
57*333d2b36SAndroid Build Coastguard Worker// It is rarely necessary, and its usage is restricted to a few allowed projects.
58*333d2b36SAndroid Build Coastguard Workerfunc DeviceForHostFactory() android.Module {
59*333d2b36SAndroid Build Coastguard Worker	module := &DeviceForHost{}
60*333d2b36SAndroid Build Coastguard Worker
61*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Worker	InitJavaModule(module, android.HostSupported)
64*333d2b36SAndroid Build Coastguard Worker	return module
65*333d2b36SAndroid Build Coastguard Worker}
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Workertype HostForDevice struct {
68*333d2b36SAndroid Build Coastguard Worker	DeviceHostConverter
69*333d2b36SAndroid Build Coastguard Worker}
70*333d2b36SAndroid Build Coastguard Worker
71*333d2b36SAndroid Build Coastguard Worker// java_host_for_device makes the classes.jar output of a host java_library module available to device
72*333d2b36SAndroid Build Coastguard Worker// java_library modules.
73*333d2b36SAndroid Build Coastguard Worker//
74*333d2b36SAndroid Build Coastguard Worker// It is rarely necessary, and its usage is restricted to a few allowed projects.
75*333d2b36SAndroid Build Coastguard Workerfunc HostForDeviceFactory() android.Module {
76*333d2b36SAndroid Build Coastguard Worker	module := &HostForDevice{}
77*333d2b36SAndroid Build Coastguard Worker
78*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
79*333d2b36SAndroid Build Coastguard Worker
80*333d2b36SAndroid Build Coastguard Worker	InitJavaModule(module, android.DeviceSupported)
81*333d2b36SAndroid Build Coastguard Worker	return module
82*333d2b36SAndroid Build Coastguard Worker}
83*333d2b36SAndroid Build Coastguard Worker
84*333d2b36SAndroid Build Coastguard Workervar deviceHostConverterDepTag = dependencyTag{name: "device_host_converter"}
85*333d2b36SAndroid Build Coastguard Worker
86*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceForHost) DepsMutator(ctx android.BottomUpMutatorContext) {
87*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
88*333d2b36SAndroid Build Coastguard Worker		deviceHostConverterDepTag, d.properties.Libs...)
89*333d2b36SAndroid Build Coastguard Worker}
90*333d2b36SAndroid Build Coastguard Worker
91*333d2b36SAndroid Build Coastguard Workerfunc (d *HostForDevice) DepsMutator(ctx android.BottomUpMutatorContext) {
92*333d2b36SAndroid Build Coastguard Worker	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(),
93*333d2b36SAndroid Build Coastguard Worker		deviceHostConverterDepTag, d.properties.Libs...)
94*333d2b36SAndroid Build Coastguard Worker}
95*333d2b36SAndroid Build Coastguard Worker
96*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleContext) {
97*333d2b36SAndroid Build Coastguard Worker	if len(d.properties.Libs) < 1 {
98*333d2b36SAndroid Build Coastguard Worker		ctx.PropertyErrorf("libs", "at least one dependency is required")
99*333d2b36SAndroid Build Coastguard Worker	}
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Worker	var transitiveHeaderJars []depset.DepSet[android.Path]
102*333d2b36SAndroid Build Coastguard Worker	var transitiveImplementationJars []depset.DepSet[android.Path]
103*333d2b36SAndroid Build Coastguard Worker	var transitiveResourceJars []depset.DepSet[android.Path]
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsWithTag(deviceHostConverterDepTag, func(m android.Module) {
106*333d2b36SAndroid Build Coastguard Worker		if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
107*333d2b36SAndroid Build Coastguard Worker			d.headerJars = append(d.headerJars, dep.HeaderJars...)
108*333d2b36SAndroid Build Coastguard Worker			d.implementationJars = append(d.implementationJars, dep.ImplementationJars...)
109*333d2b36SAndroid Build Coastguard Worker			d.implementationAndResourceJars = append(d.implementationAndResourceJars, dep.ImplementationAndResourcesJars...)
110*333d2b36SAndroid Build Coastguard Worker			d.resourceJars = append(d.resourceJars, dep.ResourceJars...)
111*333d2b36SAndroid Build Coastguard Worker
112*333d2b36SAndroid Build Coastguard Worker			d.srcJarArgs = append(d.srcJarArgs, dep.SrcJarArgs...)
113*333d2b36SAndroid Build Coastguard Worker			d.srcJarDeps = append(d.srcJarDeps, dep.SrcJarDeps...)
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Worker			transitiveHeaderJars = append(transitiveHeaderJars, dep.TransitiveStaticLibsHeaderJars)
116*333d2b36SAndroid Build Coastguard Worker			transitiveImplementationJars = append(transitiveImplementationJars, dep.TransitiveStaticLibsImplementationJars)
117*333d2b36SAndroid Build Coastguard Worker			transitiveResourceJars = append(transitiveResourceJars, dep.TransitiveStaticLibsResourceJars)
118*333d2b36SAndroid Build Coastguard Worker		} else {
119*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("libs", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
120*333d2b36SAndroid Build Coastguard Worker		}
121*333d2b36SAndroid Build Coastguard Worker	})
122*333d2b36SAndroid Build Coastguard Worker
123*333d2b36SAndroid Build Coastguard Worker	jarName := ctx.ModuleName() + ".jar"
124*333d2b36SAndroid Build Coastguard Worker
125*333d2b36SAndroid Build Coastguard Worker	if len(d.implementationAndResourceJars) > 1 {
126*333d2b36SAndroid Build Coastguard Worker		outputFile := android.PathForModuleOut(ctx, "combined", jarName)
127*333d2b36SAndroid Build Coastguard Worker		TransformJarsToJar(ctx, outputFile, "combine", d.implementationAndResourceJars,
128*333d2b36SAndroid Build Coastguard Worker			android.OptionalPath{}, false, nil, nil)
129*333d2b36SAndroid Build Coastguard Worker		d.combinedImplementationJar = outputFile
130*333d2b36SAndroid Build Coastguard Worker	} else if len(d.implementationAndResourceJars) == 1 {
131*333d2b36SAndroid Build Coastguard Worker		d.combinedImplementationJar = d.implementationAndResourceJars[0]
132*333d2b36SAndroid Build Coastguard Worker	}
133*333d2b36SAndroid Build Coastguard Worker
134*333d2b36SAndroid Build Coastguard Worker	if len(d.headerJars) > 1 {
135*333d2b36SAndroid Build Coastguard Worker		outputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
136*333d2b36SAndroid Build Coastguard Worker		TransformJarsToJar(ctx, outputFile, "turbine combine", d.headerJars,
137*333d2b36SAndroid Build Coastguard Worker			android.OptionalPath{}, false, nil, []string{"META-INF/TRANSITIVE"})
138*333d2b36SAndroid Build Coastguard Worker		d.combinedHeaderJar = outputFile
139*333d2b36SAndroid Build Coastguard Worker	} else if len(d.headerJars) == 1 {
140*333d2b36SAndroid Build Coastguard Worker		d.combinedHeaderJar = d.headerJars[0]
141*333d2b36SAndroid Build Coastguard Worker	}
142*333d2b36SAndroid Build Coastguard Worker
143*333d2b36SAndroid Build Coastguard Worker	android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
144*333d2b36SAndroid Build Coastguard Worker		HeaderJars:                             d.headerJars,
145*333d2b36SAndroid Build Coastguard Worker		LocalHeaderJars:                        d.headerJars,
146*333d2b36SAndroid Build Coastguard Worker		TransitiveStaticLibsHeaderJars:         depset.New(depset.PREORDER, nil, transitiveHeaderJars),
147*333d2b36SAndroid Build Coastguard Worker		TransitiveStaticLibsImplementationJars: depset.New(depset.PREORDER, nil, transitiveImplementationJars),
148*333d2b36SAndroid Build Coastguard Worker		TransitiveStaticLibsResourceJars:       depset.New(depset.PREORDER, nil, transitiveResourceJars),
149*333d2b36SAndroid Build Coastguard Worker		ImplementationAndResourcesJars:         d.implementationAndResourceJars,
150*333d2b36SAndroid Build Coastguard Worker		ImplementationJars:                     d.implementationJars,
151*333d2b36SAndroid Build Coastguard Worker		ResourceJars:                           d.resourceJars,
152*333d2b36SAndroid Build Coastguard Worker		SrcJarArgs:                             d.srcJarArgs,
153*333d2b36SAndroid Build Coastguard Worker		SrcJarDeps:                             d.srcJarDeps,
154*333d2b36SAndroid Build Coastguard Worker		StubsLinkType:                          Implementation,
155*333d2b36SAndroid Build Coastguard Worker		// TODO: Not sure if aconfig flags that have been moved between device and host variants
156*333d2b36SAndroid Build Coastguard Worker		// make sense.
157*333d2b36SAndroid Build Coastguard Worker	})
158*333d2b36SAndroid Build Coastguard Worker
159*333d2b36SAndroid Build Coastguard Worker}
160*333d2b36SAndroid Build Coastguard Worker
161*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) HeaderJars() android.Paths {
162*333d2b36SAndroid Build Coastguard Worker	return d.headerJars
163*333d2b36SAndroid Build Coastguard Worker}
164*333d2b36SAndroid Build Coastguard Worker
165*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) ImplementationAndResourcesJars() android.Paths {
166*333d2b36SAndroid Build Coastguard Worker	return d.implementationAndResourceJars
167*333d2b36SAndroid Build Coastguard Worker}
168*333d2b36SAndroid Build Coastguard Worker
169*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) DexJarBuildPath(ctx android.ModuleErrorfContext) android.Path {
170*333d2b36SAndroid Build Coastguard Worker	return nil
171*333d2b36SAndroid Build Coastguard Worker}
172*333d2b36SAndroid Build Coastguard Worker
173*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) DexJarInstallPath() android.Path {
174*333d2b36SAndroid Build Coastguard Worker	return nil
175*333d2b36SAndroid Build Coastguard Worker}
176*333d2b36SAndroid Build Coastguard Worker
177*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) AidlIncludeDirs() android.Paths {
178*333d2b36SAndroid Build Coastguard Worker	return nil
179*333d2b36SAndroid Build Coastguard Worker}
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
182*333d2b36SAndroid Build Coastguard Worker	return nil
183*333d2b36SAndroid Build Coastguard Worker}
184*333d2b36SAndroid Build Coastguard Worker
185*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) JacocoReportClassesFile() android.Path {
186*333d2b36SAndroid Build Coastguard Worker	return nil
187*333d2b36SAndroid Build Coastguard Worker}
188*333d2b36SAndroid Build Coastguard Worker
189*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) AndroidMk() android.AndroidMkData {
190*333d2b36SAndroid Build Coastguard Worker	return android.AndroidMkData{
191*333d2b36SAndroid Build Coastguard Worker		Class:      "JAVA_LIBRARIES",
192*333d2b36SAndroid Build Coastguard Worker		OutputFile: android.OptionalPathForPath(d.combinedImplementationJar),
193*333d2b36SAndroid Build Coastguard Worker		// Make does not support Windows Java modules
194*333d2b36SAndroid Build Coastguard Worker		Disabled: d.Os() == android.Windows,
195*333d2b36SAndroid Build Coastguard Worker		Include:  "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
196*333d2b36SAndroid Build Coastguard Worker		Extra: []android.AndroidMkExtraFunc{
197*333d2b36SAndroid Build Coastguard Worker			func(w io.Writer, outputFile android.Path) {
198*333d2b36SAndroid Build Coastguard Worker				fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
199*333d2b36SAndroid Build Coastguard Worker				fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", d.combinedHeaderJar.String())
200*333d2b36SAndroid Build Coastguard Worker				fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", d.combinedImplementationJar.String())
201*333d2b36SAndroid Build Coastguard Worker			},
202*333d2b36SAndroid Build Coastguard Worker		},
203*333d2b36SAndroid Build Coastguard Worker	}
204*333d2b36SAndroid Build Coastguard Worker}
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Worker// implement the following interface for IDE completion.
207*333d2b36SAndroid Build Coastguard Workervar _ android.IDEInfo = (*DeviceHostConverter)(nil)
208*333d2b36SAndroid Build Coastguard Worker
209*333d2b36SAndroid Build Coastguard Workerfunc (d *DeviceHostConverter) IDEInfo(ctx android.BaseModuleContext, ideInfo *android.IdeInfo) {
210*333d2b36SAndroid Build Coastguard Worker	ideInfo.Deps = append(ideInfo.Deps, d.properties.Libs...)
211*333d2b36SAndroid Build Coastguard Worker	ideInfo.Libs = append(ideInfo.Libs, d.properties.Libs...)
212*333d2b36SAndroid Build Coastguard Worker}
213