diff options
-rw-r--r-- | android/Android.bp | 1 | ||||
-rw-r--r-- | android/base_module_context.go | 60 | ||||
-rw-r--r-- | android/compliance_metadata.go | 31 | ||||
-rw-r--r-- | android/config.go | 8 | ||||
-rw-r--r-- | android/depset_generic.go | 49 | ||||
-rw-r--r-- | android/init.go | 5 | ||||
-rw-r--r-- | android/module.go | 128 | ||||
-rw-r--r-- | android/module_proxy.go | 203 | ||||
-rw-r--r-- | android/packaging.go | 68 | ||||
-rw-r--r-- | android/paths.go | 146 | ||||
-rw-r--r-- | android/provider.go | 2 | ||||
-rw-r--r-- | android/variable.go | 4 | ||||
-rw-r--r-- | apex/apex_singleton.go | 39 | ||||
-rw-r--r-- | apex/apex_test.go | 145 | ||||
-rw-r--r-- | etc/Android.bp | 1 | ||||
-rw-r--r-- | etc/adb_keys.go | 66 | ||||
-rw-r--r-- | filesystem/aconfig_files.go | 11 | ||||
-rw-r--r-- | golang/golang.go | 3 | ||||
-rw-r--r-- | java/aar.go | 6 | ||||
-rw-r--r-- | java/androidmk.go | 1 | ||||
-rw-r--r-- | java/base.go | 10 | ||||
-rw-r--r-- | java/java.go | 26 | ||||
-rw-r--r-- | java/java_test.go | 4 | ||||
-rw-r--r-- | java/sdk_library.go | 16 | ||||
-rw-r--r-- | rust/compiler.go | 4 |
25 files changed, 831 insertions, 206 deletions
diff --git a/android/Android.bp b/android/Android.bp index c2bef0bfe..eb8c64d85 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -71,6 +71,7 @@ bootstrap_go_package { "module.go", "module_context.go", "module_info_json.go", + "module_proxy.go", "mutator.go", "namespace.go", "neverallow.go", diff --git a/android/base_module_context.go b/android/base_module_context.go index c7d7573f1..670537fb5 100644 --- a/android/base_module_context.go +++ b/android/base_module_context.go @@ -33,6 +33,8 @@ type BaseModuleContext interface { blueprintBaseModuleContext() blueprint.BaseModuleContext + EqualModules(m1, m2 Module) bool + // OtherModuleName returns the name of another Module. See BaseModuleContext.ModuleName for more information. // It is intended for use inside the visit functions of Visit* and WalkDeps. OtherModuleName(m blueprint.Module) string @@ -130,6 +132,14 @@ type BaseModuleContext interface { // function, it may be invalidated by future mutators. VisitDirectDepsAllowDisabled(visit func(Module)) + // VisitDirectDepsProxyAllowDisabled calls visit for each direct dependency. If there are + // multiple direct dependencies on the same module visit will be called multiple times on + // that module and OtherModuleDependencyTag will return a different tag for each. + // + // The Module passed to the visit function should not be retained outside of the visit function, it may be + // invalidated by future mutators. + VisitDirectDepsProxyAllowDisabled(visit func(proxy Module)) + VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) // VisitDirectDepsIf calls pred for each direct dependency, and if pred returns true calls visit. If there are @@ -155,6 +165,16 @@ type BaseModuleContext interface { // invalidated by future mutators. WalkDeps(visit func(child, parent Module) bool) + // WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may + // be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the + // child and parent with different tags. OtherModuleDependencyTag will return the tag for the currently visited + // (child, parent) pair. If visit returns false WalkDeps will not continue recursing down to child. It skips + // any dependencies that are not an android.Module. + // + // The Modules passed to the visit function should not be retained outside of the visit function, they may be + // invalidated by future mutators. + WalkDepsProxy(visit func(child, parent Module) bool) + // GetWalkPath is supposed to be called in visit function passed in WalkDeps() // and returns a top-down dependency path from a start module to current child module. GetWalkPath() []Module @@ -214,15 +234,26 @@ type baseModuleContext struct { } +func getWrappedModule(module blueprint.Module) blueprint.Module { + if mp, isProxy := module.(ModuleProxy); isProxy { + return mp.module + } + return module +} + +func (b *baseModuleContext) EqualModules(m1, m2 Module) bool { + return b.bp.EqualModules(getWrappedModule(m1), getWrappedModule(m2)) +} + func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { - return b.bp.OtherModuleName(m) + return b.bp.OtherModuleName(getWrappedModule(m)) } func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) } func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) { b.bp.OtherModuleErrorf(m, fmt, args...) } func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag { - return b.bp.OtherModuleDependencyTag(m) + return b.bp.OtherModuleDependencyTag(getWrappedModule(m)) } func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) } func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool { @@ -395,6 +426,14 @@ func (b *baseModuleContext) VisitDirectDepsAllowDisabled(visit func(Module)) { }) } +func (b *baseModuleContext) VisitDirectDepsProxyAllowDisabled(visit func(proxy Module)) { + b.bp.VisitDirectDepsProxy(func(module blueprint.ModuleProxy) { + visit(ModuleProxy{ + module: module, + }) + }) +} + func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { b.bp.VisitDirectDeps(func(module blueprint.Module) { if b.bp.OtherModuleDependencyTag(module) == tag { @@ -466,6 +505,23 @@ func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { }) } +func (b *baseModuleContext) WalkDepsProxy(visit func(Module, Module) bool) { + b.walkPath = []Module{ModuleProxy{blueprint.CreateModuleProxy(b.Module())}} + b.tagPath = []blueprint.DependencyTag{} + b.bp.WalkDepsProxy(func(child, parent blueprint.ModuleProxy) bool { + childAndroidModule := ModuleProxy{child} + parentAndroidModule := ModuleProxy{parent} + // record walkPath before visit + for b.walkPath[len(b.walkPath)-1] != parentAndroidModule { + b.walkPath = b.walkPath[0 : len(b.walkPath)-1] + b.tagPath = b.tagPath[0 : len(b.tagPath)-1] + } + b.walkPath = append(b.walkPath, childAndroidModule) + b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule)) + return visit(childAndroidModule, parentAndroidModule) + }) +} + func (b *baseModuleContext) GetWalkPath() []Module { return b.walkPath } diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go index 38f138237..d28831e62 100644 --- a/android/compliance_metadata.go +++ b/android/compliance_metadata.go @@ -17,7 +17,6 @@ package android import ( "bytes" "encoding/csv" - "encoding/gob" "fmt" "slices" "strconv" @@ -126,32 +125,32 @@ type ComplianceMetadataInfo struct { properties map[string]string } +type complianceMetadataInfoGob struct { + Properties map[string]string +} + func NewComplianceMetadataInfo() *ComplianceMetadataInfo { return &ComplianceMetadataInfo{ properties: map[string]string{}, } } -func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) { - w := new(bytes.Buffer) - encoder := gob.NewEncoder(w) - err := encoder.Encode(c.properties) - if err != nil { - return nil, err +func (m *ComplianceMetadataInfo) ToGob() *complianceMetadataInfoGob { + return &complianceMetadataInfoGob{ + Properties: m.properties, } +} - return w.Bytes(), nil +func (m *ComplianceMetadataInfo) FromGob(data *complianceMetadataInfoGob) { + m.properties = data.Properties } -func (c *ComplianceMetadataInfo) GobDecode(data []byte) error { - r := bytes.NewBuffer(data) - decoder := gob.NewDecoder(r) - err := decoder.Decode(&c.properties) - if err != nil { - return err - } +func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[complianceMetadataInfoGob](c) +} - return nil +func (c *ComplianceMetadataInfo) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[complianceMetadataInfoGob](data, c) } func (c *ComplianceMetadataInfo) SetStringValue(propertyName string, value string) { diff --git a/android/config.go b/android/config.go index e51976054..06d71c06d 100644 --- a/android/config.go +++ b/android/config.go @@ -287,6 +287,10 @@ func (c Config) ReleaseReadFromNewStorage() bool { return c.config.productVariables.GetBuildFlagBool("RELEASE_READ_FROM_NEW_STORAGE") } +func (c Config) ReleaseCreateAconfigStorageFile() bool { + return c.config.productVariables.GetBuildFlagBool("RELEASE_CREATE_ACONFIG_STORAGE_FILE") +} + // A DeviceConfig object represents the configuration for a particular device // being built. For now there will only be one of these, but in the future there // may be multiple devices being built. @@ -2086,6 +2090,10 @@ func (c *config) OdmPropFiles(ctx PathContext) Paths { return PathsForSource(ctx, c.productVariables.OdmPropFiles) } +func (c *config) ExtraAllowedDepsTxt() string { + return String(c.productVariables.ExtraAllowedDepsTxt) +} + func (c *config) EnableUffdGc() string { return String(c.productVariables.EnableUffdGc) } diff --git a/android/depset_generic.go b/android/depset_generic.go index 690987a0c..d04f88b5b 100644 --- a/android/depset_generic.go +++ b/android/depset_generic.go @@ -15,10 +15,9 @@ package android import ( - "bytes" - "encoding/gob" - "errors" "fmt" + + "github.com/google/blueprint" ) // DepSet is designed to be conceptually compatible with Bazel's depsets: @@ -68,28 +67,38 @@ type DepSet[T depSettableType] struct { transitive []*DepSet[T] } -func (d *DepSet[T]) GobEncode() ([]byte, error) { - w := new(bytes.Buffer) - encoder := gob.NewEncoder(w) - err := errors.Join(encoder.Encode(d.preorder), encoder.Encode(d.reverse), - encoder.Encode(d.order), encoder.Encode(d.direct), encoder.Encode(d.transitive)) - if err != nil { - return nil, err +type depSetGob[T depSettableType] struct { + Preorder bool + Reverse bool + Order DepSetOrder + Direct []T + Transitive []*DepSet[T] +} + +func (d *DepSet[T]) ToGob() *depSetGob[T] { + return &depSetGob[T]{ + Preorder: d.preorder, + Reverse: d.reverse, + Order: d.order, + Direct: d.direct, + Transitive: d.transitive, } +} - return w.Bytes(), nil +func (d *DepSet[T]) FromGob(data *depSetGob[T]) { + d.preorder = data.Preorder + d.reverse = data.Reverse + d.order = data.Order + d.direct = data.Direct + d.transitive = data.Transitive } -func (d *DepSet[T]) GobDecode(data []byte) error { - r := bytes.NewBuffer(data) - decoder := gob.NewDecoder(r) - err := errors.Join(decoder.Decode(&d.preorder), decoder.Decode(&d.reverse), - decoder.Decode(&d.order), decoder.Decode(&d.direct), decoder.Decode(&d.transitive)) - if err != nil { - return err - } +func (d *DepSet[T]) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[depSetGob[T]](d) +} - return nil +func (d *DepSet[T]) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[depSetGob[T]](data, d) } // NewDepSet returns an immutable DepSet with the given order, direct and transitive contents. diff --git a/android/init.go b/android/init.go index b46229282..1ace34494 100644 --- a/android/init.go +++ b/android/init.go @@ -17,7 +17,12 @@ package android import "encoding/gob" func init() { + gob.Register(extraFilesZip{}) + gob.Register(InstallPath{}) + gob.Register(ModuleGenPath{}) gob.Register(ModuleOutPath{}) + gob.Register(OutputPath{}) gob.Register(PhonyPath{}) + gob.Register(SourcePath{}) gob.Register(unstableInfo{}) } diff --git a/android/module.go b/android/module.go index a1a9a4ad2..e3682fa30 100644 --- a/android/module.go +++ b/android/module.go @@ -15,9 +15,6 @@ package android import ( - "bytes" - "encoding/gob" - "errors" "fmt" "net/url" "path/filepath" @@ -1806,6 +1803,26 @@ type FinalModuleBuildTargetsInfo struct { var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]() +type CommonPropertiesProviderData struct { + Enabled bool + // Whether the module has been replaced by a prebuilt + ReplacedByPrebuilt bool +} + +var CommonPropertiesProviderKey = blueprint.NewProvider[CommonPropertiesProviderData]() + +type PrebuiltModuleProviderData struct { + // Empty for now +} + +var PrebuiltModuleProviderKey = blueprint.NewProvider[PrebuiltModuleProviderData]() + +type HostToolProviderData struct { + HostToolPath OptionalPath +} + +var HostToolProviderKey = blueprint.NewProvider[HostToolProviderData]() + func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) { ctx := &moduleContext{ module: m.module, @@ -2051,6 +2068,23 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) }) } buildComplianceMetadataProvider(ctx, m) + + commonData := CommonPropertiesProviderData{ + ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt, + } + if m.commonProperties.ForcedDisabled { + commonData.Enabled = false + } else { + commonData.Enabled = m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled) + } + SetProvider(ctx, CommonPropertiesProviderKey, commonData) + if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil { + SetProvider(ctx, PrebuiltModuleProviderKey, PrebuiltModuleProviderData{}) + } + if h, ok := m.module.(HostToolProvider); ok { + SetProvider(ctx, HostToolProviderKey, HostToolProviderData{ + HostToolPath: h.HostToolPath()}) + } } func SetJarJarPrefixHandler(handler func(ModuleContext)) { @@ -2130,36 +2164,47 @@ type katiInstall struct { orderOnlyDeps Paths executable bool extraFiles *extraFilesZip + absFrom string +} - absFrom string +type katiInstallGob struct { + From Path + To InstallPath + ImplicitDeps Paths + OrderOnlyDeps Paths + Executable bool + ExtraFiles *extraFilesZip + AbsFrom string } -func (p *katiInstall) GobEncode() ([]byte, error) { - w := new(bytes.Buffer) - encoder := gob.NewEncoder(w) - err := errors.Join(encoder.Encode(p.from), encoder.Encode(p.to), - encoder.Encode(p.implicitDeps), encoder.Encode(p.orderOnlyDeps), - encoder.Encode(p.executable), encoder.Encode(p.extraFiles), - encoder.Encode(p.absFrom)) - if err != nil { - return nil, err +func (k *katiInstall) ToGob() *katiInstallGob { + return &katiInstallGob{ + From: k.from, + To: k.to, + ImplicitDeps: k.implicitDeps, + OrderOnlyDeps: k.orderOnlyDeps, + Executable: k.executable, + ExtraFiles: k.extraFiles, + AbsFrom: k.absFrom, } +} - return w.Bytes(), nil +func (k *katiInstall) FromGob(data *katiInstallGob) { + k.from = data.From + k.to = data.To + k.implicitDeps = data.ImplicitDeps + k.orderOnlyDeps = data.OrderOnlyDeps + k.executable = data.Executable + k.extraFiles = data.ExtraFiles + k.absFrom = data.AbsFrom } -func (p *katiInstall) GobDecode(data []byte) error { - r := bytes.NewBuffer(data) - decoder := gob.NewDecoder(r) - err := errors.Join(decoder.Decode(&p.from), decoder.Decode(&p.to), - decoder.Decode(&p.implicitDeps), decoder.Decode(&p.orderOnlyDeps), - decoder.Decode(&p.executable), decoder.Decode(&p.extraFiles), - decoder.Decode(&p.absFrom)) - if err != nil { - return err - } +func (k *katiInstall) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[katiInstallGob](k) +} - return nil +func (k *katiInstall) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[katiInstallGob](data, k) } type extraFilesZip struct { @@ -2167,26 +2212,29 @@ type extraFilesZip struct { dir InstallPath } -func (p *extraFilesZip) GobEncode() ([]byte, error) { - w := new(bytes.Buffer) - encoder := gob.NewEncoder(w) - err := errors.Join(encoder.Encode(p.zip), encoder.Encode(p.dir)) - if err != nil { - return nil, err +type extraFilesZipGob struct { + Zip Path + Dir InstallPath +} + +func (e *extraFilesZip) ToGob() *extraFilesZipGob { + return &extraFilesZipGob{ + Zip: e.zip, + Dir: e.dir, } +} - return w.Bytes(), nil +func (e *extraFilesZip) FromGob(data *extraFilesZipGob) { + e.zip = data.Zip + e.dir = data.Dir } -func (p *extraFilesZip) GobDecode(data []byte) error { - r := bytes.NewBuffer(data) - decoder := gob.NewDecoder(r) - err := errors.Join(decoder.Decode(&p.zip), decoder.Decode(&p.dir)) - if err != nil { - return err - } +func (e *extraFilesZip) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[extraFilesZipGob](e) +} - return nil +func (e *extraFilesZip) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[extraFilesZipGob](data, e) } type katiInstalls []katiInstall diff --git a/android/module_proxy.go b/android/module_proxy.go new file mode 100644 index 000000000..bc5090ecb --- /dev/null +++ b/android/module_proxy.go @@ -0,0 +1,203 @@ +package android + +import ( + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +type ModuleProxy struct { + module blueprint.ModuleProxy +} + +func (m ModuleProxy) Name() string { + return m.module.Name() +} + +func (m ModuleProxy) GenerateBuildActions(context blueprint.ModuleContext) { + m.module.GenerateBuildActions(context) +} + +func (m ModuleProxy) GenerateAndroidBuildActions(context ModuleContext) { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) ComponentDepsMutator(ctx BottomUpMutatorContext) { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) DepsMutator(context BottomUpMutatorContext) { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) base() *ModuleBase { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) Disable() { + + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) Enabled(ctx ConfigurableEvaluatorContext) bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) Target() Target { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) MultiTargets() []Target { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) ImageVariation() blueprint.Variation { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) Owner() string { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInData() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInTestcases() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInSanitizerDir() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInRamdisk() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInVendorRamdisk() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInDebugRamdisk() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInRecovery() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInRoot() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInOdm() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInProduct() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInVendor() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallInSystemExt() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) InstallForceOS() (*OsType, *ArchType) { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) PartitionTag(d DeviceConfig) string { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) HideFromMake() { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) IsHideFromMake() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) IsSkipInstall() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) MakeUninstallable() { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) ReplacedByPrebuilt() { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) IsReplacedByPrebuilt() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) ExportedToMake() bool { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) EffectiveLicenseKinds() []string { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) EffectiveLicenseFiles() Paths { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) AddProperties(props ...interface{}) { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) GetProperties() []interface{} { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) BuildParamsForTests() []BuildParams { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) VariablesForTests() map[string]string { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) String() string { + return m.module.Name() +} + +func (m ModuleProxy) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) visibilityProperties() []visibilityProperty { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) HostRequiredModuleNames() []string { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) TargetRequiredModuleNames() []string { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string { + panic("method is not implemented on ModuleProxy") +} + +func (m ModuleProxy) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator { + panic("method is not implemented on ModuleProxy") +} diff --git a/android/packaging.go b/android/packaging.go index 0909936c6..3c64d56f0 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -15,9 +15,6 @@ package android import ( - "bytes" - "encoding/gob" - "errors" "fmt" "path/filepath" "sort" @@ -67,34 +64,53 @@ type PackagingSpec struct { owner string } -func (p *PackagingSpec) GobEncode() ([]byte, error) { - w := new(bytes.Buffer) - encoder := gob.NewEncoder(w) - err := errors.Join(encoder.Encode(p.relPathInPackage), encoder.Encode(p.srcPath), - encoder.Encode(p.symlinkTarget), encoder.Encode(p.executable), - encoder.Encode(p.effectiveLicenseFiles), encoder.Encode(p.partition), - encoder.Encode(p.skipInstall), encoder.Encode(p.aconfigPaths), - encoder.Encode(p.archType)) - if err != nil { - return nil, err +type packagingSpecGob struct { + RelPathInPackage string + SrcPath Path + SymlinkTarget string + Executable bool + 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, } +} - return w.Bytes(), nil +func (p *PackagingSpec) FromGob(data *packagingSpecGob) { + p.relPathInPackage = data.RelPathInPackage + p.srcPath = data.SrcPath + p.symlinkTarget = data.SymlinkTarget + p.executable = data.Executable + p.partition = data.Partition + p.skipInstall = data.SkipInstall + p.aconfigPaths = data.AconfigPaths + p.archType = data.ArchType + p.overrides = data.Overrides + p.owner = data.Owner } -func (p *PackagingSpec) GobDecode(data []byte) error { - r := bytes.NewBuffer(data) - decoder := gob.NewDecoder(r) - err := errors.Join(decoder.Decode(&p.relPathInPackage), decoder.Decode(&p.srcPath), - decoder.Decode(&p.symlinkTarget), decoder.Decode(&p.executable), - decoder.Decode(&p.effectiveLicenseFiles), decoder.Decode(&p.partition), - decoder.Decode(&p.skipInstall), decoder.Decode(&p.aconfigPaths), - decoder.Decode(&p.archType)) - if err != nil { - return err - } +func (p *PackagingSpec) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[packagingSpecGob](p) +} - return nil +func (p *PackagingSpec) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[packagingSpecGob](data, p) } func (p *PackagingSpec) Equals(other *PackagingSpec) bool { diff --git a/android/paths.go b/android/paths.go index 1c8258ede..9c2df6589 100644 --- a/android/paths.go +++ b/android/paths.go @@ -15,9 +15,6 @@ package android import ( - "bytes" - "encoding/gob" - "errors" "fmt" "os" "path/filepath" @@ -342,6 +339,11 @@ type OptionalPath struct { invalidReason string // Not applicable if path != nil. "" if the reason is unknown. } +type optionalPathGob struct { + Path Path + InvalidReason string +} + // OptionalPathForPath returns an OptionalPath containing the path. func OptionalPathForPath(path Path) OptionalPath { return OptionalPath{path: path} @@ -353,6 +355,26 @@ func InvalidOptionalPath(reason string) OptionalPath { return OptionalPath{invalidReason: reason} } +func (p *OptionalPath) ToGob() *optionalPathGob { + return &optionalPathGob{ + Path: p.path, + InvalidReason: p.invalidReason, + } +} + +func (p *OptionalPath) FromGob(data *optionalPathGob) { + p.path = data.Path + p.invalidReason = data.InvalidReason +} + +func (p OptionalPath) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[optionalPathGob](&p) +} + +func (p *OptionalPath) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[optionalPathGob](data, p) +} + // Valid returns whether there is a valid path func (p OptionalPath) Valid() bool { return p.path != nil @@ -1065,26 +1087,29 @@ type basePath struct { rel string } -func (p basePath) GobEncode() ([]byte, error) { - w := new(bytes.Buffer) - encoder := gob.NewEncoder(w) - err := errors.Join(encoder.Encode(p.path), encoder.Encode(p.rel)) - if err != nil { - return nil, err +type basePathGob struct { + Path string + Rel string +} + +func (p *basePath) ToGob() *basePathGob { + return &basePathGob{ + Path: p.path, + Rel: p.rel, } +} - return w.Bytes(), nil +func (p *basePath) FromGob(data *basePathGob) { + p.path = data.Path + p.rel = data.Rel } -func (p *basePath) GobDecode(data []byte) error { - r := bytes.NewBuffer(data) - decoder := gob.NewDecoder(r) - err := errors.Join(decoder.Decode(&p.path), decoder.Decode(&p.rel)) - if err != nil { - return err - } +func (p basePath) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[basePathGob](&p) +} - return nil +func (p *basePath) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[basePathGob](data, p) } func (p basePath) Ext() string { @@ -1337,26 +1362,32 @@ type OutputPath struct { fullPath string } -func (p OutputPath) GobEncode() ([]byte, error) { - w := new(bytes.Buffer) - encoder := gob.NewEncoder(w) - err := errors.Join(encoder.Encode(p.basePath), encoder.Encode(p.outDir), encoder.Encode(p.fullPath)) - if err != nil { - return nil, err +type outputPathGob struct { + basePath + OutDir string + FullPath string +} + +func (p *OutputPath) ToGob() *outputPathGob { + return &outputPathGob{ + basePath: p.basePath, + OutDir: p.outDir, + FullPath: p.fullPath, } +} - return w.Bytes(), nil +func (p *OutputPath) FromGob(data *outputPathGob) { + p.basePath = data.basePath + p.outDir = data.OutDir + p.fullPath = data.FullPath } -func (p *OutputPath) GobDecode(data []byte) error { - r := bytes.NewBuffer(data) - decoder := gob.NewDecoder(r) - err := errors.Join(decoder.Decode(&p.basePath), decoder.Decode(&p.outDir), decoder.Decode(&p.fullPath)) - if err != nil { - return err - } +func (p OutputPath) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[outputPathGob](&p) +} - return nil +func (p *OutputPath) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[outputPathGob](data, p) } func (p OutputPath) withRel(rel string) OutputPath { @@ -1756,30 +1787,41 @@ type InstallPath struct { fullPath string } -func (p *InstallPath) GobEncode() ([]byte, error) { - w := new(bytes.Buffer) - encoder := gob.NewEncoder(w) - err := errors.Join(encoder.Encode(p.basePath), encoder.Encode(p.soongOutDir), - encoder.Encode(p.partitionDir), encoder.Encode(p.partition), - encoder.Encode(p.makePath), encoder.Encode(p.fullPath)) - if err != nil { - return nil, err +type installPathGob struct { + basePath + SoongOutDir string + PartitionDir string + Partition string + MakePath bool + FullPath string +} + +func (p *InstallPath) ToGob() *installPathGob { + return &installPathGob{ + basePath: p.basePath, + SoongOutDir: p.soongOutDir, + PartitionDir: p.partitionDir, + Partition: p.partition, + MakePath: p.makePath, + FullPath: p.fullPath, } +} - return w.Bytes(), nil +func (p *InstallPath) FromGob(data *installPathGob) { + p.basePath = data.basePath + p.soongOutDir = data.SoongOutDir + p.partitionDir = data.PartitionDir + p.partition = data.Partition + p.makePath = data.MakePath + p.fullPath = data.FullPath } -func (p *InstallPath) GobDecode(data []byte) error { - r := bytes.NewBuffer(data) - decoder := gob.NewDecoder(r) - err := errors.Join(decoder.Decode(&p.basePath), decoder.Decode(&p.soongOutDir), - decoder.Decode(&p.partitionDir), decoder.Decode(&p.partition), - decoder.Decode(&p.makePath), decoder.Decode(&p.fullPath)) - if err != nil { - return err - } +func (p InstallPath) GobEncode() ([]byte, error) { + return blueprint.CustomGobEncode[installPathGob](&p) +} - return nil +func (p *InstallPath) GobDecode(data []byte) error { + return blueprint.CustomGobDecode[installPathGob](data, p) } // Will panic if called from outside a test environment. diff --git a/android/provider.go b/android/provider.go index 5ded4cc14..81d17a175 100644 --- a/android/provider.go +++ b/android/provider.go @@ -24,7 +24,7 @@ var _ OtherModuleProviderContext = (*TestContext)(nil) // OtherModuleProviderContext is a helper interface that accepts ModuleContext, BottomUpMutatorContext, or // TopDownMutatorContext. func OtherModuleProvider[K any](ctx OtherModuleProviderContext, module blueprint.Module, provider blueprint.ProviderKey[K]) (K, bool) { - value, ok := ctx.otherModuleProvider(module, provider) + value, ok := ctx.otherModuleProvider(getWrappedModule(module), provider) if !ok { var k K return k, false diff --git a/android/variable.go b/android/variable.go index 1aaa70a0e..417ba8978 100644 --- a/android/variable.go +++ b/android/variable.go @@ -522,6 +522,10 @@ type ProductVariables struct { DeviceProductCompatibilityMatrixFile []string `json:",omitempty"` PartitionVarsForSoongMigrationOnlyDoNotUse PartitionVariables + + ExtraAllowedDepsTxt *string `json:",omitempty"` + + AdbKeys *string `json:",omitempty"` } type PartitionQualifiedVariablesType struct { diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go index f405cb2fe..00dd44648 100644 --- a/apex/apex_singleton.go +++ b/apex/apex_singleton.go @@ -18,6 +18,7 @@ package apex import ( "encoding/json" + "strings" "github.com/google/blueprint" @@ -58,9 +59,9 @@ var ( // Diff two given lists while ignoring comments in the allowed deps file. diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{ - Description: "Diff ${allowed_deps} and ${new_allowed_deps}", + Description: "Diff ${allowed_deps_list} and ${new_allowed_deps}", Command: ` - if grep -v '^#' ${allowed_deps} | diff -B - ${new_allowed_deps}; then + if grep -v -h '^#' ${allowed_deps_list} | sort -u -f| diff -B -u - ${new_allowed_deps}; then touch ${out}; else echo -e "\n******************************"; @@ -81,10 +82,15 @@ var ( exit 1; fi; `, - }, "allowed_deps", "new_allowed_deps") + }, "allowed_deps_list", "new_allowed_deps") ) func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) { + allowedDepsSources := []android.OptionalPath{android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")} + extraAllowedDepsPath := ctx.Config().ExtraAllowedDepsTxt() + if extraAllowedDepsPath != "" { + allowedDepsSources = append(allowedDepsSources, android.ExistentPathForSource(ctx, extraAllowedDepsPath)) + } updatableFlatLists := android.Paths{} ctx.VisitAllModules(func(module android.Module) { if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok { @@ -96,37 +102,42 @@ func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContex } } }) - - allowedDepsSource := android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt") newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt") s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check") - - if !allowedDepsSource.Valid() { + hasOneValidDepsPath := false + for _, allowedDepsSource := range allowedDepsSources { + if allowedDepsSource.Valid() { + hasOneValidDepsPath = true + updatableFlatLists = append(updatableFlatLists, allowedDepsSource.Path()) + } + } + allowedDepsStrList := make([]string, len(allowedDepsSources)) + for _, value := range allowedDepsSources { + allowedDepsStrList = append(allowedDepsStrList, value.String()) + } + allowedDepsListString := strings.Join(allowedDepsStrList, " ") + if !hasOneValidDepsPath { // Unbundled projects may not have packages/modules/common/ checked out; ignore those. ctx.Build(pctx, android.BuildParams{ Rule: android.Touch, Output: s.allowedApexDepsInfoCheckResult, }) } else { - allowedDeps := allowedDepsSource.Path() - ctx.Build(pctx, android.BuildParams{ Rule: generateApexDepsInfoFilesRule, - Inputs: append(updatableFlatLists, allowedDeps), + Inputs: updatableFlatLists, Output: newAllowedDeps, }) - ctx.Build(pctx, android.BuildParams{ Rule: diffAllowedApexDepsInfoRule, Input: newAllowedDeps, Output: s.allowedApexDepsInfoCheckResult, Args: map[string]string{ - "allowed_deps": allowedDeps.String(), - "new_allowed_deps": newAllowedDeps.String(), + "allowed_deps_list": allowedDepsListString, + "new_allowed_deps": newAllowedDeps.String(), }, }) } - ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult) } diff --git a/apex/apex_test.go b/apex/apex_test.go index 153ee3108..1d2f3fb9d 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -2185,6 +2185,151 @@ func TestTrackAllowedDeps(t *testing.T) { flatlist, "yourlib(minSdkVersion:29)") } +func TestTrackCustomAllowedDepsInvalidDefaultTxt(t *testing.T) { + ctx := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + updatable: true, + native_shared_libs: [ + "mylib", + "yourlib", + ], + min_sdk_version: "29", + } + + apex { + name: "myapex2", + key: "myapex.key", + updatable: false, + native_shared_libs: ["yourlib"], + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + shared_libs: ["libbar"], + min_sdk_version: "29", + apex_available: ["myapex"], + } + + cc_library { + name: "libbar", + stubs: { versions: ["29", "30"] }, + } + + cc_library { + name: "yourlib", + srcs: ["mylib.cpp"], + min_sdk_version: "29", + apex_available: ["myapex", "myapex2", "//apex_available:platform"], + } + `, withFiles(android.MockFS{ + "packages/modules/common/build/custom_allowed_deps.txt": nil, + }), + android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.ExtraAllowedDepsTxt = proptools.StringPtr("packages/modules/common/build/custom_allowed_deps.txt") + }, + )) + + depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton") + inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings() + android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs, + "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt") + android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs, + "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt") + + myapex := ctx.ModuleForTests("myapex", "android_common_myapex") + flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx, + myapex.Output("depsinfo/flatlist.txt")), "\n") + android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep", + flatlist, "libbar(minSdkVersion:(no version)) (external)") + android.AssertStringListDoesNotContain(t, "do not track if not available for platform", + flatlist, "mylib:(minSdkVersion:29)") + android.AssertStringListContains(t, "track platform-available lib", + flatlist, "yourlib(minSdkVersion:29)") +} + +func TestTrackCustomAllowedDepsWithDefaultTxt(t *testing.T) { + ctx := testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + updatable: true, + native_shared_libs: [ + "mylib", + "yourlib", + ], + min_sdk_version: "29", + } + + apex { + name: "myapex2", + key: "myapex.key", + updatable: false, + native_shared_libs: ["yourlib"], + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + shared_libs: ["libbar"], + min_sdk_version: "29", + apex_available: ["myapex"], + } + + cc_library { + name: "libbar", + stubs: { versions: ["29", "30"] }, + } + + cc_library { + name: "yourlib", + srcs: ["mylib.cpp"], + min_sdk_version: "29", + apex_available: ["myapex", "myapex2", "//apex_available:platform"], + } + `, withFiles(android.MockFS{ + "packages/modules/common/build/custom_allowed_deps.txt": nil, + "packages/modules/common/build/allowed_deps.txt": nil, + }), + android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.ExtraAllowedDepsTxt = proptools.StringPtr("packages/modules/common/build/custom_allowed_deps.txt") + }, + )) + + depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton") + inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings() + android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs, + "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt") + android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs, + "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt") + + myapex := ctx.ModuleForTests("myapex", "android_common_myapex") + flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx, + myapex.Output("depsinfo/flatlist.txt")), "\n") + android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep", + flatlist, "libbar(minSdkVersion:(no version)) (external)") + android.AssertStringListDoesNotContain(t, "do not track if not available for platform", + flatlist, "mylib:(minSdkVersion:29)") + android.AssertStringListContains(t, "track platform-available lib", + flatlist, "yourlib(minSdkVersion:29)") +} + func TestTrackAllowedDeps_SkipWithoutAllowedDepsTxt(t *testing.T) { ctx := testApex(t, ` apex { diff --git a/etc/Android.bp b/etc/Android.bp index 580c54f9b..8e043b86e 100644 --- a/etc/Android.bp +++ b/etc/Android.bp @@ -11,6 +11,7 @@ bootstrap_go_package { "soong-android", ], srcs: [ + "adb_keys.go", "install_symlink.go", "otacerts_zip.go", "prebuilt_etc.go", diff --git a/etc/adb_keys.go b/etc/adb_keys.go new file mode 100644 index 000000000..1bce2f124 --- /dev/null +++ b/etc/adb_keys.go @@ -0,0 +1,66 @@ +// Copyright 2024 Google Inc. All rights reserved. +// +// 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 etc + +import ( + "android/soong/android" +) + +func init() { + android.RegisterModuleType("adb_keys", AdbKeysModuleFactory) +} + +type AdbKeysModule struct { + android.ModuleBase + outputPath android.OutputPath + installPath android.InstallPath +} + +func AdbKeysModuleFactory() android.Module { + module := &AdbKeysModule{} + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) + return module +} + +func (m *AdbKeysModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + productVariables := ctx.Config().ProductVariables() + if !(android.Bool(productVariables.Debuggable) && len(android.String(productVariables.AdbKeys)) > 0) { + m.Disable() + m.SkipInstall() + return + } + + m.outputPath = android.PathForModuleOut(ctx, "adb_keys").OutputPath + input := android.ExistentPathForSource(ctx, android.String(productVariables.AdbKeys)) + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, + Output: m.outputPath, + Input: input.Path(), + }) + m.installPath = android.PathForModuleInPartitionInstall(ctx, ctx.DeviceConfig().ProductPath(), "etc/security") + ctx.InstallFile(m.installPath, "adb_keys", m.outputPath) +} + +func (m *AdbKeysModule) AndroidMkEntries() []android.AndroidMkEntries { + if m.IsSkipInstall() { + return []android.AndroidMkEntries{} + } + + return []android.AndroidMkEntries{ + { + Class: "ETC", + OutputFile: android.OptionalPathForPath(m.outputPath), + }} +} diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go index 8af2ffaab..608fccdad 100644 --- a/filesystem/aconfig_files.go +++ b/filesystem/aconfig_files.go @@ -76,10 +76,13 @@ func (f *filesystem) buildAconfigFlagsFiles(ctx android.ModuleContext, builder * cmd.ImplicitOutput(outputPath) f.appendToEntry(ctx, outputPath) } - generatePartitionAconfigStorageFile("package_map", "package.map") - generatePartitionAconfigStorageFile("flag_map", "flag.map") - generatePartitionAconfigStorageFile("flag_val", "flag.val") - generatePartitionAconfigStorageFile("flag_info", "flag.info") + + if ctx.Config().ReleaseCreateAconfigStorageFile() { + generatePartitionAconfigStorageFile("package_map", "package.map") + generatePartitionAconfigStorageFile("flag_map", "flag.map") + generatePartitionAconfigStorageFile("flag_val", "flag.val") + generatePartitionAconfigStorageFile("flag_info", "flag.info") + } android.WriteExecutableFileRuleVerbatim(ctx, aconfigFlagsBuilderPath, sb.String()) } diff --git a/golang/golang.go b/golang/golang.go index 618a0852b..6ee924f1d 100644 --- a/golang/golang.go +++ b/golang/golang.go @@ -22,6 +22,7 @@ package golang import ( "android/soong/android" + "github.com/google/blueprint" "github.com/google/blueprint/bootstrap" ) @@ -46,7 +47,7 @@ type GoPackage struct { func goPackageModuleFactory() android.Module { module := &GoPackage{} module.AddProperties(module.Properties()...) - android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) + android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst) return module } diff --git a/java/aar.go b/java/aar.go index 7d73b03e4..41cc24a0d 100644 --- a/java/aar.go +++ b/java/aar.go @@ -483,9 +483,9 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio } linkFlags = append(linkFlags, "--no-static-lib-packages") - if a.isLibrary && a.useResourceProcessorBusyBox(ctx) { - // When building an android_library using ResourceProcessorBusyBox pass --merge-only to skip resource - // references validation until the final app link step when all static libraries are present. + if a.isLibrary { + // Pass --merge-only to skip resource references validation until the final + // app link step when when all static libraries are present. linkFlags = append(linkFlags, "--merge-only") } diff --git a/java/androidmk.go b/java/androidmk.go index 0539d25aa..2dff6cd9f 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -313,6 +313,7 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries { 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{ diff --git a/java/base.go b/java/base.go index fc21c44e5..7a957350a 100644 --- a/java/base.go +++ b/java/base.go @@ -1628,7 +1628,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath if j.ravenizer.enabled { ravenizerInput := outputFile - ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", jarName) + ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", "", jarName) ravenizerArgs := "" if proptools.Bool(j.properties.Ravenizer.Strip_mockito) { ravenizerArgs = "--strip-mockito" @@ -1637,6 +1637,14 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath outputFile = ravenizerOutput localImplementationJars = android.Paths{ravenizerOutput} completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, localImplementationJars, nil) + if combinedResourceJar != nil { + ravenizerInput = combinedResourceJar + ravenizerOutput = android.PathForModuleOut(ctx, "ravenizer", "resources", jarName) + TransformRavenizer(ctx, ravenizerOutput, ravenizerInput, ravenizerArgs) + combinedResourceJar = ravenizerOutput + localResourceJars = android.Paths{ravenizerOutput} + completeStaticLibsResourceJars = android.NewDepSet(android.PREORDER, localResourceJars, nil) + } } if j.shouldApiMapper() { diff --git a/java/java.go b/java/java.go index 661422b54..018850fef 100644 --- a/java/java.go +++ b/java/java.go @@ -1795,8 +1795,7 @@ type binaryProperties struct { // Name of the class containing main to be inserted into the manifest as Main-Class. Main_class *string - // Names of modules containing JNI libraries that should be installed alongside the host - // variant of the binary. + // Names of modules containing JNI libraries that should be installed alongside the binary. Jni_libs []string `android:"arch_variant"` } @@ -1809,6 +1808,8 @@ type Binary struct { wrapperFile android.Path binaryFile android.InstallPath + + androidMkNamesOfJniLibs []string } func (j *Binary) HostToolPath() android.OptionalPath { @@ -1880,6 +1881,21 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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()) + } + }) } } @@ -1888,11 +1904,9 @@ func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { j.deps(ctx) } // These dependencies ensure the installation rules will install the jar file when the - // wrapper is installed, and the jni libraries on host when the wrapper is installed. - if ctx.Arch().ArchType != android.Common && ctx.Os().Class == android.Host { - ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) - } + // 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()) diff --git a/java/java_test.go b/java/java_test.go index db154ce98..24dabdb10 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -3102,7 +3102,7 @@ func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTe } } -// Test that a dependency edge is created to the "first" variant of a native library listed in `required` of java_binary +// Test that a dependency edge is created to the matching variant of a native library listed in `jni_libs` of java_binary func TestNativeRequiredDepOfJavaBinary(t *testing.T) { findDepsOfModule := func(ctx *android.TestContext, module android.Module, depName string) []blueprint.Module { var ret []blueprint.Module @@ -3118,7 +3118,7 @@ func TestNativeRequiredDepOfJavaBinary(t *testing.T) { java_binary { name: "myjavabin", main_class: "com.android.MyJava", - required: ["mynativelib"], + jni_libs: ["mynativelib"], } cc_library_shared { name: "mynativelib", diff --git a/java/sdk_library.go b/java/sdk_library.go index f30877258..dfbde0e54 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2481,19 +2481,3 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo propertySet.AddProperty("doctag_files", dests) } } - -// TODO(b/358613520): This can be removed when modules are no longer allowed to depend on the top-level library. -func (s *SdkLibrary) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { - s.Library.IDEInfo(ctx, dpInfo) - if s.implLibraryModule != nil { - dpInfo.Deps = append(dpInfo.Deps, s.implLibraryModule.Name()) - } else { - // This java_sdk_library does not have an implementation (it sets `api_only` to true). - // Examples of this are `art.module.intra.core.api` (IntraCore api surface). - // Return the "public" stubs for these. - stubPaths := s.findClosestScopePath(apiScopePublic) - if len(stubPaths.stubsHeaderPath) > 0 { - dpInfo.Jars = append(dpInfo.Jars, stubPaths.stubsHeaderPath[0].String()) - } - } -} diff --git a/rust/compiler.go b/rust/compiler.go index 5bce16b8d..fd869174c 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -154,7 +154,7 @@ type BaseCompilerProperties struct { // list of rust automatic crate dependencies. // Rustlibs linkage is rlib for host targets and dylib for device targets. - Rustlibs []string `android:"arch_variant"` + Rustlibs proptools.Configurable[[]string] `android:"arch_variant"` // list of rust proc_macro crate dependencies Proc_macros []string `android:"arch_variant"` @@ -497,7 +497,7 @@ func (compiler *baseCompiler) strippedOutputFilePath() android.OptionalPath { func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...) - deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs...) + deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs.GetOrDefault(ctx, nil)...) deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...) deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...) deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs...) |