diff options
35 files changed, 543 insertions, 335 deletions
diff --git a/Android.bp b/Android.bp index d71bcecd8..34f9bf012 100644 --- a/Android.bp +++ b/Android.bp @@ -142,6 +142,14 @@ all_apex_contributions { visibility: ["//visibility:public"], } +// Defaults to share configs between "baremetal" Soong modules, currently only +// used for code running in kernel context within Android Virtualization +// Framework guests. +cc_defaults { + name: "cc_baremetal_defaults", + defaults_visibility: ["//visibility:public"], +} + product_config { name: "product_config", visibility: [ diff --git a/android/arch.go b/android/arch.go index 1ec971d15..3cd6e4b7a 100644 --- a/android/arch.go +++ b/android/arch.go @@ -567,10 +567,6 @@ var DarwinUniversalVariantTag = archDepTag{name: "darwin universal binary"} // "32": compile for only a single 32-bit Target supported by the OsClass. // "64": compile for only a single 64-bit Target supported by the OsClass. // "common": compile a for a single Target that will work on all Targets supported by the OsClass (for example Java). -// "common_first": compile a for a Target that will work on all Targets supported by the OsClass -// (same as "common"), plus a second Target for the preferred Target supported by the OsClass -// (same as "first"). This is used for java_binary that produces a common .jar and a wrapper -// executable script. // // Once the list of Targets is determined, the module is split into a variant for each Target. // @@ -702,11 +698,9 @@ func (a *archTransitionMutator) IncomingTransition(ctx IncomingTransitionContext return "" } - if incomingVariation == "" { - multilib, _ := decodeMultilib(ctx, base) - if multilib == "common" { - return "common" - } + multilib, _ := decodeMultilib(ctx, base) + if multilib == "common" { + return "common" } return incomingVariation } @@ -756,8 +750,7 @@ func (a *archTransitionMutator) Mutate(ctx BottomUpMutatorContext, variation str // Create a dependency for Darwin Universal binaries from the primary to secondary // architecture. The module itself will be responsible for calling lipo to merge the outputs. if os == Darwin { - isUniversalBinary := (allArchInfo.Multilib == "darwin_universal" && len(allArchInfo.Targets) == 2) || - allArchInfo.Multilib == "darwin_universal_common_first" && len(allArchInfo.Targets) == 3 + isUniversalBinary := allArchInfo.Multilib == "darwin_universal" && len(allArchInfo.Targets) == 2 isPrimary := variation == ctx.Config().BuildArch.String() hasSecondaryConfigured := len(ctx.Config().Targets[Darwin]) > 1 if isUniversalBinary && isPrimary && hasSecondaryConfigured { @@ -825,11 +818,7 @@ func decodeMultilib(ctx ConfigContext, base *ModuleBase) (multilib, extraMultili // !UseTargetVariants, as the module has opted into handling the arch-specific logic on // its own. if os == Darwin && multilib != "common" && multilib != "32" { - if multilib == "common_first" { - multilib = "darwin_universal_common_first" - } else { - multilib = "darwin_universal" - } + multilib = "darwin_universal" } return multilib, "" @@ -1369,7 +1358,7 @@ func GetCompoundTargetField(os OsType, arch ArchType) string { // Returns the structs corresponding to the properties specific to the given // architecture and OS in archProperties. -func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch Arch, os OsType, nativeBridgeEnabled bool) []reflect.Value { +func getArchProperties(ctx BaseModuleContext, archProperties interface{}, arch Arch, os OsType, nativeBridgeEnabled bool) []reflect.Value { result := make([]reflect.Value, 0) archPropValues := reflect.ValueOf(archProperties).Elem() @@ -1941,13 +1930,6 @@ func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([] switch multilib { case "common": buildTargets = getCommonTargets(targets) - case "common_first": - buildTargets = getCommonTargets(targets) - if prefer32 { - buildTargets = append(buildTargets, FirstTarget(targets, "lib32", "lib64")...) - } else { - buildTargets = append(buildTargets, FirstTarget(targets, "lib64", "lib32")...) - } case "both": if prefer32 { buildTargets = append(buildTargets, filterMultilibTargets(targets, "lib32")...) @@ -1978,10 +1960,6 @@ func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([] // Reverse the targets so that the first architecture can depend on the second // architecture module in order to merge the outputs. ReverseSliceInPlace(buildTargets) - case "darwin_universal_common_first": - archTargets := filterMultilibTargets(targets, "lib64") - ReverseSliceInPlace(archTargets) - buildTargets = append(getCommonTargets(targets), archTargets...) default: return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", "prefer32" or "first_prefer32" found %q`, multilib) diff --git a/android/defaults.go b/android/defaults.go index 3d06c69c9..8fe28796e 100644 --- a/android/defaults.go +++ b/android/defaults.go @@ -274,7 +274,7 @@ func (defaultable *DefaultableModuleBase) applyDefaultProperties(ctx BottomUpMut func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) { ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel() - ctx.BottomUp("defaults", defaultsMutator).Parallel() + ctx.BottomUp("defaults", defaultsMutator).Parallel().UsesCreateModule() } func defaultsDepsMutator(ctx BottomUpMutatorContext) { diff --git a/android/early_module_context.go b/android/early_module_context.go index 11de77146..9b1a9ea7e 100644 --- a/android/early_module_context.go +++ b/android/early_module_context.go @@ -29,7 +29,7 @@ type EarlyModuleContext interface { Module() Module // ModuleName returns the name of the module. This is generally the value that was returned by Module.Name() when - // the module was created, but may have been modified by calls to BaseMutatorContext.Rename. + // the module was created, but may have been modified by calls to BottomUpMutatorContext.Rename. ModuleName() string // ModuleDir returns the path to the directory that contains the definition of the module. diff --git a/android/module.go b/android/module.go index 142cffa99..8415118cb 100644 --- a/android/module.go +++ b/android/module.go @@ -605,10 +605,9 @@ type hostCrossProperties struct { type Multilib string const ( - MultilibBoth Multilib = "both" - MultilibFirst Multilib = "first" - MultilibCommon Multilib = "common" - MultilibCommonFirst Multilib = "common_first" + MultilibBoth Multilib = "both" + MultilibFirst Multilib = "first" + MultilibCommon Multilib = "common" ) type HostOrDeviceSupported int diff --git a/android/mutator.go b/android/mutator.go index 8265458ba..0da3ec7d0 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -192,25 +192,10 @@ func FinalDepsMutators(f RegisterMutatorFunc) { finalDeps = append(finalDeps, f) } -type BaseMutatorContext interface { - BaseModuleContext - - // MutatorName returns the name that this mutator was registered with. - MutatorName() string - - // Rename all variants of a module. The new name is not visible to calls to ModuleName, - // AddDependency or OtherModuleName until after this mutator pass is complete. - Rename(name string) - - // CreateModule creates a new module by calling the factory method for the specified moduleType, and applies - // the specified property structs to it as if the properties were set in a blueprint file. - CreateModule(ModuleFactory, ...interface{}) Module -} - type TopDownMutator func(TopDownMutatorContext) type TopDownMutatorContext interface { - BaseMutatorContext + BaseModuleContext } type topDownMutatorContext struct { @@ -221,7 +206,7 @@ type topDownMutatorContext struct { type BottomUpMutator func(BottomUpMutatorContext) type BottomUpMutatorContext interface { - BaseMutatorContext + BaseModuleContext // AddDependency adds a dependency to the given module. It returns a slice of modules for each // dependency (some entries may be nil). @@ -236,7 +221,8 @@ type BottomUpMutatorContext interface { // Does not affect the ordering of the current mutator pass, but will be ordered // correctly for all future mutator passes. All reverse dependencies for a destination module are // collected until the end of the mutator pass, sorted by name, and then appended to the destination - // module's dependency list. + // module's dependency list. May only be called by mutators that were marked with + // UsesReverseDependencies during registration. AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) // AddVariationDependencies adds deps as dependencies of the current module, but uses the variations @@ -250,14 +236,15 @@ type BottomUpMutatorContext interface { // be ordered correctly for all future mutator passes. AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module - // AddReverseVariationDependencies adds a dependency from the named module to the current + // AddReverseVariationDependency adds a dependency from the named module to the current // module. The given variations will be added to the current module's varations, and then the // result will be used to find the correct variation of the depending module, which must exist. // // Does not affect the ordering of the current mutator pass, but will be ordered // correctly for all future mutator passes. All reverse dependencies for a destination module are // collected until the end of the mutator pass, sorted by name, and then appended to the destination - // module's dependency list. + // module's dependency list. May only be called by mutators that were marked with + // UsesReverseDependencies during registration. AddReverseVariationDependency([]blueprint.Variation, blueprint.DependencyTag, string) // AddFarVariationDependencies adds deps as dependencies of the current module, but uses the @@ -277,14 +264,26 @@ type BottomUpMutatorContext interface { // ReplaceDependencies finds all the variants of the module with the specified name, then // replaces all dependencies onto those variants with the current variant of this module. - // Replacements don't take effect until after the mutator pass is finished. + // Replacements don't take effect until after the mutator pass is finished. May only + // be called by mutators that were marked with UsesReplaceDependencies during registration. ReplaceDependencies(string) // ReplaceDependenciesIf finds all the variants of the module with the specified name, then // replaces all dependencies onto those variants with the current variant of this module // as long as the supplied predicate returns true. - // Replacements don't take effect until after the mutator pass is finished. + // Replacements don't take effect until after the mutator pass is finished. May only + // be called by mutators that were marked with UsesReplaceDependencies during registration. ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate) + + // Rename all variants of a module. The new name is not visible to calls to ModuleName, + // AddDependency or OtherModuleName until after this mutator pass is complete. May only be called + // by mutators that were marked with UsesRename during registration. + Rename(name string) + + // CreateModule creates a new module by calling the factory method for the specified moduleType, and applies + // the specified property structs to it as if the properties were set in a blueprint file. May only + // be called by mutators that were marked with UsesCreateModule during registration. + CreateModule(ModuleFactory, ...interface{}) Module } // An outgoingTransitionContextImpl and incomingTransitionContextImpl is created for every dependency of every module @@ -627,13 +626,60 @@ func (mutator *mutator) register(ctx *Context) { } else if mutator.transitionMutator != nil { blueprintCtx.RegisterTransitionMutator(mutator.name, mutator.transitionMutator) } + + // Forward booleans set on the MutatorHandle to the blueprint.MutatorHandle. if mutator.parallel { handle.Parallel() } + if mutator.usesRename { + handle.UsesRename() + } + if mutator.usesReverseDependencies { + handle.UsesReverseDependencies() + } + if mutator.usesReplaceDependencies { + handle.UsesReplaceDependencies() + } + if mutator.usesCreateModule { + handle.UsesCreateModule() + } + if mutator.mutatesDependencies { + handle.MutatesDependencies() + } + if mutator.mutatesGlobalState { + handle.MutatesGlobalState() + } } type MutatorHandle interface { + // Parallel sets the mutator to visit modules in parallel while maintaining ordering. Calling any + // method on the mutator context is thread-safe, but the mutator must handle synchronization + // for any modifications to global state or any modules outside the one it was invoked on. Parallel() MutatorHandle + + // UsesRename marks the mutator as using the BottomUpMutatorContext.Rename method, which prevents + // coalescing adjacent mutators into a single mutator pass. + UsesRename() MutatorHandle + + // UsesReverseDependencies marks the mutator as using the BottomUpMutatorContext.AddReverseDependency + // method, which prevents coalescing adjacent mutators into a single mutator pass. + UsesReverseDependencies() MutatorHandle + + // UsesReplaceDependencies marks the mutator as using the BottomUpMutatorContext.ReplaceDependencies + // method, which prevents coalescing adjacent mutators into a single mutator pass. + UsesReplaceDependencies() MutatorHandle + + // UsesCreateModule marks the mutator as using the BottomUpMutatorContext.CreateModule method, + // which prevents coalescing adjacent mutators into a single mutator pass. + UsesCreateModule() MutatorHandle + + // MutatesDependencies marks the mutator as modifying properties in dependencies, which prevents + // coalescing adjacent mutators into a single mutator pass. + MutatesDependencies() MutatorHandle + + // MutatesGlobalState marks the mutator as modifying global state, which prevents coalescing + // adjacent mutators into a single mutator pass. + MutatesGlobalState() MutatorHandle } func (mutator *mutator) Parallel() MutatorHandle { @@ -641,6 +687,36 @@ func (mutator *mutator) Parallel() MutatorHandle { return mutator } +func (mutator *mutator) UsesRename() MutatorHandle { + mutator.usesRename = true + return mutator +} + +func (mutator *mutator) UsesReverseDependencies() MutatorHandle { + mutator.usesReverseDependencies = true + return mutator +} + +func (mutator *mutator) UsesReplaceDependencies() MutatorHandle { + mutator.usesReplaceDependencies = true + return mutator +} + +func (mutator *mutator) UsesCreateModule() MutatorHandle { + mutator.usesCreateModule = true + return mutator +} + +func (mutator *mutator) MutatesDependencies() MutatorHandle { + mutator.mutatesDependencies = true + return mutator +} + +func (mutator *mutator) MutatesGlobalState() MutatorHandle { + mutator.mutatesGlobalState = true + return mutator +} + func RegisterComponentsMutator(ctx RegisterMutatorsContext) { ctx.BottomUp("component-deps", componentDepsMutator).Parallel() } @@ -660,7 +736,7 @@ func depsMutator(ctx BottomUpMutatorContext) { } func registerDepsMutator(ctx RegisterMutatorsContext) { - ctx.BottomUp("deps", depsMutator).Parallel() + ctx.BottomUp("deps", depsMutator).Parallel().UsesReverseDependencies() } // android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that @@ -669,32 +745,6 @@ func registerDepsMutator(ctx RegisterMutatorsContext) { // non-overridden method has to be forwarded. There are fewer non-overridden methods, so use the latter. The following // methods forward to the identical blueprint versions for topDownMutatorContext and bottomUpMutatorContext. -func (t *topDownMutatorContext) MutatorName() string { - return t.bp.MutatorName() -} - -func (t *topDownMutatorContext) Rename(name string) { - t.bp.Rename(name) - t.Module().base().commonProperties.DebugName = name -} - -func (t *topDownMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module { - return t.bp.CreateModule(factory, name, props...) -} - -func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module { - return createModule(t, factory, "_topDownMutatorModule", props...) -} - -func (t *topDownMutatorContext) createModuleWithoutInheritance(factory ModuleFactory, props ...interface{}) Module { - module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), "", props...).(Module) - return module -} - -func (b *bottomUpMutatorContext) MutatorName() string { - return b.bp.MutatorName() -} - func (b *bottomUpMutatorContext) Rename(name string) { b.bp.Rename(name) b.Module().base().commonProperties.DebugName = name diff --git a/android/mutator_test.go b/android/mutator_test.go index 5d4074a54..33fca9e8b 100644 --- a/android/mutator_test.go +++ b/android/mutator_test.go @@ -134,10 +134,6 @@ func TestModuleString(t *testing.T) { return []string{"a", "b"} }, }) - ctx.TopDown("rename_top_down", func(ctx TopDownMutatorContext) { - moduleStrings = append(moduleStrings, ctx.Module().String()) - ctx.Rename(ctx.Module().base().Name() + "_renamed1") - }) }) ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { @@ -161,8 +157,8 @@ func TestModuleString(t *testing.T) { }) ctx.BottomUp("rename_bottom_up", func(ctx BottomUpMutatorContext) { moduleStrings = append(moduleStrings, ctx.Module().String()) - ctx.Rename(ctx.Module().base().Name() + "_renamed2") - }) + ctx.Rename(ctx.Module().base().Name() + "_renamed1") + }).UsesRename() ctx.BottomUp("final", func(ctx BottomUpMutatorContext) { moduleStrings = append(moduleStrings, ctx.Module().String()) }) @@ -181,17 +177,23 @@ func TestModuleString(t *testing.T) { "foo{pre_arch:b}", "foo{pre_arch:a}", - // After rename_top_down (reversed because pre_deps TransitionMutator.Split is TopDown). - "foo_renamed1{pre_arch:b}", - "foo_renamed1{pre_arch:a}", - // After pre_deps (reversed because post_deps TransitionMutator.Split is TopDown). - "foo_renamed1{pre_arch:b,pre_deps:d}", - "foo_renamed1{pre_arch:b,pre_deps:c}", - "foo_renamed1{pre_arch:a,pre_deps:d}", - "foo_renamed1{pre_arch:a,pre_deps:c}", + "foo{pre_arch:b,pre_deps:d}", + "foo{pre_arch:b,pre_deps:c}", + "foo{pre_arch:a,pre_deps:d}", + "foo{pre_arch:a,pre_deps:c}", // After post_deps. + "foo{pre_arch:a,pre_deps:c,post_deps:e}", + "foo{pre_arch:a,pre_deps:c,post_deps:f}", + "foo{pre_arch:a,pre_deps:d,post_deps:e}", + "foo{pre_arch:a,pre_deps:d,post_deps:f}", + "foo{pre_arch:b,pre_deps:c,post_deps:e}", + "foo{pre_arch:b,pre_deps:c,post_deps:f}", + "foo{pre_arch:b,pre_deps:d,post_deps:e}", + "foo{pre_arch:b,pre_deps:d,post_deps:f}", + + // After rename_bottom_up. "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:e}", "foo_renamed1{pre_arch:a,pre_deps:c,post_deps:f}", "foo_renamed1{pre_arch:a,pre_deps:d,post_deps:e}", @@ -200,16 +202,6 @@ func TestModuleString(t *testing.T) { "foo_renamed1{pre_arch:b,pre_deps:c,post_deps:f}", "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:e}", "foo_renamed1{pre_arch:b,pre_deps:d,post_deps:f}", - - // After rename_bottom_up. - "foo_renamed2{pre_arch:a,pre_deps:c,post_deps:e}", - "foo_renamed2{pre_arch:a,pre_deps:c,post_deps:f}", - "foo_renamed2{pre_arch:a,pre_deps:d,post_deps:e}", - "foo_renamed2{pre_arch:a,pre_deps:d,post_deps:f}", - "foo_renamed2{pre_arch:b,pre_deps:c,post_deps:e}", - "foo_renamed2{pre_arch:b,pre_deps:c,post_deps:f}", - "foo_renamed2{pre_arch:b,pre_deps:d,post_deps:e}", - "foo_renamed2{pre_arch:b,pre_deps:d,post_deps:f}", } AssertDeepEquals(t, "module String() values", want, moduleStrings) diff --git a/android/namespace.go b/android/namespace.go index ebf85a1fd..866d12594 100644 --- a/android/namespace.go +++ b/android/namespace.go @@ -457,7 +457,7 @@ func NamespaceFactory() Module { } func RegisterNamespaceMutator(ctx RegisterMutatorsContext) { - ctx.BottomUp("namespace_deps", namespaceMutator).Parallel() + ctx.BottomUp("namespace_deps", namespaceMutator).Parallel().MutatesGlobalState() } func namespaceMutator(ctx BottomUpMutatorContext) { diff --git a/android/namespace_test.go b/android/namespace_test.go index ea51c6eae..0327e7824 100644 --- a/android/namespace_test.go +++ b/android/namespace_test.go @@ -646,7 +646,7 @@ var prepareForTestWithNamespace = GroupFixturePreparers( ctx.RegisterModuleType("test_module", newTestModule) ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule) ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) { - ctx.BottomUp("rename", renameMutator) + ctx.BottomUp("rename", renameMutator).UsesRename() }) }), ) @@ -709,9 +709,6 @@ type testModule struct { } func (m *testModule) DepsMutator(ctx BottomUpMutatorContext) { - if m.properties.Rename != "" { - ctx.Rename(m.properties.Rename) - } for _, d := range m.properties.Deps { ctx.AddDependency(ctx.Module(), nil, d) } diff --git a/android/override_module.go b/android/override_module.go index f69f96309..d844da616 100644 --- a/android/override_module.go +++ b/android/override_module.go @@ -234,8 +234,9 @@ func (b *OverridableModuleBase) OverridablePropertiesDepsMutator(ctx BottomUpMut // Mutators for override/overridable modules. All the fun happens in these functions. It is critical // to keep them in this order and not put any order mutators between them. func RegisterOverridePostDepsMutators(ctx RegisterMutatorsContext) { - ctx.BottomUp("override_deps", overrideModuleDepsMutator).Parallel() + ctx.BottomUp("override_deps", overrideModuleDepsMutator).Parallel().MutatesDependencies() // modifies deps via addOverride ctx.Transition("override", &overrideTransitionMutator{}) + ctx.BottomUp("override_apply", overrideApplyMutator).Parallel().MutatesDependencies() // overridableModuleDepsMutator calls OverridablePropertiesDepsMutator so that overridable modules can // add deps from overridable properties. ctx.BottomUp("overridable_deps", overridableModuleDepsMutator).Parallel() @@ -243,8 +244,8 @@ func RegisterOverridePostDepsMutators(ctx RegisterMutatorsContext) { // prebuilt's ReplaceDependencies doesn't affect to those deps added by overridable properties. // By running PrebuiltPostDepsMutator again after overridableModuleDepsMutator, deps via overridable properties // can be replaced with prebuilts. - ctx.BottomUp("replace_deps_on_prebuilts_for_overridable_deps_again", PrebuiltPostDepsMutator).Parallel() - ctx.BottomUp("replace_deps_on_override", replaceDepsOnOverridingModuleMutator).Parallel() + ctx.BottomUp("replace_deps_on_prebuilts_for_overridable_deps_again", PrebuiltPostDepsMutator).Parallel().UsesReplaceDependencies() + ctx.BottomUp("replace_deps_on_override", replaceDepsOnOverridingModuleMutator).Parallel().UsesReplaceDependencies() } type overrideBaseDependencyTag struct { @@ -330,6 +331,9 @@ func (overrideTransitionMutator) IncomingTransition(ctx IncomingTransitionContex } func (overrideTransitionMutator) Mutate(ctx BottomUpMutatorContext, variation string) { +} + +func overrideApplyMutator(ctx BottomUpMutatorContext) { if o, ok := ctx.Module().(OverrideModule); ok { overridableDeps := ctx.GetDirectDepsWithTag(overrideBaseDepTag) if len(overridableDeps) > 1 { diff --git a/android/packaging.go b/android/packaging.go index 3c64d56f0..d6158715c 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -65,30 +65,32 @@ type PackagingSpec struct { } type packagingSpecGob struct { - RelPathInPackage string - SrcPath Path - SymlinkTarget string - Executable bool - Partition string - SkipInstall bool - AconfigPaths *Paths - ArchType ArchType - Overrides *[]string - Owner string + RelPathInPackage string + SrcPath Path + SymlinkTarget string + Executable bool + EffectiveLicenseFiles *Paths + Partition string + SkipInstall bool + AconfigPaths *Paths + ArchType ArchType + Overrides *[]string + Owner string } func (p *PackagingSpec) ToGob() *packagingSpecGob { return &packagingSpecGob{ - RelPathInPackage: p.relPathInPackage, - SrcPath: p.srcPath, - SymlinkTarget: p.symlinkTarget, - Executable: p.executable, - Partition: p.partition, - SkipInstall: p.skipInstall, - AconfigPaths: p.aconfigPaths, - ArchType: p.archType, - Overrides: p.overrides, - Owner: p.owner, + RelPathInPackage: p.relPathInPackage, + SrcPath: p.srcPath, + SymlinkTarget: p.symlinkTarget, + Executable: p.executable, + EffectiveLicenseFiles: p.effectiveLicenseFiles, + Partition: p.partition, + SkipInstall: p.skipInstall, + AconfigPaths: p.aconfigPaths, + ArchType: p.archType, + Overrides: p.overrides, + Owner: p.owner, } } @@ -97,6 +99,7 @@ func (p *PackagingSpec) FromGob(data *packagingSpecGob) { p.srcPath = data.SrcPath p.symlinkTarget = data.SymlinkTarget p.executable = data.Executable + p.effectiveLicenseFiles = data.EffectiveLicenseFiles p.partition = data.Partition p.skipInstall = data.SkipInstall p.aconfigPaths = data.AconfigPaths diff --git a/android/paths.go b/android/paths.go index 9c2df6589..ec05831ca 100644 --- a/android/paths.go +++ b/android/paths.go @@ -1363,21 +1363,21 @@ type OutputPath struct { } type outputPathGob struct { - basePath + BasePath basePath OutDir string FullPath string } func (p *OutputPath) ToGob() *outputPathGob { return &outputPathGob{ - basePath: p.basePath, + BasePath: p.basePath, OutDir: p.outDir, FullPath: p.fullPath, } } func (p *OutputPath) FromGob(data *outputPathGob) { - p.basePath = data.basePath + p.basePath = data.BasePath p.outDir = data.OutDir p.fullPath = data.FullPath } @@ -1788,7 +1788,7 @@ type InstallPath struct { } type installPathGob struct { - basePath + BasePath basePath SoongOutDir string PartitionDir string Partition string @@ -1798,7 +1798,7 @@ type installPathGob struct { func (p *InstallPath) ToGob() *installPathGob { return &installPathGob{ - basePath: p.basePath, + BasePath: p.basePath, SoongOutDir: p.soongOutDir, PartitionDir: p.partitionDir, Partition: p.partition, @@ -1808,7 +1808,7 @@ func (p *InstallPath) ToGob() *installPathGob { } func (p *InstallPath) FromGob(data *installPathGob) { - p.basePath = data.basePath + p.basePath = data.BasePath p.soongOutDir = data.SoongOutDir p.partitionDir = data.PartitionDir p.partition = data.Partition diff --git a/android/prebuilt.go b/android/prebuilt.go index 4f04d057b..017ba76c3 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -400,13 +400,13 @@ func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module { } func RegisterPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) { - ctx.BottomUp("prebuilt_rename", PrebuiltRenameMutator).Parallel() + ctx.BottomUp("prebuilt_rename", PrebuiltRenameMutator).Parallel().UsesRename() } func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) { - ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel() + ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel().UsesReverseDependencies() ctx.BottomUp("prebuilt_select", PrebuiltSelectModuleMutator).Parallel() - ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel() + ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel().UsesReplaceDependencies() } // Returns the name of the source module corresponding to a prebuilt module @@ -677,7 +677,7 @@ type createdByJavaSdkLibraryName interface { // // Even though this is a cc_prebuilt_library_shared, we create both the variants today // https://source.corp.google.com/h/googleplex-android/platform/build/soong/+/e08e32b45a18a77bc3c3e751f730539b1b374f1b:cc/library.go;l=2113-2116;drc=2c4a9779cd1921d0397a12b3d3521f4c9b30d747;bpv=1;bpt=0 -func (p *Prebuilt) variantIsDisabled(ctx BaseMutatorContext, prebuilt Module) bool { +func (p *Prebuilt) variantIsDisabled(ctx BaseModuleContext, prebuilt Module) bool { return p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 } @@ -687,7 +687,7 @@ type apexVariationName interface { // usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt // will be used if it is marked "prefer" or if the source module is disabled. -func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt Module) bool { +func (p *Prebuilt) usePrebuilt(ctx BaseModuleContext, source Module, prebuilt Module) bool { isMainlinePrebuilt := func(prebuilt Module) bool { apex, ok := prebuilt.(apexVariationName) if !ok { diff --git a/android/register.go b/android/register.go index 2ce602580..94d875d19 100644 --- a/android/register.go +++ b/android/register.go @@ -91,7 +91,14 @@ type mutator struct { bottomUpMutator blueprint.BottomUpMutator topDownMutator blueprint.TopDownMutator transitionMutator blueprint.TransitionMutator - parallel bool + + parallel bool + usesRename bool + usesReverseDependencies bool + usesReplaceDependencies bool + usesCreateModule bool + mutatesDependencies bool + mutatesGlobalState bool } var _ sortableComponent = &mutator{} diff --git a/android/variable.go b/android/variable.go index 248e1e853..4210f6720 100644 --- a/android/variable.go +++ b/android/variable.go @@ -478,6 +478,8 @@ type ProductVariables struct { ProductManufacturer string `json:",omitempty"` ProductBrand string `json:",omitempty"` + ProductDevice string `json:",omitempty"` + ProductModel string `json:",omitempty"` ReleaseVersion string `json:",omitempty"` ReleaseAconfigValueSets []string `json:",omitempty"` diff --git a/androidmk/parser/parser_test.go b/androidmk/parser/parser_test.go index e238f8b11..21baf6bf9 100644 --- a/androidmk/parser/parser_test.go +++ b/androidmk/parser/parser_test.go @@ -142,7 +142,7 @@ endif t.Fatalf("Unexpected errors while parsing: %v", errs) } - if got[0].End() < got[len(got) -1].Pos() { - t.Errorf("Rule's end (%d) is smaller than directive that inside of rule's start (%v)\n", got[0].End(), got[len(got) -1].Pos()) + if got[0].End() < got[len(got)-1].Pos() { + t.Errorf("Rule's end (%d) is smaller than directive that inside of rule's start (%v)\n", got[0].End(), got[len(got)-1].Pos()) } } diff --git a/apex/apex.go b/apex/apex.go index d3e7eee9d..6bb2a1a5b 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -55,7 +55,7 @@ func registerApexBuildComponents(ctx android.RegistrationContext) { } func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel() + ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel().UsesReverseDependencies() } func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { @@ -67,7 +67,7 @@ func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { // it should create a platform variant. ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel() ctx.Transition("apex", &apexTransitionMutator{}) - ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel() + ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel().MutatesDependencies() ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel() } @@ -292,7 +292,7 @@ type ResolvedApexNativeDependencies struct { } // Merge combines another ApexNativeDependencies into this one -func (a *ResolvedApexNativeDependencies) Merge(ctx android.BaseMutatorContext, b ApexNativeDependencies) { +func (a *ResolvedApexNativeDependencies) Merge(ctx android.BaseModuleContext, b ApexNativeDependencies) { a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs.GetOrDefault(ctx, nil)...) a.Jni_libs = append(a.Jni_libs, b.Jni_libs.GetOrDefault(ctx, nil)...) a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...) @@ -110,7 +110,7 @@ func (lto *lto) flags(ctx ModuleContext, flags Flags) Flags { var ltoLdFlags []string // Do not perform costly LTO optimizations for Eng builds. - if Bool(lto.Properties.Lto_O0) || ctx.optimizeForSize() || ctx.Config().Eng() { + if Bool(lto.Properties.Lto_O0) || ctx.Config().Eng() { ltoLdFlags = append(ltoLdFlags, "-Wl,--lto-O0") } diff --git a/cmd/release_config/release_config_lib/release_config.go b/cmd/release_config/release_config_lib/release_config.go index adf0e62da..ee71336c5 100644 --- a/cmd/release_config/release_config_lib/release_config.go +++ b/cmd/release_config/release_config_lib/release_config.go @@ -280,11 +280,28 @@ func (config *ReleaseConfig) GenerateReleaseConfig(configs *ReleaseConfigs) erro directories := []string{} valueDirectories := []string{} + // These path prefixes are exclusive for a release config. + // "A release config shall exist in at most one of these." + // If we find a benefit to generalizing this, we can do so at that time. + exclusiveDirPrefixes := []string{ + "build/release", + "vendor/google_shared/build/release", + } + var exclusiveDir string for idx, confDir := range configs.configDirs { if _, ok := myDirsMap[idx]; ok { directories = append(directories, confDir) } if _, ok := myValueDirsMap[idx]; ok { + for _, dir := range exclusiveDirPrefixes { + if strings.HasPrefix(confDir, dir) { + if exclusiveDir != "" && !strings.HasPrefix(exclusiveDir, dir) { + return fmt.Errorf("%s is declared in both %s and %s", + config.Name, exclusiveDir, confDir) + } + exclusiveDir = confDir + } + } valueDirectories = append(valueDirectories, confDir) } } diff --git a/compliance/notice_test.go b/compliance/notice_test.go index 6187e5332..e8578ec3b 100644 --- a/compliance/notice_test.go +++ b/compliance/notice_test.go @@ -35,4 +35,4 @@ func TestPrebuiltEtcOutputFile(t *testing.T) { m := result.Module("notice_xml_system", "android_arm64_armv8-a").(*NoticeXmlModule) android.AssertStringEquals(t, "output file", "NOTICE.xml.gz", m.outputFile.Base()) -}
\ No newline at end of file +} diff --git a/etc/install_symlink.go b/etc/install_symlink.go index 2182b8669..aa33445e1 100644 --- a/etc/install_symlink.go +++ b/etc/install_symlink.go @@ -26,6 +26,7 @@ func init() { func RegisterInstallSymlinkBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("install_symlink", InstallSymlinkFactory) + ctx.RegisterModuleType("install_symlink_host", InstallSymlinkHostFactory) } // install_symlink can be used to install an symlink with an arbitrary target to an arbitrary path @@ -37,6 +38,14 @@ func InstallSymlinkFactory() android.Module { return module } +// install_symlink can be used to install an symlink to an arbitrary path on the host. +func InstallSymlinkHostFactory() android.Module { + module := &InstallSymlink{} + module.AddProperties(&module.properties) + android.InitAndroidMultiTargetsArchModule(module, android.HostSupported, android.MultilibCommon) + return module +} + type InstallSymlinkProperties struct { // Where to install this symlink, relative to the partition it's installed on. // Which partition it's installed on can be controlled by the vendor, system_ext, ramdisk, etc. diff --git a/etc/install_symlink_test.go b/etc/install_symlink_test.go index d7165e5de..c97d97c65 100644 --- a/etc/install_symlink_test.go +++ b/etc/install_symlink_test.go @@ -133,3 +133,39 @@ func TestErrorOnInstalledPathStartingWithSlash(t *testing.T) { } `) } + +var prepareForInstallSymlinkHostTest = android.GroupFixturePreparers( + android.PrepareForTestWithAndroidBuildComponents, + android.FixtureRegisterWithContext(RegisterInstallSymlinkBuildComponents), +) + +func TestInstallSymlinkHostBasic(t *testing.T) { + result := prepareForInstallSymlinkHostTest.RunTestWithBp(t, ` + install_symlink_host { + name: "foo", + installed_location: "bin/foo", + symlink_target: "aa/bb/cc", + } + `) + + buildOS := result.Config.BuildOS.String() + foo := result.ModuleForTests("foo", buildOS+"_common").Module() + + androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo) + if len(androidMkEntries) != 1 { + t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries)) + } + + symlinks := androidMkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"] + if len(symlinks) != 1 { + t.Fatalf("Expected 1 symlink, got %d", len(symlinks)) + } + + if !strings.HasSuffix(symlinks[0], "bin/foo") { + t.Fatalf("Expected symlink install path to end in bin/foo, got: %s", symlinks[0]) + } + + if !strings.Contains(symlinks[0], "host") { + t.Fatalf("Expected symlink install path to contain `host`, got: %s", symlinks[0]) + } +} diff --git a/filesystem/Android.bp b/filesystem/Android.bp index a08f7cf17..23ec3da81 100644 --- a/filesystem/Android.bp +++ b/filesystem/Android.bp @@ -16,6 +16,7 @@ bootstrap_go_package { ], srcs: [ "aconfig_files.go", + "android_device.go", "avb_add_hash_footer.go", "avb_gen_vbmeta_image.go", "bootimg.go", diff --git a/filesystem/android_device.go b/filesystem/android_device.go new file mode 100644 index 000000000..68e60532e --- /dev/null +++ b/filesystem/android_device.go @@ -0,0 +1,73 @@ +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package filesystem + +import ( + "android/soong/android" + + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +type PartitionNameProperties struct { + // Name of the Boot_partition_name partition filesystem module + Boot_partition_name *string + // Name of the System partition filesystem module + System_partition_name *string + // Name of the System_ext partition filesystem module + System_ext_partition_name *string + // Name of the Product partition filesystem module + Product_partition_name *string + // Name of the Vendor partition filesystem module + Vendor_partition_name *string +} + +type androidDevice struct { + android.ModuleBase + + partitionProps PartitionNameProperties +} + +func AndroidDeviceFactory() android.Module { + module := &androidDevice{} + module.AddProperties(&module.partitionProps) + android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) + + return module +} + +type partitionDepTagType struct { + blueprint.BaseDependencyTag +} + +var filesystemDepTag partitionDepTagType + +func (a *androidDevice) DepsMutator(ctx android.BottomUpMutatorContext) { + addDependencyIfDefined := func(dep *string) { + if dep != nil { + ctx.AddDependency(ctx.Module(), filesystemDepTag, proptools.String(dep)) + } + } + + addDependencyIfDefined(a.partitionProps.Boot_partition_name) + addDependencyIfDefined(a.partitionProps.System_partition_name) + addDependencyIfDefined(a.partitionProps.System_ext_partition_name) + addDependencyIfDefined(a.partitionProps.Product_partition_name) + addDependencyIfDefined(a.partitionProps.Vendor_partition_name) +} + +func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) { + +} diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 09d8fba5e..9b3eae471 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -434,7 +434,7 @@ func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android. // Type string that build_image.py accepts. fsTypeStr := func(t fsType) string { switch t { - // TODO(jiyong): add more types like f2fs, erofs, etc. + // TODO(372522486): add more types like f2fs, erofs, etc. case ext4Type: return "ext4" } diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index a9f4256ec..d75a4a206 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -66,14 +66,35 @@ func (f *filesystemCreator) createInternalModules(ctx android.LoadHookContext) { f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, partitionType) } } + f.createDeviceModule(ctx) } -func (f *filesystemCreator) generatedModuleNameForPartition(cfg android.Config, partitionType string) string { +func (f *filesystemCreator) generatedModuleName(cfg android.Config, suffix string) string { prefix := "soong" if cfg.HasDeviceProduct() { prefix = cfg.DeviceProduct() } - return fmt.Sprintf("%s_generated_%s_image", prefix, partitionType) + return fmt.Sprintf("%s_generated_%s", prefix, suffix) +} + +func (f *filesystemCreator) generatedModuleNameForPartition(cfg android.Config, partitionType string) string { + return f.generatedModuleName(cfg, fmt.Sprintf("%s_image", partitionType)) +} + +func (f *filesystemCreator) createDeviceModule(ctx android.LoadHookContext) { + baseProps := &struct { + Name *string + }{ + Name: proptools.StringPtr(f.generatedModuleName(ctx.Config(), "device")), + } + + // Currently, only the system partition module is created. + partitionProps := &filesystem.PartitionNameProperties{} + if android.InList("system", f.properties.Generated_partition_types) { + partitionProps.System_partition_name = proptools.StringPtr(f.generatedModuleNameForPartition(ctx.Config(), "system")) + } + + ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps) } // Creates a soong module to build the given partition. Returns false if we can't support building @@ -109,6 +130,7 @@ func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partiti // BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE fsProps.Type = proptools.StringPtr(specificPartitionVars.BoardFileSystemType) if *fsProps.Type != "ext4" { + // TODO(b/372522486): Support other FS types. // Currently the android_filesystem module type only supports ext4: // https://cs.android.com/android/platform/superproject/main/+/main:build/soong/filesystem/filesystem.go;l=416;drc=98047cfd07944b297a12d173453bc984806760d2 return false diff --git a/genrule/genrule.go b/genrule/genrule.go index e5222a432..18ec0a40c 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -139,8 +139,7 @@ type generatorProperties struct { Export_include_dirs []string // list of input files - Srcs proptools.Configurable[[]string] `android:"path,arch_variant"` - ResolvedSrcs []string `blueprint:"mutated"` + Srcs proptools.Configurable[[]string] `android:"path,arch_variant"` // input files to exclude Exclude_srcs []string `android:"path,arch_variant"` @@ -426,8 +425,8 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) { } return srcFiles } - g.properties.ResolvedSrcs = g.properties.Srcs.GetOrDefault(ctx, nil) - srcFiles := addLabelsForInputs("srcs", g.properties.ResolvedSrcs, g.properties.Exclude_srcs) + srcs := g.properties.Srcs.GetOrDefault(ctx, nil) + srcFiles := addLabelsForInputs("srcs", srcs, g.properties.Exclude_srcs) android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcFiles.Strings()}) var copyFrom android.Paths @@ -659,7 +658,7 @@ func (g *Module) setOutputFiles(ctx android.ModuleContext) { // Collect information for opening IDE project files in java/jdeps.go. func (g *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...) - for _, src := range g.properties.ResolvedSrcs { + for _, src := range g.properties.Srcs.GetOrDefault(ctx, nil) { if strings.HasPrefix(src, ":") { src = strings.Trim(src, ":") dpInfo.Deps = append(dpInfo.Deps, src) diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go index 9278f1574..f190750d1 100644 --- a/genrule/genrule_test.go +++ b/genrule/genrule_test.go @@ -24,6 +24,7 @@ import ( "android/soong/android" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -694,8 +695,12 @@ func TestGenruleDefaults(t *testing.T) { expectedCmd := "cp in1 __SBOX_SANDBOX_DIR__/out/out" android.AssertStringEquals(t, "cmd", expectedCmd, gen.rawCommands[0]) + srcsFileProvider, ok := android.OtherModuleProvider(result.TestContext, gen, blueprint.SrcsFileProviderKey) + if !ok { + t.Fatal("Expected genrule to have a SrcsFileProviderData, but did not") + } expectedSrcs := []string{"in1"} - android.AssertDeepEquals(t, "srcs", expectedSrcs, gen.properties.ResolvedSrcs) + android.AssertDeepEquals(t, "srcs", expectedSrcs, srcsFileProvider.SrcPaths) } func TestGenruleAllowMissingDependencies(t *testing.T) { diff --git a/golang/golang_test.go b/golang/golang_test.go index b51214402..0a4baedb4 100644 --- a/golang/golang_test.go +++ b/golang/golang_test.go @@ -16,9 +16,10 @@ package golang import ( "android/soong/android" - "github.com/google/blueprint/bootstrap" - "path/filepath" + "regexp" "testing" + + "github.com/google/blueprint/bootstrap" ) func TestGolang(t *testing.T) { @@ -39,13 +40,19 @@ func TestGolang(t *testing.T) { android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { RegisterGoModuleTypes(ctx) ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { - ctx.BottomUpBlueprint("bootstrap_deps", bootstrap.BootstrapDeps) + ctx.BottomUpBlueprint("bootstrap_deps", bootstrap.BootstrapDeps).UsesReverseDependencies() }) }), ).RunTestWithBp(t, bp) bin := result.ModuleForTests("gobin", result.Config.BuildOSTarget.String()) - expected := filepath.Join("out/soong/host", result.Config.PrebuiltOS(), "bin/go/gobin/obj/gobin") - android.AssertPathsRelativeToTopEquals(t, "output files", []string{expected}, bin.OutputFiles(result.TestContext, t, "")) + expected := "^out/soong/host/" + result.Config.PrebuiltOS() + "/bin/go/gobin/?[^/]*/obj/gobin$" + actual := android.PathsRelativeToTop(bin.OutputFiles(result.TestContext, t, "")) + if len(actual) != 1 { + t.Fatalf("Expected 1 output file, got %v", actual) + } + if match, err := regexp.Match(expected, []byte(actual[0])); err != nil || !match { + t.Fatalf("Expected output file to match %q, but got %q", expected, actual[0]) + } } diff --git a/java/androidmk.go b/java/androidmk.go index 2dff6cd9f..bacd92522 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -281,50 +281,24 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries { return nil } - if !binary.isWrapperVariant { - return []android.AndroidMkEntries{android.AndroidMkEntries{ - Class: "JAVA_LIBRARIES", - OutputFile: android.OptionalPathForPath(binary.outputFile), - Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", - ExtraEntries: []android.AndroidMkExtraEntriesFunc{ - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.SetPath("LOCAL_SOONG_HEADER_JAR", binary.headerJarFile) - entries.SetPath("LOCAL_SOONG_CLASSES_JAR", binary.implementationAndResourcesJar) - if binary.dexJarFile.IsSet() { - entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile.Path()) - } - if len(binary.dexpreopter.builtInstalled) > 0 { - entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled) - } - }, - }, - ExtraFooters: []android.AndroidMkExtraFootersFunc{ - func(w io.Writer, name, prefix, moduleDir string) { - fmt.Fprintln(w, "jar_installed_module := $(LOCAL_INSTALLED_MODULE)") - }, - }, - }} - } else { - outputFile := binary.wrapperFile - - return []android.AndroidMkEntries{android.AndroidMkEntries{ - Class: "EXECUTABLES", - OutputFile: android.OptionalPathForPath(outputFile), - ExtraEntries: []android.AndroidMkExtraEntriesFunc{ - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.SetBool("LOCAL_STRIP_MODULE", false) - entries.AddStrings("LOCAL_REQUIRED_MODULES", binary.androidMkNamesOfJniLibs...) - }, - }, - ExtraFooters: []android.AndroidMkExtraFootersFunc{ - func(w io.Writer, name, prefix, moduleDir string) { - // Ensure that the wrapper script timestamp is always updated when the jar is updated - fmt.Fprintln(w, "$(LOCAL_INSTALLED_MODULE): $(jar_installed_module)") - fmt.Fprintln(w, "jar_installed_module :=") - }, + return []android.AndroidMkEntries{{ + Class: "JAVA_LIBRARIES", + OutputFile: android.OptionalPathForPath(binary.outputFile), + Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { + entries.SetPath("LOCAL_SOONG_HEADER_JAR", binary.headerJarFile) + entries.SetPath("LOCAL_SOONG_CLASSES_JAR", binary.implementationAndResourcesJar) + if binary.dexJarFile.IsSet() { + entries.SetPath("LOCAL_SOONG_DEX_JAR", binary.dexJarFile.Path()) + } + if len(binary.dexpreopter.builtInstalled) > 0 { + entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", binary.dexpreopter.builtInstalled) + } + entries.AddStrings("LOCAL_REQUIRED_MODULES", binary.androidMkNamesOfJniLibs...) }, - }} - } + }, + }} } func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries { diff --git a/java/base.go b/java/base.go index 7a957350a..a9399cbd3 100644 --- a/java/base.go +++ b/java/base.go @@ -2172,16 +2172,14 @@ func (j *Module) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { // Collect information for opening IDE project files in java/jdeps.go. func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { - // jarjar rules will repackage the sources. To prevent misleading results, IdeInfo should contain the - // repackaged jar instead of the input sources. if j.expandJarjarRules != nil { dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String()) + // Add the header jar so that the rdeps can be resolved to the repackaged classes. dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String()) - } else { - dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) - dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) - dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...) } + dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) + dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) + dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...) dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...) dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...) dpInfo.Static_libs = append(dpInfo.Static_libs, j.staticLibs(ctx)...) diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp index 1cca7ad49..da865404b 100644 --- a/java/core-libraries/Android.bp +++ b/java/core-libraries/Android.bp @@ -41,10 +41,50 @@ java_defaults { is_stubs_module: true, } +soong_config_module_type { + name: "core_current_stubs_soong_config_defaults", + module_type: "java_defaults", + config_namespace: "ANDROID", + bool_variables: [ + "release_hidden_api_exportable_stubs", + ], + properties: [ + "dist.targets", + "dist.dest", + ], +} + +core_current_stubs_soong_config_defaults { + name: "core_current_stubs_everything_soong_config_defaults", + soong_config_variables: { + release_hidden_api_exportable_stubs: { + conditions_default: { + dist: { + targets: dist_targets, + dest: "core.current.stubs.jar", + }, + }, + }, + }, +} + +core_current_stubs_soong_config_defaults { + name: "core_current_stubs_exportable_soong_config_defaults", + soong_config_variables: { + release_hidden_api_exportable_stubs: { + dist: { + targets: dist_targets, + dest: "core.current.stubs.jar", + }, + }, + }, +} + java_library { name: "core.current.stubs", defaults: [ "core.current.stubs.defaults", + "core_current_stubs_everything_soong_config_defaults", ], static_libs: [ "art.module.public.api.stubs", @@ -76,16 +116,13 @@ java_library { name: "core.current.stubs.exportable", defaults: [ "core.current.stubs.defaults", + "core_current_stubs_exportable_soong_config_defaults", ], static_libs: [ "art.module.public.api.stubs.exportable", "conscrypt.module.public.api.stubs.exportable", "i18n.module.public.api.stubs.exportable", ], - dist: { - targets: dist_targets, - dest: "core.current.stubs.jar", - }, } // Distributed with the SDK for turning into system modules to compile apps diff --git a/java/java.go b/java/java.go index 018850fef..d97288768 100644 --- a/java/java.go +++ b/java/java.go @@ -450,7 +450,6 @@ var ( javaApiContributionTag = dependencyTag{name: "java-api-contribution"} aconfigDeclarationTag = dependencyTag{name: "aconfig-declaration"} jniInstallTag = dependencyTag{name: "jni install", runtimeLinked: true, installable: true} - binaryInstallTag = dependencyTag{name: "binary install", runtimeLinked: true, installable: true} usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false) usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true) usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true) @@ -1004,13 +1003,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.compile(ctx, nil, nil, nil, nil) - // If this module is an impl library created from java_sdk_library, - // install the files under the java_sdk_library module outdir instead of this module outdir. - if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") { - j.setInstallRules(ctx, proptools.String(j.SdkLibraryName())) - } else { - j.setInstallRules(ctx, ctx.ModuleName()) - } + j.setInstallRules(ctx) android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{ TestOnly: Bool(j.sourceProperties.Test_only), @@ -1020,7 +1013,27 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { setOutputFiles(ctx, j.Module) } -func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName string) { +func (j *Library) getJarInstallDir(ctx android.ModuleContext) android.InstallPath { + var installDir android.InstallPath + if ctx.InstallInTestcases() { + var archDir string + if !ctx.Host() { + archDir = ctx.DeviceConfig().DeviceArch() + } + installModuleName := ctx.ModuleName() + // If this module is an impl library created from java_sdk_library, + // install the files under the java_sdk_library module outdir instead of this module outdir. + if j.SdkLibraryName() != nil && strings.HasSuffix(j.Name(), ".impl") { + installModuleName = proptools.String(j.SdkLibraryName()) + } + installDir = android.PathForModuleInstall(ctx, installModuleName, archDir) + } else { + installDir = android.PathForModuleInstall(ctx, "framework") + } + return installDir +} + +func (j *Library) setInstallRules(ctx android.ModuleContext) { apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if (Bool(j.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() { @@ -1034,17 +1047,7 @@ func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName s android.PathForHostDexInstall(ctx, "framework"), j.Stem()+"-hostdex.jar", j.outputFile) } - var installDir android.InstallPath - if ctx.InstallInTestcases() { - var archDir string - if !ctx.Host() { - archDir = ctx.DeviceConfig().DeviceArch() - } - installDir = android.PathForModuleInstall(ctx, installModuleName, archDir) - } else { - installDir = android.PathForModuleInstall(ctx, "framework") - } - j.installFile = ctx.InstallFileWithoutCheckbuild(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) + j.installFile = ctx.InstallFileWithoutCheckbuild(j.getJarInstallDir(ctx), j.Stem()+".jar", j.outputFile, extraInstallDeps...) } } @@ -1804,8 +1807,6 @@ type Binary struct { binaryProperties binaryProperties - isWrapperVariant bool - wrapperFile android.Path binaryFile android.InstallPath @@ -1819,97 +1820,94 @@ func (j *Binary) HostToolPath() android.OptionalPath { func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName()) - if ctx.Arch().ArchType == android.Common { - // Compile the jar - if j.binaryProperties.Main_class != nil { - if j.properties.Manifest != nil { - ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set") - } - manifestFile := android.PathForModuleOut(ctx, "manifest.txt") - GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class)) - j.overrideManifest = android.OptionalPathForPath(manifestFile) - } - - j.Library.GenerateAndroidBuildActions(ctx) + // Handle the binary wrapper. This comes before compiling the jar so that the wrapper + // is the first PackagingSpec + if j.binaryProperties.Wrapper != nil { + j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper) } else { - // Handle the binary wrapper - j.isWrapperVariant = true - - if j.binaryProperties.Wrapper != nil { - j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper) - } else { - if ctx.Windows() { - ctx.PropertyErrorf("wrapper", "wrapper is required for Windows") - } + if ctx.Windows() { + ctx.PropertyErrorf("wrapper", "wrapper is required for Windows") + } - if ctx.Device() { - // device binary should have a main_class property if it does not - // have a specific wrapper, so that a default wrapper can - // be generated for it. - if j.binaryProperties.Main_class == nil { - ctx.PropertyErrorf("main_class", "main_class property "+ - "is required for device binary if no default wrapper is assigned") - } else { - wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh") - jarName := j.Stem() + ".jar" - partition := j.PartitionTag(ctx.DeviceConfig()) - ctx.Build(pctx, android.BuildParams{ - Rule: deviceBinaryWrapper, - Output: wrapper, - Args: map[string]string{ - "jar_name": jarName, - "partition": partition, - "main_class": String(j.binaryProperties.Main_class), - }, - }) - j.wrapperFile = wrapper - } + if ctx.Device() { + // device binary should have a main_class property if it does not + // have a specific wrapper, so that a default wrapper can + // be generated for it. + if j.binaryProperties.Main_class == nil { + ctx.PropertyErrorf("main_class", "main_class property "+ + "is required for device binary if no default wrapper is assigned") } else { - j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") + wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh") + jarName := j.Stem() + ".jar" + partition := j.PartitionTag(ctx.DeviceConfig()) + ctx.Build(pctx, android.BuildParams{ + Rule: deviceBinaryWrapper, + Output: wrapper, + Args: map[string]string{ + "jar_name": jarName, + "partition": partition, + "main_class": String(j.binaryProperties.Main_class), + }, + }) + j.wrapperFile = wrapper } + } else { + j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") } + } - ext := "" - if ctx.Windows() { - ext = ".bat" + ext := "" + if ctx.Windows() { + ext = ".bat" + } + + // The host installation rules make the installed wrapper depend on all the dependencies + // of the wrapper variant, which will include the common variant's jar file and any JNI + // libraries. This is verified by TestBinary. Also make it depend on the jar file so that + // the binary file timestamp will update when the jar file timestamp does. The jar file is + // built later on, in j.Library.GenerateAndroidBuildActions, so we have to create an identical + // installpath representing it here. + j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), + ctx.ModuleName()+ext, j.wrapperFile, j.getJarInstallDir(ctx).Join(ctx, j.Stem()+".jar")) + + // Set the jniLibs of this binary. + // These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will + // install these alongside the java binary. + ctx.VisitDirectDepsWithTag(jniInstallTag, func(jni android.Module) { + // Use the BaseModuleName of the dependency (without any prebuilt_ prefix) + bmn, _ := jni.(interface{ BaseModuleName() string }) + j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, bmn.BaseModuleName()+":"+jni.Target().Arch.ArchType.Bitness()) + }) + // Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead. + ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) { + if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo { + ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name()) } + }) - // The host installation rules make the installed wrapper depend on all the dependencies - // of the wrapper variant, which will include the common variant's jar file and any JNI - // libraries. This is verified by TestBinary. - j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), - ctx.ModuleName()+ext, j.wrapperFile) - - setOutputFiles(ctx, j.Library.Module) - - // Set the jniLibs of this binary. - // These will be added to `LOCAL_REQUIRED_MODULES`, and the kati packaging system will - // install these alongside the java binary. - ctx.VisitDirectDepsWithTag(jniInstallTag, func(jni android.Module) { - // Use the BaseModuleName of the dependency (without any prebuilt_ prefix) - bmn, _ := jni.(interface{ BaseModuleName() string }) - j.androidMkNamesOfJniLibs = append(j.androidMkNamesOfJniLibs, bmn.BaseModuleName()+":"+jni.Target().Arch.ArchType.Bitness()) - }) - // Check that native libraries are not listed in `required`. Prompt users to use `jni_libs` instead. - ctx.VisitDirectDepsWithTag(android.RequiredDepTag, func(dep android.Module) { - if _, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider); hasSharedLibraryInfo { - ctx.ModuleErrorf("cc_library %s is no longer supported in `required` of java_binary modules. Please use jni_libs instead.", dep.Name()) - } - }) + // Compile the jar + if j.binaryProperties.Main_class != nil { + if j.properties.Manifest != nil { + ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set") + } + manifestFile := android.PathForModuleOut(ctx, "manifest.txt") + GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class)) + j.overrideManifest = android.OptionalPathForPath(manifestFile) } + + j.Library.GenerateAndroidBuildActions(ctx) } func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { - if ctx.Arch().ArchType == android.Common { - j.deps(ctx) - } + j.deps(ctx) // These dependencies ensure the installation rules will install the jar file when the // wrapper is installed, and the jni libraries when the wrapper is installed. - if ctx.Arch().ArchType != android.Common { - ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) - ctx.AddVariationDependencies( - []blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}}, - binaryInstallTag, ctx.ModuleName()) + if ctx.Os().Class == android.Host { + ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniInstallTag, j.binaryProperties.Jni_libs...) + } else if ctx.Os().Class == android.Device { + ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), jniInstallTag, j.binaryProperties.Jni_libs...) + } else { + ctx.ModuleErrorf("Unknown os class") } } @@ -1929,7 +1927,7 @@ func BinaryFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) - android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) + android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(module) return module @@ -1947,7 +1945,7 @@ func BinaryHostFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) - android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) android.InitDefaultableModule(module) return module } diff --git a/java/java_test.go b/java/java_test.go index 24dabdb10..51cfdabb0 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -569,8 +569,7 @@ func TestBinary(t *testing.T) { bar := ctx.ModuleForTests("bar", buildOS+"_common") barJar := bar.Output("bar.jar").Output.String() - barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64") - barWrapperDeps := barWrapper.Output("bar").Implicits.Strings() + barWrapperDeps := bar.Output("bar").Implicits.Strings() libjni := ctx.ModuleForTests("libjni", buildOS+"_x86_64_shared") libjniSO := libjni.Rule("Cp").Output.String() @@ -1931,7 +1930,7 @@ func TestDeviceBinaryWrapperGeneration(t *testing.T) { main_class: "foo.bar.jb", } `) - wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_arm64_armv8-a").AllOutputs()) + wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_common").AllOutputs()) if !strings.Contains(wrapperPath, "foo.sh") { t.Errorf("wrapper file foo.sh is not generated") } @@ -3125,13 +3124,6 @@ cc_library_shared { } ` res, _ := testJava(t, bp) - // The first variant installs the native library via the common variant, so check the deps of both variants. - nativeVariantDepsWithDups := findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_arm64_armv8-a").Module(), "mynativelib") - nativeVariantDepsWithDups = append(nativeVariantDepsWithDups, findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_common").Module(), "mynativelib")...) - - nativeVariantDepsUnique := map[blueprint.Module]bool{} - for _, dep := range nativeVariantDepsWithDups { - nativeVariantDepsUnique[dep] = true - } - android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(nativeVariantDepsUnique)) + deps := findDepsOfModule(res, res.ModuleForTests("myjavabin", "android_common").Module(), "mynativelib") + android.AssertIntEquals(t, "Create a dep on the first variant", 1, len(deps)) } diff --git a/java/jdeps_test.go b/java/jdeps_test.go index d282f1976..7a0fb10cb 100644 --- a/java/jdeps_test.go +++ b/java/jdeps_test.go @@ -109,7 +109,7 @@ func TestCollectJavaLibraryWithJarJarRules(t *testing.T) { module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library) dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey) - android.AssertBoolEquals(t, "IdeInfo.Srcs of repackaged library should be empty", true, len(dpInfo.Srcs) == 0) + android.AssertStringEquals(t, "IdeInfo.Srcs of repackaged library should not be empty", "foo.java", dpInfo.Srcs[0]) android.AssertStringEquals(t, "IdeInfo.Jar_rules of repackaged library should not be empty", "jarjar_rules.txt", dpInfo.Jarjar_rules[0]) if !android.SubstringInList(dpInfo.Jars, "soong/.intermediates/javalib/android_common/jarjar/turbine/javalib.jar") { t.Errorf("IdeInfo.Jars of repackaged library should contain the output of jarjar-ing. All outputs: %v\n", dpInfo.Jars) |