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