Merge "Remove versioned_ndk_headers module type." into main
diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go
index 9b638e7..250fd56 100644
--- a/aconfig/aconfig_declarations.go
+++ b/aconfig/aconfig_declarations.go
@@ -219,11 +219,4 @@
android.SetProvider(ctx, android.AconfigReleaseDeclarationsProviderKey, providerData)
}
-func (module *DeclarationsModule) BuildActionProviderKeys() []blueprint.AnyProviderKey {
- return []blueprint.AnyProviderKey{
- android.AconfigDeclarationsProviderKey,
- android.AconfigReleaseDeclarationsProviderKey,
- }
-}
-
var _ blueprint.Incremental = &DeclarationsModule{}
diff --git a/aconfig/init.go b/aconfig/init.go
index 5fa7e76..6f91d8e 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -15,8 +15,6 @@
package aconfig
import (
- "encoding/gob"
-
"android/soong/android"
"github.com/google/blueprint"
@@ -108,10 +106,6 @@
RegisterBuildComponents(android.InitRegistrationContext)
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("soong_zip", "soong_zip")
-
- gob.Register(android.AconfigDeclarationsProviderData{})
- gob.Register(android.AconfigReleaseDeclarationsProviderData{})
- gob.Register(android.ModuleOutPath{})
}
func RegisterBuildComponents(ctx android.RegistrationContext) {
diff --git a/android/Android.bp b/android/Android.bp
index 78eca11..16a34b7 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -59,6 +59,7 @@
"gen_notice.go",
"hooks.go",
"image.go",
+ "init.go",
"license.go",
"license_kind.go",
"license_metadata.go",
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index f0675dd..6bfbf37 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -136,7 +136,7 @@
AconfigFiles: mergedAconfigFiles,
ModeInfos: mergedModeInfos,
})
- ctx.Module().base().aconfigFilePaths = getAconfigFilePaths(ctx.Module().base(), mergedAconfigFiles)
+ ctx.setAconfigPaths(getAconfigFilePaths(ctx.Module().base(), mergedAconfigFiles))
}
}
diff --git a/android/androidmk.go b/android/androidmk.go
index 68a6415..fb51531 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -554,6 +554,14 @@
a.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install))
}
+ if info.UncheckedModule {
+ a.SetBool("LOCAL_DONT_CHECK_MODULE", true)
+ } else if info.CheckbuildTarget != nil {
+ a.SetPath("LOCAL_CHECKED_MODULE", info.CheckbuildTarget)
+ } else {
+ a.SetOptionalPath("LOCAL_CHECKED_MODULE", a.OutputFile)
+ }
+
if len(info.TestData) > 0 {
a.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...)
}
diff --git a/android/apex.go b/android/apex.go
index b19c477..29b2a9f 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -712,7 +712,7 @@
base.ApexProperties.InAnyApex = true
base.ApexProperties.DirectlyInAnyApex = inApex == directlyInApex
- if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) {
+ if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) && module.NotAvailableForPlatform() {
// Do not install the module for platform, but still allow it to output
// uninstallable AndroidMk entries in certain cases when they have side
// effects. TODO(jiyong): move this routine to somewhere else
diff --git a/android/arch_list.go b/android/arch_list.go
index f1289a3..2937092 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -159,6 +159,9 @@
"armv9-a": {
"dotprod",
},
+ "armv9-2a": {
+ "dotprod",
+ },
},
X86: {
"amberlake": {
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index a7b65e0..38f1382 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -17,6 +17,7 @@
import (
"bytes"
"encoding/csv"
+ "encoding/gob"
"fmt"
"slices"
"strconv"
@@ -131,6 +132,28 @@
}
}
+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
+ }
+
+ return w.Bytes(), nil
+}
+
+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
+ }
+
+ return nil
+}
+
func (c *ComplianceMetadataInfo) SetStringValue(propertyName string, value string) {
if !slices.Contains(COMPLIANCE_METADATA_PROPS, propertyName) {
panic(fmt.Errorf("Unknown metadata property: %s.", propertyName))
diff --git a/android/config.go b/android/config.go
index bbb08dd..cf3499f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1490,11 +1490,6 @@
}
}
if coverage && len(c.config.productVariables.NativeCoverageExcludePaths) > 0 {
- // Workaround coverage boot failure.
- // http://b/269981180
- if strings.HasPrefix(path, "external/protobuf") {
- coverage = false
- }
if HasAnyPrefix(path, c.config.productVariables.NativeCoverageExcludePaths) {
coverage = false
}
diff --git a/android/container.go b/android/container.go
index 63fb362..c048d6c 100644
--- a/android/container.go
+++ b/android/container.go
@@ -91,6 +91,10 @@
"framework-annotations-lib",
"unsupportedappusage",
+ // TODO(b/363016634): Remove from the allowlist when the module is converted
+ // to java_sdk_library and the java_aconfig_library modules depend on the stub.
+ "aconfig_storage_reader_java",
+
// framework-res provides core resources essential for building apps and system UI.
// This module is implicitly added as a dependency for java modules even when the
// dependency specifies sdk_version.
@@ -225,7 +229,6 @@
// ----------------------------------------------------------------------------
type InstallableModule interface {
- ContainersInfo() ContainersInfo
StaticDependencyTags() []blueprint.DependencyTag
DynamicDependencyTags() []blueprint.DependencyTag
}
@@ -453,7 +456,7 @@
func getContainerModuleInfo(ctx ModuleContext, module Module) (ContainersInfo, bool) {
if ctx.Module() == module {
- return module.ContainersInfo(), true
+ return ctx.getContainersInfo(), true
}
return OtherModuleProvider(ctx, module, ContainersInfoProvider)
@@ -468,7 +471,7 @@
if _, ok := ctx.Module().(InstallableModule); ok {
containersInfo := generateContainerInfo(ctx)
- ctx.Module().base().containersInfo = containersInfo
+ ctx.setContainersInfo(containersInfo)
SetProvider(ctx, ContainersInfoProvider, containersInfo)
}
}
diff --git a/android/depset_generic.go b/android/depset_generic.go
index 45c1937..690987a 100644
--- a/android/depset_generic.go
+++ b/android/depset_generic.go
@@ -15,6 +15,9 @@
package android
import (
+ "bytes"
+ "encoding/gob"
+ "errors"
"fmt"
)
@@ -65,6 +68,30 @@
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
+ }
+
+ return w.Bytes(), nil
+}
+
+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
+ }
+
+ return nil
+}
+
// NewDepSet returns an immutable DepSet with the given order, direct and transitive contents.
func NewDepSet[T depSettableType](order DepSetOrder, direct []T, transitive []*DepSet[T]) *DepSet[T] {
var directCopy []T
diff --git a/android/init.go b/android/init.go
new file mode 100644
index 0000000..d5b486b
--- /dev/null
+++ b/android/init.go
@@ -0,0 +1,22 @@
+// 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 android
+
+import "encoding/gob"
+
+func init() {
+ gob.Register(ModuleOutPath{})
+ gob.Register(unstableInfo{})
+}
diff --git a/android/module.go b/android/module.go
index 2f2c8c2..009b0df 100644
--- a/android/module.go
+++ b/android/module.go
@@ -15,6 +15,9 @@
package android
import (
+ "bytes"
+ "encoding/gob"
+ "errors"
"fmt"
"net/url"
"path/filepath"
@@ -112,9 +115,6 @@
VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string
ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator
-
- // Get the information about the containers this module belongs to.
- ContainersInfo() ContainersInfo
}
// Qualified id for a module
@@ -495,6 +495,10 @@
// vintf_fragment Modules required from this module.
Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"`
+
+ // List of module names that are prevented from being installed when this module gets
+ // installed.
+ Overrides []string
}
type distProperties struct {
@@ -839,17 +843,6 @@
buildParams []BuildParams
ruleParams map[blueprint.Rule]blueprint.RuleParams
variables map[string]string
-
- // Merged Aconfig files for all transitive deps.
- aconfigFilePaths Paths
-
- // complianceMetadataInfo is for different module types to dump metadata.
- // See android.ModuleContext interface.
- complianceMetadataInfo *ComplianceMetadataInfo
-
- // containersInfo stores the information about the containers and the information of the
- // apexes the module belongs to.
- containersInfo ContainersInfo
}
func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
@@ -1559,26 +1552,43 @@
return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
}
+func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) {
+ namespacePrefix := ctx.Namespace().id
+ if namespacePrefix != "" {
+ namespacePrefix = namespacePrefix + "-"
+ }
+
+ if !ctx.uncheckedModule {
+ name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild"
+ ctx.Phony(name, ctx.checkbuildFiles...)
+ ctx.checkbuildTarget = PathForPhony(ctx, name)
+ }
+
+}
+
func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
var allInstalledFiles InstallPaths
- var allCheckbuildFiles Paths
+ var allCheckbuildTargets Paths
ctx.VisitAllModuleVariants(func(module Module) {
a := module.base()
- var checkBuilds Paths
+ var checkbuildTarget Path
+ var uncheckedModule bool
if a == m {
allInstalledFiles = append(allInstalledFiles, ctx.installFiles...)
- checkBuilds = ctx.checkbuildFiles
+ checkbuildTarget = ctx.checkbuildTarget
+ uncheckedModule = ctx.uncheckedModule
} else {
info := OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider)
allInstalledFiles = append(allInstalledFiles, info.InstallFiles...)
- checkBuilds = info.CheckbuildFiles
+ checkbuildTarget = info.CheckbuildTarget
+ uncheckedModule = info.UncheckedModule
}
// A module's -checkbuild phony targets should
// not be created if the module is not exported to make.
// Those could depend on the build target and fail to compile
// for the current build target.
- if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a) {
- allCheckbuildFiles = append(allCheckbuildFiles, checkBuilds...)
+ if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a)) && !uncheckedModule && checkbuildTarget != nil {
+ allCheckbuildTargets = append(allCheckbuildTargets, checkbuildTarget)
}
})
@@ -1599,11 +1609,10 @@
deps = append(deps, info.InstallTarget)
}
- if len(allCheckbuildFiles) > 0 {
+ if len(allCheckbuildTargets) > 0 {
name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
- ctx.Phony(name, allCheckbuildFiles...)
- info.CheckbuildTarget = PathForPhony(ctx, name)
- deps = append(deps, info.CheckbuildTarget)
+ ctx.Phony(name, allCheckbuildTargets...)
+ deps = append(deps, PathForPhony(ctx, name))
}
if len(deps) > 0 {
@@ -1720,9 +1729,11 @@
}
type InstallFilesInfo struct {
- InstallFiles InstallPaths
- CheckbuildFiles Paths
- PackagingSpecs []PackagingSpec
+ InstallFiles InstallPaths
+ CheckbuildFiles Paths
+ CheckbuildTarget Path
+ UncheckedModule bool
+ PackagingSpecs []PackagingSpec
// katiInstalls tracks the install rules that were created by Soong but are being exported
// to Make to convert to ninja rules so that Make can add additional dependencies.
KatiInstalls katiInstalls
@@ -1893,61 +1904,16 @@
return
}
- incrementalAnalysis := false
- incrementalEnabled := false
- var cacheKey *blueprint.BuildActionCacheKey = nil
- var incrementalModule *blueprint.Incremental = nil
- if ctx.bp.GetIncrementalEnabled() {
- if im, ok := m.module.(blueprint.Incremental); ok {
- incrementalModule = &im
- incrementalEnabled = im.IncrementalSupported()
- incrementalAnalysis = ctx.bp.GetIncrementalAnalysis() && incrementalEnabled
- }
- }
- if incrementalEnabled {
- hash, err := proptools.CalculateHash(m.GetProperties())
- if err != nil {
- ctx.ModuleErrorf("failed to calculate properties hash: %s", err)
- return
- }
- cacheInput := new(blueprint.BuildActionCacheInput)
- cacheInput.PropertiesHash = hash
- ctx.VisitDirectDeps(func(module Module) {
- cacheInput.ProvidersHash =
- append(cacheInput.ProvidersHash, ctx.bp.OtherModuleProviderInitialValueHashes(module))
- })
- hash, err = proptools.CalculateHash(&cacheInput)
- if err != nil {
- ctx.ModuleErrorf("failed to calculate cache input hash: %s", err)
- return
- }
- cacheKey = &blueprint.BuildActionCacheKey{
- Id: ctx.bp.ModuleCacheKey(),
- InputHash: hash,
- }
+ m.module.GenerateAndroidBuildActions(ctx)
+ if ctx.Failed() {
+ return
}
- restored := false
- if incrementalAnalysis && cacheKey != nil {
- restored = ctx.bp.RestoreBuildActions(cacheKey)
- }
-
- if !restored {
- m.module.GenerateAndroidBuildActions(ctx)
- if ctx.Failed() {
- return
- }
-
- if x, ok := m.module.(IDEInfo); ok {
- var result IdeInfo
- x.IDEInfo(ctx, &result)
- result.BaseModuleName = x.BaseModuleName()
- SetProvider(ctx, IdeInfoProviderKey, result)
- }
- }
-
- if incrementalEnabled && cacheKey != nil {
- ctx.bp.CacheBuildActions(cacheKey, incrementalModule)
+ if x, ok := m.module.(IDEInfo); ok {
+ var result IdeInfo
+ x.IDEInfo(ctx, &result)
+ result.BaseModuleName = x.BaseModuleName()
+ SetProvider(ctx, IdeInfoProviderKey, result)
}
// Create the set of tagged dist files after calling GenerateAndroidBuildActions
@@ -1959,9 +1925,13 @@
return
}
+ m.generateVariantTarget(ctx)
+
installFiles.LicenseMetadataFile = ctx.licenseMetadataFile
installFiles.InstallFiles = ctx.installFiles
installFiles.CheckbuildFiles = ctx.checkbuildFiles
+ installFiles.CheckbuildTarget = ctx.checkbuildTarget
+ installFiles.UncheckedModule = ctx.uncheckedModule
installFiles.PackagingSpecs = ctx.packagingSpecs
installFiles.KatiInstalls = ctx.katiInstalls
installFiles.KatiSymlinks = ctx.katiSymlinks
@@ -2027,7 +1997,7 @@
TargetDependencies: targetRequired,
HostDependencies: hostRequired,
Data: data,
- Required: m.RequiredModuleNames(ctx),
+ Required: append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...),
}
SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
}
@@ -2092,10 +2062,6 @@
return variant
}
-func (m *ModuleBase) ContainersInfo() ContainersInfo {
- return m.containersInfo
-}
-
// Check the supplied dist structure to make sure that it is valid.
//
// property - the base property, e.g. dist or dists[1], which is combined with the
@@ -2134,11 +2100,61 @@
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
+ }
+
+ return w.Bytes(), nil
+}
+
+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
+ }
+
+ return nil
+}
+
type extraFilesZip struct {
zip Path
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
+ }
+
+ return w.Bytes(), nil
+}
+
+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
+ }
+
+ return nil
+}
+
type katiInstalls []katiInstall
// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
diff --git a/android/module_context.go b/android/module_context.go
index 5322240..3889e40 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -122,6 +122,16 @@
// dependency tags for which IsInstallDepNeeded returns true.
InstallFile(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
+ // InstallFileWithoutCheckbuild creates a rule to copy srcPath to name in the installPath directory,
+ // with the given additional dependencies, but does not add the file to the list of files to build
+ // during `m checkbuild`.
+ //
+ // The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
+ // installed file will be returned by PackagingSpecs() on this module or by
+ // TransitivePackagingSpecs() on modules that depend on this module through dependency tags
+ // for which IsInstallDepNeeded returns true.
+ InstallFileWithoutCheckbuild(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
+
// InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath
// directory, and also unzip a zip file containing extra files to install into the same
// directory.
@@ -168,7 +178,8 @@
// dependency tags for which IsInstallDepNeeded returns true.
PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
- CheckbuildFile(srcPath Path)
+ CheckbuildFile(srcPaths ...Path)
+ UncheckedModule()
InstallInData() bool
InstallInTestcases() bool
@@ -226,16 +237,24 @@
// which usually happens in GenerateAndroidBuildActions() of a module type.
// See android.ModuleBase.complianceMetadataInfo
ComplianceMetadataInfo() *ComplianceMetadataInfo
+
+ // Get the information about the containers this module belongs to.
+ getContainersInfo() ContainersInfo
+ setContainersInfo(info ContainersInfo)
+
+ setAconfigPaths(paths Paths)
}
type moduleContext struct {
bp blueprint.ModuleContext
baseModuleContext
- packagingSpecs []PackagingSpec
- installFiles InstallPaths
- checkbuildFiles Paths
- module Module
- phonies map[string]Paths
+ packagingSpecs []PackagingSpec
+ installFiles InstallPaths
+ checkbuildFiles Paths
+ checkbuildTarget Path
+ uncheckedModule bool
+ module Module
+ phonies map[string]Paths
// outputFiles stores the output of a module by tag and is used to set
// the OutputFilesProvider in GenerateBuildActions
outputFiles OutputFilesInfo
@@ -270,6 +289,17 @@
// moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
// be included in the final module-info.json produced by Make.
moduleInfoJSON *ModuleInfoJSON
+
+ // containersInfo stores the information about the containers and the information of the
+ // apexes the module belongs to.
+ containersInfo ContainersInfo
+
+ // Merged Aconfig files for all transitive deps.
+ aconfigFilePaths Paths
+
+ // complianceMetadataInfo is for different module types to dump metadata.
+ // See android.ModuleContext interface.
+ complianceMetadataInfo *ComplianceMetadataInfo
}
var _ ModuleContext = &moduleContext{}
@@ -495,17 +525,22 @@
func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
deps ...InstallPath) InstallPath {
- return m.installFile(installPath, name, srcPath, deps, false, true, nil)
+ return m.installFile(installPath, name, srcPath, deps, false, true, true, nil)
+}
+
+func (m *moduleContext) InstallFileWithoutCheckbuild(installPath InstallPath, name string, srcPath Path,
+ deps ...InstallPath) InstallPath {
+ return m.installFile(installPath, name, srcPath, deps, false, true, false, nil)
}
func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
deps ...InstallPath) InstallPath {
- return m.installFile(installPath, name, srcPath, deps, true, true, nil)
+ return m.installFile(installPath, name, srcPath, deps, true, true, true, nil)
}
func (m *moduleContext) InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path,
extraZip Path, deps ...InstallPath) InstallPath {
- return m.installFile(installPath, name, srcPath, deps, false, true, &extraFilesZip{
+ return m.installFile(installPath, name, srcPath, deps, false, true, true, &extraFilesZip{
zip: extraZip,
dir: installPath,
})
@@ -517,11 +552,16 @@
}
func (m *moduleContext) getAconfigPaths() *Paths {
- return &m.module.base().aconfigFilePaths
+ return &m.aconfigFilePaths
+}
+
+func (m *moduleContext) setAconfigPaths(paths Paths) {
+ m.aconfigFilePaths = paths
}
func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
licenseFiles := m.Module().EffectiveLicenseFiles()
+ overrides := CopyOf(m.Module().base().commonProperties.Overrides)
spec := PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: srcPath,
@@ -532,13 +572,15 @@
skipInstall: m.skipInstall(),
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
+ overrides: &overrides,
+ owner: m.ModuleName(),
}
m.packagingSpecs = append(m.packagingSpecs, spec)
return spec
}
func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []InstallPath,
- executable bool, hooks bool, extraZip *extraFilesZip) InstallPath {
+ executable bool, hooks bool, checkbuild bool, extraZip *extraFilesZip) InstallPath {
fullInstallPath := installPath.Join(m, name)
if hooks {
@@ -605,7 +647,9 @@
m.packageFile(fullInstallPath, srcPath, executable)
- m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
+ if checkbuild {
+ m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
+ }
return fullInstallPath
}
@@ -646,9 +690,9 @@
}
m.installFiles = append(m.installFiles, fullInstallPath)
- m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
}
+ overrides := CopyOf(m.Module().base().commonProperties.Overrides)
m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: nil,
@@ -658,6 +702,8 @@
skipInstall: m.skipInstall(),
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
+ overrides: &overrides,
+ owner: m.ModuleName(),
})
return fullInstallPath
@@ -693,6 +739,7 @@
m.installFiles = append(m.installFiles, fullInstallPath)
}
+ overrides := CopyOf(m.Module().base().commonProperties.Overrides)
m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: nil,
@@ -702,6 +749,8 @@
skipInstall: m.skipInstall(),
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
+ overrides: &overrides,
+ owner: m.ModuleName(),
})
return fullInstallPath
@@ -713,15 +762,21 @@
ret := make(InstallPaths, 0, len(data))
for _, d := range data {
relPath := d.ToRelativeInstallPath()
- installed := m.installFile(installPath, relPath, d.SrcPath, nil, false, false, nil)
+ installed := m.installFile(installPath, relPath, d.SrcPath, nil, false, false, true, nil)
ret = append(ret, installed)
}
return ret
}
-func (m *moduleContext) CheckbuildFile(srcPath Path) {
- m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
+// CheckbuildFile specifies the output files that should be built by checkbuild.
+func (m *moduleContext) CheckbuildFile(srcPaths ...Path) {
+ m.checkbuildFiles = append(m.checkbuildFiles, srcPaths...)
+}
+
+// UncheckedModule marks the current module has having no files that should be built by checkbuild.
+func (m *moduleContext) UncheckedModule() {
+ m.uncheckedModule = true
}
func (m *moduleContext) blueprintModuleContext() blueprint.ModuleContext {
@@ -768,12 +823,10 @@
}
func (m *moduleContext) ComplianceMetadataInfo() *ComplianceMetadataInfo {
- if complianceMetadataInfo := m.module.base().complianceMetadataInfo; complianceMetadataInfo != nil {
- return complianceMetadataInfo
+ if m.complianceMetadataInfo == nil {
+ m.complianceMetadataInfo = NewComplianceMetadataInfo()
}
- complianceMetadataInfo := NewComplianceMetadataInfo()
- m.module.base().complianceMetadataInfo = complianceMetadataInfo
- return complianceMetadataInfo
+ return m.complianceMetadataInfo
}
// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
@@ -813,3 +866,11 @@
func (m *moduleContext) TargetRequiredModuleNames() []string {
return m.module.TargetRequiredModuleNames()
}
+
+func (m *moduleContext) getContainersInfo() ContainersInfo {
+ return m.containersInfo
+}
+
+func (m *moduleContext) setContainersInfo(info ContainersInfo) {
+ m.containersInfo = info
+}
diff --git a/android/neverallow.go b/android/neverallow.go
index a68f5ea..b89d150 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -60,6 +60,7 @@
AddNeverAllowRules(createCcStubsRule())
AddNeverAllowRules(createJavaExcludeStaticLibsRule())
AddNeverAllowRules(createProhibitHeaderOnlyRule())
+ AddNeverAllowRules(createLimitNdkExportRule()...)
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -182,6 +183,7 @@
"packages/modules/SdkExtensions/derive_sdk",
// These are for apps and shouldn't be used by non-SDK variant modules.
"prebuilts/ndk",
+ "frameworks/native/libs/binder/ndk",
"tools/test/graphicsbenchmark/apps/sample_app",
"tools/test/graphicsbenchmark/functional_tests/java",
"vendor/xts/gts-tests/hostsidetests/gamedevicecert/apps/javatests",
@@ -266,6 +268,22 @@
Because("headers_only can only be used for generating framework-minus-apex headers for non-updatable modules")
}
+func createLimitNdkExportRule() []Rule {
+ reason := "If the headers you're trying to export are meant to be a part of the NDK, they should be exposed by an ndk_headers module. If the headers shouldn't be a part of the NDK, the headers should instead be exposed from a separate `cc_library_headers` which consumers depend on."
+ // DO NOT ADD HERE - please consult danalbert@
+ // b/357711733
+ return []Rule{
+ NeverAllow().
+ NotIn("frameworks/native/libs/binder/ndk").
+ ModuleType("ndk_library").
+ WithMatcher("export_header_libs", isSetMatcherInstance).Because(reason),
+ NeverAllow().ModuleType("ndk_library").WithMatcher("export_generated_headers", isSetMatcherInstance).Because(reason),
+ NeverAllow().ModuleType("ndk_library").WithMatcher("export_include_dirs", isSetMatcherInstance).Because(reason),
+ NeverAllow().ModuleType("ndk_library").WithMatcher("export_shared_lib_headers", isSetMatcherInstance).Because(reason),
+ NeverAllow().ModuleType("ndk_library").WithMatcher("export_static_lib_headers", isSetMatcherInstance).Because(reason),
+ }
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
diff --git a/android/packaging.go b/android/packaging.go
index 42009d5..0909936 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -15,6 +15,9 @@
package android
import (
+ "bytes"
+ "encoding/gob"
+ "errors"
"fmt"
"path/filepath"
"sort"
@@ -56,6 +59,42 @@
// ArchType of the module which produced this packaging spec
archType ArchType
+
+ // List of module names that this packaging spec overrides
+ overrides *[]string
+
+ // Name of the module where this packaging spec is output of
+ 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
+ }
+
+ return w.Bytes(), nil
+}
+
+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
+ }
+
+ return nil
}
func (p *PackagingSpec) Equals(other *PackagingSpec) bool {
@@ -325,7 +364,10 @@
}
func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec {
- m := make(map[string]PackagingSpec)
+ // all packaging specs gathered from the dep.
+ var all []PackagingSpec
+ // list of module names overridden
+ var overridden []string
var arches []ArchType
for _, target := range getSupportedTargets(ctx) {
@@ -357,17 +399,33 @@
continue
}
}
- dstPath := ps.relPathInPackage
- if existingPs, ok := m[dstPath]; ok {
- if !existingPs.Equals(&ps) {
- ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
- }
- continue
+ all = append(all, ps)
+ if ps.overrides != nil {
+ overridden = append(overridden, *ps.overrides...)
}
-
- m[dstPath] = ps
}
})
+
+ // all minus packaging specs that are overridden
+ var filtered []PackagingSpec
+ for _, ps := range all {
+ if ps.owner != "" && InList(ps.owner, overridden) {
+ continue
+ }
+ filtered = append(filtered, ps)
+ }
+
+ m := make(map[string]PackagingSpec)
+ for _, ps := range filtered {
+ dstPath := ps.relPathInPackage
+ if existingPs, ok := m[dstPath]; ok {
+ if !existingPs.Equals(&ps) {
+ ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
+ }
+ continue
+ }
+ m[dstPath] = ps
+ }
return m
}
diff --git a/android/packaging_test.go b/android/packaging_test.go
index 19b46fe..0f7bb39 100644
--- a/android/packaging_test.go
+++ b/android/packaging_test.go
@@ -28,6 +28,7 @@
props struct {
Deps []string
Skip_install *bool
+ Overrides []string
}
}
@@ -650,3 +651,64 @@
runPackagingTest(t, config, bp, tc.expected)
}
}
+
+func TestOverrides(t *testing.T) {
+ bpTemplate := `
+ component {
+ name: "foo",
+ deps: ["bar"],
+ }
+
+ component {
+ name: "bar",
+ }
+
+ component {
+ name: "bar_override",
+ overrides: ["bar"],
+ }
+
+ component {
+ name: "baz",
+ deps: ["bar_override"],
+ }
+
+ package_module {
+ name: "package",
+ deps: %DEPS%,
+ }
+ `
+ testcases := []struct {
+ deps []string
+ expected []string
+ }{
+ {
+ deps: []string{"foo"},
+ expected: []string{"lib64/foo", "lib64/bar"},
+ },
+ {
+ deps: []string{"foo", "bar_override"},
+ expected: []string{"lib64/foo", "lib64/bar_override"},
+ },
+ {
+ deps: []string{"foo", "bar", "bar_override"},
+ expected: []string{"lib64/foo", "lib64/bar_override"},
+ },
+ {
+ deps: []string{"bar", "bar_override"},
+ expected: []string{"lib64/bar_override"},
+ },
+ {
+ deps: []string{"foo", "baz"},
+ expected: []string{"lib64/foo", "lib64/baz", "lib64/bar_override"},
+ },
+ }
+ for _, tc := range testcases {
+ config := testConfig{
+ multiTarget: true,
+ depsCollectFirstTargetOnly: false,
+ }
+ bp := strings.Replace(bpTemplate, "%DEPS%", `["`+strings.Join(tc.deps, `", "`)+`"]`, -1)
+ runPackagingTest(t, config, bp, tc.expected)
+ }
+}
diff --git a/android/paths.go b/android/paths.go
index d20b84a..e457959 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1766,6 +1766,32 @@
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
+ }
+
+ return w.Bytes(), nil
+}
+
+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
+ }
+
+ return nil
+}
+
// Will panic if called from outside a test environment.
func ensureTestOnly() {
if PrefixInList(os.Args, "-test.") {
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 95e2b92..18bbcab 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -463,6 +463,8 @@
r.build(name, desc, true)
}
+var sandboxEnvOnceKey = NewOnceKey("sandbox_environment_variables")
+
func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString bool) {
name = ninjaNameEscape(name)
@@ -580,16 +582,44 @@
})
}
- // Set OUT_DIR to the relative path of the sandboxed out directory.
- // Otherwise, OUT_DIR will be inherited from the rest of the build,
- // which will allow scripts to escape the sandbox if OUT_DIR is an
- // absolute path.
- command.Env = append(command.Env, &sbox_proto.EnvironmentVariable{
- Name: proto.String("OUT_DIR"),
- State: &sbox_proto.EnvironmentVariable_Value{
- Value: sboxOutSubDir,
- },
- })
+ // Only allow the build to access certain environment variables
+ command.DontInheritEnv = proto.Bool(true)
+ command.Env = r.ctx.Config().Once(sandboxEnvOnceKey, func() interface{} {
+ // The list of allowed variables was found by running builds of all
+ // genrules and seeing what failed
+ var result []*sbox_proto.EnvironmentVariable
+ inheritedVars := []string{
+ "PATH",
+ "JAVA_HOME",
+ "TMPDIR",
+ // Allow RBE variables because the art tests invoke RBE manually
+ "RBE_log_dir",
+ "RBE_platform",
+ "RBE_server_address",
+ // TODO: RBE_exec_root is set to the absolute path to the root of the source
+ // tree, which we don't want sandboxed actions to find. Remap it to ".".
+ "RBE_exec_root",
+ }
+ for _, v := range inheritedVars {
+ result = append(result, &sbox_proto.EnvironmentVariable{
+ Name: proto.String(v),
+ State: &sbox_proto.EnvironmentVariable_Inherit{
+ Inherit: true,
+ },
+ })
+ }
+ // Set OUT_DIR to the relative path of the sandboxed out directory.
+ // Otherwise, OUT_DIR will be inherited from the rest of the build,
+ // which will allow scripts to escape the sandbox if OUT_DIR is an
+ // absolute path.
+ result = append(result, &sbox_proto.EnvironmentVariable{
+ Name: proto.String("OUT_DIR"),
+ State: &sbox_proto.EnvironmentVariable_Value{
+ Value: sboxOutSubDir,
+ },
+ })
+ return result
+ }).([]*sbox_proto.EnvironmentVariable)
command.Chdir = proto.Bool(true)
}
diff --git a/android/selects_test.go b/android/selects_test.go
index fc020a4..90d7091 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -1009,6 +1009,28 @@
},
expectedError: `variable already set in inherited scope, previous assignment:`,
},
+ {
+ name: "Basic string list postprocessor",
+ bp: `
+my_defaults {
+ name: "defaults_a",
+ my_string_list: ["a", "b", "c"],
+ string_list_postprocessor_add_to_elements: "1",
+}
+my_defaults {
+ name: "defaults_b",
+ my_string_list: ["d", "e", "f"],
+ string_list_postprocessor_add_to_elements: "2",
+}
+my_module_type {
+ name: "foo",
+ defaults: ["defaults_a", "defaults_b"],
+}
+`,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"d2", "e2", "f2", "a1", "b1", "c1"},
+ },
+ },
}
for _, tc := range testCases {
@@ -1161,9 +1183,15 @@
return m
}
+type selectsMockDefaultsProperties struct {
+ String_list_postprocessor_add_to_elements string
+}
+
type selectsMockModuleDefaults struct {
ModuleBase
DefaultsModuleBase
+ myProperties selectsMockModuleProperties
+ defaultsProperties selectsMockDefaultsProperties
}
func (d *selectsMockModuleDefaults) GenerateAndroidBuildActions(ctx ModuleContext) {
@@ -1173,10 +1201,22 @@
module := &selectsMockModuleDefaults{}
module.AddProperties(
- &selectsMockModuleProperties{},
+ &module.myProperties,
+ &module.defaultsProperties,
)
InitDefaultsModule(module)
+ AddLoadHook(module, func(lhc LoadHookContext) {
+ if module.defaultsProperties.String_list_postprocessor_add_to_elements != "" {
+ module.myProperties.My_string_list.AddPostProcessor(func(x []string) []string {
+ for i := range x {
+ x[i] = x[i] + module.defaultsProperties.String_list_postprocessor_add_to_elements
+ }
+ return x
+ })
+ }
+ })
+
return module
}
diff --git a/androidmk/parser/ast.go b/androidmk/parser/ast.go
index d5d1354..c3d198f 100644
--- a/androidmk/parser/ast.go
+++ b/androidmk/parser/ast.go
@@ -84,6 +84,7 @@
Prerequisites *MakeString
RecipePos Pos
Recipe string
+ RecipeEndPos Pos
}
func (x *Rule) Dump() string {
@@ -95,7 +96,7 @@
}
func (x *Rule) Pos() Pos { return x.Target.Pos() }
-func (x *Rule) End() Pos { return Pos(int(x.RecipePos) + len(x.Recipe)) }
+func (x *Rule) End() Pos { return x.RecipeEndPos }
type Variable struct {
Name *MakeString
diff --git a/androidmk/parser/parser.go b/androidmk/parser/parser.go
index 8a20bb0..f2477db 100644
--- a/androidmk/parser/parser.go
+++ b/androidmk/parser/parser.go
@@ -448,6 +448,7 @@
Prerequisites: prerequisites,
Recipe: recipe,
RecipePos: recipePos,
+ RecipeEndPos: p.pos(),
})
}
}
diff --git a/androidmk/parser/parser_test.go b/androidmk/parser/parser_test.go
index fb03c23..e238f8b 100644
--- a/androidmk/parser/parser_test.go
+++ b/androidmk/parser/parser_test.go
@@ -124,3 +124,25 @@
})
}
}
+
+func TestRuleEnd(t *testing.T) {
+ name := "ruleEndTest"
+ in := `all:
+ifeq (A, A)
+ echo foo
+ echo foo
+ echo foo
+ echo foo
+endif
+ echo bar
+`
+ p := NewParser(name, bytes.NewBufferString(in))
+ got, errs := p.Parse()
+ if len(errs) != 0 {
+ 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())
+ }
+}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 4112108..933682a 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -136,6 +136,11 @@
fmt.Fprintln(w, "LOCAL_SOONG_INSTALLED_MODULE :=", filepath.Join(modulePath, fi.stem()))
fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_PAIRS :=", fi.builtFile.String()+":"+filepath.Join(modulePath, fi.stem()))
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", fi.builtFile.String())
+ if fi.checkbuildTarget != nil {
+ fmt.Fprintln(w, "LOCAL_CHECKED_MODULE :=", fi.checkbuildTarget.String())
+ } else {
+ fmt.Fprintln(w, "LOCAL_CHECKED_MODULE :=", fi.builtFile.String())
+ }
fmt.Fprintln(w, "LOCAL_MODULE_CLASS :=", fi.class.nameInMake())
if fi.module != nil {
// This apexFile's module comes from Soong
diff --git a/apex/apex.go b/apex/apex.go
index d5776b5..6421c8e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -577,6 +577,8 @@
customStem string
symlinks []string // additional symlinks
+ checkbuildTarget android.Path
+
// Info for Android.mk Module name of `module` in AndroidMk. Note the generated AndroidMk
// module for apexFile is named something like <AndroidMk module name>.<apex name>[<apex
// suffix>]
@@ -612,6 +614,9 @@
module: module,
}
if module != nil {
+ if installFilesInfo, ok := android.OtherModuleProvider(ctx, module, android.InstallFilesProvider); ok {
+ ret.checkbuildTarget = installFilesInfo.CheckbuildTarget
+ }
ret.moduleDir = ctx.OtherModuleDir(module)
ret.partition = module.PartitionTag(ctx.DeviceConfig())
ret.requiredModuleNames = module.RequiredModuleNames(ctx)
@@ -1937,8 +1942,6 @@
// visitor skips these from this list of module names
unwantedTransitiveDeps []string
-
- aconfigFiles []android.Path
}
func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
@@ -2005,7 +2008,6 @@
fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
fi.isJniLib = isJniLib
vctx.filesInfo = append(vctx.filesInfo, fi)
- addAconfigFiles(vctx, ctx, child)
// Collect the list of stub-providing libs except:
// - VNDK libs are only for vendors
// - bootstrap bionic libs are treated as provided by system
@@ -2017,7 +2019,6 @@
fi := apexFileForRustLibrary(ctx, ch)
fi.isJniLib = isJniLib
vctx.filesInfo = append(vctx.filesInfo, fi)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
@@ -2026,11 +2027,9 @@
switch ch := child.(type) {
case *cc.Module:
vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
case *rust.Module:
vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("binaries",
@@ -2070,7 +2069,6 @@
return false
}
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
@@ -2079,14 +2077,11 @@
switch ap := child.(type) {
case *java.AndroidApp:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
case *java.AndroidAppImport:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- addAconfigFiles(vctx, ctx, child)
case *java.AndroidTestHelperApp:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- addAconfigFiles(vctx, ctx, child)
case *java.AndroidAppSet:
appDir := "app"
if ap.Privileged() {
@@ -2100,7 +2095,6 @@
af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
af.certificate = java.PresignedCertificate
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
default:
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
}
@@ -2132,7 +2126,6 @@
for _, etcFile := range filesToCopy {
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
}
- addAconfigFiles(vctx, ctx, child)
} else {
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
}
@@ -2147,7 +2140,6 @@
af := apexFileForExecutable(ctx, ccTest)
af.class = nativeTest
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
} else {
ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
@@ -2227,7 +2219,6 @@
}
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
} else if rm, ok := child.(*rust.Module); ok {
if !android.IsDepInSameApex(ctx, am, am) {
@@ -2237,7 +2228,6 @@
af := apexFileForRustLibrary(ctx, rm)
af.transitiveDep = true
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
}
} else if cc.IsHeaderDepTag(depTag) {
@@ -2260,7 +2250,6 @@
af := apexFileForRustLibrary(ctx, rustm)
af.transitiveDep = true
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
}
} else if rust.IsRlibDepTag(depTag) {
@@ -2279,7 +2268,6 @@
return false
}
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("bootclasspath_fragments",
@@ -2294,7 +2282,6 @@
if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil {
vctx.filesInfo = append(vctx.filesInfo, *profileAf)
}
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("systemserverclasspath_fragments",
@@ -2312,19 +2299,6 @@
return false
}
-func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
- if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigPropagatingProviderKey); ok {
- if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
- vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
- }
- }
-
- validationFlag := ctx.DeviceConfig().AconfigContainerValidation()
- if validationFlag == "error" || validationFlag == "warning" {
- android.VerifyAconfigBuildMode(ctx, ctx.ModuleName(), module, validationFlag == "error")
- }
-}
-
func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
// TODO(b/263308293) remove this
if a.properties.IsCoverageVariant {
@@ -2406,13 +2380,16 @@
// 3) some fields in apexBundle struct are configured
a.installDir = android.PathForModuleInstall(ctx, "apex")
a.filesInfo = vctx.filesInfo
- a.aconfigFiles = android.FirstUniquePaths(vctx.aconfigFiles)
a.setPayloadFsType(ctx)
a.setSystemLibLink(ctx)
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
////////////////////////////////////////////////////////////////////////////////////////////
+ // 3.a) some artifacts are generated from the collected files
+ a.filesInfo = append(a.filesInfo, a.buildAconfigFiles(ctx)...)
+
+ ////////////////////////////////////////////////////////////////////////////////////////////
// 4) generate the build rules to create the APEX. This is done in builder.go.
a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
a.buildApex(ctx)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 8305333..685cb37 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -267,6 +267,7 @@
}
func ensureMatches(t *testing.T, result string, expectedRex string) {
+ t.Helper()
ok, err := regexp.MatchString(expectedRex, result)
if err != nil {
t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", result, expectedRex, err)
@@ -277,6 +278,14 @@
}
}
+func ensureListContainsMatch(t *testing.T, result []string, expectedRex string) {
+ t.Helper()
+ p := regexp.MustCompile(expectedRex)
+ if android.IndexListPred(func(s string) bool { return p.MatchString(s) }, result) == -1 {
+ t.Errorf("%q is not found in %v", expectedRex, result)
+ }
+}
+
func ensureListContains(t *testing.T, result []string, expected string) {
t.Helper()
if !android.InList(expected, result) {
@@ -10791,14 +10800,14 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 8 {
- t.Fatalf("Expected 5 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 12 {
+ t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
- ensureMatches(t, copyCmds[5], "^cp -f .*/package.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[6], "^cp -f .*/flag.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[7], "^cp -f .*/flag.val .*/image.apex/etc$")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
@@ -10926,14 +10935,14 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 12 {
- t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 16 {
+ t.Fatalf("Expected 16 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
- ensureMatches(t, copyCmds[9], "^cp -f .*/package.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[10], "^cp -f .*/flag.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[11], "^cp -f .*/flag.val .*/image.apex/etc$")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
@@ -11094,14 +11103,14 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 32 {
- t.Fatalf("Expected 28 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 36 {
+ t.Fatalf("Expected 36 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[28], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
- ensureMatches(t, copyCmds[29], "^cp -f .*/package.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[30], "^cp -f .*/flag.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[31], "^cp -f .*/flag.val .*/image.apex/etc$")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
diff --git a/apex/builder.go b/apex/builder.go
index 0d08483..437189f 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -83,6 +83,7 @@
pctx.HostBinToolVariable("assemble_vintf", "assemble_vintf")
pctx.HostBinToolVariable("apex_elf_checker", "apex_elf_checker")
pctx.HostBinToolVariable("aconfig", "aconfig")
+ pctx.HostBinToolVariable("host_apex_verifier", "host_apex_verifier")
}
type createStorageStruct struct {
@@ -249,6 +250,13 @@
Description: "run apex_linkerconfig_validation",
}, "image_dir")
+ apexHostVerifierRule = pctx.StaticRule("apexHostVerifierRule", blueprint.RuleParams{
+ Command: `${host_apex_verifier} --deapexer=${deapexer} --debugfs=${debugfs_static} ` +
+ `--fsckerofs=${fsck_erofs} --apex=${in} && touch ${out}`,
+ CommandDeps: []string{"${host_apex_verifier}", "${deapexer}", "${debugfs_static}", "${fsck_erofs}"},
+ Description: "run host_apex_verifier",
+ })
+
assembleVintfRule = pctx.StaticRule("assembleVintfRule", blueprint.RuleParams{
Command: `rm -f $out && VINTF_IGNORE_TARGET_FCM_VERSION=true ${assemble_vintf} -i $in -o $out`,
CommandDeps: []string{"${assemble_vintf}"},
@@ -262,6 +270,58 @@
}, "tool_path", "unwanted")
)
+func (a *apexBundle) buildAconfigFiles(ctx android.ModuleContext) []apexFile {
+ var aconfigFiles android.Paths
+ for _, file := range a.filesInfo {
+ if file.module == nil {
+ continue
+ }
+ if dep, ok := android.OtherModuleProvider(ctx, file.module, android.AconfigPropagatingProviderKey); ok {
+ if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
+ aconfigFiles = append(aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
+ }
+ }
+
+ validationFlag := ctx.DeviceConfig().AconfigContainerValidation()
+ if validationFlag == "error" || validationFlag == "warning" {
+ android.VerifyAconfigBuildMode(ctx, ctx.ModuleName(), file.module, validationFlag == "error")
+ }
+ }
+ aconfigFiles = android.FirstUniquePaths(aconfigFiles)
+
+ var files []apexFile
+ if len(aconfigFiles) > 0 {
+ apexAconfigFile := android.PathForModuleOut(ctx, "aconfig_flags.pb")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfig.AllDeclarationsRule,
+ Inputs: aconfigFiles,
+ Output: apexAconfigFile,
+ Description: "combine_aconfig_declarations",
+ Args: map[string]string{
+ "cache_files": android.JoinPathsWithPrefix(aconfigFiles, "--cache "),
+ },
+ })
+ files = append(files, newApexFile(ctx, apexAconfigFile, "aconfig_flags", "etc", etc, nil))
+
+ for _, info := range createStorageInfo {
+ outputFile := android.PathForModuleOut(ctx, info.Output_file)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfig.CreateStorageRule,
+ Inputs: aconfigFiles,
+ Output: outputFile,
+ Description: info.Desc,
+ Args: map[string]string{
+ "container": ctx.ModuleName(),
+ "file_type": info.File_type,
+ "cache_files": android.JoinPathsWithPrefix(aconfigFiles, "--cache "),
+ },
+ })
+ files = append(files, newApexFile(ctx, outputFile, info.File_type, "etc", etc, nil))
+ }
+ }
+ return files
+}
+
// buildManifest creates buile rules to modify the input apex_manifest.json to add information
// gathered by the build system such as provided/required native libraries. Two output files having
// different formats are generated. a.manifestJsonOut is JSON format for Q devices, and
@@ -644,48 +704,10 @@
outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
- defaultReadOnlyFiles := []string{"apex_manifest.json", "apex_manifest.pb"}
- aconfigDest := imageDir.Join(ctx, "etc").String()
- if len(a.aconfigFiles) > 0 {
- apexAconfigFile := android.PathForModuleOut(ctx, "aconfig_flags.pb")
- ctx.Build(pctx, android.BuildParams{
- Rule: aconfig.AllDeclarationsRule,
- Inputs: a.aconfigFiles,
- Output: apexAconfigFile,
- Description: "combine_aconfig_declarations",
- Args: map[string]string{
- "cache_files": android.JoinPathsWithPrefix(a.aconfigFiles, "--cache "),
- },
- })
-
- copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+aconfigDest)
- implicitInputs = append(implicitInputs, apexAconfigFile)
- defaultReadOnlyFiles = append(defaultReadOnlyFiles, "etc/"+apexAconfigFile.Base())
-
- for _, info := range createStorageInfo {
- outputFile := android.PathForModuleOut(ctx, info.Output_file)
- ctx.Build(pctx, android.BuildParams{
- Rule: aconfig.CreateStorageRule,
- Inputs: a.aconfigFiles,
- Output: outputFile,
- Description: info.Desc,
- Args: map[string]string{
- "container": ctx.ModuleName(),
- "file_type": info.File_type,
- "cache_files": android.JoinPathsWithPrefix(a.aconfigFiles, "--cache "),
- },
- })
-
- copyCommands = append(copyCommands, "cp -f "+outputFile.String()+" "+aconfigDest)
- implicitInputs = append(implicitInputs, outputFile)
- defaultReadOnlyFiles = append(defaultReadOnlyFiles, "etc/"+outputFile.Base())
- }
- }
-
////////////////////////////////////////////////////////////////////////////////////
// Step 2: create canned_fs_config which encodes filemode,uid,gid of each files
// in this APEX. The file will be used by apexer in later steps.
- cannedFsConfig := a.buildCannedFsConfig(ctx, defaultReadOnlyFiles)
+ cannedFsConfig := a.buildCannedFsConfig(ctx)
implicitInputs = append(implicitInputs, cannedFsConfig)
////////////////////////////////////////////////////////////////////////////////////
@@ -952,6 +974,9 @@
validations = append(validations,
runApexElfCheckerUnwanted(ctx, unsignedOutputFile.OutputPath, a.properties.Unwanted_transitive_deps))
}
+ if !a.testApex && android.InList(a.payloadFsType, []fsType{ext4, erofs}) {
+ validations = append(validations, runApexHostVerifier(ctx, unsignedOutputFile.OutputPath))
+ }
ctx.Build(pctx, android.BuildParams{
Rule: rule,
Description: "signapk",
@@ -1139,8 +1164,8 @@
a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
}
-func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext, defaultReadOnlyFiles []string) android.OutputPath {
- var readOnlyPaths = defaultReadOnlyFiles
+func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath {
+ var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
var executablePaths []string // this also includes dirs
var appSetDirs []string
appSetFiles := make(map[string]android.Path)
@@ -1246,3 +1271,13 @@
})
return timestamp
}
+
+func runApexHostVerifier(ctx android.ModuleContext, apexFile android.OutputPath) android.Path {
+ timestamp := android.PathForModuleOut(ctx, "host_apex_verifier.timestamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: apexHostVerifierRule,
+ Input: apexFile,
+ Output: timestamp,
+ })
+ return timestamp
+}
diff --git a/cc/cc.go b/cc/cc.go
index 927935c..b534737 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2507,8 +2507,14 @@
}
if c.isNDKStubLibrary() {
- // ndk_headers do not have any variations
- actx.AddFarVariationDependencies([]blueprint.Variation{}, depTag, lib)
+ variationExists := actx.OtherModuleDependencyVariantExists(nil, lib)
+ if variationExists {
+ actx.AddVariationDependencies(nil, depTag, lib)
+ } else {
+ // dependencies to ndk_headers fall here as ndk_headers do not have
+ // any variants.
+ actx.AddFarVariationDependencies([]blueprint.Variation{}, depTag, lib)
+ }
} else if c.IsStubs() && !c.isImportedApiLibrary() {
actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()),
depTag, lib)
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index beb68e1..761afcf 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -41,11 +41,18 @@
"armv8-2a-dotprod": []string{
"-march=armv8.2-a+dotprod",
},
+ // On ARMv9 and later, Pointer Authentication Codes (PAC) are mandatory,
+ // so -fstack-protector is unnecessary.
"armv9-a": []string{
"-march=armv8.2-a+dotprod",
"-mbranch-protection=standard",
"-fno-stack-protector",
},
+ "armv9-2a": []string{
+ "-march=armv9.2-a",
+ "-mbranch-protection=standard",
+ "-fno-stack-protector",
+ },
}
arm64Ldflags = []string{
diff --git a/cc/config/global.go b/cc/config/global.go
index 0e8fff6..c838357 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -287,8 +287,7 @@
"-Wno-error=deprecated-builtins", // http://b/241601211
"-Wno-error=deprecated", // in external/googletest/googletest
// New warnings to be fixed after clang-r475365
- "-Wno-error=single-bit-bitfield-constant-conversion", // http://b/243965903
- "-Wno-error=enum-constexpr-conversion", // http://b/243964282
+ "-Wno-error=enum-constexpr-conversion", // http://b/243964282
// New warnings to be fixed after clang-r522817
"-Wno-error=invalid-offsetof",
"-Wno-error=thread-safety-reference-return",
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 3e35ef5..bd6dfa3 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -103,8 +103,17 @@
// https://github.com/android-ndk/ndk/issues/265.
Unversioned_until *string
- // Headers presented by this library to the Public API Surface
+ // DO NOT USE THIS
+ // NDK libraries should not export their headers. Headers belonging to NDK
+ // libraries should be added to the NDK with an ndk_headers module.
Export_header_libs []string
+
+ // Do not add other export_* properties without consulting with danalbert@.
+ // Consumers of ndk_library modules should emulate the typical NDK build
+ // behavior as closely as possible (that is, all NDK APIs are exposed to
+ // builds via --sysroot). Export behaviors used in Soong will not be present
+ // for app developers as they don't use Soong, and reliance on these export
+ // behaviors can mask issues with the NDK sysroot.
}
type stubDecorator struct {
@@ -484,7 +493,8 @@
// Add a dependency on the header modules of this ndk_library
func (linker *stubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
return Deps{
- HeaderLibs: linker.properties.Export_header_libs,
+ ReexportHeaderLibHeaders: linker.properties.Export_header_libs,
+ HeaderLibs: linker.properties.Export_header_libs,
}
}
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index 6459ea1..f3931a4 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -275,7 +275,10 @@
if !state.Inherit {
return nil, fmt.Errorf("Can't have inherit set to false")
}
- env = append(env, *envVar.Name+"="+os.Getenv(*envVar.Name))
+ val, ok := os.LookupEnv(*envVar.Name)
+ if ok {
+ env = append(env, *envVar.Name+"="+val)
+ }
default:
return nil, fmt.Errorf("Unhandled state type")
}
diff --git a/java/aar.go b/java/aar.go
index 1bd372f..42866f8 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -403,6 +403,7 @@
packageName: a.manifestValues.applicationId,
}
a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], manifestMergerParams)
+ ctx.CheckbuildFile(a.mergedManifestFile)
if !a.isLibrary {
// Only use the merged manifest for applications. For libraries, the transitive closure of manifests
// will be propagated to the final application and merged there. The merged manifest for libraries is
@@ -537,6 +538,8 @@
aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt,
linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages,
opts.aconfigTextFiles)
+ ctx.CheckbuildFile(packageRes)
+
// Extract assets from the resource package output so that they can be used later in aapt2link
// for modules that depend on this one.
if android.PrefixInList(linkFlags, "-A ") {
@@ -887,7 +890,6 @@
var res android.Paths
if a.androidLibraryProperties.BuildAAR {
BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
- ctx.CheckbuildFile(a.aarFile)
}
prebuiltJniPackages := android.Paths{}
@@ -991,7 +993,7 @@
// Functionality common to Module and Import.
embeddableInModuleAndImport
- providesTransitiveHeaderJars
+ providesTransitiveHeaderJarsForR8
properties AARImportProperties
@@ -1252,10 +1254,12 @@
transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
aapt2Link(ctx, exportPackage, nil, proguardOptionsFile, aaptRTxt,
linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)
+ ctx.CheckbuildFile(exportPackage)
a.exportPackage = exportPackage
rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, rJar, nil, true, nil, false)
+ ctx.CheckbuildFile(rJar)
a.rJar = rJar
aapt2ExtractExtraPackages(ctx, extraAaptPackagesFile, a.rJar)
@@ -1286,7 +1290,7 @@
android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
- a.collectTransitiveHeaderJars(ctx)
+ a.collectTransitiveHeaderJarsForR8(ctx)
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
@@ -1350,14 +1354,17 @@
a.headerJarFile = classpathFile
}
+ ctx.CheckbuildFile(a.headerJarFile)
+ ctx.CheckbuildFile(a.implementationJarFile)
+
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
- HeaderJars: android.PathsIfNonNil(a.headerJarFile),
- ResourceJars: android.PathsIfNonNil(resourceJarFile),
- TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars,
- TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
- ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationAndResourcesJarFile),
- ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
- StubsLinkType: Implementation,
+ HeaderJars: android.PathsIfNonNil(a.headerJarFile),
+ ResourceJars: android.PathsIfNonNil(resourceJarFile),
+ TransitiveLibsHeaderJarsForR8: a.transitiveLibsHeaderJarsForR8,
+ TransitiveStaticLibsHeaderJarsForR8: a.transitiveStaticLibsHeaderJarsForR8,
+ ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationAndResourcesJarFile),
+ ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
+ StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
diff --git a/java/app.go b/java/app.go
index abd78b7..d5c220d 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1009,6 +1009,8 @@
ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile, extraInstalledPaths...)
}
+ ctx.CheckbuildFile(a.outputFile)
+
a.buildAppDependencyInfo(ctx)
providePrebuiltInfo(ctx,
@@ -1471,7 +1473,23 @@
return testConfig
}
+func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
+ // Instrument the android_test_helper target to log potential API calls at the run time.
+ // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
+ ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
+ a.setApiMapper(true)
+ }
+ a.AndroidApp.DepsMutator(ctx)
+}
+
func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
+ // Instrument the android_test_helper target to log potential API calls at the run time.
+ // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
+ ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
+ a.setApiMapper(true)
+ }
a.AndroidApp.DepsMutator(ctx)
}
diff --git a/java/base.go b/java/base.go
index e516891..75b552f 100644
--- a/java/base.go
+++ b/java/base.go
@@ -15,6 +15,7 @@
package java
import (
+ "encoding/gob"
"fmt"
"path/filepath"
"reflect"
@@ -233,6 +234,10 @@
// Contributing api surface of the stub module. Is not visible to bp modules, and should
// only be set for stub submodules generated by the java_sdk_library
Stub_contributing_api *string `blueprint:"mutated"`
+
+ // If true, enable the "ApiMapper" tool on the output jar. "ApiMapper" is a tool to inject
+ // bytecode to log API calls.
+ ApiMapper bool `blueprint:"mutated"`
}
// Properties that are specific to device modules. Host module factories should not add these when
@@ -739,6 +744,10 @@
ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
}
+func (j *Module) shouldApiMapper() bool {
+ return j.properties.ApiMapper
+}
+
func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
return j.properties.Supports_static_instrumentation &&
j.shouldInstrument(ctx) &&
@@ -767,6 +776,10 @@
j.properties.Instrument = value
}
+func (j *Module) setApiMapper(value bool) {
+ j.properties.ApiMapper = value
+}
+
func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
}
@@ -1272,10 +1285,12 @@
}
j.headerJarFile = combinedHeaderJarFile
+ ctx.CheckbuildFile(j.headerJarFile)
+
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
- TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
- TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
+ TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
+ TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
AidlIncludeDirs: j.exportAidlIncludeDirs,
ExportedPlugins: j.exportedPluginJars,
ExportedPluginClasses: j.exportedPluginClasses,
@@ -1598,6 +1613,18 @@
outputFile = ravenizerOutput
}
+ if j.shouldApiMapper() {
+ inputFile := outputFile
+ apiMapperFile := android.PathForModuleOut(ctx, "apimapper", jarName)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: apimapper,
+ Description: "apimapper",
+ Input: inputFile,
+ Output: apiMapperFile,
+ })
+ outputFile = apiMapperFile
+ }
+
// Check package restrictions if necessary.
if len(j.properties.Permitted_packages) > 0 {
// Time stamp file created by the package check rule.
@@ -1740,6 +1767,8 @@
j.dexpreopt(ctx, libName, dexOutputFile)
outputFile = dexOutputFile
+
+ ctx.CheckbuildFile(dexOutputFile)
} else {
// There is no code to compile into a dex jar, make sure the resources are propagated
// to the APK if this is an app.
@@ -1783,13 +1812,14 @@
j.collectTransitiveSrcFiles(ctx, srcFiles)
- ctx.CheckbuildFile(outputFile)
+ ctx.CheckbuildFile(j.implementationJarFile)
+ ctx.CheckbuildFile(j.headerJarFile)
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
RepackagedHeaderJars: android.PathsIfNonNil(j.repackagedHeaderJarFile),
- TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
- TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
+ TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
+ TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
ResourceJars: android.PathsIfNonNil(j.resourceJar),
@@ -1951,6 +1981,8 @@
TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{},
false, nil, []string{"META-INF/TRANSITIVE"})
+ ctx.CheckbuildFile(combinedHeaderJarOutputPath)
+
return headerJar, combinedHeaderJarOutputPath
}
@@ -1967,22 +1999,18 @@
return instrumentedJar
}
-type providesTransitiveHeaderJars struct {
+type providesTransitiveHeaderJarsForR8 struct {
// set of header jars for all transitive libs deps
- transitiveLibsHeaderJars *android.DepSet[android.Path]
+ transitiveLibsHeaderJarsForR8 *android.DepSet[android.Path]
// set of header jars for all transitive static libs deps
- transitiveStaticLibsHeaderJars *android.DepSet[android.Path]
+ transitiveStaticLibsHeaderJarsForR8 *android.DepSet[android.Path]
}
-func (j *providesTransitiveHeaderJars) TransitiveLibsHeaderJars() *android.DepSet[android.Path] {
- return j.transitiveLibsHeaderJars
-}
-
-func (j *providesTransitiveHeaderJars) TransitiveStaticLibsHeaderJars() *android.DepSet[android.Path] {
- return j.transitiveStaticLibsHeaderJars
-}
-
-func (j *providesTransitiveHeaderJars) collectTransitiveHeaderJars(ctx android.ModuleContext) {
+// collectTransitiveHeaderJarsForR8 visits direct dependencies and collects all transitive libs and static_libs
+// header jars. The semantics of the collected jars are odd (it collects combined jars that contain the static
+// libs, but also the static libs, and it collects transitive libs dependencies of static_libs), so these
+// are only used to expand the --lib arguments to R8.
+func (j *providesTransitiveHeaderJarsForR8) collectTransitiveHeaderJarsForR8(ctx android.ModuleContext) {
directLibs := android.Paths{}
directStaticLibs := android.Paths{}
transitiveLibs := []*android.DepSet[android.Path]{}
@@ -2005,16 +2033,16 @@
return
}
- if dep.TransitiveLibsHeaderJars != nil {
- transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJars)
+ if dep.TransitiveLibsHeaderJarsForR8 != nil {
+ transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJarsForR8)
}
- if dep.TransitiveStaticLibsHeaderJars != nil {
- transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJars)
+ if dep.TransitiveStaticLibsHeaderJarsForR8 != nil {
+ transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJarsForR8)
}
}
})
- j.transitiveLibsHeaderJars = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs)
- j.transitiveStaticLibsHeaderJars = android.NewDepSet(android.POSTORDER, directStaticLibs, transitiveStaticLibs)
+ j.transitiveLibsHeaderJarsForR8 = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs)
+ j.transitiveStaticLibsHeaderJarsForR8 = android.NewDepSet(android.POSTORDER, directStaticLibs, transitiveStaticLibs)
}
func (j *Module) HeaderJars() android.Paths {
@@ -2280,7 +2308,7 @@
sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName())
- j.collectTransitiveHeaderJars(ctx)
+ j.collectTransitiveHeaderJarsForR8(ctx)
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -2492,6 +2520,8 @@
func init() {
android.SetJarJarPrefixHandler(mergeJarJarPrefixes)
+
+ gob.Register(BaseJarJarProviderData{})
}
// BaseJarJarProviderData contains information that will propagate across dependencies regardless of
diff --git a/java/builder.go b/java/builder.go
index 49207e5..81b0feb 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -265,6 +265,13 @@
},
)
+ apimapper = pctx.AndroidStaticRule("apimapper",
+ blueprint.RuleParams{
+ Command: "${apimapper} --in-jar $in --out-jar $out",
+ CommandDeps: []string{"${apimapper}"},
+ },
+ )
+
zipalign = pctx.AndroidStaticRule("zipalign",
blueprint.RuleParams{
Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " +
@@ -315,6 +322,7 @@
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("ravenizer", "ravenizer")
+ pctx.HostBinToolVariable("apimapper", "apimapper")
pctx.HostBinToolVariable("keep-flagged-apis", "keep-flagged-apis")
}
diff --git a/java/dex.go b/java/dex.go
index 6c739a2..7d42efc 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -108,7 +108,7 @@
resourcesInput android.OptionalPath
resourcesOutput android.OptionalPath
- providesTransitiveHeaderJars
+ providesTransitiveHeaderJarsForR8
}
func (d *dexer) effectiveOptimizeEnabled() bool {
@@ -307,14 +307,14 @@
r8Deps = append(r8Deps, flags.dexClasspath...)
transitiveStaticLibsLookupMap := map[android.Path]bool{}
- if d.transitiveStaticLibsHeaderJars != nil {
- for _, jar := range d.transitiveStaticLibsHeaderJars.ToList() {
+ if d.transitiveStaticLibsHeaderJarsForR8 != nil {
+ for _, jar := range d.transitiveStaticLibsHeaderJarsForR8.ToList() {
transitiveStaticLibsLookupMap[jar] = true
}
}
transitiveHeaderJars := android.Paths{}
- if d.transitiveLibsHeaderJars != nil {
- for _, jar := range d.transitiveLibsHeaderJars.ToList() {
+ if d.transitiveLibsHeaderJarsForR8 != nil {
+ for _, jar := range d.transitiveLibsHeaderJarsForR8.ToList() {
if _, ok := transitiveStaticLibsLookupMap[jar]; ok {
// don't include a lib if it is already packaged in the current JAR as a static lib
continue
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index f949b12..1c63e3f 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -489,6 +489,7 @@
d.configPath = android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "dexpreopt.config")
dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath)
+ ctx.CheckbuildFile(d.configPath)
if d.dexpreoptDisabled(ctx, libName) {
return
@@ -592,7 +593,8 @@
}
} else if !d.preventInstall {
- ctx.InstallFile(installPath, installBase, install.From)
+ // Install without adding to checkbuild to match behavior of previous Make-based checkbuild rules
+ ctx.InstallFileWithoutCheckbuild(installPath, installBase, install.From)
}
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 137ec92..6bcdf85 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -970,10 +970,14 @@
d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
- // Make sure that existing UnflaggedApi issues are reported as warnings but issues in
- // new/changed code are treated as errors by the Build Warnings Aye Aye Analyzer in Gerrit.
+ // If UnflaggedApi issues have not already been configured then make sure that existing
+ // UnflaggedApi issues are reported as warnings but issues in new/changed code are treated as
+ // errors by the Build Warnings Aye Aye Analyzer in Gerrit.
// Once existing issues have been fixed this will be changed to error.
- cmd.Flag("--error-when-new UnflaggedApi")
+ // TODO(b/362771529): Switch to --error
+ if !strings.Contains(cmd.String(), " UnflaggedApi ") {
+ cmd.Flag("--error-when-new UnflaggedApi")
+ }
// TODO(b/154317059): Clean up this allowlist by baselining and/or checking in last-released.
if d.Name() != "android.car-system-stubs-docs" &&
diff --git a/java/java.go b/java/java.go
index 55c878e..8cc1085 100644
--- a/java/java.go
+++ b/java/java.go
@@ -259,10 +259,10 @@
RepackagedHeaderJars android.Paths
// set of header jars for all transitive libs deps
- TransitiveLibsHeaderJars *android.DepSet[android.Path]
+ TransitiveLibsHeaderJarsForR8 *android.DepSet[android.Path]
// set of header jars for all transitive static libs deps
- TransitiveStaticLibsHeaderJars *android.DepSet[android.Path]
+ TransitiveStaticLibsHeaderJarsForR8 *android.DepSet[android.Path]
// ImplementationAndResourceJars is a list of jars that contain the implementations of classes
// in the module as well as any resources included in the module.
@@ -2634,7 +2634,7 @@
var flags javaBuilderFlags
- j.collectTransitiveHeaderJars(ctx)
+ j.collectTransitiveHeaderJarsForR8(ctx)
var staticJars android.Paths
var staticResourceJars android.Paths
var staticHeaderJars android.Paths
@@ -2735,6 +2735,8 @@
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
+ ctx.CheckbuildFile(outputFile)
+
if ctx.Device() {
// If this is a variant created for a prebuilt_apex then use the dex implementation jar
// obtained from the associated deapexer module.
@@ -2801,6 +2803,7 @@
if ctx.Failed() {
return
}
+ ctx.CheckbuildFile(dexOutputFile)
// Initialize the hiddenapi structure.
j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex)
@@ -2814,14 +2817,14 @@
}
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
- HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
- TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
- TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
- ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile),
- ImplementationJars: android.PathsIfNonNil(implementationJarFile.WithoutRel()),
- ResourceJars: android.PathsIfNonNil(resourceJarFile),
- AidlIncludeDirs: j.exportAidlIncludeDirs,
- StubsLinkType: j.stubsLinkType,
+ HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
+ TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
+ TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
+ ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile),
+ ImplementationJars: android.PathsIfNonNil(implementationJarFile.WithoutRel()),
+ ResourceJars: android.PathsIfNonNil(resourceJarFile),
+ AidlIncludeDirs: j.exportAidlIncludeDirs,
+ StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
diff --git a/java/sdk_library.go b/java/sdk_library.go
index a7a254a..98b65dd 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1595,6 +1595,11 @@
module.hostdexInstallFile = module.implLibraryModule.hostdexInstallFile
}
+ if installFilesInfo, ok := android.OtherModuleProvider(ctx, module.implLibraryModule, android.InstallFilesProvider); ok {
+ if installFilesInfo.CheckbuildTarget != nil {
+ ctx.CheckbuildFile(installFilesInfo.CheckbuildTarget)
+ }
+ }
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: module.implLibraryModule.uniqueSrcFiles.Strings()})
}
diff --git a/rust/rust.go b/rust/rust.go
index 5a973c4..240c221 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -947,6 +947,7 @@
sourceLib := sourceMod.(*Module).compiler.(*libraryDecorator)
mod.sourceProvider.setOutputFiles(sourceLib.sourceProvider.Srcs())
}
+ ctx.CheckbuildFile(mod.sourceProvider.Srcs()...)
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: mod.sourceProvider.Srcs().Strings()})
}
@@ -957,15 +958,13 @@
return
}
mod.outputFile = android.OptionalPathForPath(buildOutput.outputFile)
+ ctx.CheckbuildFile(buildOutput.outputFile)
if buildOutput.kytheFile != nil {
mod.kytheFiles = append(mod.kytheFiles, buildOutput.kytheFile)
}
bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), android.OptionalPathForPath(mod.compiler.unstrippedOutputFilePath()))
mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps)
- if mod.docTimestampFile.Valid() {
- ctx.CheckbuildFile(mod.docTimestampFile.Path())
- }
apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider)
if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) && !mod.ProcMacro() {
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 5b644fd..2fb3a3f 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -211,6 +211,11 @@
OutputFile: s.snapshotFile,
DistFiles: android.MakeDefaultDistFiles(s.snapshotFile.Path(), s.infoFile.Path()),
Include: "$(BUILD_PHONY_PACKAGE)",
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetBool("LOCAL_DONT_CHECK_MODULE", true)
+ },
+ },
ExtraFooters: []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string) {
// Allow the sdk to be built by simply passing its name on the command line.
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 057b370..416dce6 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -131,11 +131,7 @@
java_import {
name: "myjavalib",
prefer: false,
- visibility: [
- "//other/foo",
- "//package",
- "//prebuilts/mysdk",
- ],
+ visibility: ["//visibility:public"],
apex_available: ["//apex_available:platform"],
jars: ["java/myjavalib.jar"],
}
@@ -151,11 +147,7 @@
java_import {
name: "mydefaultedjavalib",
prefer: false,
- visibility: [
- "//other/bar",
- "//package",
- "//prebuilts/mysdk",
- ],
+ visibility: ["//visibility:public"],
apex_available: ["//apex_available:platform"],
jars: ["java/mydefaultedjavalib.jar"],
}
@@ -163,10 +155,7 @@
java_import {
name: "myprivatejavalib",
prefer: false,
- visibility: [
- "//package",
- "//prebuilts/mysdk",
- ],
+ visibility: ["//visibility:public"],
apex_available: ["//apex_available:platform"],
jars: ["java/myprivatejavalib.jar"],
}
@@ -185,28 +174,6 @@
`)
}
-func TestPrebuiltVisibilityProperty_AddPrivate(t *testing.T) {
- testSdkError(t, `prebuilt_visibility: "//visibility:private" does not widen the visibility`, `
- sdk {
- name: "mysdk",
- prebuilt_visibility: [
- "//visibility:private",
- ],
- java_header_libs: [
- "myjavalib",
- ],
- }
-
- java_library {
- name: "myjavalib",
- // Uses package default visibility
- srcs: ["Test.java"],
- system_modules: "none",
- sdk_version: "none",
- }
-`)
-}
-
func TestSdkInstall(t *testing.T) {
sdk := `
sdk {
diff --git a/sdk/update.go b/sdk/update.go
index a4b1967..9379f36 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -563,11 +563,11 @@
}
builder.infoContents = string(output)
android.WriteFileRuleVerbatim(ctx, info, builder.infoContents)
- installedInfo := ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), info.Base(), info)
+ installedInfo := ctx.InstallFileWithoutCheckbuild(android.PathForMainlineSdksInstall(ctx), info.Base(), info)
s.infoFile = android.OptionalPathForPath(installedInfo)
// Install the zip, making sure that the info file has been installed as well.
- installedZip := ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), outputZipFile.Base(), outputZipFile, installedInfo)
+ installedZip := ctx.InstallFileWithoutCheckbuild(android.PathForMainlineSdksInstall(ctx), outputZipFile.Base(), outputZipFile, installedInfo)
s.snapshotFile = android.OptionalPathForPath(installedZip)
}
@@ -1109,20 +1109,22 @@
// same package so can be marked as private.
m.AddProperty("visibility", []string{"//visibility:private"})
} else {
- // Extract visibility information from a member variant. All variants have the same
- // visibility so it doesn't matter which one is used.
- visibilityRules := android.EffectiveVisibilityRules(s.ctx, variant)
-
- // Add any additional visibility rules needed for the prebuilts to reference each other.
- err := visibilityRules.Widen(s.sdk.properties.Prebuilt_visibility)
- if err != nil {
- s.ctx.PropertyErrorf("prebuilt_visibility", "%s", err)
- }
-
- visibility := visibilityRules.Strings()
- if len(visibility) != 0 {
- m.AddProperty("visibility", visibility)
- }
+ // Change the visibility of the module SDK prebuilts to public.
+ // This includes
+ // 1. Stub libraries of `sdk` modules
+ // 2. Binaries and libraries of `module_exports` modules
+ //
+ // This is a workaround to improve maintainlibility of the module SDK.
+ // Since module sdks are generated from release branches and dropped to development
+ // branches, there might be a visibility skew between the sources and prebuilts
+ // of a specific module.
+ // To reconcile this potential skew, change the visibility to public
+ //
+ // This is safe for (1) since these are stub libraries.
+ // This is ok for (2) since these are host and test exports and are intended for
+ // ART development.
+ // TODO (b/361303067): This can be removed if ART uses full manifests.
+ m.AddProperty("visibility", []string{"//visibility:public"})
}
// Where available copy apex_available properties from the member.
diff --git a/ui/build/config.go b/ui/build/config.go
index 6432348..711f325 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -41,6 +41,7 @@
const (
envConfigDir = "vendor/google/tools/soong_config"
jsonSuffix = "json"
+ abfsSrcDir = "/src"
)
var (
@@ -214,6 +215,10 @@
sandboxConfig: &SandboxConfig{},
ninjaWeightListSource: DEFAULT,
}
+ wd, err := os.Getwd()
+ if err != nil {
+ ctx.Fatalln("Failed to get working directory:", err)
+ }
// Skip soong tests by default on Linux
if runtime.GOOS == "linux" {
@@ -245,17 +250,13 @@
// Make sure OUT_DIR is set appropriately
if outDir, ok := ret.environ.Get("OUT_DIR"); ok {
- ret.environ.Set("OUT_DIR", filepath.Clean(outDir))
+ ret.environ.Set("OUT_DIR", ret.sandboxPath(wd, filepath.Clean(outDir)))
} else {
outDir := "out"
if baseDir, ok := ret.environ.Get("OUT_DIR_COMMON_BASE"); ok {
- if wd, err := os.Getwd(); err != nil {
- ctx.Fatalln("Failed to get working directory:", err)
- } else {
- outDir = filepath.Join(baseDir, filepath.Base(wd))
- }
+ outDir = filepath.Join(baseDir, filepath.Base(wd))
}
- ret.environ.Set("OUT_DIR", outDir)
+ ret.environ.Set("OUT_DIR", ret.sandboxPath(wd, outDir))
}
// loadEnvConfig needs to know what the OUT_DIR is, so it should
@@ -350,6 +351,9 @@
// Use config.useN2 instead.
"SOONG_USE_N2",
+
+ // Leaks usernames into environment.
+ "HOME",
)
if ret.UseGoma() || ret.ForceUseGoma() {
@@ -361,12 +365,12 @@
ret.environ.Set("PYTHONDONTWRITEBYTECODE", "1")
tmpDir := absPath(ctx, ret.TempDir())
- ret.environ.Set("TMPDIR", tmpDir)
+ ret.environ.Set("TMPDIR", ret.sandboxPath(wd, tmpDir))
// Always set ASAN_SYMBOLIZER_PATH so that ASAN-based tools can symbolize any crashes
symbolizerPath := filepath.Join("prebuilts/clang/host", ret.HostPrebuiltTag(),
"llvm-binutils-stable/llvm-symbolizer")
- ret.environ.Set("ASAN_SYMBOLIZER_PATH", absPath(ctx, symbolizerPath))
+ ret.environ.Set("ASAN_SYMBOLIZER_PATH", ret.sandboxPath(wd, absPath(ctx, symbolizerPath)))
// Precondition: the current directory is the top of the source tree
checkTopDir(ctx)
@@ -426,9 +430,9 @@
}
ret.environ.Unset("OVERRIDE_ANDROID_JAVA_HOME")
- ret.environ.Set("JAVA_HOME", absJavaHome)
- ret.environ.Set("ANDROID_JAVA_HOME", javaHome)
- ret.environ.Set("ANDROID_JAVA8_HOME", java8Home)
+ ret.environ.Set("JAVA_HOME", ret.sandboxPath(wd, absJavaHome))
+ ret.environ.Set("ANDROID_JAVA_HOME", ret.sandboxPath(wd, javaHome))
+ ret.environ.Set("ANDROID_JAVA8_HOME", ret.sandboxPath(wd, java8Home))
ret.environ.Set("PATH", strings.Join(newPath, string(filepath.ListSeparator)))
// b/286885495, https://bugzilla.redhat.com/show_bug.cgi?id=2227130: some versions of Fedora include patches
@@ -444,7 +448,7 @@
ret.buildDateTime = strconv.FormatInt(time.Now().Unix(), 10)
}
- ret.environ.Set("BUILD_DATETIME_FILE", buildDateTimeFile)
+ ret.environ.Set("BUILD_DATETIME_FILE", ret.sandboxPath(wd, buildDateTimeFile))
if _, ok := ret.environ.Get("BUILD_USERNAME"); !ok {
username := "unknown"
@@ -455,6 +459,7 @@
}
ret.environ.Set("BUILD_USERNAME", username)
}
+ ret.environ.Set("PWD", ret.sandboxPath(wd, wd))
if ret.UseRBE() {
for k, v := range getRBEVars(ctx, Config{ret}) {
@@ -1296,6 +1301,19 @@
return err == nil
}
+func (c *configImpl) sandboxPath(base, in string) string {
+ if !c.UseABFS() {
+ return in
+ }
+
+ rel, err := filepath.Rel(base, in)
+ if err != nil {
+ return in
+ }
+
+ return filepath.Join(abfsSrcDir, rel)
+}
+
func (c *configImpl) UseRBE() bool {
// These alternate modes of running Soong do not use RBE / reclient.
if c.Queryview() || c.JsonModuleGraph() {
@@ -1722,6 +1740,11 @@
}
func (c *configImpl) SkipMetricsUpload() bool {
+ // b/362625275 - Metrics upload sometimes prevents abfs unmount
+ if c.UseABFS() {
+ return true
+ }
+
return c.skipMetricsUpload
}
diff --git a/ui/build/path.go b/ui/build/path.go
index 51ebff1..075bf2e 100644
--- a/ui/build/path.go
+++ b/ui/build/path.go
@@ -57,6 +57,22 @@
return ret
}
+func updatePathForSandbox(config Config) {
+ wd, err := os.Getwd()
+ if err != nil {
+ return
+ }
+
+ var newPath []string
+ if path, ok := config.Environment().Get("PATH"); ok && path != "" {
+ entries := strings.Split(path, string(filepath.ListSeparator))
+ for _, ent := range entries {
+ newPath = append(newPath, config.sandboxPath(wd, ent))
+ }
+ }
+ config.Environment().Set("PATH", strings.Join(newPath, string(filepath.ListSeparator)))
+}
+
// SetupLitePath is the "lite" version of SetupPath used for dumpvars, or other
// places that does not need the full logging capabilities of path_interposer,
// wants the minimal performance overhead, and still get the benefits of $PATH
@@ -121,6 +137,7 @@
// Set $PATH to be the directories containing the host tool symlinks, and
// the prebuilts directory for the current host OS.
config.Environment().Set("PATH", myPath)
+ updatePathForSandbox(config)
config.pathReplaced = true
}
@@ -265,5 +282,6 @@
// Replace the $PATH variable with the path_interposer symlinks, and
// checked-in prebuilts.
config.Environment().Set("PATH", myPath)
+ updatePathForSandbox(config)
config.pathReplaced = true
}
diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go
index d9ca854..95b71a7 100644
--- a/ui/build/sandbox_linux.go
+++ b/ui/build/sandbox_linux.go
@@ -50,7 +50,6 @@
const (
nsjailPath = "prebuilts/build-tools/linux-x86/bin/nsjail"
- abfsSrcDir = "/src"
)
var sandboxConfig struct {
@@ -148,20 +147,42 @@
return sandboxConfig.working
}
-func (c *Cmd) srcDirArg() string {
- if !c.config.UseABFS() {
- return sandboxConfig.srcDir
+// Assumes input path is absolute, clean, and if applicable, an evaluated
+// symlink. If path is not a subdirectory of src dir or relative path
+// cannot be determined, return the input untouched.
+func (c *Cmd) relFromSrcDir(path string) string {
+ if !strings.HasPrefix(path, sandboxConfig.srcDir) {
+ return path
}
- return sandboxConfig.srcDir + ":" + abfsSrcDir
+ rel, err := filepath.Rel(sandboxConfig.srcDir, path)
+ if err != nil {
+ return path
+ }
+
+ return rel
+}
+
+func (c *Cmd) dirArg(path string) string {
+ if !c.config.UseABFS() {
+ return path
+ }
+
+ rel := c.relFromSrcDir(path)
+
+ return path + ":" + filepath.Join(abfsSrcDir, rel)
+}
+
+func (c *Cmd) srcDirArg() string {
+ return c.dirArg(sandboxConfig.srcDir)
}
func (c *Cmd) outDirArg() string {
- if !c.config.UseABFS() {
- return sandboxConfig.outDir
- }
+ return c.dirArg(sandboxConfig.outDir)
+}
- return sandboxConfig.outDir + ":" + filepath.Join(abfsSrcDir, sandboxConfig.outDir)
+func (c *Cmd) distDirArg() string {
+ return c.dirArg(sandboxConfig.distDir)
}
// When configured to use ABFS, we need to allow the creation of the /src
@@ -187,8 +208,17 @@
return args
}
+func (c *Cmd) workDir() string {
+ if !c.config.UseABFS() {
+ wd, _ := os.Getwd()
+ return wd
+ }
+
+ return abfsSrcDir
+}
+
func (c *Cmd) wrapSandbox() {
- wd, _ := os.Getwd()
+ wd := c.workDir()
var sandboxArgs []string
sandboxArgs = append(sandboxArgs,
@@ -226,7 +256,7 @@
)
sandboxArgs = append(sandboxArgs,
- c.readMountArgs()...
+ c.readMountArgs()...,
)
sandboxArgs = append(sandboxArgs,
@@ -264,7 +294,7 @@
if _, err := os.Stat(sandboxConfig.distDir); !os.IsNotExist(err) {
//Mount dist dir as read-write if it already exists
- sandboxArgs = append(sandboxArgs, "-B", sandboxConfig.distDir)
+ sandboxArgs = append(sandboxArgs, "-B", c.distDirArg())
}
if c.Sandbox.AllowBuildBrokenUsesNetwork && c.config.BuildBrokenUsesNetwork() {