diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 780 |
1 files changed, 533 insertions, 247 deletions
diff --git a/java/java.go b/java/java.go index 2482f325d..2553a30bd 100644 --- a/java/java.go +++ b/java/java.go @@ -29,6 +29,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/dexpreopt" "android/soong/java/config" "android/soong/tradefed" ) @@ -44,7 +45,7 @@ func init() { PropertyName: "java_libs", }, func(j *Library) android.Path { - implementationJars := j.ImplementationJars() + implementationJars := j.ImplementationAndResourcesJars() if len(implementationJars) != 1 { panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) } @@ -140,10 +141,15 @@ func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { // Findbugs type CompilerProperties struct { - // list of source files used to compile the Java module. May be .java, .logtags, .proto, + // list of source files used to compile the Java module. May be .java, .kt, .logtags, .proto, // or .aidl files. Srcs []string `android:"path,arch_variant"` + // list Kotlin of source files containing Kotlin code that should be treated as common code in + // a codebase that supports Kotlin multiplatform. See + // https://kotlinlang.org/docs/reference/multiplatform.html. May be only be .kt files. + Common_srcs []string `android:"path,arch_variant"` + // list of source files that should not be used to build the Java module. // This is most useful in the arch/multilib variants to remove non-common files Exclude_srcs []string `android:"path,arch_variant"` @@ -253,12 +259,12 @@ type CompilerProperties struct { // List of files to include in the META-INF/services folder of the resulting jar. Services []string `android:"path,arch_variant"` + + // If true, package the kotlin stdlib into the jar. Defaults to true. + Static_kotlin_stdlib *bool `android:"arch_variant"` } type CompilerDeviceProperties struct { - // list of module-specific flags that will be used for dex compiles - Dxflags []string `android:"arch_variant"` - // if not blank, set to the version of the sdk to compile against. // Defaults to compiling against the current platform. Sdk_version *string @@ -304,54 +310,38 @@ type CompilerDeviceProperties struct { } } - // If set to true, compile dex regardless of installable. Defaults to false. - Compile_dex *bool - - Optimize struct { - // If false, disable all optimization. Defaults to true for android_app and android_test - // modules, false for java_library and java_test modules. - Enabled *bool - // True if the module containing this has it set by default. - EnabledByDefault bool `blueprint:"mutated"` - - // If true, optimize for size by removing unused code. Defaults to true for apps, - // false for libraries and tests. - Shrink *bool - - // If true, optimize bytecode. Defaults to false. - Optimize *bool - - // If true, obfuscate bytecode. Defaults to false. - Obfuscate *bool - - // If true, do not use the flag files generated by aapt that automatically keep - // classes referenced by the app manifest. Defaults to false. - No_aapt_flags *bool - - // Flags to pass to proguard. - Proguard_flags []string - - // Specifies the locations of files containing proguard flags. - Proguard_flags_files []string `android:"path"` - } - // When targeting 1.9 and above, override the modules to use with --system, // otherwise provides defaults libraries to add to the bootclasspath. System_modules *string + // The name of the module as used in build configuration. + // + // Allows a library to separate its actual name from the name used in + // build configuration, e.g.ctx.Config().BootJars(). + ConfigurationName *string `blueprint:"mutated"` + // set the name of the output Stem *string - UncompressDex bool `blueprint:"mutated"` - IsSDKLibrary bool `blueprint:"mutated"` -} + IsSDKLibrary bool `blueprint:"mutated"` -func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool { - return BoolDefault(me.Optimize.Enabled, me.Optimize.EnabledByDefault) + // If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file. + // Defaults to false. + V4_signature *bool } // Functionality common to Module and Import +// +// It is embedded in Module so its functionality can be used by methods in Module +// but it is currently only initialized by Import and Library. type embeddableInModuleAndImport struct { + + // Functionality related to this being used as a component of a java_sdk_library. + EmbeddableSdkLibraryComponent +} + +func (e *embeddableInModuleAndImport) initModuleAndImport(moduleBase *android.ModuleBase) { + e.initSdkLibraryComponent(moduleBase) } // Module/Import's DepIsInSameApex(...) delegates to this method. @@ -408,9 +398,6 @@ type Module struct { // output file containing uninstrumented classes that will be instrumented by jacoco jacocoReportClassesFile android.Path - // output file containing mapping of obfuscated names - proguardDictionary android.Path - // output file of the module, which may be a classes jar or a dex jar outputFile android.Path extraOutputFiles android.Paths @@ -426,14 +413,11 @@ type Module struct { compiledJavaSrcs android.Paths compiledSrcJars android.Paths - // list of extra progurad flag files - extraProguardFlagFiles android.Paths - // manifest file to use instead of properties.Manifest overrideManifest android.OptionalPath - // list of SDK lib names that this java module is exporting - exportedSdkLibs []string + // map of SDK libs exported by this java module to their build and install paths + exportedSdkLibs dexpreopt.LibraryPaths // list of plugins that this java module is exporting exportedPluginJars android.Paths @@ -455,12 +439,38 @@ type Module struct { extraResources android.Paths hiddenAPI + dexer dexpreopter + usesLibrary + linter // list of the xref extraction files kytheFiles android.Paths - distFile android.Path + distFiles android.TaggedDistFiles + + // Collect the module directory for IDE info in java/jdeps.go. + modulePaths []string + + hideApexVariantFromMake bool +} + +func (j *Module) addHostProperties() { + j.AddProperties( + &j.properties, + &j.protoProperties, + &j.usesLibraryProperties, + ) +} + +func (j *Module) addHostAndDeviceProperties() { + j.addHostProperties() + j.AddProperties( + &j.deviceProperties, + &j.dexer.dexProperties, + &j.dexpreoptProperties, + &j.linter.properties, + ) } func (j *Module) OutputFiles(tag string) (android.Paths, error) { @@ -470,7 +480,10 @@ func (j *Module) OutputFiles(tag string) (android.Paths, error) { case ".jar": return android.Paths{j.implementationAndResourcesJar}, nil case ".proguard_map": - return android.Paths{j.proguardDictionary}, nil + if j.dexer.proguardDictionary.Valid() { + return android.Paths{j.dexer.proguardDictionary.Path()}, nil + } + return nil, fmt.Errorf("%q was requested, but no output file was found.", tag) default: return nil, fmt.Errorf("unsupported module reference tag %q", tag) } @@ -478,25 +491,31 @@ func (j *Module) OutputFiles(tag string) (android.Paths, error) { var _ android.OutputFileProducer = (*Module)(nil) -type Dependency interface { +// Methods that need to be implemented for a module that is added to apex java_libs property. +type ApexDependency interface { HeaderJars() android.Paths + ImplementationAndResourcesJars() android.Paths +} + +// Provides build path and install path to DEX jars. +type UsesLibraryDependency interface { + DexJarBuildPath() android.Path + DexJarInstallPath() android.Path +} + +type Dependency interface { + ApexDependency + UsesLibraryDependency ImplementationJars() android.Paths ResourceJars() android.Paths - ImplementationAndResourcesJars() android.Paths - DexJar() android.Path AidlIncludeDirs() android.Paths - ExportedSdkLibs() []string + ExportedSdkLibs() dexpreopt.LibraryPaths ExportedPlugins() (android.Paths, []string) SrcJarArgs() ([]string, android.Paths) BaseModuleName() string JacocoReportClassesFile() android.Path } -type SdkLibraryDependency interface { - SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths - SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths -} - type xref interface { XrefJavaFiles() android.Paths } @@ -506,7 +525,20 @@ func (j *Module) XrefJavaFiles() android.Paths { } func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) { - android.InitAndroidArchModule(module, hod, android.MultilibCommon) + initJavaModule(module, hod, false) +} + +func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) { + initJavaModule(module, hod, true) +} + +func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) { + multilib := android.MultilibCommon + if multiTargets { + android.InitAndroidMultiTargetsArchModule(module, hod, multilib) + } else { + android.InitAndroidArchModule(module, hod, multilib) + } android.InitDefaultableModule(module) } @@ -525,6 +557,7 @@ func IsJniDepTag(depTag blueprint.DependencyTag) bool { } var ( + dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} staticLibTag = dependencyTag{name: "staticlib"} libTag = dependencyTag{name: "javalib"} java9LibTag = dependencyTag{name: "java9lib"} @@ -533,13 +566,13 @@ var ( bootClasspathTag = dependencyTag{name: "bootclasspath"} systemModulesTag = dependencyTag{name: "system modules"} frameworkResTag = dependencyTag{name: "framework-res"} - frameworkApkTag = dependencyTag{name: "framework-apk"} kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"} kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations"} proguardRaiseTag = dependencyTag{name: "proguard-raise"} certificateTag = dependencyTag{name: "certificate"} instrumentationForTag = dependencyTag{name: "instrumentation_for"} usesLibTag = dependencyTag{name: "uses-library"} + extraLintCheckTag = dependencyTag{name: "extra-lint-check"} ) func IsLibDepTag(depTag blueprint.DependencyTag) bool { @@ -551,7 +584,7 @@ func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool { } type sdkDep struct { - useModule, useFiles, useDefaultLibs, invalidVersion bool + useModule, useFiles, invalidVersion bool // The modules that will be added to the bootclasspath when targeting 1.8 or lower bootclasspath []string @@ -560,7 +593,11 @@ type sdkDep struct { // modules are to be used. systemModules string + // The modules that will be added to the classpath regardless of the Java language level targeted + classpath []string + // The modules that will be added ot the classpath when targeting 1.9 or higher + // (normally these will be on the bootclasspath when targeting 1.8 or lower) java9Classpath []string frameworkResModule string @@ -580,14 +617,17 @@ func (s sdkDep) hasFrameworkLibs() bool { } type jniLib struct { - name string - path android.Path - target android.Target - coverageFile android.OptionalPath + name string + path android.Path + target android.Target + coverageFile android.OptionalPath + unstrippedFile android.Path } func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool { - return j.properties.Instrument && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") + return j.properties.Instrument && + ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") && + ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir()) } func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool { @@ -596,6 +636,22 @@ func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool { ctx.Config().UnbundledBuild()) } +func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool { + // Force enable the instrumentation for java code that is built for APEXes ... + // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent + // doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true. + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + isJacocoAgent := ctx.ModuleName() == "jacocoagent" + if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() { + if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { + return true + } else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { + return true + } + } + return false +} + func (j *Module) sdkVersion() sdkSpec { return sdkSpecFrom(String(j.deviceProperties.Sdk_version)) } @@ -632,30 +688,29 @@ func (j *Module) AvailableFor(what string) bool { return j.ApexModuleBase.AvailableFor(what) } +func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext sdkContext, d dexer) { + sdkDep := decodeSdkDep(ctx, sdkContext) + if sdkDep.useModule { + ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) + ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) + ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...) + if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { + ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...) + } + if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() { + ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...) + } + } + if sdkDep.systemModules != "" { + ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) + } +} + func (j *Module) deps(ctx android.BottomUpMutatorContext) { if ctx.Device() { - sdkDep := decodeSdkDep(ctx, sdkContext(j)) - if sdkDep.useDefaultLibs { - ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...) - ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules) - if sdkDep.hasFrameworkLibs() { - ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...) - } - } else if sdkDep.useModule { - ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) - ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) - ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) - if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { - ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...) - ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...) - } - } + j.linter.deps(ctx) - if ctx.ModuleName() == "android_stubs_current" || - ctx.ModuleName() == "android_system_stubs_current" || - ctx.ModuleName() == "android_test_stubs_current" { - ctx.AddVariationDependencies(nil, frameworkApkTag, "framework-res") - } + sdkDeps(ctx, sdkContext(j), j.dexer) } syspropPublicStubs := syspropPublicStubs(ctx.Config()) @@ -683,9 +738,21 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { return ret } - ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...) + libDeps := ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...) ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...) + // For library dependencies that are component libraries (like stubs), add the implementation + // as a dependency (dexpreopt needs to be against the implementation library, not stubs). + for _, dep := range libDeps { + if dep != nil { + if component, ok := dep.(SdkLibraryComponentDependency); ok { + if lib := component.OptionalSdkLibraryImplementation(); lib != nil { + ctx.AddVariationDependencies(nil, usesLibTag, *lib) + } + } + } + } + ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...) ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...) @@ -821,41 +888,47 @@ type linkTypeContext interface { } func (m *Module) getLinkType(name string) (ret linkType, stubs bool) { - ver := m.sdkVersion() - switch { - case name == "core.current.stubs" || name == "core.platform.api.stubs" || - name == "stub-annotations" || name == "private-stub-annotations-jar" || - name == "core-lambda-stubs" || name == "core-generated-annotation-stubs": + switch name { + case "core.current.stubs", "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs", + "stub-annotations", "private-stub-annotations-jar", + "core-lambda-stubs", "core-generated-annotation-stubs": return javaCore, true - case ver.kind == sdkCore: - return javaCore, false - case name == "android_system_stubs_current": + case "android_stubs_current": + return javaSdk, true + case "android_system_stubs_current": return javaSystem, true - case ver.kind == sdkSystem: - return javaSystem, false - case name == "android_test_stubs_current": + case "android_module_lib_stubs_current": + return javaModule, true + case "android_system_server_stubs_current": + return javaSystemServer, true + case "android_test_stubs_current": return javaSystem, true - case ver.kind == sdkTest: - return javaPlatform, false - case name == "android_stubs_current": - return javaSdk, true - case ver.kind == sdkPublic: + } + + if stub, linkType := moduleStubLinkType(name); stub { + return linkType, true + } + + ver := m.sdkVersion() + switch ver.kind { + case sdkCore: + return javaCore, false + case sdkSystem: + return javaSystem, false + case sdkPublic: return javaSdk, false - case name == "android_module_lib_stubs_current": - return javaModule, true - case ver.kind == sdkModule: + case sdkModule: return javaModule, false - case name == "android_system_server_stubs_current": - return javaSystemServer, true - case ver.kind == sdkSystemServer: + case sdkSystemServer: return javaSystemServer, false - case ver.kind == sdkPrivate || ver.kind == sdkNone || ver.kind == sdkCorePlatform: + case sdkPrivate, sdkNone, sdkCorePlatform, sdkTest: return javaPlatform, false - case !ver.valid(): + } + + if !ver.valid() { panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw)) - default: - return javaSdk, false } + return javaSdk, false } func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, tag dependencyTag) { @@ -943,7 +1016,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { case libTag: deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...) // names of sdk libs that are directly depended are exported - j.exportedSdkLibs = append(j.exportedSdkLibs, otherName) + j.exportedSdkLibs.MaybeAddLibraryPath(ctx, dep.OptionalImplicitSdkLibrary(), dep.DexJarBuildPath(), dep.DexJarInstallPath()) case staticLibTag: ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName) } @@ -954,7 +1027,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { case libTag, instrumentationForTag: deps.classpath = append(deps.classpath, dep.HeaderJars()...) // sdk lib names from dependencies are re-exported - j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...) + j.exportedSdkLibs.AddLibraryPaths(dep.ExportedSdkLibs()) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) pluginJars, pluginClasses := dep.ExportedPlugins() addPlugins(&deps, pluginJars, pluginClasses...) @@ -966,7 +1039,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...) deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...) // sdk lib names from dependencies are re-exported - j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...) + j.exportedSdkLibs.AddLibraryPaths(dep.ExportedSdkLibs()) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) pluginJars, pluginClasses := dep.ExportedPlugins() addPlugins(&deps, pluginJars, pluginClasses...) @@ -993,18 +1066,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { } else { ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName) } - case frameworkApkTag: - if ctx.ModuleName() == "android_stubs_current" || - ctx.ModuleName() == "android_system_stubs_current" || - ctx.ModuleName() == "android_test_stubs_current" { - // framework stubs.jar need to depend on framework-res.apk, in order to pull the - // resource files out of there for aapt. - // - // Normally the package rule runs aapt, which includes the resource, - // but we're not running that in our package rule so just copy in the - // resource files here. - deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage) - } case kotlinStdlibTag: deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars()...) case kotlinAnnotationsTag: @@ -1041,8 +1102,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { } }) - j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs) - return deps } @@ -1052,19 +1111,10 @@ func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) { } func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion { - sdk, err := sdkContext.sdkVersion().effectiveVersion(ctx) - if err != nil { - ctx.PropertyErrorf("sdk_version", "%s", err) - } if javaVersion != "" { return normalizeJavaVersion(ctx, javaVersion) - } else if ctx.Device() && sdk <= 23 { - return JAVA_VERSION_7 - } else if ctx.Device() && sdk <= 29 { - return JAVA_VERSION_8 - } else if ctx.Device() && ctx.Config().UnbundledBuildUsePrebuiltSdks() { - // TODO(b/142896162): once we have prebuilt system modules we can use 1.9 for unbundled builds - return JAVA_VERSION_8 + } else if ctx.Device() { + return sdkContext.sdkVersion().defaultJavaLanguageVersion(ctx) } else { return JAVA_VERSION_9 } @@ -1131,9 +1181,9 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB if flags.javaVersion.usesJavaModules() { javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...) } - if ctx.Config().MinimizeJavaDebugInfo() { - // Override the -g flag passed globally to remove local variable debug info to reduce - // disk and memory usage. + if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() { + // For non-host binaries, override the -g flag passed globally to remove + // local variable debug info to reduce disk and memory usage. javacFlags = append(javacFlags, "-g:source,lines") } javacFlags = append(javacFlags, "-Xlint:-dep-ann") @@ -1229,6 +1279,11 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags) } + kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil) + if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 { + ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files") + } + srcFiles = j.genSources(ctx, srcFiles, flags) srcJars := srcFiles.FilterByExt(".srcjar") @@ -1282,6 +1337,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // Collect .kt files for AIDEGen j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...) + j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...) flags.classpath = append(flags.classpath, deps.kotlinStdlib...) flags.classpath = append(flags.classpath, deps.kotlinAnnotations...) @@ -1292,15 +1348,17 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { if len(flags.processorPath) > 0 { // Use kapt for annotation processing kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar") - kotlinKapt(ctx, kaptSrcJar, kotlinSrcFiles, srcJars, flags) + kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar") + kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags) srcJars = append(srcJars, kaptSrcJar) + kotlinJars = append(kotlinJars, kaptResJar) // Disable annotation processing in javac, it's already been handled by kapt flags.processorPath = nil flags.processors = nil } kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName) - kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, srcJars, flags) + kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags) if ctx.Failed() { return } @@ -1308,9 +1366,11 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { // Make javac rule depend on the kotlinc rule flags.classpath = append(flags.classpath, kotlinJar) - // Jar kotlin classes into the final jar after javac kotlinJars = append(kotlinJars, kotlinJar) - kotlinJars = append(kotlinJars, deps.kotlinStdlib...) + // Jar kotlin classes into the final jar after javac + if BoolDefault(j.properties.Static_kotlin_stdlib, true) { + kotlinJars = append(kotlinJars, deps.kotlinStdlib...) + } } jars := append(android.Paths(nil), kotlinJars...) @@ -1444,13 +1504,19 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { serviceFile := file.String() zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile) } + rule := zip + args := map[string]string{ + "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "), + } + if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") { + rule = zipRE + args["implicits"] = strings.Join(services.Strings(), ",") + } ctx.Build(pctx, android.BuildParams{ - Rule: zip, + Rule: rule, Output: servicesJar, Implicits: services, - Args: map[string]string{ - "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "), - }, + Args: args, }) jars = append(jars, servicesJar) } @@ -1518,11 +1584,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.headerJarFile = j.implementationJarFile } - // Force enable the instrumentation for java code that is built for APEXes ... - // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent - // doesn't make sense) - isJacocoAgent := ctx.ModuleName() == "jacocoagent" - if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() { + if j.shouldInstrumentInApex(ctx) { j.properties.Instrument = true } @@ -1543,9 +1605,10 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.implementationAndResourcesJar = implementationAndResourcesJar // Enable dex compilation for the APEX variants, unless it is disabled explicitly - if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !j.IsForPlatform() { - if j.deviceProperties.Compile_dex == nil { - j.deviceProperties.Compile_dex = proptools.BoolPtr(true) + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if j.DirectlyInAnyApex() && !apexInfo.IsForPlatform() { + if j.dexProperties.Compile_dex == nil { + j.dexProperties.Compile_dex = proptools.BoolPtr(true) } if j.deviceProperties.Hostdex == nil { j.deviceProperties.Hostdex = proptools.BoolPtr(true) @@ -1553,17 +1616,27 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { } if ctx.Device() && j.hasCode(ctx) && - (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) { + (Bool(j.properties.Installable) || Bool(j.dexProperties.Compile_dex)) { + if j.shouldInstrumentStatic(ctx) { + j.dexer.extraProguardFlagFiles = append(j.dexer.extraProguardFlagFiles, + android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags")) + } // Dex compilation var dexOutputFile android.ModuleOutPath - dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName) + dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName) if ctx.Failed() { return } + configurationName := j.ConfigurationName() + primary := configurationName == ctx.ModuleName() + // If the prebuilt is being used rather than the from source, skip this + // module to prevent duplicated classes + primary = primary && !j.IsReplacedByPrebuilt() + // Hidden API CSV generation and dex encoding - dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile, - j.deviceProperties.UncompressDex) + dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, j.implementationJarFile, + proptools.Bool(j.dexProperties.Uncompress_dex)) // merge dex jar with resources if necessary if j.resourceJar != nil { @@ -1571,7 +1644,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName) TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{}, false, nil, nil) - if j.deviceProperties.UncompressDex { + if *j.dexProperties.Uncompress_dex { combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName) TransformZipAlign(ctx, combinedAlignedJar, combinedJar) dexOutputFile = combinedAlignedJar @@ -1596,6 +1669,31 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { outputFile = implementationAndResourcesJar } + if ctx.Device() { + lintSDKVersionString := func(sdkSpec sdkSpec) string { + if v := sdkSpec.version; v.isNumbered() { + return v.String() + } else { + return ctx.Config().DefaultAppTargetSdk(ctx).String() + } + } + + j.linter.name = ctx.ModuleName() + j.linter.srcs = srcFiles + j.linter.srcJars = srcJars + j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...) + j.linter.classes = j.implementationJarFile + j.linter.minSdkVersion = lintSDKVersionString(j.minSdkVersion()) + j.linter.targetSdkVersion = lintSDKVersionString(j.targetSdkVersion()) + j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion()) + j.linter.javaLanguageLevel = flags.javaVersion.String() + j.linter.kotlinLanguageLevel = "1.3" + if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() { + j.linter.buildModuleReportZip = true + } + j.linter.lint(ctx) + } + ctx.CheckbuildFile(outputFile) // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource @@ -1721,10 +1819,14 @@ func (j *Module) ImplementationJars() android.Paths { return android.Paths{j.implementationJarFile} } -func (j *Module) DexJar() android.Path { +func (j *Module) DexJarBuildPath() android.Path { return j.dexJarFile } +func (j *Module) DexJarInstallPath() android.Path { + return j.installFile +} + func (j *Module) ResourceJars() android.Paths { if j.resourceJar == nil { return nil @@ -1744,8 +1846,7 @@ func (j *Module) AidlIncludeDirs() android.Paths { return j.exportAidlIncludeDirs } -func (j *Module) ExportedSdkLibs() []string { - // exportedSdkLibs is type []string +func (j *Module) ExportedSdkLibs() dexpreopt.LibraryPaths { return j.exportedSdkLibs } @@ -1772,6 +1873,7 @@ func (j *Module) IDEInfo(dpInfo *android.IdeInfo) { if j.expandJarjarRules != nil { dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String()) } + dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...) } func (j *Module) CompilerDeps() []string { @@ -1790,10 +1892,33 @@ func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu return j.depIsInSameApex(ctx, dep) } +func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, + sdkVersion android.ApiLevel) error { + sdkSpec := j.minSdkVersion() + if !sdkSpec.specified() { + return fmt.Errorf("min_sdk_version is not specified") + } + if sdkSpec.kind == sdkCore { + return nil + } + ver, err := sdkSpec.effectiveVersion(ctx) + if err != nil { + return err + } + if ver.ApiLevel(ctx).GreaterThan(sdkVersion) { + return fmt.Errorf("newer SDK(%v)", ver) + } + return nil +} + func (j *Module) Stem() string { return proptools.StringDefault(j.deviceProperties.Stem, j.Name()) } +func (j *Module) ConfigurationName() string { + return proptools.StringDefault(j.deviceProperties.ConfigurationName, j.BaseModuleName()) +} + func (j *Module) JacocoReportClassesFile() android.Path { return j.jacocoReportClassesFile } @@ -1806,24 +1931,26 @@ func (j *Module) IsInstallable() bool { // Java libraries (.jar file) // -type LibraryProperties struct { - Dist struct { - // The tag of the output of this module that should be output. - Tag *string `android:"arch_variant"` - } `android:"arch_variant"` -} - type Library struct { Module - libraryProperties LibraryProperties - InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) } +// Provides access to the list of permitted packages from updatable boot jars. +type PermittedPackagesForUpdatableBootJars interface { + PermittedPackagesForUpdatableBootJars() []string +} + +var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil) + +func (j *Library) PermittedPackagesForUpdatableBootJars() []string { + return j.properties.Permitted_packages +} + func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { // Store uncompressed (and aligned) any dex files from jars in APEXes. - if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() { + if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { return true } @@ -1845,31 +1972,47 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo } func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if !apexInfo.IsForPlatform() { + j.hideApexVariantFromMake = true + } + j.checkSdkVersions(ctx) j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary - j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) - j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex + if j.dexProperties.Uncompress_dex == nil { + // If the value was not force-set by the user, use reasonable default based on the module. + j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter)) + } + j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex + j.exportedSdkLibs = make(dexpreopt.LibraryPaths) j.compile(ctx, nil) - exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform() + // Collect the module directory for IDE info in java/jdeps.go. + j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) + + exclusivelyForApex := !apexInfo.IsForPlatform() if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex { var extraInstallDeps android.Paths if j.InstallMixin != nil { extraInstallDeps = j.InstallMixin(ctx, j.outputFile) } j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), - ctx.ModuleName()+".jar", j.outputFile, extraInstallDeps...) + j.Stem()+".jar", j.outputFile, extraInstallDeps...) } - // Verify Dist.Tag is set to a supported output - if j.libraryProperties.Dist.Tag != nil { - distFiles, err := j.OutputFiles(*j.libraryProperties.Dist.Tag) - if err != nil { - ctx.PropertyErrorf("dist.tag", "%s", err.Error()) - } - j.distFile = distFiles[0] + // If this is a component library (stubs, etc.) for a java_sdk_library then + // add the name of that java_sdk_library to the exported sdk libs to make sure + // that, if necessary, a <uses-library> element for that java_sdk_library is + // added to the Android manifest. + j.exportedSdkLibs.MaybeAddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), j.DexJarBuildPath(), j.DexJarInstallPath()) + + // A non-SDK library may provide a <uses-library> (the name may be different from the module name). + if lib := proptools.String(j.usesLibraryProperties.Provides_uses_lib); lib != "" { + j.exportedSdkLibs.AddLibraryPath(ctx, lib, j.DexJarBuildPath(), j.DexJarInstallPath()) } + + j.distFiles = j.GenerateTaggedDistFiles(ctx) } func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -1986,12 +2129,9 @@ var javaHeaderLibsSdkMemberType android.SdkMemberType = &librarySdkMemberType{ func LibraryFactory() android.Module { module := &Library{} - module.AddProperties( - &module.Module.properties, - &module.Module.deviceProperties, - &module.Module.dexpreoptProperties, - &module.Module.protoProperties, - &module.libraryProperties) + module.addHostAndDeviceProperties() + + module.initModuleAndImport(&module.ModuleBase) android.InitApexModule(module) android.InitSdkAwareModule(module) @@ -2011,9 +2151,7 @@ func LibraryStaticFactory() android.Module { func LibraryHostFactory() android.Module { module := &Library{} - module.AddProperties( - &module.Module.properties, - &module.Module.protoProperties) + module.addHostProperties() module.Module.properties.Installable = proptools.BoolPtr(true) @@ -2026,6 +2164,12 @@ func LibraryHostFactory() android.Module { // Java Tests // +// Test option struct. +type TestOptions struct { + // a list of extra test configuration files that should be installed with the module. + Extra_test_configs []string `android:"path,arch_variant"` +} + type testProperties struct { // list of compatibility suites (for example "cts", "vts") that the module should be // installed into. @@ -2047,6 +2191,18 @@ type testProperties struct { // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true // explicitly. Auto_gen_config *bool + + // Add parameterized mainline modules to auto generated test config. The options will be + // handled by TradeFed to do downloading and installing the specified modules on the device. + Test_mainline_modules []string + + // Test options. + Test_options TestOptions +} + +type hostTestProperties struct { + // list of native binary modules that should be installed alongside the test + Data_native_bins []string `android:"arch_variant"` } type testHelperLibraryProperties struct { @@ -2070,8 +2226,15 @@ type Test struct { testProperties testProperties - testConfig android.Path - data android.Paths + testConfig android.Path + extraTestConfigs android.Paths + data android.Paths +} + +type TestHost struct { + Test + + testHostProperties hostTestProperties } type TestHelperLibrary struct { @@ -2086,13 +2249,31 @@ type JavaTestImport struct { prebuiltTestProperties prebuiltTestProperties testConfig android.Path + dexJarFile android.Path +} + +func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { + if len(j.testHostProperties.Data_native_bins) > 0 { + for _, target := range ctx.MultiTargets() { + ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...) + } + } + + j.deps(ctx) } func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, j.testProperties.Test_suites, j.testProperties.Auto_gen_config) + j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data) + j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs) + + ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) { + j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) + }) + j.Library.GenerateAndroidBuildActions(ctx) } @@ -2177,15 +2358,12 @@ func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, func TestFactory() android.Module { module := &Test{} - module.AddProperties( - &module.Module.properties, - &module.Module.deviceProperties, - &module.Module.dexpreoptProperties, - &module.Module.protoProperties, - &module.testProperties) + module.addHostAndDeviceProperties() + module.AddProperties(&module.testProperties) module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true + module.Module.linter.test = true InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -2195,15 +2373,12 @@ func TestFactory() android.Module { func TestHelperLibraryFactory() android.Module { module := &TestHelperLibrary{} - module.AddProperties( - &module.Module.properties, - &module.Module.deviceProperties, - &module.Module.dexpreoptProperties, - &module.Module.protoProperties, - &module.testHelperLibraryProperties) + module.addHostAndDeviceProperties() + module.AddProperties(&module.testHelperLibraryProperties) module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true + module.Module.linter.test = true InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -2239,16 +2414,15 @@ func JavaTestImportFactory() android.Module { // A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were // compiled against the host bootclasspath. func TestHostFactory() android.Module { - module := &Test{} + module := &TestHost{} - module.AddProperties( - &module.Module.properties, - &module.Module.protoProperties, - &module.testProperties) + module.addHostProperties() + module.AddProperties(&module.testProperties) + module.AddProperties(&module.testHostProperties) module.Module.properties.Installable = proptools.BoolPtr(true) - InitJavaModule(module, android.HostSupported) + InitJavaModuleMultiTargets(module, android.HostSupported) return module } @@ -2328,12 +2502,8 @@ func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { func BinaryFactory() android.Module { module := &Binary{} - module.AddProperties( - &module.Module.properties, - &module.Module.deviceProperties, - &module.Module.dexpreoptProperties, - &module.Module.protoProperties, - &module.binaryProperties) + module.addHostAndDeviceProperties() + module.AddProperties(&module.binaryProperties) module.Module.properties.Installable = proptools.BoolPtr(true) @@ -2349,10 +2519,8 @@ func BinaryFactory() android.Module { func BinaryHostFactory() android.Module { module := &Binary{} - module.AddProperties( - &module.Module.properties, - &module.Module.protoProperties, - &module.binaryProperties) + module.addHostProperties() + module.AddProperties(&module.binaryProperties) module.Module.properties.Installable = proptools.BoolPtr(true) @@ -2404,21 +2572,41 @@ type Import struct { // Functionality common to Module and Import. embeddableInModuleAndImport + hiddenAPI + dexer + properties ImportProperties + // output file containing classes.dex and resources + dexJarFile android.Path + combinedClasspathFile android.Path - exportedSdkLibs []string + exportedSdkLibs dexpreopt.LibraryPaths exportAidlIncludeDirs android.Paths + + hideApexVariantFromMake bool } func (j *Import) sdkVersion() sdkSpec { return sdkSpecFrom(String(j.properties.Sdk_version)) } +func (j *Import) makeSdkVersion() string { + return j.sdkVersion().raw +} + +func (j *Import) systemModules() string { + return "none" +} + func (j *Import) minSdkVersion() sdkSpec { return j.sdkVersion() } +func (j *Import) targetSdkVersion() sdkSpec { + return j.sdkVersion() +} + func (j *Import) MinSdkVersion() string { return j.minSdkVersion().version.String() } @@ -2445,9 +2633,17 @@ func (a *Import) JacocoReportClassesFile() android.Path { func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) + + if ctx.Device() && Bool(j.dexProperties.Compile_dex) { + sdkDeps(ctx, sdkContext(j), j.dexer) + } } func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { + if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() { + j.hideApexVariantFromMake = true + } + jars := android.PathsForModuleSrc(ctx, j.properties.Jars) jarName := j.Stem() + ".jar" @@ -2460,6 +2656,9 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { TransformJetifier(ctx, outputFile, inputFile) } j.combinedClasspathFile = outputFile + j.exportedSdkLibs = make(dexpreopt.LibraryPaths) + + var flags javaBuilderFlags ctx.VisitDirectDeps(func(module android.Module) { otherName := ctx.OtherModuleName(module) @@ -2469,27 +2668,75 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { case Dependency: switch tag { case libTag, staticLibTag: + flags.classpath = append(flags.classpath, dep.HeaderJars()...) // sdk lib names from dependencies are re-exported - j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...) + j.exportedSdkLibs.AddLibraryPaths(dep.ExportedSdkLibs()) + case bootClasspathTag: + flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars()...) } case SdkLibraryDependency: switch tag { case libTag: + flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...) // names of sdk libs that are directly depended are exported - j.exportedSdkLibs = append(j.exportedSdkLibs, otherName) + j.exportedSdkLibs.AddLibraryPath(ctx, otherName, dep.DexJarBuildPath(), dep.DexJarInstallPath()) } } }) - j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs) + var installFile android.Path if Bool(j.properties.Installable) { - ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), + installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), jarName, outputFile) } + // If this is a component library (impl, stubs, etc.) for a java_sdk_library then + // add the name of that java_sdk_library to the exported sdk libs to make sure + // that, if necessary, a <uses-library> element for that java_sdk_library is + // added to the Android manifest. + j.exportedSdkLibs.MaybeAddLibraryPath(ctx, j.OptionalImplicitSdkLibrary(), outputFile, installFile) + j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) + + if ctx.Device() && Bool(j.dexProperties.Compile_dex) { + sdkDep := decodeSdkDep(ctx, sdkContext(j)) + if sdkDep.invalidVersion { + ctx.AddMissingDependencies(sdkDep.bootclasspath) + ctx.AddMissingDependencies(sdkDep.java9Classpath) + } else if sdkDep.useFiles { + // sdkDep.jar is actually equivalent to turbine header.jar. + flags.classpath = append(flags.classpath, sdkDep.jars...) + } + + // Dex compilation + var dexOutputFile android.ModuleOutPath + dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName) + if ctx.Failed() { + return + } + + configurationName := j.BaseModuleName() + primary := j.Prebuilt().UsePrebuilt() + + // Hidden API CSV generation and dex encoding + dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, outputFile, + proptools.Bool(j.dexProperties.Uncompress_dex)) + + j.dexJarFile = dexOutputFile + } +} + +func (j *Import) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case ".jar": + return android.Paths{j.combinedClasspathFile}, nil + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) + } } +var _ android.OutputFileProducer = (*Import)(nil) + var _ Dependency = (*Import)(nil) func (j *Import) HeaderJars() android.Paths { @@ -2517,7 +2764,11 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths { return android.Paths{j.combinedClasspathFile} } -func (j *Import) DexJar() android.Path { +func (j *Import) DexJarBuildPath() android.Path { + return j.dexJarFile +} + +func (j *Import) DexJarInstallPath() android.Path { return nil } @@ -2525,7 +2776,7 @@ func (j *Import) AidlIncludeDirs() android.Paths { return j.exportAidlIncludeDirs } -func (j *Import) ExportedSdkLibs() []string { +func (j *Import) ExportedSdkLibs() dexpreopt.LibraryPaths { return j.exportedSdkLibs } @@ -2541,6 +2792,12 @@ func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu return j.depIsInSameApex(ctx, dep) } +func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, + sdkVersion android.ApiLevel) error { + // Do not check for prebuilts against the min_sdk_version of enclosing APEX + return nil +} + // Add compile time check for interface implementation var _ android.IDEInfo = (*Import)(nil) var _ android.IDECustomizedModuleName = (*Import)(nil) @@ -2577,7 +2834,14 @@ var _ android.PrebuiltInterface = (*Import)(nil) func ImportFactory() android.Module { module := &Import{} - module.AddProperties(&module.properties) + module.AddProperties( + &module.properties, + &module.dexer.dexProperties, + ) + + module.initModuleAndImport(&module.ModuleBase) + + module.dexProperties.Optimize.EnabledByDefault = false android.InitPrebuiltModule(module, &module.properties.Jars) android.InitApexModule(module) @@ -2623,6 +2887,8 @@ type DexImport struct { maybeStrippedDexJarFile android.Path dexpreopter + + hideApexVariantFromMake bool } func (j *DexImport) Prebuilt() *android.Prebuilt { @@ -2641,6 +2907,14 @@ func (j *DexImport) Stem() string { return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) } +func (a *DexImport) JacocoReportClassesFile() android.Path { + return nil +} + +func (a *DexImport) LintDepSets() LintDepSets { + return LintDepSets{} +} + func (j *DexImport) IsInstallable() bool { return true } @@ -2650,6 +2924,11 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.PropertyErrorf("jars", "exactly one jar must be provided") } + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if !apexInfo.IsForPlatform() { + j.hideApexVariantFromMake = true + } + j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) @@ -2694,14 +2973,22 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.maybeStrippedDexJarFile = dexOutputFile - ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), - ctx.ModuleName()+".jar", dexOutputFile) + if apexInfo.IsForPlatform() { + ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), + j.Stem()+".jar", dexOutputFile) + } } -func (j *DexImport) DexJar() android.Path { +func (j *DexImport) DexJarBuildPath() android.Path { return j.dexJarFile } +func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, + sdkVersion android.ApiLevel) error { + // we don't check prebuilt modules for sdk_version + return nil +} + // dex_import imports a `.jar` file containing classes.dex files. // // A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed @@ -2767,6 +3054,7 @@ func DefaultsFactory() android.Module { module.AddProperties( &CompilerProperties{}, &CompilerDeviceProperties{}, + &DexProperties{}, &DexpreoptProperties{}, &android.ProtoProperties{}, &aaptProperties{}, @@ -2774,6 +3062,7 @@ func DefaultsFactory() android.Module { &appProperties{}, &appTestProperties{}, &overridableAppProperties{}, + &testProperties{}, &ImportProperties{}, &AARImportProperties{}, &sdkLibraryProperties{}, @@ -2781,6 +3070,7 @@ func DefaultsFactory() android.Module { &DexImportProperties{}, &android.ApexProperties{}, &RuntimeResourceOverlayProperties{}, + &LintProperties{}, ) android.InitDefaultsModule(module) @@ -2803,11 +3093,7 @@ func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonC }) // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets if len(xrefTargets) > 0 { - ctx.Build(pctx, android.BuildParams{ - Rule: blueprint.Phony, - Output: android.PathForPhony(ctx, "xref_java"), - Inputs: xrefTargets, - }) + ctx.Phony("xref_java", xrefTargets...) } } |