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