diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 158 | 
1 files changed, 125 insertions, 33 deletions
| diff --git a/java/java.go b/java/java.go index f684a00e7..59ec94d5b 100644 --- a/java/java.go +++ b/java/java.go @@ -40,20 +40,55 @@ func init() {  	// Register sdk member types.  	android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) +	// Register java implementation libraries for use only in module_exports (not sdk).  	android.RegisterSdkMemberType(&librarySdkMemberType{  		android.SdkMemberTypeBase{  			PropertyName: "java_libs",  		}, -		func(j *Library) android.Path { +		func(_ android.SdkMemberContext, j *Library) android.Path {  			implementationJars := j.ImplementationAndResourcesJars()  			if len(implementationJars) != 1 {  				panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))  			} -  			return implementationJars[0]  		}, +		sdkSnapshotFilePathForJar, +		copyEverythingToSnapshot, +	}) + +	// Register java boot libraries for use in sdk. +	// +	// The build has some implicit dependencies (via the boot jars configuration) on a number of +	// modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are +	// provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise +	// used outside those mainline modules. +	// +	// As they are not needed outside the mainline modules adding them to the sdk/module-exports as +	// either java_libs, or java_header_libs would end up exporting more information than was strictly +	// necessary. The java_boot_libs property to allow those modules to be exported as part of the +	// sdk/module_exports without exposing any unnecessary information. +	android.RegisterSdkMemberType(&librarySdkMemberType{ +		android.SdkMemberTypeBase{ +			PropertyName: "java_boot_libs", +			SupportsSdk:  true, +		}, +		func(ctx android.SdkMemberContext, j *Library) android.Path { +			// Java boot libs are only provided in the SDK to provide access to their dex implementation +			// jar for use by dexpreopting and boot jars package check. They do not need to provide an +			// actual implementation jar but the java_import will need a file that exists so just copy an +			// empty file. Any attempt to use that file as a jar will cause a build error. +			return ctx.SnapshotBuilder().EmptyFile() +		}, +		func(osPrefix, name string) string { +			// Create a special name for the implementation jar to try and provide some useful information +			// to a developer that attempts to compile against this. +			// TODO(b/175714559): Provide a proper error message in Soong not ninja. +			return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) +		}, +		onlyCopyJarToSnapshot,  	}) +	// Register java test libraries for use only in module_exports (not sdk).  	android.RegisterSdkMemberType(&testSdkMemberType{  		SdkMemberTypeBase: android.SdkMemberTypeBase{  			PropertyName: "java_tests", @@ -2165,9 +2200,22 @@ type librarySdkMemberType struct {  	// Function to retrieve the appropriate output jar (implementation or header) from  	// the library. -	jarToExportGetter func(j *Library) android.Path +	jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path + +	// Function to compute the snapshot relative path to which the named library's +	// jar should be copied. +	snapshotPathGetter func(osPrefix, name string) string + +	// True if only the jar should be copied to the snapshot, false if the jar plus any additional +	// files like aidl files should also be copied. +	onlyCopyJarToSnapshot bool  } +const ( +	onlyCopyJarToSnapshot    = true +	copyEverythingToSnapshot = false +) +  func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {  	mctx.AddVariationDependencies(nil, dependencyTag, names...)  } @@ -2195,21 +2243,32 @@ type librarySdkMemberProperties struct {  func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {  	j := variant.(*Library) -	p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(j) +	p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) +  	p.AidlIncludeDirs = j.AidlIncludeDirs()  }  func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {  	builder := ctx.SnapshotBuilder() +	memberType := ctx.MemberType().(*librarySdkMemberType) +  	exportedJar := p.JarToExport  	if exportedJar != nil { -		snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name()) +		// Delegate the creation of the snapshot relative path to the member type. +		snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(p.OsPrefix(), ctx.Name()) + +		// Copy the exported jar to the snapshot.  		builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)  		propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})  	} +	// Do not copy anything else to the snapshot. +	if memberType.onlyCopyJarToSnapshot { +		return +	} +  	aidlIncludeDirs := p.AidlIncludeDirs  	if len(aidlIncludeDirs) != 0 {  		sdkModuleContext := ctx.SdkModuleContext() @@ -2230,7 +2289,7 @@ var javaHeaderLibsSdkMemberType android.SdkMemberType = &librarySdkMemberType{  		PropertyName: "java_header_libs",  		SupportsSdk:  true,  	}, -	func(j *Library) android.Path { +	func(_ android.SdkMemberContext, j *Library) android.Path {  		headerJars := j.HeaderJars()  		if len(headerJars) != 1 {  			panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) @@ -2238,6 +2297,8 @@ var javaHeaderLibsSdkMemberType android.SdkMemberType = &librarySdkMemberType{  		return headerJars[0]  	}, +	sdkSnapshotFilePathForJar, +	copyEverythingToSnapshot,  }  // java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well. @@ -2770,6 +2831,10 @@ func (a *Import) JacocoReportClassesFile() android.Path {  	return nil  } +func (j *Import) LintDepSets() LintDepSets { +	return LintDepSets{} +} +  func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {  	ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) @@ -2798,6 +2863,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {  	j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)  	var flags javaBuilderFlags +	var deapexerModule android.Module  	ctx.VisitDirectDeps(func(module android.Module) {  		tag := ctx.OtherModuleDependencyTag(module) @@ -2818,6 +2884,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {  		}  		addCLCFromDep(ctx, module, j.classLoaderContexts) + +		// Save away the `deapexer` module on which this depends, if any. +		if tag == android.DeapexerTag { +			deapexerModule = module +		}  	})  	if Bool(j.properties.Installable) { @@ -2827,39 +2898,60 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {  	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...) -		} +	if ctx.Device() { +		// If this is a variant created for a prebuilt_apex then use the dex implementation jar +		// obtained from the associated deapexer module. +		ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) +		if ai.ForPrebuiltApex { +			if deapexerModule == nil { +				// This should never happen as a variant for a prebuilt_apex is only created if the +				// deapxer module has been configured to export the dex implementation jar for this module. +				ctx.ModuleErrorf("internal error: module %q does not depend on a `deapexer` module for prebuilt_apex %q", +					j.Name(), ai.ApexVariationName) +			} -		// Dex compilation +			// Get the path of the dex implementation jar from the `deapexer` module. +			di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) +			j.dexJarFile = di.PrebuiltExportPath(j.BaseModuleName(), ".dexjar") +			if j.dexJarFile == nil { +				// This should never happen as a variant for a prebuilt_apex is only created if the +				// prebuilt_apex has been configured to export the java library dex file. +				ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name()) +			} +		} else if 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...) +			} -		j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", jarName) -		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 +			// Dex compilation -		var dexOutputFile android.ModuleOutPath -		dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName) -		if ctx.Failed() { -			return -		} +			j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", jarName) +			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 -		configurationName := j.BaseModuleName() -		primary := j.Prebuilt().UsePrebuilt() +			var dexOutputFile android.ModuleOutPath +			dexOutputFile = j.dexer.compileDex(ctx, flags, j.minSdkVersion(), outputFile, jarName) +			if ctx.Failed() { +				return +			} -		// Hidden API CSV generation and dex encoding -		dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, outputFile, -			proptools.Bool(j.dexProperties.Uncompress_dex)) +			configurationName := j.BaseModuleName() +			primary := j.Prebuilt().UsePrebuilt() -		j.dexJarFile = dexOutputFile +			// 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 +		}  	}  } |