Merge "Revert "Enable -Wfortify-source"" 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 96e8133..16a34b7 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -41,6 +41,7 @@
"build_prop.go",
"compliance_metadata.go",
"config.go",
+ "container_violations.go",
"container.go",
"test_config.go",
"configurable_properties.go",
@@ -58,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 f6f4889..fb51531 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -157,6 +157,7 @@
}
type AndroidMkEntriesContext interface {
+ OtherModuleProviderContext
Config() Config
}
@@ -354,14 +355,15 @@
availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
}
+ info := OtherModuleProviderOrDefault(a.entryContext, mod, InstallFilesProvider)
// If the distFiles created by GenerateTaggedDistFiles contains paths for the
// DefaultDistTag then that takes priority so delete any existing paths.
- if _, ok := amod.distFiles[DefaultDistTag]; ok {
+ if _, ok := info.DistFiles[DefaultDistTag]; ok {
delete(availableTaggedDists, DefaultDistTag)
}
// Finally, merge the distFiles created by GenerateTaggedDistFiles.
- availableTaggedDists = availableTaggedDists.merge(amod.distFiles)
+ availableTaggedDists = availableTaggedDists.merge(info.DistFiles)
if len(availableTaggedDists) == 0 {
// Nothing dist-able for this module.
@@ -372,7 +374,7 @@
distContributions := &distContributions{}
if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
- distContributions.licenseMetadataFile = amod.licenseMetadataFile
+ distContributions.licenseMetadataFile = info.LicenseMetadataFile
}
// Iterate over this module's dist structs, merged from the dist and dists properties.
@@ -552,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)...)
}
@@ -590,10 +600,10 @@
}
if !base.InVendorRamdisk() {
- a.AddPaths("LOCAL_FULL_INIT_RC", base.initRcPaths)
+ a.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths)
}
- if len(base.vintfFragmentsPaths) > 0 {
- a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", base.vintfFragmentsPaths)
+ if len(info.VintfFragmentsPaths) > 0 {
+ a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths)
}
a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
@@ -910,7 +920,6 @@
case "*phony.PhonyRule": // writes phony deps and acts like `.PHONY`
case "*selinux.selinuxContextsModule": // license properties written
case "*sysprop.syspropLibrary": // license properties written
- case "*vintf.vintfCompatibilityMatrixRule": // use case like phony
default:
if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
return fmt.Errorf("custom make rules not allowed for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), ctx.ModuleName(mod))
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 72b8654..c37eeab 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -46,7 +46,6 @@
func (m *customModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- m.base().licenseMetadataFile = PathForOutput(ctx, "meta_lic")
var defaultDistPaths Paths
// If the dist_output_file: true then create an output file that is stored in
@@ -276,7 +275,8 @@
)
}
for idx, line := range androidMkLines {
- expectedLine := strings.ReplaceAll(expectedAndroidMkLines[idx], "meta_lic", module.base().licenseMetadataFile.String())
+ expectedLine := strings.ReplaceAll(expectedAndroidMkLines[idx], "meta_lic",
+ OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).LicenseMetadataFile.String())
if line != expectedLine {
t.Errorf(
"Expected AndroidMk line to be '%s', got '%s'",
diff --git a/android/apex.go b/android/apex.go
index 028be57..29b2a9f 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "reflect"
"slices"
"sort"
"strconv"
@@ -145,6 +146,17 @@
return false
}
+// To satisfy the comparable interface
+func (i ApexInfo) Equal(other any) bool {
+ otherApexInfo, ok := other.(ApexInfo)
+ return ok && i.ApexVariationName == otherApexInfo.ApexVariationName &&
+ i.MinSdkVersion == otherApexInfo.MinSdkVersion &&
+ i.Updatable == otherApexInfo.Updatable &&
+ i.UsePlatformApis == otherApexInfo.UsePlatformApis &&
+ reflect.DeepEqual(i.InApexVariants, otherApexInfo.InApexVariants) &&
+ reflect.DeepEqual(i.InApexModules, otherApexInfo.InApexModules)
+}
+
// ApexTestForInfo stores the contents of APEXes for which this module is a test - although this
// module is not part of the APEX - and thus has access to APEX internals.
type ApexTestForInfo struct {
@@ -475,13 +487,6 @@
AvailableToAnyApex = "//apex_available:anyapex"
)
-var (
- AvailableToRecognziedWildcards = []string{
- AvailableToPlatform,
- AvailableToAnyApex,
- }
-)
-
// CheckAvailableForApex provides the default algorithm for checking the apex availability. When the
// availability is empty, it defaults to ["//apex_available:platform"] which means "available to the
// platform but not available to any APEX". When the list is not empty, `what` is matched against
@@ -707,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/build_prop.go b/android/build_prop.go
index 13d59f9..ede93ed 100644
--- a/android/build_prop.go
+++ b/android/build_prop.go
@@ -63,6 +63,8 @@
return ctx.Config().SystemExtPropFiles(ctx)
} else if partition == "product" {
return ctx.Config().ProductPropFiles(ctx)
+ } else if partition == "odm" {
+ return ctx.Config().OdmPropFiles(ctx)
}
return nil
}
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index 4c92f71..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))
@@ -189,8 +212,8 @@
installed = append(installed, ctx.installFiles...)
installed = append(installed, ctx.katiInstalls.InstallPaths()...)
installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
- installed = append(installed, m.katiInitRcInstalls.InstallPaths()...)
- installed = append(installed, m.katiVintfInstalls.InstallPaths()...)
+ installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
+ installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
complianceMetadataInfo.SetListValue(ComplianceMetadataProp.INSTALLED_FILES, FirstUniqueStrings(installed.Strings()))
}
ctx.setProvider(ComplianceMetadataProvider, complianceMetadataInfo)
diff --git a/android/config.go b/android/config.go
index d6d76a4..cf3499f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -173,6 +173,13 @@
return c.IsEnvTrue("DISABLE_VERIFY_OVERLAPS") || c.ReleaseDisableVerifyOverlaps() || !c.ReleaseDefaultModuleBuildFromSource()
}
+func (c Config) CoverageSuffix() string {
+ if v := c.IsEnvTrue("EMMA_INSTRUMENT"); v {
+ return "coverage."
+ }
+ return ""
+}
+
// MaxPageSizeSupported returns the max page size supported by the device. This
// value will define the ELF segment alignment for binaries (executables and
// shared libraries).
@@ -1483,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
}
@@ -2050,22 +2052,10 @@
return PathsForSource(ctx, c.productVariables.ProductPropFiles)
}
+func (c *config) OdmPropFiles(ctx PathContext) Paths {
+ return PathsForSource(ctx, c.productVariables.OdmPropFiles)
+}
+
func (c *config) EnableUffdGc() string {
return String(c.productVariables.EnableUffdGc)
}
-
-func (c *config) DeviceFrameworkCompatibilityMatrixFile() []string {
- return c.productVariables.DeviceFrameworkCompatibilityMatrixFile
-}
-
-func (c *config) DeviceProductCompatibilityMatrixFile() []string {
- return c.productVariables.DeviceProductCompatibilityMatrixFile
-}
-
-func (c *config) BoardAvbEnable() bool {
- return Bool(c.productVariables.BoardAvbEnable)
-}
-
-func (c *config) BoardAvbSystemAddHashtreeFooterArgs() []string {
- return c.productVariables.BoardAvbSystemAddHashtreeFooterArgs
-}
diff --git a/android/container.go b/android/container.go
index 10aff4d..c048d6c 100644
--- a/android/container.go
+++ b/android/container.go
@@ -15,8 +15,10 @@
package android
import (
+ "fmt"
"reflect"
"slices"
+ "strings"
"github.com/google/blueprint"
)
@@ -89,10 +91,18 @@
"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.
"framework-res",
+
+ // jacocoagent is implicitly added as a dependency in coverage builds, and is not installed
+ // on the device.
+ "jacocoagent",
}
// Returns true when the dependency is globally allowlisted for inter-container dependency
@@ -219,7 +229,6 @@
// ----------------------------------------------------------------------------
type InstallableModule interface {
- ContainersInfo() ContainersInfo
StaticDependencyTags() []blueprint.DependencyTag
DynamicDependencyTags() []blueprint.DependencyTag
}
@@ -391,6 +400,40 @@
var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()
+func satisfyAllowedExceptions(ctx ModuleContext, allowedExceptionLabels []exceptionHandleFuncLabel, m, dep Module) bool {
+ for _, label := range allowedExceptionLabels {
+ if exceptionHandleFunctionsTable[label](ctx, m, dep) {
+ return true
+ }
+ }
+ return false
+}
+
+func (c *ContainersInfo) GetViolations(mctx ModuleContext, m, dep Module, depInfo ContainersInfo) []string {
+ var violations []string
+
+ // Any containers that the module belongs to but the dependency does not belong to must be examined.
+ _, containersUniqueToModule, _ := ListSetDifference(c.belongingContainers, depInfo.belongingContainers)
+
+ // Apex container should be examined even if both the module and the dependency belong to
+ // the apex container to check that the two modules belong to the same apex.
+ if InList(ApexContainer, c.belongingContainers) && !InList(ApexContainer, containersUniqueToModule) {
+ containersUniqueToModule = append(containersUniqueToModule, ApexContainer)
+ }
+
+ for _, containerUniqueToModule := range containersUniqueToModule {
+ for _, restriction := range containerUniqueToModule.restricted {
+ if InList(restriction.dependency, depInfo.belongingContainers) {
+ if !satisfyAllowedExceptions(mctx, restriction.allowedExceptions, m, dep) {
+ violations = append(violations, restriction.errorMessage)
+ }
+ }
+ }
+ }
+
+ return violations
+}
+
func generateContainerInfo(ctx ModuleContext) ContainersInfo {
var containers []*container
@@ -413,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)
@@ -428,7 +471,36 @@
if _, ok := ctx.Module().(InstallableModule); ok {
containersInfo := generateContainerInfo(ctx)
- ctx.Module().base().containersInfo = containersInfo
+ ctx.setContainersInfo(containersInfo)
SetProvider(ctx, ContainersInfoProvider, containersInfo)
}
}
+
+func checkContainerViolations(ctx ModuleContext) {
+ if _, ok := ctx.Module().(InstallableModule); ok {
+ containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module())
+ ctx.VisitDirectDepsIgnoreBlueprint(func(dep Module) {
+ if !dep.Enabled(ctx) {
+ return
+ }
+
+ // Pre-existing violating dependencies are tracked in containerDependencyViolationAllowlist.
+ // If this dependency is allowlisted, do not check for violation.
+ // If not, check if this dependency matches any restricted dependency and
+ // satisfies any exception functions, which allows bypassing the
+ // restriction. If all of the exceptions are not satisfied, throw an error.
+ if depContainersInfo, ok := getContainerModuleInfo(ctx, dep); ok {
+ if allowedViolations, ok := ContainerDependencyViolationAllowlist[ctx.ModuleName()]; ok && InList(dep.Name(), allowedViolations) {
+ return
+ } else {
+ violations := containersInfo.GetViolations(ctx, ctx.Module(), dep, depContainersInfo)
+ if len(violations) > 0 {
+ errorMessage := fmt.Sprintf("%s cannot depend on %s. ", ctx.ModuleName(), dep.Name())
+ errorMessage += strings.Join(violations, " ")
+ ctx.ModuleErrorf(errorMessage)
+ }
+ }
+ }
+ })
+ }
+}
diff --git a/android/container_violations.go b/android/container_violations.go
new file mode 100644
index 0000000..e67533d
--- /dev/null
+++ b/android/container_violations.go
@@ -0,0 +1,1042 @@
+// 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
+
+var ContainerDependencyViolationAllowlist = map[string][]string{
+ "android.car-module.impl": {
+ "modules-utils-preconditions", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
+ },
+
+ "AppInstalledOnMultipleUsers": {
+ "framework", // cts -> unstable
+ },
+
+ "art-aconfig-flags-java-lib": {
+ "framework-api-annotations-lib", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> system
+ },
+
+ "Bluetooth": {
+ "app-compat-annotations", // apex [com.android.btservices] -> system
+ "framework-bluetooth-pre-jarjar", // apex [com.android.btservices] -> system
+ },
+
+ "bluetooth-nano-protos": {
+ "libprotobuf-java-nano", // apex [com.android.btservices] -> apex [com.android.wifi, test_com.android.wifi]
+ },
+
+ "bluetooth.change-ids": {
+ "app-compat-annotations", // apex [com.android.btservices] -> system
+ },
+
+ "CarServiceUpdatable": {
+ "modules-utils-os", // apex [com.android.car.framework] -> apex [com.android.permission, test_com.android.permission]
+ "modules-utils-preconditions", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
+ "modules-utils-shell-command-handler", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.art, com.android.art.debug, com.android.art.testing, com.android.btservices, com.android.configinfrastructure, com.android.mediaprovider, com.android.nfcservices, com.android.permission, com.android.scheduling, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.mediaprovider, test_com.android.permission, test_com.android.wifi, test_imgdiag_com.android.art, test_jitzygote_com.android.art]
+ },
+
+ "connectivity-net-module-utils-bpf": {
+ "net-utils-device-common-struct-base", // apex [com.android.tethering] -> system
+ },
+
+ "conscrypt-aconfig-flags-lib": {
+ "aconfig-annotations-lib-sdk-none", // apex [com.android.conscrypt, test_com.android.conscrypt] -> system
+ },
+
+ "cronet_aml_base_base_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ "jsr305", // apex [com.android.tethering] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+ },
+
+ "cronet_aml_build_android_build_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_base_feature_overrides_java_proto": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_cronet_api_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_cronet_impl_common_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_cronet_impl_native_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ "jsr305", // apex [com.android.tethering] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+ },
+
+ "cronet_aml_components_cronet_android_cronet_jni_registration_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_cronet_shared_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_cronet_stats_log_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_cronet_urlconnection_impl_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_flags_java_proto": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_components_cronet_android_request_context_config_java_proto": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_net_android_net_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ "jsr305", // apex [com.android.tethering] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+ },
+
+ "cronet_aml_net_android_net_thread_stats_uid_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_third_party_jni_zero_jni_zero_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "cronet_aml_url_url_java": {
+ "framework-connectivity-pre-jarjar-without-cronet", // apex [com.android.tethering] -> system
+ },
+
+ "CtsAdservicesHostTestApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAdServicesNotInAllowListEndToEndTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAdServicesPermissionsAppOptOutEndToEndTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAdServicesPermissionsNoPermEndToEndTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAdServicesPermissionsValidEndToEndTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAlarmManagerTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAndroidAppTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAppExitTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAppFgsStartTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAppFgsTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAppOpsTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAppSearchTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAppTestStubsApp2": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsAudioHostTestApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsBackgroundActivityAppAllowCrossUidFlagDefault": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsBatterySavingTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsBluetoothTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsBootDisplayModeApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsBroadcastTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsBRSTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsCompanionDeviceManagerCoreTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsCompanionDeviceManagerMultiProcessTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsCompanionDeviceManagerUiAutomationTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsContentSuggestionsTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsContentTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsCredentialManagerBackupRestoreApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsCrossProfileEnabledApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsCrossProfileEnabledNoPermsApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsCrossProfileNotEnabledApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsCrossProfileUserEnabledApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDeviceAndProfileOwnerApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDeviceAndProfileOwnerApp23": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDeviceAndProfileOwnerApp25": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDeviceAndProfileOwnerApp30": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDeviceLockTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDeviceOwnerApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDevicePolicySimTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDevicePolicyTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDreamsTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsDrmTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsEphemeralTestsEphemeralApp1": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsFgsBootCompletedTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsFgsBootCompletedTestCasesApi35": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsFgsStartTestHelperApi34": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsFgsStartTestHelperCurrent": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsFileDescriptorTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsHostsideCompatChangeTestsApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsHostsideNetworkPolicyTestsApp2": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsIdentityTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsIkeTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsInstalledLoadingProgressDeviceTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsInstantAppTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsIntentSenderApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsJobSchedulerTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsKeystoreTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsLegacyNotification27TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsLibcoreTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsLibcoreWycheproofConscryptTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsListeningPortsTest": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsLocationCoarseTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsLocationFineTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsLocationNoneTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsLocationPrivilegedTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsManagedProfileApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaAudioTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaBetterTogetherTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaCodecTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaDecoderTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaDrmFrameworkTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaEncoderTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaExtractorTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaMiscTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaMuxerTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaPerformanceClassTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaPlayerTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaProjectionSDK33TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaProjectionSDK34TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaProjectionTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaProviderTranscodeTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaRecorderTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaRouterHostSideTestBluetoothPermissionsApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaRouterHostSideTestMediaRoutingControlApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaRouterHostSideTestModifyAudioRoutingApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMediaV2TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMimeMapTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsModifyQuietModeEnabledApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsMusicRecognitionTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsNativeMediaAAudioTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsNetTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsNetTestCasesLegacyApi22": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsNetTestCasesMaxTargetSdk30": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsNetTestCasesMaxTargetSdk31": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsNetTestCasesMaxTargetSdk33": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsNetTestCasesUpdateStatsPermission": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsNfcTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsOnDevicePersonalizationTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsPackageInstallerApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsPackageManagerTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsPackageSchemeTestsWithoutVisibility": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsPackageSchemeTestsWithVisibility": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsPermissionsSyncTestApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsPreservedSettingsApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsProtoTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsProviderTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsProxyMediaRouterTestHelperApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsRebootReadinessTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsResourcesLoaderTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsResourcesTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSandboxedAdIdManagerTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSandboxedAppSetIdManagerTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSandboxedFledgeManagerTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSandboxedMeasurementManagerTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSandboxedTopicsManagerTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSdkExtensionsTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSdkSandboxInprocessTests": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSecureElementTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSecurityTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSelinuxEphemeralTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSelinuxTargetSdk25TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSelinuxTargetSdk27TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSelinuxTargetSdk28TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSelinuxTargetSdk29TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSelinuxTargetSdk30TestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSelinuxTargetSdkCurrentTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSettingsDeviceOwnerApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSharedUserMigrationTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsShortFgsTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSimRestrictedApisTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSliceTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSpeechTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsStatsSecurityApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSuspendAppsTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsSystemUiTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsTareTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsTelephonyTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsTetheringTest": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsThreadNetworkTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsUsageStatsTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsUsbManagerTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsUserRestrictionTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsUtilTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsUwbTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsVcnTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsVideoCodecTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsVideoTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsViewReceiveContentTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsVirtualDevicesAppLaunchTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsVirtualDevicesAudioTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsVirtualDevicesCameraTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsVirtualDevicesSensorTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsVirtualDevicesTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsWearableSensingServiceTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsWebViewCompatChangeApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsWidgetTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsWidgetTestCases29": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsWifiNonUpdatableTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsWifiTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsWindowManagerExternalApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsWindowManagerTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "CtsZipValidateApp": {
+ "framework", // cts -> unstable
+ },
+
+ "CVE-2021-0965": {
+ "framework", // cts -> unstable
+ },
+
+ "device_config_reboot_flags_java_lib": {
+ "ext", // apex [com.android.configinfrastructure] -> system
+ "framework", // apex [com.android.configinfrastructure] -> system
+ },
+
+ "devicelockcontroller-lib": {
+ "modules-utils-expresslog", // apex [com.android.devicelock] -> apex [com.android.btservices, com.android.car.framework]
+ },
+
+ "FederatedCompute": {
+ "auto_value_annotations", // apex [com.android.ondevicepersonalization] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "framework-adservices.impl": {
+ "adservices_flags_lib", // apex [com.android.adservices, com.android.extservices] -> system
+ },
+
+ "framework-bluetooth.impl": {
+ "app-compat-annotations", // apex [com.android.btservices] -> system
+ },
+
+ "framework-connectivity-t.impl": {
+ "app-compat-annotations", // apex [com.android.tethering] -> system
+ "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+ },
+
+ "framework-connectivity.impl": {
+ "app-compat-annotations", // apex [com.android.tethering] -> system
+ },
+
+ "framework-ondevicepersonalization.impl": {
+ "ondevicepersonalization_flags_lib", // apex [com.android.ondevicepersonalization] -> system
+ },
+
+ "framework-pdf.impl": {
+ "modules-utils-preconditions", // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
+ },
+
+ "framework-permission-s.impl": {
+ "app-compat-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+ },
+
+ "framework-wifi.impl": {
+ "aconfig_storage_reader_java", // apex [com.android.wifi, test_com.android.wifi] -> system
+ "app-compat-annotations", // apex [com.android.wifi, test_com.android.wifi] -> system
+ },
+
+ "grpc-java-core-internal": {
+ "gson", // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> apex [com.android.virt]
+ "perfmark-api-lib", // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> system
+ },
+
+ "httpclient_impl": {
+ "httpclient_api", // apex [com.android.tethering] -> system
+ },
+
+ "IncrementalTestAppValidator": {
+ "framework", // cts -> unstable
+ },
+
+ "libcore-aconfig-flags-lib": {
+ "framework-api-annotations-lib", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> system
+ },
+
+ "loadlibrarytest_product_app": {
+ "libnativeloader_vendor_shared_lib", // product -> vendor
+ },
+
+ "loadlibrarytest_testlib": {
+ "libnativeloader_vendor_shared_lib", // system -> vendor
+ },
+
+ "MctsMediaDrmFrameworkTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "MctsMediaTranscodingTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ "MediaProvider": {
+ "app-compat-annotations", // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> system
+ },
+
+ "mediaprovider_flags_java_lib": {
+ "ext", // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> system
+ "framework", // apex [com.android.mediaprovider, test_com.android.mediaprovider] -> system
+ },
+
+ "MockSatelliteGatewayServiceApp": {
+ "framework", // cts -> unstable
+ },
+
+ "MockSatelliteServiceApp": {
+ "framework", // cts -> unstable
+ },
+
+ "net-utils-device-common-netlink": {
+ "net-utils-device-common-struct-base", // apex [com.android.tethering] -> system
+ },
+
+ "net-utils-device-common-struct": {
+ "net-utils-device-common-struct-base", // apex [com.android.tethering] -> system
+ },
+
+ "NfcNciApex": {
+ "android.permission.flags-aconfig-java", // apex [com.android.nfcservices] -> apex [com.android.permission, test_com.android.permission]
+ },
+
+ "okhttp-norepackage": {
+ "okhttp-android-util-log", // apex [com.android.adservices, com.android.devicelock, com.android.extservices] -> system
+ },
+
+ "ondevicepersonalization-plugin-lib": {
+ "auto_value_annotations", // apex [com.android.ondevicepersonalization] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "opencensus-java-api": {
+ "auto_value_annotations", // apex [com.android.devicelock] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "PermissionController-lib": {
+ "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+ },
+
+ "PlatformProperties": {
+ "sysprop-library-stub-platform", // apex [com.android.btservices, com.android.nfcservices, com.android.tethering, com.android.virt, com.android.wifi, test_com.android.wifi] -> system
+ },
+
+ "safety-center-config": {
+ "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+ },
+
+ "safety-center-internal-data": {
+ "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+ },
+
+ "safety-center-pending-intents": {
+ "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+ },
+
+ "safety-center-persistence": {
+ "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+ },
+
+ "safety-center-resources-lib": {
+ "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+ },
+
+ "SdkSandboxManagerDisabledTests": {
+ "framework", // cts -> unstable
+ },
+
+ "SdkSandboxManagerTests": {
+ "framework", // cts -> unstable
+ },
+
+ "service-art.impl": {
+ "auto_value_annotations", // apex [com.android.art, com.android.art.debug, com.android.art.testing, test_imgdiag_com.android.art, test_jitzygote_com.android.art] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "service-bluetooth-pre-jarjar": {
+ "framework-bluetooth-pre-jarjar", // apex [com.android.btservices] -> system
+ "service-bluetooth.change-ids", // apex [com.android.btservices] -> system
+ },
+
+ "service-connectivity": {
+ "libprotobuf-java-nano", // apex [com.android.tethering] -> apex [com.android.wifi, test_com.android.wifi]
+ },
+
+ "service-connectivity-pre-jarjar": {
+ "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+ },
+
+ "service-connectivity-protos": {
+ "libprotobuf-java-nano", // apex [com.android.tethering] -> apex [com.android.wifi, test_com.android.wifi]
+ },
+
+ "service-connectivity-tiramisu-pre-jarjar": {
+ "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+ "framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system
+ },
+
+ "service-entitlement": {
+ "auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "service-entitlement-api": {
+ "auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "service-entitlement-data": {
+ "auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "service-entitlement-impl": {
+ "auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "service-healthfitness.impl": {
+ "modules-utils-preconditions", // apex [com.android.healthfitness] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
+ },
+
+ "service-networksecurity-pre-jarjar": {
+ "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+ },
+
+ "service-permission.impl": {
+ "jsr305", // apex [com.android.permission, test_com.android.permission] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+ "safety-center-annotations", // apex [com.android.permission, test_com.android.permission] -> system
+ },
+
+ "service-remoteauth-pre-jarjar": {
+ "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+ "framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system
+ },
+
+ "service-thread-pre-jarjar": {
+ "framework-connectivity-pre-jarjar", // apex [com.android.tethering] -> system
+ "framework-connectivity-t-pre-jarjar", // apex [com.android.tethering] -> system
+ },
+
+ "service-uwb-pre-jarjar": {
+ "framework-uwb-pre-jarjar", // apex [com.android.uwb] -> system
+ },
+
+ "service-wifi": {
+ "auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ },
+
+ "TelephonyDeviceTest": {
+ "framework", // cts -> unstable
+ },
+
+ "tensorflowlite_java": {
+ "android-support-annotations", // apex [com.android.adservices, com.android.extservices, com.android.ondevicepersonalization] -> system
+ },
+
+ "TestExternalImsServiceApp": {
+ "framework", // cts -> unstable
+ },
+
+ "TestSmsRetrieverApp": {
+ "framework", // cts -> unstable
+ },
+
+ "TetheringApiCurrentLib": {
+ "connectivity-internal-api-util", // apex [com.android.tethering] -> system
+ },
+
+ "TetheringNext": {
+ "connectivity-internal-api-util", // apex [com.android.tethering] -> system
+ },
+
+ "tetheringstatsprotos": {
+ "ext", // apex [com.android.tethering] -> system
+ "framework", // apex [com.android.tethering] -> system
+ },
+
+ "uwb_aconfig_flags_lib": {
+ "ext", // apex [com.android.uwb] -> system
+ "framework", // apex [com.android.uwb] -> system
+ },
+
+ "uwb_androidx_backend": {
+ "android-support-annotations", // apex [com.android.tethering] -> system
+ },
+
+ "wifi-service-pre-jarjar": {
+ "app-compat-annotations", // apex [com.android.wifi, test_com.android.wifi] -> system
+ "auto_value_annotations", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.extservices, com.android.extservices_tplus]
+ "framework-wifi-pre-jarjar", // apex [com.android.wifi, test_com.android.wifi] -> system
+ "jsr305", // apex [com.android.wifi, test_com.android.wifi] -> apex [com.android.adservices, com.android.devicelock, com.android.extservices, com.android.healthfitness, com.android.media, com.android.mediaprovider, test_com.android.media, test_com.android.mediaprovider]
+ },
+}
diff --git a/android/defaults.go b/android/defaults.go
index c0a2fc6..0d51d9d 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -28,7 +28,7 @@
var DefaultsDepTag defaultsDependencyTag
type defaultsProperties struct {
- Defaults proptools.Configurable[[]string]
+ Defaults []string
}
type DefaultableModuleBase struct {
@@ -278,13 +278,13 @@
func defaultsDepsMutator(ctx BottomUpMutatorContext) {
if defaultable, ok := ctx.Module().(Defaultable); ok {
- ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults.GetOrDefault(ctx, nil)...)
+ ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
}
}
func defaultsMutator(ctx TopDownMutatorContext) {
if defaultable, ok := ctx.Module().(Defaultable); ok {
- defaults := defaultable.defaults().Defaults.GetOrDefault(ctx, nil)
+ defaults := defaultable.defaults().Defaults
if len(defaults) > 0 {
var defaultsList []Defaults
seen := make(map[Defaults]bool)
@@ -295,7 +295,7 @@
if !seen[defaults] {
seen[defaults] = true
defaultsList = append(defaultsList, defaults)
- return len(defaults.defaults().Defaults.GetOrDefault(ctx, nil)) > 0
+ return len(defaults.defaults().Defaults) > 0
}
} else {
ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
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/license_metadata.go b/android/license_metadata.go
index cd69749..0ac975f 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -152,7 +152,7 @@
// Install map
args = append(args,
- JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(base.licenseInstallMap), "-m "))
+ JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(ctx.licenseInstallMap), "-m "))
// Built files
if len(outputFiles) > 0 {
diff --git a/android/makevars.go b/android/makevars.go
index 810eb38..8305d8e 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -281,8 +281,8 @@
if m.ExportedToMake() {
info := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider)
katiInstalls = append(katiInstalls, info.KatiInstalls...)
- katiInitRcInstalls = append(katiInitRcInstalls, m.base().katiInitRcInstalls...)
- katiVintfManifestInstalls = append(katiVintfManifestInstalls, m.base().katiVintfInstalls...)
+ katiInitRcInstalls = append(katiInitRcInstalls, info.KatiInitRcInstalls...)
+ katiVintfManifestInstalls = append(katiVintfManifestInstalls, info.KatiVintfInstalls...)
katiSymlinks = append(katiSymlinks, info.KatiSymlinks...)
}
})
diff --git a/android/module.go b/android/module.go
index e74af83..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"
@@ -87,8 +90,6 @@
ReplacedByPrebuilt()
IsReplacedByPrebuilt() bool
ExportedToMake() bool
- InitRc() Paths
- VintfFragments() Paths
EffectiveLicenseKinds() []string
EffectiveLicenseFiles() Paths
@@ -113,14 +114,7 @@
TargetRequiredModuleNames() []string
VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string
- // TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive
- // dependencies with dependency tags for which IsInstallDepNeeded() returns true.
- TransitivePackagingSpecs() []PackagingSpec
-
ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator
-
- // Get the information about the containers this module belongs to.
- ContainersInfo() ContainersInfo
}
// Qualified id for a module
@@ -501,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 {
@@ -835,16 +833,7 @@
// The primary licenses property, may be nil, records license metadata for the module.
primaryLicensesProperty applicableLicensesProperty
- noAddressSanitizer bool
- installFilesDepSet *DepSet[InstallPath]
- packagingSpecsDepSet *DepSet[PackagingSpec]
- // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
- // allowed to have duplicates across modules and variants.
- katiInitRcInstalls katiInstalls
- katiVintfInstalls katiInstalls
-
- // The files to copy to the dist as explicitly specified in the .bp file.
- distFiles TaggedDistFiles
+ noAddressSanitizer bool
hooks hooks
@@ -854,34 +843,6 @@
buildParams []BuildParams
ruleParams map[blueprint.Rule]blueprint.RuleParams
variables map[string]string
-
- initRcPaths Paths
- vintfFragmentsPaths Paths
-
- installedInitRcPaths InstallPaths
- installedVintfFragmentsPaths InstallPaths
-
- // Merged Aconfig files for all transitive deps.
- aconfigFilePaths Paths
-
- // set of dependency module:location mappings used to populate the license metadata for
- // apex containers.
- licenseInstallMap []string
-
- // The path to the generated license metadata file for the module.
- licenseMetadataFile WritablePath
-
- // 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
-
- // 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{}) {
@@ -1454,12 +1415,13 @@
if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
// Installation is still handled by Make, so anything hidden from Make is not
// installable.
+ info := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider)
if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
- installDeps = append(installDeps, dep.base().installFilesDepSet)
+ installDeps = append(installDeps, info.TransitiveInstallFiles)
}
// Add packaging deps even when the dependency is not installed so that uninstallable
// modules can still be packaged. Often the package will be installed instead.
- packagingSpecs = append(packagingSpecs, dep.base().packagingSpecsDepSet)
+ packagingSpecs = append(packagingSpecs, info.TransitivePackagingSpecs)
}
})
@@ -1477,10 +1439,6 @@
return IsInstallDepNeededTag(tag)
}
-func (m *ModuleBase) TransitivePackagingSpecs() []PackagingSpec {
- return m.packagingSpecsDepSet.ToList()
-}
-
func (m *ModuleBase) NoAddressSanitizer() bool {
return m.noAddressSanitizer
}
@@ -1594,44 +1552,43 @@
return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
}
-func (m *ModuleBase) InitRc() Paths {
- return append(Paths{}, m.initRcPaths...)
-}
+func (m *ModuleBase) generateVariantTarget(ctx *moduleContext) {
+ namespacePrefix := ctx.Namespace().id
+ if namespacePrefix != "" {
+ namespacePrefix = namespacePrefix + "-"
+ }
-func (m *ModuleBase) VintfFragments() Paths {
- return append(Paths{}, m.vintfFragmentsPaths...)
-}
+ if !ctx.uncheckedModule {
+ name := namespacePrefix + ctx.ModuleName() + "-" + ctx.ModuleSubDir() + "-checkbuild"
+ ctx.Phony(name, ctx.checkbuildFiles...)
+ ctx.checkbuildTarget = PathForPhony(ctx, name)
+ }
-func (m *ModuleBase) CompileMultilib() *string {
- return m.base().commonProperties.Compile_multilib
-}
-
-// SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
-// apex container for use when generation the license metadata file.
-func (m *ModuleBase) SetLicenseInstallMap(installMap []string) {
- m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
}
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)
}
})
@@ -1652,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 {
@@ -1773,17 +1729,36 @@
}
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
- KatiSymlinks katiInstalls
- TestData []DataPath
+ KatiInstalls katiInstalls
+ KatiSymlinks katiInstalls
+ TestData []DataPath
+ TransitivePackagingSpecs *DepSet[PackagingSpec]
+ LicenseMetadataFile WritablePath
+
+ // The following fields are private before, make it private again once we have
+ // better solution.
+ TransitiveInstallFiles *DepSet[InstallPath]
+ // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
+ // allowed to have duplicates across modules and variants.
+ KatiInitRcInstalls katiInstalls
+ KatiVintfInstalls katiInstalls
+ InitRcPaths Paths
+ VintfFragmentsPaths Paths
+ InstalledInitRcPaths InstallPaths
+ InstalledVintfFragmentsPaths InstallPaths
+
+ // The files to copy to the dist as explicitly specified in the .bp file.
+ DistFiles TaggedDistFiles
}
-var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]()
+var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
type FinalModuleBuildTargetsInfo struct {
// Used by buildTargetSingleton to create checkbuild and per-directory build targets
@@ -1793,7 +1768,7 @@
BlueprintDir string
}
-var InstallFilesProvider = blueprint.NewProvider[InstallFilesInfo]()
+var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]()
func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
ctx := &moduleContext{
@@ -1805,14 +1780,17 @@
}
setContainerInfo(ctx)
+ if ctx.Config().Getenv("DISABLE_CONTAINER_CHECK") != "true" {
+ checkContainerViolations(ctx)
+ }
- m.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
+ ctx.licenseMetadataFile = PathForModuleOut(ctx, "meta_lic")
dependencyInstallFiles, dependencyPackagingSpecs := m.computeInstallDeps(ctx)
- // set m.installFilesDepSet to only the transitive dependencies to be used as the dependencies
+ // set the TransitiveInstallFiles to only the transitive dependencies to be used as the dependencies
// of installed files of this module. It will be replaced by a depset including the installed
// files of this module at the end for use by modules that depend on this one.
- m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, nil, dependencyInstallFiles)
+ ctx.TransitiveInstallFiles = NewDepSet[InstallPath](TOPOLOGICAL, nil, dependencyInstallFiles)
// Temporarily continue to call blueprintCtx.GetMissingDependencies() to maintain the previous behavior of never
// reporting missing dependency errors in Blueprint when AllowMissingDependencies == true.
@@ -1856,6 +1834,8 @@
checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
}
+ var installFiles InstallFilesInfo
+
if m.Enabled(ctx) {
// ensure all direct android.Module deps are enabled
ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
@@ -1873,30 +1853,36 @@
// so only a single rule is created for each init.rc or vintf fragment file.
if !m.InVendorRamdisk() {
- m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
+ ctx.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
rcDir := PathForModuleInstall(ctx, "etc", "init")
- for _, src := range m.initRcPaths {
+ for _, src := range ctx.initRcPaths {
installedInitRc := rcDir.Join(ctx, src.Base())
- m.katiInitRcInstalls = append(m.katiInitRcInstalls, katiInstall{
+ ctx.katiInitRcInstalls = append(ctx.katiInitRcInstalls, katiInstall{
from: src,
to: installedInitRc,
})
ctx.PackageFile(rcDir, src.Base(), src)
- m.installedInitRcPaths = append(m.installedInitRcPaths, installedInitRc)
+ ctx.installedInitRcPaths = append(ctx.installedInitRcPaths, installedInitRc)
}
+ installFiles.InitRcPaths = ctx.initRcPaths
+ installFiles.KatiInitRcInstalls = ctx.katiInitRcInstalls
+ installFiles.InstalledInitRcPaths = ctx.installedInitRcPaths
}
- m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
+ ctx.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
- for _, src := range m.vintfFragmentsPaths {
+ for _, src := range ctx.vintfFragmentsPaths {
installedVintfFragment := vintfDir.Join(ctx, src.Base())
- m.katiVintfInstalls = append(m.katiVintfInstalls, katiInstall{
+ ctx.katiVintfInstalls = append(ctx.katiVintfInstalls, katiInstall{
from: src,
to: installedVintfFragment,
})
ctx.PackageFile(vintfDir, src.Base(), src)
- m.installedVintfFragmentsPaths = append(m.installedVintfFragmentsPaths, installedVintfFragment)
+ ctx.installedVintfFragmentsPaths = append(ctx.installedVintfFragmentsPaths, installedVintfFragment)
}
+ installFiles.VintfFragmentsPaths = ctx.vintfFragmentsPaths
+ installFiles.KatiVintfInstalls = ctx.katiVintfInstalls
+ installFiles.InstalledVintfFragmentsPaths = ctx.installedVintfFragmentsPaths
}
licensesPropertyFlattener(ctx)
@@ -1918,73 +1904,38 @@
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 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
// as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
// output paths being set which must be done before or during
// GenerateAndroidBuildActions.
- m.distFiles = m.GenerateTaggedDistFiles(ctx)
+ installFiles.DistFiles = m.GenerateTaggedDistFiles(ctx)
if ctx.Failed() {
return
}
- SetProvider(ctx, InstallFilesProvider, InstallFilesInfo{
- InstallFiles: ctx.installFiles,
- CheckbuildFiles: ctx.checkbuildFiles,
- PackagingSpecs: ctx.packagingSpecs,
- KatiInstalls: ctx.katiInstalls,
- KatiSymlinks: ctx.katiSymlinks,
- TestData: ctx.testData,
- })
+ 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
+ installFiles.TestData = ctx.testData
} else if ctx.Config().AllowMissingDependencies() {
// If the module is not enabled it will not create any build rules, nothing will call
// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
@@ -2000,17 +1951,19 @@
}
}
- m.installFilesDepSet = NewDepSet[InstallPath](TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
- m.packagingSpecsDepSet = NewDepSet[PackagingSpec](TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
+ ctx.TransitiveInstallFiles = NewDepSet[InstallPath](TOPOLOGICAL, ctx.installFiles, dependencyInstallFiles)
+ installFiles.TransitiveInstallFiles = ctx.TransitiveInstallFiles
+ installFiles.TransitivePackagingSpecs = NewDepSet[PackagingSpec](TOPOLOGICAL, ctx.packagingSpecs, dependencyPackagingSpecs)
- buildLicenseMetadata(ctx, m.licenseMetadataFile)
+ SetProvider(ctx, InstallFilesProvider, installFiles)
+ buildLicenseMetadata(ctx, ctx.licenseMetadataFile)
- if m.moduleInfoJSON != nil {
+ if ctx.moduleInfoJSON != nil {
var installed InstallPaths
installed = append(installed, ctx.katiInstalls.InstallPaths()...)
installed = append(installed, ctx.katiSymlinks.InstallPaths()...)
- installed = append(installed, m.katiInitRcInstalls.InstallPaths()...)
- installed = append(installed, m.katiVintfInstalls.InstallPaths()...)
+ installed = append(installed, ctx.katiInitRcInstalls.InstallPaths()...)
+ installed = append(installed, ctx.katiVintfInstalls.InstallPaths()...)
installedStrings := installed.Strings()
var targetRequired, hostRequired []string
@@ -2025,28 +1978,28 @@
data = append(data, d.ToRelativeInstallPath())
}
- if m.moduleInfoJSON.Uninstallable {
+ if ctx.moduleInfoJSON.Uninstallable {
installedStrings = nil
- if len(m.moduleInfoJSON.CompatibilitySuites) == 1 && m.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
- m.moduleInfoJSON.CompatibilitySuites = nil
- m.moduleInfoJSON.TestConfig = nil
- m.moduleInfoJSON.AutoTestConfig = nil
+ if len(ctx.moduleInfoJSON.CompatibilitySuites) == 1 && ctx.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
+ ctx.moduleInfoJSON.CompatibilitySuites = nil
+ ctx.moduleInfoJSON.TestConfig = nil
+ ctx.moduleInfoJSON.AutoTestConfig = nil
data = nil
}
}
- m.moduleInfoJSON.core = CoreModuleInfoJSON{
- RegisterName: m.moduleInfoRegisterName(ctx, m.moduleInfoJSON.SubName),
+ ctx.moduleInfoJSON.core = CoreModuleInfoJSON{
+ RegisterName: m.moduleInfoRegisterName(ctx, ctx.moduleInfoJSON.SubName),
Path: []string{ctx.ModuleDir()},
Installed: installedStrings,
- ModuleName: m.BaseModuleName() + m.moduleInfoJSON.SubName,
+ ModuleName: m.BaseModuleName() + ctx.moduleInfoJSON.SubName,
SupportedVariants: []string{m.moduleInfoVariant(ctx)},
TargetDependencies: targetRequired,
HostDependencies: hostRequired,
Data: data,
- Required: m.RequiredModuleNames(ctx),
+ Required: append(m.RequiredModuleNames(ctx), m.VintfFragmentModuleNames(ctx)...),
}
- SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON)
+ SetProvider(ctx, ModuleInfoJSONProvider, ctx.moduleInfoJSON)
}
m.buildParams = ctx.buildParams
@@ -2109,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
@@ -2151,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
@@ -2745,7 +2744,7 @@
// Collect information for opening IDE project files in java/jdeps.go.
type IDEInfo interface {
- IDEInfo(ideInfo *IdeInfo)
+ IDEInfo(ctx BaseModuleContext, ideInfo *IdeInfo)
BaseModuleName() string
}
@@ -2757,7 +2756,9 @@
IDECustomizedModuleName() string
}
+// Collect information for opening IDE project files in java/jdeps.go.
type IdeInfo struct {
+ BaseModuleName string `json:"-"`
Deps []string `json:"dependencies,omitempty"`
Srcs []string `json:"srcs,omitempty"`
Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
@@ -2771,6 +2772,31 @@
Libs []string `json:"libs,omitempty"`
}
+// Merge merges two IdeInfos and produces a new one, leaving the origional unchanged
+func (i IdeInfo) Merge(other IdeInfo) IdeInfo {
+ return IdeInfo{
+ Deps: mergeStringLists(i.Deps, other.Deps),
+ Srcs: mergeStringLists(i.Srcs, other.Srcs),
+ Aidl_include_dirs: mergeStringLists(i.Aidl_include_dirs, other.Aidl_include_dirs),
+ Jarjar_rules: mergeStringLists(i.Jarjar_rules, other.Jarjar_rules),
+ Jars: mergeStringLists(i.Jars, other.Jars),
+ Classes: mergeStringLists(i.Classes, other.Classes),
+ Installed_paths: mergeStringLists(i.Installed_paths, other.Installed_paths),
+ SrcJars: mergeStringLists(i.SrcJars, other.SrcJars),
+ Paths: mergeStringLists(i.Paths, other.Paths),
+ Static_libs: mergeStringLists(i.Static_libs, other.Static_libs),
+ Libs: mergeStringLists(i.Libs, other.Libs),
+ }
+}
+
+// mergeStringLists appends the two string lists together and returns a new string list,
+// leaving the originals unchanged. Duplicate strings will be deduplicated.
+func mergeStringLists(a, b []string) []string {
+ return FirstUniqueStrings(Concat(a, b))
+}
+
+var IdeInfoProviderKey = blueprint.NewProvider[IdeInfo]()
+
func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
bpctx := ctx.blueprintBaseModuleContext()
return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents)
diff --git a/android/module_context.go b/android/module_context.go
index e9fbb8c..3889e40 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -107,68 +107,79 @@
// InstallExecutable creates a rule to copy srcPath to name in the installPath directory,
// with the given additional dependencies. The file is marked executable after copying.
//
- // 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.
+ // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+ // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+ // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+ // dependency tags for which IsInstallDepNeeded returns true.
InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
// InstallFile creates a rule to copy srcPath to name in the installPath directory,
// with the given additional dependencies.
//
+ // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+ // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+ // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+ // 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.
- InstallFile(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
+ 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.
//
- // 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.
+ // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+ // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+ // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+ // dependency tags for which IsInstallDepNeeded returns true.
InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...InstallPath) InstallPath
// InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
// directory.
//
- // The installed symlink 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.
+ // The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+ // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+ // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+ // dependency tags for which IsInstallDepNeeded returns true.
InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
// InstallAbsoluteSymlink creates a rule to create an absolute symlink from src srcPath to name
// in the installPath directory.
//
- // The installed symlink 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.
+ // The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+ // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
+ // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+ // dependency tags for which IsInstallDepNeeded returns true.
InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
// InstallTestData creates rules to install test data (e.g. data files used during a test) into
// the installPath directory.
//
- // The installed files will be returned by FilesToInstall(), and the PackagingSpec for the
- // installed files 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.
+ // The installed files can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
+ // for the installed files can be accessed by InstallFilesInfo.PackagingSpecs on this module
+ // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+ // dependency tags for which IsInstallDepNeeded returns true.
InstallTestData(installPath InstallPath, data []DataPath) InstallPaths
// PackageFile creates a PackagingSpec as if InstallFile was called, but without creating
// the rule to copy the file. This is useful to define how a module would be packaged
// without installing it into the global installation directories.
//
- // The created PackagingSpec for the 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.
+ // The created PackagingSpec can be accessed by InstallFilesInfo.PackagingSpecs on this module
+ // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
+ // 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
@@ -218,26 +229,55 @@
GetOutputFiles() OutputFilesInfo
+ // SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
+ // apex container for use when generation the license metadata file.
+ SetLicenseInstallMap(installMap []string)
+
// ComplianceMetadataInfo returns a ComplianceMetadataInfo instance for different module types to dump metadata,
// 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
+ TransitiveInstallFiles *DepSet[InstallPath]
+
+ // set of dependency module:location mappings used to populate the license metadata for
+ // apex containers.
+ licenseInstallMap []string
+
+ // The path to the generated license metadata file for the module.
+ licenseMetadataFile WritablePath
+
katiInstalls katiInstalls
katiSymlinks katiInstalls
+ // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
+ // allowed to have duplicates across modules and variants.
+ katiInitRcInstalls katiInstalls
+ katiVintfInstalls katiInstalls
+ initRcPaths Paths
+ vintfFragmentsPaths Paths
+ installedInitRcPaths InstallPaths
+ installedVintfFragmentsPaths InstallPaths
testData []DataPath
@@ -245,6 +285,21 @@
buildParams []BuildParams
ruleParams map[blueprint.Rule]blueprint.RuleParams
variables map[string]string
+
+ // 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{}
@@ -470,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,
})
@@ -492,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,
@@ -507,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 {
@@ -521,9 +588,9 @@
}
if m.requiresFullInstall() {
- deps = append(deps, InstallPaths(m.module.base().installFilesDepSet.ToList())...)
- deps = append(deps, m.module.base().installedInitRcPaths...)
- deps = append(deps, m.module.base().installedVintfFragmentsPaths...)
+ deps = append(deps, InstallPaths(m.TransitiveInstallFiles.ToList())...)
+ deps = append(deps, m.installedInitRcPaths...)
+ deps = append(deps, m.installedVintfFragmentsPaths...)
var implicitDeps, orderOnlyDeps Paths
@@ -580,7 +647,9 @@
m.packageFile(fullInstallPath, srcPath, executable)
- m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
+ if checkbuild {
+ m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
+ }
return fullInstallPath
}
@@ -621,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,
@@ -633,6 +702,8 @@
skipInstall: m.skipInstall(),
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
+ overrides: &overrides,
+ owner: m.ModuleName(),
})
return fullInstallPath
@@ -668,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,
@@ -677,6 +749,8 @@
skipInstall: m.skipInstall(),
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
+ overrides: &overrides,
+ owner: m.ModuleName(),
})
return fullInstallPath
@@ -688,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 {
@@ -704,15 +784,15 @@
}
func (m *moduleContext) LicenseMetadataFile() Path {
- return m.module.base().licenseMetadataFile
+ return m.licenseMetadataFile
}
func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON {
- if moduleInfoJSON := m.module.base().moduleInfoJSON; moduleInfoJSON != nil {
+ if moduleInfoJSON := m.moduleInfoJSON; moduleInfoJSON != nil {
return moduleInfoJSON
}
moduleInfoJSON := &ModuleInfoJSON{}
- m.module.base().moduleInfoJSON = moduleInfoJSON
+ m.moduleInfoJSON = moduleInfoJSON
return moduleInfoJSON
}
@@ -738,13 +818,15 @@
return m.outputFiles
}
+func (m *moduleContext) SetLicenseInstallMap(installMap []string) {
+ m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
+}
+
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
@@ -784,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/module_test.go b/android/module_test.go
index 92041ec..d64e3a5 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -722,6 +722,7 @@
propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "x86_64 a"},
propInfo{Name: "B", Type: "bool", Value: "true"},
propInfo{Name: "C", Type: "string slice", Values: []string{"default_c", "c"}},
+ propInfo{Name: "Defaults", Type: "string slice", Values: []string{"foo_defaults"}},
propInfo{Name: "Embedded_prop", Type: "string", Value: "a"},
propInfo{Name: "Name", Type: "string", Value: "foo"},
propInfo{Name: "Nested.E", Type: "string", Value: "nested e"},
diff --git a/android/neverallow.go b/android/neverallow.go
index 0f363e7..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 {
@@ -287,7 +305,7 @@
continue
}
- if !n.appliesToProperties(properties) {
+ if !n.appliesToProperties(ctx, properties) {
continue
}
@@ -604,9 +622,9 @@
return (len(r.moduleTypes) == 0 || InList(moduleType, r.moduleTypes)) && !InList(moduleType, r.unlessModuleTypes)
}
-func (r *rule) appliesToProperties(properties []interface{}) bool {
- includeProps := hasAllProperties(properties, r.props)
- excludeProps := hasAnyProperty(properties, r.unlessProps)
+func (r *rule) appliesToProperties(ctx BottomUpMutatorContext, properties []interface{}) bool {
+ includeProps := hasAllProperties(ctx, properties, r.props)
+ excludeProps := hasAnyProperty(ctx, properties, r.unlessProps)
return includeProps && !excludeProps
}
@@ -644,25 +662,25 @@
return names
}
-func hasAnyProperty(properties []interface{}, props []ruleProperty) bool {
+func hasAnyProperty(ctx BottomUpMutatorContext, properties []interface{}, props []ruleProperty) bool {
for _, v := range props {
- if hasProperty(properties, v) {
+ if hasProperty(ctx, properties, v) {
return true
}
}
return false
}
-func hasAllProperties(properties []interface{}, props []ruleProperty) bool {
+func hasAllProperties(ctx BottomUpMutatorContext, properties []interface{}, props []ruleProperty) bool {
for _, v := range props {
- if !hasProperty(properties, v) {
+ if !hasProperty(ctx, properties, v) {
return false
}
}
return true
}
-func hasProperty(properties []interface{}, prop ruleProperty) bool {
+func hasProperty(ctx BottomUpMutatorContext, properties []interface{}, prop ruleProperty) bool {
for _, propertyStruct := range properties {
propertiesValue := reflect.ValueOf(propertyStruct).Elem()
for _, v := range prop.fields {
@@ -679,14 +697,14 @@
return prop.matcher.Test(value)
}
- if matchValue(propertiesValue, check) {
+ if matchValue(ctx, propertiesValue, check) {
return true
}
}
return false
}
-func matchValue(value reflect.Value, check func(string) bool) bool {
+func matchValue(ctx BottomUpMutatorContext, value reflect.Value, check func(string) bool) bool {
if !value.IsValid() {
return false
}
@@ -698,19 +716,26 @@
value = value.Elem()
}
- switch value.Kind() {
- case reflect.String:
- return check(value.String())
- case reflect.Bool:
- return check(strconv.FormatBool(value.Bool()))
- case reflect.Int:
- return check(strconv.FormatInt(value.Int(), 10))
- case reflect.Slice:
- slice, ok := value.Interface().([]string)
- if !ok {
- panic("Can only handle slice of string")
+ switch v := value.Interface().(type) {
+ case string:
+ return check(v)
+ case bool:
+ return check(strconv.FormatBool(v))
+ case int:
+ return check(strconv.FormatInt((int64)(v), 10))
+ case []string:
+ for _, v := range v {
+ if check(v) {
+ return true
+ }
}
- for _, v := range slice {
+ return false
+ case proptools.Configurable[string]:
+ return check(v.GetOrDefault(ctx, ""))
+ case proptools.Configurable[bool]:
+ return check(strconv.FormatBool(v.GetOrDefault(ctx, false)))
+ case proptools.Configurable[[]string]:
+ for _, v := range v.GetOrDefault(ctx, nil) {
if check(v) {
return true
}
diff --git a/android/notices.go b/android/notices.go
index b9c1682..3c41d92 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -36,10 +36,22 @@
return SortedUniqueStrings(dirs)
}
-func modulesLicenseMetadata(ctx BuilderContext, modules ...Module) Paths {
+type BuilderAndOtherModuleProviderContext interface {
+ BuilderContext
+ OtherModuleProviderContext
+}
+
+func modulesLicenseMetadata(ctx OtherModuleProviderContext, modules ...Module) Paths {
result := make(Paths, 0, len(modules))
+ mctx, isMctx := ctx.(ModuleContext)
for _, module := range modules {
- if mf := module.base().licenseMetadataFile; mf != nil {
+ var mf Path
+ if isMctx && mctx.Module() == module {
+ mf = mctx.LicenseMetadataFile()
+ } else {
+ mf = OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider).LicenseMetadataFile
+ }
+ if mf != nil {
result = append(result, mf)
}
}
@@ -48,7 +60,7 @@
// buildNoticeOutputFromLicenseMetadata writes out a notice file.
func buildNoticeOutputFromLicenseMetadata(
- ctx BuilderContext, tool, ruleName string, outputFile WritablePath,
+ ctx BuilderAndOtherModuleProviderContext, tool, ruleName string, outputFile WritablePath,
libraryName string, stripPrefix []string, modules ...Module) {
depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", "."))
rule := NewRuleBuilder(pctx, ctx)
@@ -84,7 +96,7 @@
// on the license metadata files for the input `modules` defaulting to the
// current context module if none given.
func BuildNoticeTextOutputFromLicenseMetadata(
- ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
+ ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
stripPrefix []string, modules ...Module) {
buildNoticeOutputFromLicenseMetadata(ctx, "textnotice", "text_notice_"+ruleName,
outputFile, libraryName, stripPrefix, modules...)
@@ -94,7 +106,7 @@
// on the license metadata files for the input `modules` defaulting to the
// current context module if none given.
func BuildNoticeHtmlOutputFromLicenseMetadata(
- ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
+ ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
stripPrefix []string, modules ...Module) {
buildNoticeOutputFromLicenseMetadata(ctx, "htmlnotice", "html_notice_"+ruleName,
outputFile, libraryName, stripPrefix, modules...)
@@ -104,7 +116,7 @@
// on the license metadata files for the input `modules` defaulting to the
// current context module if none given.
func BuildNoticeXmlOutputFromLicenseMetadata(
- ctx BuilderContext, outputFile WritablePath, ruleName, libraryName string,
+ ctx BuilderAndOtherModuleProviderContext, outputFile WritablePath, ruleName, libraryName string,
stripPrefix []string, modules ...Module) {
buildNoticeOutputFromLicenseMetadata(ctx, "xmlnotice", "xml_notice_"+ruleName,
outputFile, libraryName, stripPrefix, modules...)
diff --git a/android/packaging.go b/android/packaging.go
index c247ed2..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) {
@@ -346,7 +388,8 @@
if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() {
return
}
- for _, ps := range child.TransitivePackagingSpecs() {
+ for _, ps := range OtherModuleProviderOrDefault(
+ ctx, child, InstallFilesProvider).TransitivePackagingSpecs.ToList() {
if !filterArch(ps) {
continue
}
@@ -356,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/product_config.go b/android/product_config.go
index 20b29a7..04180bf 100644
--- a/android/product_config.go
+++ b/android/product_config.go
@@ -37,8 +37,10 @@
if targetProduct != "" {
targetProduct += "."
}
- soongVariablesPath := PathForOutput(ctx, "soong."+targetProduct+"variables")
- extraVariablesPath := PathForOutput(ctx, "soong."+targetProduct+"extra.variables")
+
+ coverageSuffix := ctx.Config().CoverageSuffix()
+ soongVariablesPath := PathForOutput(ctx, "soong."+targetProduct+coverageSuffix+"variables")
+ extraVariablesPath := PathForOutput(ctx, "soong."+targetProduct+coverageSuffix+"extra.variables")
rule := NewRuleBuilder(pctx, ctx)
rule.Command().BuiltTool("merge_json").
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 464aca4..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,6 +582,44 @@
})
}
+ // 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/android/variable.go b/android/variable.go
index c8744ed..14f1756 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -512,13 +512,9 @@
SystemPropFiles []string `json:",omitempty"`
SystemExtPropFiles []string `json:",omitempty"`
ProductPropFiles []string `json:",omitempty"`
+ OdmPropFiles []string `json:",omitempty"`
EnableUffdGc *string `json:",omitempty"`
-
- BoardAvbEnable *bool `json:",omitempty"`
- BoardAvbSystemAddHashtreeFooterArgs []string `json:",omitempty"`
- DeviceFrameworkCompatibilityMatrixFile []string `json:",omitempty"`
- DeviceProductCompatibilityMatrixFile []string `json:",omitempty"`
}
type PartitionQualifiedVariablesType struct {
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/aconfig_test.go b/apex/aconfig_test.go
index 14c0b63..bb811f5 100644
--- a/apex/aconfig_test.go
+++ b/apex/aconfig_test.go
@@ -74,6 +74,8 @@
apex_available: [
"myapex",
],
+ sdk_version: "none",
+ system_modules: "none",
}`,
},
{
@@ -122,6 +124,8 @@
apex_available: [
"myapex",
],
+ sdk_version: "none",
+ system_modules: "none",
}`,
},
{
@@ -345,6 +349,8 @@
apex_available: [
"myapex",
],
+ sdk_version: "none",
+ system_modules: "none",
}`,
expectedError: `.*my_java_library_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
},
@@ -392,6 +398,8 @@
apex_available: [
"myapex",
],
+ sdk_version: "none",
+ system_modules: "none",
}`,
expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
},
@@ -693,6 +701,8 @@
apex_available: [
"myapex",
],
+ sdk_version: "none",
+ system_modules: "none",
}`,
expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
},
@@ -769,6 +779,8 @@
apex_available: [
"myapex",
],
+ sdk_version: "none",
+ system_modules: "none",
}`,
},
}
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 ec71c18..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)
@@ -699,6 +704,8 @@
// If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will
// also be added as exported members of that SDK.
memberType android.SdkMemberType
+
+ installable bool
}
func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
@@ -717,18 +724,23 @@
return !d.sourceOnly
}
+func (d *dependencyTag) InstallDepNeeded() bool {
+ return d.installable
+}
+
var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{}
var _ android.SdkMemberDependencyTag = &dependencyTag{}
var (
- androidAppTag = &dependencyTag{name: "androidApp", payload: true}
- bpfTag = &dependencyTag{name: "bpf", payload: true}
- certificateTag = &dependencyTag{name: "certificate"}
- dclaTag = &dependencyTag{name: "dcla"}
- executableTag = &dependencyTag{name: "executable", payload: true}
- fsTag = &dependencyTag{name: "filesystem", payload: true}
- bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
- sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType}
+ androidAppTag = &dependencyTag{name: "androidApp", payload: true}
+ bpfTag = &dependencyTag{name: "bpf", payload: true}
+ certificateTag = &dependencyTag{name: "certificate"}
+ dclaTag = &dependencyTag{name: "dcla"}
+ executableTag = &dependencyTag{name: "executable", payload: true}
+ fsTag = &dependencyTag{name: "filesystem", payload: true}
+ bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType}
+ // The dexpreopt artifacts of apex system server jars are installed onto system image.
+ sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType, installable: true}
compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
javaLibTag = &dependencyTag{name: "javaLib", payload: true}
jniLibTag = &dependencyTag{name: "jniLib", payload: true}
@@ -1686,12 +1698,10 @@
if sdkLib, ok := module.(*java.SdkLibrary); ok {
for _, install := range sdkLib.BuiltInstalledForApex() {
af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
- install.PackageFile(ctx)
}
} else if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
- install.PackageFile(ctx)
}
}
return af
@@ -1932,8 +1942,6 @@
// visitor skips these from this list of module names
unwantedTransitiveDeps []string
-
- aconfigFiles []android.Path
}
func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
@@ -2000,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
@@ -2012,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)
@@ -2021,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",
@@ -2065,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))
@@ -2074,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() {
@@ -2095,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)
}
@@ -2127,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)
}
@@ -2142,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)
@@ -2222,13 +2219,15 @@
}
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) {
+ return false
+ }
+
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) {
@@ -2244,10 +2243,13 @@
}
} else if rust.IsDylibDepTag(depTag) {
if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
+ if !android.IsDepInSameApex(ctx, am, am) {
+ return false
+ }
+
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) {
@@ -2266,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",
@@ -2281,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",
@@ -2299,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 {
@@ -2393,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)
@@ -2860,7 +2850,7 @@
}
// Collect information for opening IDE project files in java/jdeps.go.
-func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
+func (a *apexBundle) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
dpInfo.Deps = append(dpInfo.Deps, a.properties.ResolvedSystemserverclasspathFragments...)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 6b9944d..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) {
@@ -906,7 +915,7 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["mylib2", "mylib3"],
+ shared_libs: ["mylib2", "mylib3", "my_prebuilt_platform_lib", "my_prebuilt_platform_stub_only_lib"],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -919,6 +928,7 @@
system_shared_libs: [],
stl: "none",
stubs: {
+ symbol_file: "mylib2.map.txt",
versions: ["1", "2", "3"],
},
}
@@ -930,6 +940,7 @@
system_shared_libs: [],
stl: "none",
stubs: {
+ symbol_file: "mylib3.map.txt",
versions: ["10", "11", "12"],
},
apex_available: [ "myapex" ],
@@ -943,6 +954,24 @@
apex_available: [ "myapex" ],
}
+ cc_prebuilt_library_shared {
+ name: "my_prebuilt_platform_lib",
+ stubs: {
+ symbol_file: "my_prebuilt_platform_lib.map.txt",
+ versions: ["1", "2", "3"],
+ },
+ srcs: ["foo.so"],
+ }
+
+ // Similar to my_prebuilt_platform_lib, but this library only provides stubs, i.e. srcs is empty
+ cc_prebuilt_library_shared {
+ name: "my_prebuilt_platform_stub_only_lib",
+ stubs: {
+ symbol_file: "my_prebuilt_platform_stub_only_lib.map.txt",
+ versions: ["1", "2", "3"],
+ }
+ }
+
rust_binary {
name: "foo.rust",
srcs: ["foo.rs"],
@@ -1022,6 +1051,20 @@
apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so")
+
+ // Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib
+ ensureContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_lib.so")
+ // ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib
+ ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_lib.so")
+ // Ensure that genstub for platform-provided lib is invoked with --systemapi
+ ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+
+ // Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib
+ ensureContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_stub_only_lib.so")
+ // ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib
+ ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_stub_only_lib.so")
+ // Ensure that genstub for platform-provided lib is invoked with --systemapi
+ ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_stub_only_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
}
func TestApexShouldNotEmbedStubVariant(t *testing.T) {
@@ -1156,6 +1199,7 @@
system_shared_libs: [],
stl: "none",
stubs: {
+ symbol_file: "mylib2.map.txt",
versions: ["28", "29", "30", "current"],
},
min_sdk_version: "28",
@@ -1168,6 +1212,7 @@
system_shared_libs: [],
stl: "none",
stubs: {
+ symbol_file: "mylib3.map.txt",
versions: ["28", "29", "30", "current"],
},
apex_available: [ "myapex" ],
@@ -4893,6 +4938,7 @@
java_import {
name: "libfoo",
jars: ["libfoo.jar"],
+ sdk_version: "core_current",
}
java_sdk_library_import {
@@ -4933,6 +4979,22 @@
t.Run("prebuilt with source preferred", func(t *testing.T) {
bp := `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: false,
+ java_libs: [
+ "libfoo",
+ "libbar",
+ ],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
prebuilt_apex {
name: "myapex",
arch: {
@@ -4949,10 +5011,21 @@
java_import {
name: "libfoo",
jars: ["libfoo.jar"],
+ apex_available: [
+ "myapex",
+ ],
+ compile_dex: true,
+ sdk_version: "core_current",
}
java_library {
name: "libfoo",
+ srcs: ["foo/bar/MyClass.java"],
+ apex_available: [
+ "myapex",
+ ],
+ compile_dex: true,
+ sdk_version: "core_current",
}
java_sdk_library_import {
@@ -4960,12 +5033,21 @@
public: {
jars: ["libbar.jar"],
},
+ apex_available: [
+ "myapex",
+ ],
+ compile_dex: true,
}
java_sdk_library {
name: "libbar",
srcs: ["foo/bar/MyClass.java"],
unsafe_ignore_missing_latest_api: true,
+ apex_available: [
+ "myapex",
+ ],
+ compile_dex: true,
+ sdk_version: "core_current",
}
`
@@ -4974,11 +5056,9 @@
checkDexJarBuildPath(t, ctx, "prebuilt_libfoo")
checkDexJarInstallPath(t, ctx, "prebuilt_libfoo")
- ensureNoSourceVariant(t, ctx, "libfoo")
checkDexJarBuildPath(t, ctx, "prebuilt_libbar")
checkDexJarInstallPath(t, ctx, "prebuilt_libbar")
- ensureNoSourceVariant(t, ctx, "libbar")
})
t.Run("prebuilt preferred with source", func(t *testing.T) {
@@ -5004,6 +5084,7 @@
java_library {
name: "libfoo",
+ sdk_version: "core_current",
}
java_sdk_library_import {
@@ -5130,6 +5211,7 @@
jars: ["libfoo.jar"],
apex_available: ["myapex"],
permitted_packages: ["foo"],
+ sdk_version: "core_current",
}
java_sdk_library_import {
@@ -5284,12 +5366,14 @@
name: "libfoo",
jars: ["libfoo.jar"],
apex_available: ["myapex"],
+ sdk_version: "core_current",
}
java_library {
name: "libfoo",
srcs: ["foo/bar/MyClass.java"],
apex_available: ["myapex"],
+ sdk_version: "core_current",
}
java_sdk_library_import {
@@ -5381,6 +5465,7 @@
jars: ["libfoo.jar"],
apex_available: ["myapex"],
permitted_packages: ["foo"],
+ sdk_version: "core_current",
}
java_library {
@@ -5388,6 +5473,7 @@
srcs: ["foo/bar/MyClass.java"],
apex_available: ["myapex"],
installable: true,
+ sdk_version: "core_current",
}
java_sdk_library_import {
@@ -5478,6 +5564,7 @@
name: "libfoo",
jars: ["libfoo.jar"],
apex_available: ["myapex"],
+ sdk_version: "core_current",
}
java_library {
@@ -5486,6 +5573,7 @@
apex_available: ["myapex"],
permitted_packages: ["foo"],
installable: true,
+ sdk_version: "core_current",
}
java_sdk_library_import {
@@ -5504,6 +5592,7 @@
apex_available: ["myapex"],
permitted_packages: ["bar"],
compile_dex: true,
+ sdk_version: "core_current",
}
`
@@ -6098,6 +6187,7 @@
name: "TesterHelpAppFoo",
srcs: ["foo/bar/MyClass.java"],
apex_available: [ "myapex" ],
+ sdk_version: "test_current",
}
`)
@@ -7700,7 +7790,7 @@
srcs: ["foo/bar/MyClass.java"],
sdk_version: "none",
system_modules: "none",
- libs: ["myotherjar"],
+ static_libs: ["myotherjar"],
apex_available: [
"myapex",
"myapex.updatable",
@@ -8361,6 +8451,7 @@
apex_available: [
"myapex",
],
+ sdk_version: "current",
}
systemserverclasspath_fragment {
@@ -9403,6 +9494,7 @@
srcs: ["mybootclasspathlib.java"],
apex_available: ["myapex"],
compile_dex: true,
+ sdk_version: "current",
}
systemserverclasspath_fragment {
@@ -9718,6 +9810,7 @@
unsafe_ignore_missing_latest_api: true,
min_sdk_version: "31",
static_libs: ["util"],
+ sdk_version: "core_current",
}
java_library {
@@ -9726,6 +9819,7 @@
apex_available: ["myapex"],
min_sdk_version: "31",
static_libs: ["another_util"],
+ sdk_version: "core_current",
}
java_library {
@@ -9733,6 +9827,7 @@
srcs: ["a.java"],
min_sdk_version: "31",
apex_available: ["myapex"],
+ sdk_version: "core_current",
}
`)
})
@@ -9788,7 +9883,7 @@
})
t.Run("bootclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
- preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mybootclasspathlib".*must set min_sdk_version`)).
+ preparer.
RunTestWithBp(t, `
apex {
name: "myapex",
@@ -9819,6 +9914,8 @@
apex_available: ["myapex"],
compile_dex: true,
unsafe_ignore_missing_latest_api: true,
+ sdk_version: "current",
+ min_sdk_version: "30",
}
`)
})
@@ -10071,6 +10168,9 @@
key: "myapex.key",
bootclasspath_fragments: ["mybootclasspathfragment"],
min_sdk_version: "29",
+ java_libs: [
+ "jacocoagent",
+ ],
}
apex_key {
name: "myapex.key",
@@ -10700,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",
@@ -10835,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",
@@ -11003,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",
@@ -11940,7 +12040,7 @@
).RunTest(t)
ldRule := result.ModuleForTests("installedlib", "android_arm64_armv8-a_shared").Rule("ld")
- android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared/libfoo.so")
+ android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared_current/libfoo.so")
installRules := result.InstallMakeRulesForTesting(t)
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 25131ee..7cad337 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -104,6 +104,7 @@
test: {
enabled: true,
},
+ sdk_version: "core_current",
}
java_library {
@@ -749,6 +750,7 @@
],
srcs: ["b.java"],
compile_dex: true,
+ sdk_version: "core_current",
}
java_sdk_library {
@@ -922,6 +924,7 @@
],
srcs: ["b.java"],
compile_dex: true,
+ sdk_version: "core_current",
}
java_library {
@@ -1093,6 +1096,7 @@
],
srcs: ["b.java"],
compile_dex: true,
+ sdk_version: "core_current",
}
java_library {
@@ -1245,6 +1249,7 @@
],
srcs: ["b.java"],
compile_dex: true,
+ sdk_version: "core_current",
}
java_library {
diff --git a/apex/builder.go b/apex/builder.go
index bfe1692..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
@@ -595,7 +655,7 @@
if len(installMapSet) > 0 {
var installs []string
installs = append(installs, android.SortedKeys(installMapSet)...)
- a.SetLicenseInstallMap(installs)
+ ctx.SetLicenseInstallMap(installs)
}
////////////////////////////////////////////////////////////////////////////////////////////
@@ -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/apex/classpath_element_test.go b/apex/classpath_element_test.go
index b9a9198..9e1ac94 100644
--- a/apex/classpath_element_test.go
+++ b/apex/classpath_element_test.go
@@ -92,6 +92,7 @@
],
srcs: ["b.java"],
installable: true,
+ sdk_version: "core_current",
}
java_library {
diff --git a/apex/container_test.go b/apex/container_test.go
index 3931174..d28b1a6 100644
--- a/apex/container_test.go
+++ b/apex/container_test.go
@@ -30,7 +30,7 @@
result := android.GroupFixturePreparers(
prepareForApexTest,
java.PrepareForTestWithJavaSdkLibraryFiles,
- java.FixtureWithLastReleaseApis("mybootclasspathlib"),
+ java.FixtureWithLastReleaseApis("mybootclasspathlib", "bar"),
).RunTestWithBp(t, `
apex {
name: "myapex",
@@ -68,16 +68,17 @@
],
compile_dex: true,
static_libs: [
- "foo",
+ "food",
"baz",
],
libs: [
- "bar",
+ "bar.stubs",
],
min_sdk_version: "30",
+ sdk_version: "current",
}
java_library {
- name: "foo",
+ name: "food",
srcs:[
"A.java",
],
@@ -85,13 +86,15 @@
"myapex",
],
min_sdk_version: "30",
+ sdk_version: "core_current",
}
- java_library {
+ java_sdk_library {
name: "bar",
srcs:[
"A.java",
],
min_sdk_version: "30",
+ sdk_version: "core_current",
}
java_library {
name: "baz",
@@ -103,6 +106,7 @@
"myapex",
],
min_sdk_version: "30",
+ sdk_version: "core_current",
}
`)
testcases := []struct {
@@ -130,7 +134,7 @@
isApexContainer: false,
},
{
- moduleName: "foo",
+ moduleName: "food",
variant: "android_common_apex30",
isSystemContainer: true,
isApexContainer: true,
@@ -162,7 +166,7 @@
result := android.GroupFixturePreparers(
prepareForApexTest,
java.PrepareForTestWithJavaSdkLibraryFiles,
- java.FixtureWithLastReleaseApis("mybootclasspathlib"),
+ java.FixtureWithLastReleaseApis("mybootclasspathlib", "bar"),
).RunTestWithBp(t, `
apex {
name: "myapex",
@@ -199,26 +203,30 @@
],
compile_dex: true,
static_libs: [
- "foo",
+ "food",
],
libs: [
- "bar",
+ "bar.stubs",
],
+ sdk_version: "current",
}
java_library {
- name: "foo",
+ name: "food",
srcs:[
"A.java",
],
apex_available: [
"myapex",
],
+ sdk_version: "core_current",
}
- java_library {
+ java_sdk_library {
name: "bar",
srcs:[
"A.java",
],
+ sdk_version: "none",
+ system_modules: "none",
}
`)
testcases := []struct {
@@ -246,7 +254,7 @@
isApexContainer: false,
},
{
- moduleName: "foo",
+ moduleName: "food",
variant: "android_common_apex10000",
isSystemContainer: true,
isApexContainer: true,
diff --git a/apex/dexpreopt_bootjars_test.go b/apex/dexpreopt_bootjars_test.go
index 95db37d..d8ee4ba 100644
--- a/apex/dexpreopt_bootjars_test.go
+++ b/apex/dexpreopt_bootjars_test.go
@@ -409,3 +409,106 @@
android.AssertStringListContains(t, tc.desc, inputs, tc.expectedProfile)
}
}
+
+// Check that dexpreopt works with Google mainline prebuilts even in workspaces where source is missing
+func TestDexpreoptWithMainlinePrebuiltNoSource(t *testing.T) {
+ bp := `
+ // Platform.
+
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "art-bootclasspath-fragment",
+ },
+ ],
+ }
+
+ // Source AOSP ART apex
+ java_library {
+ name: "core-oj",
+ srcs: ["core-oj.java"],
+ installable: true,
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ contents: ["core-oj"],
+ apex_available: [
+ "com.android.art",
+ ],
+ hidden_api: {
+ split_packages: ["*"],
+ },
+ }
+
+ apex_key {
+ name: "com.android.art.key",
+ public_key: "com.android.art.avbpubkey",
+ private_key: "com.android.art.pem",
+ }
+
+ apex {
+ name: "com.android.art",
+ key: "com.android.art.key",
+ bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ updatable: false,
+ }
+
+
+ // Prebuilt Google ART APEX.
+
+ java_import {
+ name: "core-oj",
+ jars: ["core-oj.jar"],
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "art-bootclasspath-fragment",
+ image_name: "art",
+ contents: ["core-oj"],
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
+ apex_available: [
+ "com.android.art",
+ ],
+ }
+
+ prebuilt_apex {
+ name: "com.google.android.art",
+ apex_name: "com.android.art",
+ src: "com.android.art-arm.apex",
+ exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
+ }
+
+ apex_contributions {
+ name: "art.prebuilt.contributions",
+ api_domain: "com.android.art",
+ contents: ["prebuilt_com.google.android.art"],
+ }
+ `
+ res := android.GroupFixturePreparers(
+ java.PrepareForTestWithDexpreopt,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureConfigureBootJars("com.android.art:core-oj"),
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithArtApex,
+ android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "art.prebuilt.contributions"),
+ ).RunTestWithBp(t, bp)
+ if !java.CheckModuleHasDependency(t, res.TestContext, "dex_bootjars", "android_common", "prebuilt_com.google.android.art") {
+ t.Errorf("Expected dexpreopt to use prebuilt apex")
+ }
+}
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 920fc0c..9c2d899 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -293,6 +293,7 @@
],
srcs: ["b.java"],
installable: true,
+ sdk_version: "core_current",
}
// Add a java_import that is not preferred and so won't have an appropriate apex variant created
@@ -791,6 +792,128 @@
`)
}
+// Skip bcp_fragment content validation of source apexes if prebuilts are active.
+func TestNonBootJarInPrebuilts(t *testing.T) {
+ testCases := []struct {
+ description string
+ selectedApexContributions string
+ expectedError string
+ }{
+ {
+ description: "source is active",
+ selectedApexContributions: "",
+ expectedError: "in contents must also be declared in PRODUCT_APEX_BOOT_JARS",
+ },
+ {
+ description: "prebuilts are active",
+ selectedApexContributions: "myapex.prebuilt.contributions",
+ expectedError: "", // skip content validation of source bcp fragment
+ },
+ }
+ bp := `
+// Source
+apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: ["apex-fragment"],
+ updatable: false,
+ min_sdk_version: "29",
+}
+
+override_apex {
+ name: "myapex.override", // overrides the min_sdk_version, thereby creating different variants of its transitive deps
+ base: "myapex",
+ min_sdk_version: "34",
+}
+
+apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+}
+
+java_library {
+ name: "foo",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["foo"],
+ min_sdk_version: "29",
+}
+
+java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["bar"],
+ min_sdk_version: "29",
+}
+
+bootclasspath_fragment {
+ name: "apex-fragment",
+ contents: ["foo", "bar"],
+ apex_available:[ "myapex" ],
+ hidden_api: {
+ split_packages: ["*"],
+ },
+}
+
+platform_bootclasspath {
+ name: "myplatform-bootclasspath",
+ fragments: [{
+ apex: "myapex",
+ module:"apex-fragment",
+ }],
+}
+
+// prebuilts
+prebuilt_apex {
+ name: "myapex",
+ apex_name: "myapex",
+ src: "myapex.apex",
+ exported_bootclasspath_fragments: ["apex-fragment"],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "apex-fragment",
+ contents: ["foo"],
+ hidden_api: {
+ annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
+ metadata: "my-bootclasspath-fragment/metadata.csv",
+ index: "my-bootclasspath-fragment/index.csv",
+ stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
+ all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ },
+ }
+ java_import {
+ name: "foo",
+ jars: ["foo.jar"],
+ }
+
+apex_contributions {
+ name: "myapex.prebuilt.contributions",
+ api_domain: "myapex",
+ contents: ["prebuilt_myapex"],
+}
+`
+
+ for _, tc := range testCases {
+ fixture := android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ java.FixtureConfigureApexBootJars("myapex:foo"),
+ android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", tc.selectedApexContributions),
+ )
+ if tc.expectedError != "" {
+ fixture = fixture.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError))
+ }
+ fixture.RunTestWithBp(t, bp)
+ }
+
+}
+
// Source and prebuilt apex provide different set of boot jars
func TestNonBootJarMissingInPrebuiltFragment(t *testing.T) {
bp := `
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 9dc8a63..f1a134e 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -195,7 +195,6 @@
// If this apex contains a system server jar, then the dexpreopt artifacts should be added as required
for _, install := range p.Dexpreopter.DexpreoptBuiltInstalledForApex() {
p.requiredModuleNames = append(p.requiredModuleNames, install.FullModuleName())
- install.PackageFile(ctx)
}
}
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index 452a43e..fd9020b 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -80,6 +80,7 @@
apex_available: [
"myapex",
],
+ sdk_version: "core_current",
}
systemserverclasspath_fragment {
@@ -350,6 +351,7 @@
apex_available: [
"myapex",
],
+ sdk_version: "core_current",
}
systemserverclasspath_fragment {
diff --git a/bin/aninja b/bin/aninja
index 5acb968..5cb5a55 100755
--- a/bin/aninja
+++ b/bin/aninja
@@ -34,5 +34,5 @@
esac
cd $(gettop)
-prebuilts/build-tools/${host_arch}/bin/ninja -f out/combined-${TARGET_PRODUCT}.ninja "$@"
+prebuilts/build-tools/${host_arch}/bin/ninja -f $(getoutdir)/combined-${TARGET_PRODUCT}.ninja "$@"
diff --git a/cc/cc.go b/cc/cc.go
index 947dc1a..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)
@@ -3042,7 +3048,7 @@
}
if dep.Target().Os != ctx.Os() {
- ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
+ ctx.ModuleErrorf("OS mismatch between %q (%s) and %q (%s)", ctx.ModuleName(), ctx.Os().Name, depName, dep.Target().Os.Name)
return
}
if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 79e386f..93630db 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -927,7 +927,7 @@
cc_prebuilt_library_shared {
name: "libllndkprebuilt",
- stubs: { versions: ["1", "2"] },
+ stubs: { versions: ["1", "2"] , symbol_file: "libllndkprebuilt.map.txt" },
llndk: {
symbol_file: "libllndkprebuilt.map.txt",
},
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/library.go b/cc/library.go
index 6017848..65a923a 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -594,43 +594,7 @@
return objs
}
if library.buildStubs() {
- symbolFile := String(library.Properties.Stubs.Symbol_file)
- if symbolFile != "" && !strings.HasSuffix(symbolFile, ".map.txt") {
- ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
- return Objects{}
- }
- library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
- // b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
- // systemapi, respectively. The former is for symbols defined in platform libraries
- // and the latter is for symbols defined in APEXes.
- // A single library can contain either # apex or # systemapi, but not both.
- // The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
- // However, having this distinction helps guard accidental
- // promotion or demotion of API and also helps the API review process b/191371676
- var flag string
- if ctx.Module().(android.ApexModule).NotInPlatform() {
- flag = "--apex"
- } else {
- flag = "--systemapi"
- }
- // b/184712170, unless the lib is an NDK library, exclude all public symbols from
- // the stub so that it is mandated that all symbols are explicitly marked with
- // either apex or systemapi.
- if !ctx.Module().(*Module).IsNdk(ctx.Config()) {
- flag = flag + " --no-ndk"
- }
- nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
- android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
- library.versionScriptPath = android.OptionalPathForPath(
- nativeAbiResult.versionScript)
-
- // Parse symbol file to get API list for coverage
- if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
- library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
- }
-
- return objs
+ return library.compileModuleLibApiStubs(ctx, flags, deps)
}
srcs := library.baseCompiler.Properties.Srcs.GetOrDefault(ctx, nil)
@@ -681,6 +645,61 @@
return objs
}
+// Compile stubs for the API surface between platform and apex
+// This method will be used by source and prebuilt cc module types.
+func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
+ // TODO (b/275273834): Make this a hard error when the symbol files have been added to module sdk.
+ if library.Properties.Stubs.Symbol_file == nil {
+ return Objects{}
+ }
+ symbolFile := String(library.Properties.Stubs.Symbol_file)
+ library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
+ // b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
+ // systemapi, respectively. The former is for symbols defined in platform libraries
+ // and the latter is for symbols defined in APEXes.
+ // A single library can contain either # apex or # systemapi, but not both.
+ // The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
+ // However, having this distinction helps guard accidental
+ // promotion or demotion of API and also helps the API review process b/191371676
+ var flag string
+ if ctx.Module().(android.ApexModule).NotInPlatform() {
+ flag = "--apex"
+ } else {
+ flag = "--systemapi"
+ }
+ // b/184712170, unless the lib is an NDK library, exclude all public symbols from
+ // the stub so that it is mandated that all symbols are explicitly marked with
+ // either apex or systemapi.
+ if !ctx.Module().(*Module).IsNdk(ctx.Config()) &&
+ // the symbol files of libclang libs are autogenerated and do not contain systemapi tags
+ // TODO (spandandas): Update mapfile.py to include #systemapi tag on all symbols
+ !strings.Contains(ctx.ModuleName(), "libclang_rt") {
+ flag = flag + " --no-ndk"
+ }
+ // TODO(b/361303067): Remove this special case if bionic/ projects are added to ART development branches.
+ if isBionic(ctx.baseModuleName()) {
+ // set the flags explicitly for bionic libs.
+ // this is necessary for development in minimal branches which does not contain bionic/*.
+ // In such minimal branches, e.g. on the prebuilt libc stubs
+ // 1. IsNdk will return false (since the ndk_library definition for libc does not exist)
+ // 2. NotInPlatform will return true (since the source com.android.runtime does not exist)
+ flag = "--apex"
+ }
+ nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
+ android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
+ objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+
+ library.versionScriptPath = android.OptionalPathForPath(
+ nativeAbiResult.versionScript)
+
+ // Parse symbol file to get API list for coverage
+ if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
+ library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+ }
+
+ return objs
+}
+
type libraryInterface interface {
versionedInterface
@@ -1182,12 +1201,17 @@
return unstrippedOutputFile
}
-func addStubDependencyProviders(ctx ModuleContext) {
+// Visits the stub variants of the library and returns a struct containing the stub .so paths
+func addStubDependencyProviders(ctx ModuleContext) []SharedStubLibrary {
+ stubsInfo := []SharedStubLibrary{}
stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
if len(stubs) > 0 {
- var stubsInfo []SharedStubLibrary
for _, stub := range stubs {
- stubInfo, _ := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
+ stubInfo, ok := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
+ // TODO (b/275273834): Make this a hard error when the symbol files have been added to module sdk.
+ if !ok {
+ continue
+ }
flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider)
stubsInfo = append(stubsInfo, SharedStubLibrary{
Version: moduleLibraryInterface(stub).stubsVersion(),
@@ -1195,11 +1219,14 @@
FlagExporterInfo: flagInfo,
})
}
- android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
- SharedStubLibraries: stubsInfo,
- IsLLNDK: ctx.IsLlndk(),
- })
+ if len(stubsInfo) > 0 {
+ android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
+ SharedStubLibraries: stubsInfo,
+ IsLLNDK: ctx.IsLlndk(),
+ })
+ }
}
+ return stubsInfo
}
func (library *libraryDecorator) unstrippedOutputFilePath() android.Path {
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/cc/prebuilt.go b/cc/prebuilt.go
index fb151d8..299fb51 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -16,6 +16,7 @@
import (
"path/filepath"
+ "strings"
"github.com/google/blueprint/proptools"
@@ -95,10 +96,6 @@
return p.libraryDecorator.linkerDeps(ctx, deps)
}
-func (p *prebuiltLibraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- return flags
-}
-
func (p *prebuiltLibraryLinker) linkerProps() []interface{} {
return p.libraryDecorator.linkerProps()
}
@@ -117,6 +114,30 @@
// TODO(ccross): verify shared library dependencies
srcs := p.prebuiltSrcs(ctx)
+ stubInfo := addStubDependencyProviders(ctx)
+
+ // Stub variants will create a stub .so file from stub .c files
+ if p.buildStubs() && objs.objFiles != nil {
+ // TODO (b/275273834): Make objs.objFiles == nil a hard error when the symbol files have been added to module sdk.
+
+ // The map.txt files of libclang_rt.* contain version information, but the checked in .so files do not.
+ // e.g. libclang_rt.* libs impl
+ // $ nm -D prebuilts/../libclang_rt.hwasan-aarch64-android.so
+ // __hwasan_init
+
+ // stubs generated from .map.txt
+ // $ nm -D out/soong/.intermediates/../<stubs>/libclang_rt.hwasan-aarch64-android.so
+ // __hwasan_init@@LIBCLANG_RT_ASAN
+
+ // Special-case libclang_rt.* libs to account for this discrepancy.
+ // TODO (spandandas): Remove this special case https://r.android.com/3236596 has been submitted, and a new set of map.txt
+ // files of libclang_rt.* libs have been generated.
+ if strings.Contains(ctx.ModuleName(), "libclang_rt.") {
+ p.versionScriptPath = android.OptionalPathForPath(nil)
+ }
+ return p.linkShared(ctx, flags, deps, objs)
+ }
+
if len(srcs) > 0 {
if len(srcs) > 1 {
ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
@@ -203,6 +224,16 @@
return outputFile
}
+ } else if p.shared() && len(stubInfo) > 0 {
+ // This is a prebuilt which does not have any implementation (nil `srcs`), but provides APIs.
+ // Provide the latest (i.e. `current`) stubs to reverse dependencies.
+ latestStub := stubInfo[len(stubInfo)-1].SharedLibraryInfo.SharedLibrary
+ android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
+ SharedLibrary: latestStub,
+ Target: ctx.Target(),
+ })
+
+ return latestStub
}
if p.header() {
@@ -257,11 +288,11 @@
func NewPrebuiltLibrary(hod android.HostOrDeviceSupported, srcsProperty string) (*Module, *libraryDecorator) {
module, library := NewLibrary(hod)
- module.compiler = nil
prebuilt := &prebuiltLibraryLinker{
libraryDecorator: library,
}
+ module.compiler = prebuilt
module.linker = prebuilt
module.library = prebuilt
@@ -280,6 +311,13 @@
return module, library
}
+func (p *prebuiltLibraryLinker) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
+ if p.buildStubs() && p.stubsVersion() != "" {
+ return p.compileModuleLibApiStubs(ctx, flags, deps)
+ }
+ return Objects{}
+}
+
// cc_prebuilt_library installs a precompiled shared library that are
// listed in the srcs property in the device's directory.
func PrebuiltLibraryFactory() android.Module {
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index e69a930..f3931a4 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -27,6 +27,7 @@
"os"
"os/exec"
"path/filepath"
+ "regexp"
"strconv"
"strings"
"time"
@@ -51,6 +52,8 @@
sandboxDirPlaceholder = "__SBOX_SANDBOX_DIR__"
)
+var envVarNameRegex = regexp.MustCompile("^[a-zA-Z0-9_-]+$")
+
func init() {
flag.StringVar(&sandboxesRoot, "sandbox-path", "",
"root of temp directory to put the sandbox into")
@@ -238,6 +241,51 @@
return &manifest, nil
}
+func createEnv(command *sbox_proto.Command) ([]string, error) {
+ env := []string{}
+ if command.DontInheritEnv == nil || !*command.DontInheritEnv {
+ env = os.Environ()
+ }
+ for _, envVar := range command.Env {
+ if envVar.Name == nil || !envVarNameRegex.MatchString(*envVar.Name) {
+ name := "nil"
+ if envVar.Name != nil {
+ name = *envVar.Name
+ }
+ return nil, fmt.Errorf("Invalid environment variable name: %q", name)
+ }
+ if envVar.State == nil {
+ return nil, fmt.Errorf("Must set state")
+ }
+ switch state := envVar.State.(type) {
+ case *sbox_proto.EnvironmentVariable_Value:
+ env = append(env, *envVar.Name+"="+state.Value)
+ case *sbox_proto.EnvironmentVariable_Unset:
+ if !state.Unset {
+ return nil, fmt.Errorf("Can't have unset set to false")
+ }
+ prefix := *envVar.Name + "="
+ for i := 0; i < len(env); i++ {
+ if strings.HasPrefix(env[i], prefix) {
+ env = append(env[:i], env[i+1:]...)
+ i--
+ }
+ }
+ case *sbox_proto.EnvironmentVariable_Inherit:
+ if !state.Inherit {
+ return nil, fmt.Errorf("Can't have inherit set to false")
+ }
+ val, ok := os.LookupEnv(*envVar.Name)
+ if ok {
+ env = append(env, *envVar.Name+"="+val)
+ }
+ default:
+ return nil, fmt.Errorf("Unhandled state type")
+ }
+ }
+ return env, nil
+}
+
// runCommand runs a single command from a manifest. If the command references the
// __SBOX_DEPFILE__ placeholder it returns the name of the depfile that was used.
func runCommand(command *sbox_proto.Command, tempDir string, commandIndex int) (depFile string, err error) {
@@ -313,6 +361,12 @@
return "", fmt.Errorf("Failed to update PATH: %w", err)
}
}
+
+ cmd.Env, err = createEnv(command)
+ if err != nil {
+ return "", err
+ }
+
err = cmd.Run()
if err != nil {
diff --git a/cmd/sbox/sbox_proto/sbox.pb.go b/cmd/sbox/sbox_proto/sbox.pb.go
index 7c84f2c..271039c 100644
--- a/cmd/sbox/sbox_proto/sbox.pb.go
+++ b/cmd/sbox/sbox_proto/sbox.pb.go
@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.26.0
-// protoc v3.9.1
+// protoc-gen-go v1.33.0
+// protoc v3.21.12
// source: sbox.proto
package sbox_proto
@@ -116,6 +116,13 @@
// A list of files that will be copied before the sandboxed command, and whose contents should be
// copied as if they were listed in copy_before.
RspFiles []*RspFile `protobuf:"bytes,6,rep,name=rsp_files,json=rspFiles" json:"rsp_files,omitempty"`
+ // The environment variables that will be set or unset while running the command.
+ // Also see dont_inherit_env.
+ Env []*EnvironmentVariable `protobuf:"bytes,7,rep,name=env" json:"env,omitempty"`
+ // By default, all environment variables are inherited from the calling process, but may be
+ // replaced or unset by env. If dont_inherit_env is set, no environment variables will be
+ // inherited, and instead only the variables in env will be defined.
+ DontInheritEnv *bool `protobuf:"varint,8,opt,name=dont_inherit_env,json=dontInheritEnv" json:"dont_inherit_env,omitempty"`
}
func (x *Command) Reset() {
@@ -192,6 +199,129 @@
return nil
}
+func (x *Command) GetEnv() []*EnvironmentVariable {
+ if x != nil {
+ return x.Env
+ }
+ return nil
+}
+
+func (x *Command) GetDontInheritEnv() bool {
+ if x != nil && x.DontInheritEnv != nil {
+ return *x.DontInheritEnv
+ }
+ return false
+}
+
+type EnvironmentVariable struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The name of the environment variable
+ Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
+ // Types that are assignable to State:
+ //
+ // *EnvironmentVariable_Value
+ // *EnvironmentVariable_Unset
+ // *EnvironmentVariable_Inherit
+ State isEnvironmentVariable_State `protobuf_oneof:"state"`
+}
+
+func (x *EnvironmentVariable) Reset() {
+ *x = EnvironmentVariable{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sbox_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *EnvironmentVariable) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*EnvironmentVariable) ProtoMessage() {}
+
+func (x *EnvironmentVariable) ProtoReflect() protoreflect.Message {
+ mi := &file_sbox_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use EnvironmentVariable.ProtoReflect.Descriptor instead.
+func (*EnvironmentVariable) Descriptor() ([]byte, []int) {
+ return file_sbox_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *EnvironmentVariable) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
+ }
+ return ""
+}
+
+func (m *EnvironmentVariable) GetState() isEnvironmentVariable_State {
+ if m != nil {
+ return m.State
+ }
+ return nil
+}
+
+func (x *EnvironmentVariable) GetValue() string {
+ if x, ok := x.GetState().(*EnvironmentVariable_Value); ok {
+ return x.Value
+ }
+ return ""
+}
+
+func (x *EnvironmentVariable) GetUnset() bool {
+ if x, ok := x.GetState().(*EnvironmentVariable_Unset); ok {
+ return x.Unset
+ }
+ return false
+}
+
+func (x *EnvironmentVariable) GetInherit() bool {
+ if x, ok := x.GetState().(*EnvironmentVariable_Inherit); ok {
+ return x.Inherit
+ }
+ return false
+}
+
+type isEnvironmentVariable_State interface {
+ isEnvironmentVariable_State()
+}
+
+type EnvironmentVariable_Value struct {
+ // The value to set the environment variable to.
+ Value string `protobuf:"bytes,2,opt,name=value,oneof"`
+}
+
+type EnvironmentVariable_Unset struct {
+ // This environment variable should be unset in the command.
+ Unset bool `protobuf:"varint,3,opt,name=unset,oneof"`
+}
+
+type EnvironmentVariable_Inherit struct {
+ // This environment variable should be inherited from the parent process.
+ // Can be combined with dont_inherit_env to only inherit certain environment
+ // variables.
+ Inherit bool `protobuf:"varint,4,opt,name=inherit,oneof"`
+}
+
+func (*EnvironmentVariable_Value) isEnvironmentVariable_State() {}
+
+func (*EnvironmentVariable_Unset) isEnvironmentVariable_State() {}
+
+func (*EnvironmentVariable_Inherit) isEnvironmentVariable_State() {}
+
// Copy describes a from-to pair of files to copy. The paths may be relative, the root that they
// are relative to is specific to the context the Copy is used in and will be different for
// from and to.
@@ -209,7 +339,7 @@
func (x *Copy) Reset() {
*x = Copy{}
if protoimpl.UnsafeEnabled {
- mi := &file_sbox_proto_msgTypes[2]
+ mi := &file_sbox_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -222,7 +352,7 @@
func (*Copy) ProtoMessage() {}
func (x *Copy) ProtoReflect() protoreflect.Message {
- mi := &file_sbox_proto_msgTypes[2]
+ mi := &file_sbox_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -235,7 +365,7 @@
// Deprecated: Use Copy.ProtoReflect.Descriptor instead.
func (*Copy) Descriptor() ([]byte, []int) {
- return file_sbox_proto_rawDescGZIP(), []int{2}
+ return file_sbox_proto_rawDescGZIP(), []int{3}
}
func (x *Copy) GetFrom() string {
@@ -274,7 +404,7 @@
func (x *RspFile) Reset() {
*x = RspFile{}
if protoimpl.UnsafeEnabled {
- mi := &file_sbox_proto_msgTypes[3]
+ mi := &file_sbox_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -287,7 +417,7 @@
func (*RspFile) ProtoMessage() {}
func (x *RspFile) ProtoReflect() protoreflect.Message {
- mi := &file_sbox_proto_msgTypes[3]
+ mi := &file_sbox_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -300,7 +430,7 @@
// Deprecated: Use RspFile.ProtoReflect.Descriptor instead.
func (*RspFile) Descriptor() ([]byte, []int) {
- return file_sbox_proto_rawDescGZIP(), []int{3}
+ return file_sbox_proto_rawDescGZIP(), []int{4}
}
func (x *RspFile) GetFile() string {
@@ -330,7 +460,7 @@
func (x *PathMapping) Reset() {
*x = PathMapping{}
if protoimpl.UnsafeEnabled {
- mi := &file_sbox_proto_msgTypes[4]
+ mi := &file_sbox_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -343,7 +473,7 @@
func (*PathMapping) ProtoMessage() {}
func (x *PathMapping) ProtoReflect() protoreflect.Message {
- mi := &file_sbox_proto_msgTypes[4]
+ mi := &file_sbox_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -356,7 +486,7 @@
// Deprecated: Use PathMapping.ProtoReflect.Descriptor instead.
func (*PathMapping) Descriptor() ([]byte, []int) {
- return file_sbox_proto_rawDescGZIP(), []int{4}
+ return file_sbox_proto_rawDescGZIP(), []int{5}
}
func (x *PathMapping) GetFrom() string {
@@ -383,7 +513,7 @@
0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x44, 0x65, 0x70, 0x66, 0x69, 0x6c, 0x65,
- 0x22, 0xdc, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2b, 0x0a, 0x0b,
+ 0x22, 0xb3, 0x02, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2b, 0x0a, 0x0b,
0x63, 0x6f, 0x70, 0x79, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x0a, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x52, 0x0a, 0x63,
0x6f, 0x70, 0x79, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x64,
@@ -396,23 +526,37 @@
0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x48,
0x61, 0x73, 0x68, 0x12, 0x2a, 0x0a, 0x09, 0x72, 0x73, 0x70, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73,
0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x52, 0x73,
- 0x70, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x72, 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x22,
- 0x4a, 0x0a, 0x04, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18,
- 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74,
- 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x65,
- 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x55, 0x0a, 0x07, 0x52,
- 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01,
- 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x61,
- 0x74, 0x68, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70,
- 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x70, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
- 0x67, 0x73, 0x22, 0x31, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
- 0x67, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52,
- 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28,
- 0x09, 0x52, 0x02, 0x74, 0x6f, 0x42, 0x23, 0x5a, 0x21, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x73, 0x62, 0x6f, 0x78, 0x2f,
- 0x73, 0x62, 0x6f, 0x78, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x70, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x72, 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12,
+ 0x2b, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73,
+ 0x62, 0x6f, 0x78, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56,
+ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x28, 0x0a, 0x10,
+ 0x64, 0x6f, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x5f, 0x65, 0x6e, 0x76,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x6f, 0x6e, 0x74, 0x49, 0x6e, 0x68, 0x65,
+ 0x72, 0x69, 0x74, 0x45, 0x6e, 0x76, 0x22, 0x7e, 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f,
+ 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+ 0x65, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x75, 0x6e, 0x73,
+ 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e, 0x73, 0x65,
+ 0x74, 0x12, 0x1a, 0x0a, 0x07, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x42, 0x07, 0x0a,
+ 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x4a, 0x0a, 0x04, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x12,
+ 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72,
+ 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02,
+ 0x74, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62,
+ 0x6c, 0x65, 0x22, 0x55, 0x0a, 0x07, 0x52, 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a,
+ 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c,
+ 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e,
+ 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e,
+ 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x70, 0x61, 0x74,
+ 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x31, 0x0a, 0x0b, 0x50, 0x61, 0x74,
+ 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d,
+ 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02,
+ 0x74, 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x42, 0x23, 0x5a, 0x21,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d,
+ 0x64, 0x2f, 0x73, 0x62, 0x6f, 0x78, 0x2f, 0x73, 0x62, 0x6f, 0x78, 0x5f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f,
}
var (
@@ -427,25 +571,27 @@
return file_sbox_proto_rawDescData
}
-var file_sbox_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_sbox_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_sbox_proto_goTypes = []interface{}{
- (*Manifest)(nil), // 0: sbox.Manifest
- (*Command)(nil), // 1: sbox.Command
- (*Copy)(nil), // 2: sbox.Copy
- (*RspFile)(nil), // 3: sbox.RspFile
- (*PathMapping)(nil), // 4: sbox.PathMapping
+ (*Manifest)(nil), // 0: sbox.Manifest
+ (*Command)(nil), // 1: sbox.Command
+ (*EnvironmentVariable)(nil), // 2: sbox.EnvironmentVariable
+ (*Copy)(nil), // 3: sbox.Copy
+ (*RspFile)(nil), // 4: sbox.RspFile
+ (*PathMapping)(nil), // 5: sbox.PathMapping
}
var file_sbox_proto_depIdxs = []int32{
1, // 0: sbox.Manifest.commands:type_name -> sbox.Command
- 2, // 1: sbox.Command.copy_before:type_name -> sbox.Copy
- 2, // 2: sbox.Command.copy_after:type_name -> sbox.Copy
- 3, // 3: sbox.Command.rsp_files:type_name -> sbox.RspFile
- 4, // 4: sbox.RspFile.path_mappings:type_name -> sbox.PathMapping
- 5, // [5:5] is the sub-list for method output_type
- 5, // [5:5] is the sub-list for method input_type
- 5, // [5:5] is the sub-list for extension type_name
- 5, // [5:5] is the sub-list for extension extendee
- 0, // [0:5] is the sub-list for field type_name
+ 3, // 1: sbox.Command.copy_before:type_name -> sbox.Copy
+ 3, // 2: sbox.Command.copy_after:type_name -> sbox.Copy
+ 4, // 3: sbox.Command.rsp_files:type_name -> sbox.RspFile
+ 2, // 4: sbox.Command.env:type_name -> sbox.EnvironmentVariable
+ 5, // 5: sbox.RspFile.path_mappings:type_name -> sbox.PathMapping
+ 6, // [6:6] is the sub-list for method output_type
+ 6, // [6:6] is the sub-list for method input_type
+ 6, // [6:6] is the sub-list for extension type_name
+ 6, // [6:6] is the sub-list for extension extendee
+ 0, // [0:6] is the sub-list for field type_name
}
func init() { file_sbox_proto_init() }
@@ -479,7 +625,7 @@
}
}
file_sbox_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*Copy); i {
+ switch v := v.(*EnvironmentVariable); i {
case 0:
return &v.state
case 1:
@@ -491,7 +637,7 @@
}
}
file_sbox_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*RspFile); i {
+ switch v := v.(*Copy); i {
case 0:
return &v.state
case 1:
@@ -503,6 +649,18 @@
}
}
file_sbox_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RspFile); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_sbox_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PathMapping); i {
case 0:
return &v.state
@@ -515,13 +673,18 @@
}
}
}
+ file_sbox_proto_msgTypes[2].OneofWrappers = []interface{}{
+ (*EnvironmentVariable_Value)(nil),
+ (*EnvironmentVariable_Unset)(nil),
+ (*EnvironmentVariable_Inherit)(nil),
+ }
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_sbox_proto_rawDesc,
NumEnums: 0,
- NumMessages: 5,
+ NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/cmd/sbox/sbox_proto/sbox.proto b/cmd/sbox/sbox_proto/sbox.proto
index 2f0dcf0..1158554 100644
--- a/cmd/sbox/sbox_proto/sbox.proto
+++ b/cmd/sbox/sbox_proto/sbox.proto
@@ -51,6 +51,30 @@
// A list of files that will be copied before the sandboxed command, and whose contents should be
// copied as if they were listed in copy_before.
repeated RspFile rsp_files = 6;
+
+ // The environment variables that will be set or unset while running the command.
+ // Also see dont_inherit_env.
+ repeated EnvironmentVariable env = 7;
+
+ // By default, all environment variables are inherited from the calling process, but may be
+ // replaced or unset by env. If dont_inherit_env is set, no environment variables will be
+ // inherited, and instead only the variables in env will be defined.
+ optional bool dont_inherit_env = 8;
+}
+
+message EnvironmentVariable {
+ // The name of the environment variable
+ required string name = 1;
+ oneof state {
+ // The value to set the environment variable to.
+ string value = 2;
+ // This environment variable should be unset in the command.
+ bool unset = 3;
+ // This environment variable should be inherited from the parent process.
+ // Can be combined with dont_inherit_env to only inherit certain environment
+ // variables.
+ bool inherit = 4;
+ }
}
// Copy describes a from-to pair of files to copy. The paths may be relative, the root that they
diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go
index e483fe4..988a57b 100644
--- a/filesystem/logical_partition.go
+++ b/filesystem/logical_partition.go
@@ -146,9 +146,16 @@
partitionNames[pName] = true
}
// Get size of the partition by reading the -size.txt file
- pSize := fmt.Sprintf("$(cat %s)", sparseImageSizes[pName])
+ var pSize string
+ if size, hasSize := sparseImageSizes[pName]; hasSize {
+ pSize = fmt.Sprintf("$(cat %s)", size)
+ } else {
+ pSize = "0"
+ }
cmd.FlagWithArg("--partition=", fmt.Sprintf("%s:readonly:%s:%s", pName, pSize, gName))
- cmd.FlagWithInput("--image="+pName+"=", sparseImages[pName])
+ if image, hasImage := sparseImages[pName]; hasImage {
+ cmd.FlagWithInput("--image="+pName+"=", image)
+ }
}
}
@@ -192,6 +199,9 @@
// Add a rule that converts the filesystem for the given partition to the given rule builder. The
// path to the sparse file and the text file having the size of the partition are returned.
func sparseFilesystem(ctx android.ModuleContext, p partitionProperties, builder *android.RuleBuilder) (sparseImg android.OutputPath, sizeTxt android.OutputPath) {
+ if p.Filesystem == nil {
+ return
+ }
img := android.PathForModuleSrc(ctx, proptools.String(p.Filesystem))
name := proptools.String(p.Name)
sparseImg = android.PathForModuleOut(ctx, name+".img").OutputPath
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index 7c71b77..4f1b320 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -17,7 +17,6 @@
var (
SandboxingDenyModuleList = []string{
// go/keep-sorted start
- "aidl_camera_build_version",
"com.google.pixel.camera.hal.manifest",
// go/keep-sorted end
}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 9195643..fd72d3c 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -243,13 +243,35 @@
}
}
+var buildNumberAllowlistKey = android.NewOnceKey("genruleBuildNumberAllowlistKey")
+
// This allowlist should be kept to the bare minimum, it's
// intended for things that existed before the build number
// was tightly controlled. Prefer using libbuildversion
// via the use_version_lib property of cc modules.
-var genrule_build_number_allowlist = map[string]bool{
- "build/soong/tests:gen": true,
- "tools/tradefederation/core:tradefed_zip": true,
+// This is a function instead of a global map so that
+// soong plugins cannot add entries to the allowlist
+func isModuleInBuildNumberAllowlist(ctx android.ModuleContext) bool {
+ allowlist := ctx.Config().Once(buildNumberAllowlistKey, func() interface{} {
+ // Define the allowlist as a list and then copy it into a map so that
+ // gofmt doesn't change unnecessary lines trying to align the values of the map.
+ allowlist := []string{
+ // go/keep-sorted start
+ "build/soong/tests:gen",
+ "hardware/google/camera/common/hal/aidl_service:aidl_camera_build_version",
+ "tools/tradefederation/core:tradefed_zip",
+ "vendor/google/services/LyricCameraHAL/src/apex:com.google.pixel.camera.hal.manifest",
+ // go/keep-sorted end
+ }
+ allowlistMap := make(map[string]bool, len(allowlist))
+ for _, a := range allowlist {
+ allowlistMap[a] = true
+ }
+ return allowlistMap
+ }).(map[string]bool)
+
+ _, ok := allowlist[ctx.ModuleDir()+":"+ctx.ModuleName()]
+ return ok
}
// generateCommonBuildActions contains build action generation logic
@@ -320,7 +342,8 @@
ctx.ModuleErrorf("host tool %q missing output file", tool)
return
}
- if specs := t.TransitivePackagingSpecs(); specs != nil {
+ if specs := android.OtherModuleProviderOrDefault(
+ ctx, t, android.InstallFilesProvider).TransitivePackagingSpecs.ToList(); specs != nil {
// If the HostToolProvider has PackgingSpecs, which are definitions of the
// required relative locations of the tool and its dependencies, use those
// instead. They will be copied to those relative locations in the sbox
@@ -546,7 +569,7 @@
cmd.ImplicitTools(tools)
cmd.ImplicitPackagedTools(packagedTools)
if proptools.Bool(g.properties.Uses_order_only_build_number_file) {
- if _, ok := genrule_build_number_allowlist[ctx.ModuleDir()+":"+ctx.ModuleName()]; !ok {
+ if !isModuleInBuildNumberAllowlist(ctx) {
ctx.ModuleErrorf("Only allowlisted modules may use uses_order_only_build_number_file: true")
}
cmd.OrderOnly(ctx.Config().BuildNumberFile(ctx))
@@ -624,7 +647,7 @@
}
// Collect information for opening IDE project files in java/jdeps.go.
-func (g *Module) IDEInfo(dpInfo *android.IdeInfo) {
+func (g *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...)
for _, src := range g.properties.ResolvedSrcs {
if strings.HasPrefix(src, ":") {
diff --git a/java/aar.go b/java/aar.go
index e6ad502..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{}
@@ -914,12 +916,12 @@
setOutputFiles(ctx, a.Library.Module)
}
-func (a *AndroidLibrary) IDEInfo(dpInfo *android.IdeInfo) {
- a.Library.IDEInfo(dpInfo)
- a.aapt.IDEInfo(dpInfo)
+func (a *AndroidLibrary) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
+ a.Library.IDEInfo(ctx, dpInfo)
+ a.aapt.IDEInfo(ctx, dpInfo)
}
-func (a *aapt) IDEInfo(dpInfo *android.IdeInfo) {
+func (a *aapt) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
if a.rJar != nil {
dpInfo.Jars = append(dpInfo.Jars, a.rJar.String())
}
@@ -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
})
@@ -1451,6 +1458,6 @@
return module
}
-func (a *AARImport) IDEInfo(dpInfo *android.IdeInfo) {
+func (a *AARImport) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
dpInfo.Jars = append(dpInfo.Jars, a.headerJarFile.String(), a.rJar.String())
}
diff --git a/java/app.go b/java/app.go
index 1ebf658..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,
@@ -1243,9 +1245,9 @@
var _ cc.Coverage = (*AndroidApp)(nil)
-func (a *AndroidApp) IDEInfo(dpInfo *android.IdeInfo) {
- a.Library.IDEInfo(dpInfo)
- a.aapt.IDEInfo(dpInfo)
+func (a *AndroidApp) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
+ a.Library.IDEInfo(ctx, dpInfo)
+ a.aapt.IDEInfo(ctx, dpInfo)
}
func (a *AndroidApp) productCharacteristicsRROPackageName() string {
@@ -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 9101457..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
@@ -593,6 +598,13 @@
return j.ProductSpecific()
}
+var _ android.StubsAvailableModule = (*Module)(nil)
+
+// To safisfy the StubsAvailableModule interface
+func (j *Module) IsStubsModule() bool {
+ return proptools.Bool(j.properties.Is_stubs_module)
+}
+
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
sdkVersion := j.SdkVersion(ctx)
if sdkVersion.Stable() {
@@ -732,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) &&
@@ -760,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))
}
@@ -1265,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,
@@ -1591,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.
@@ -1733,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.
@@ -1776,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),
@@ -1944,6 +1981,8 @@
TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{},
false, nil, []string{"META-INF/TRANSITIVE"})
+ ctx.CheckbuildFile(combinedHeaderJarOutputPath)
+
return headerJar, combinedHeaderJarOutputPath
}
@@ -1960,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]{}
@@ -1998,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 {
@@ -2049,7 +2084,7 @@
}
// Collect information for opening IDE project files in java/jdeps.go.
-func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
+func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
// jarjar rules will repackage the sources. To prevent misleading results, IdeInfo should contain the
// repackaged jar instead of the input sources.
if j.expandJarjarRules != nil {
@@ -2273,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)
@@ -2485,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/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index bce507a..bef3b58 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -836,7 +836,7 @@
}
// Collect information for opening IDE project files in java/jdeps.go.
-func (b *BootclasspathFragmentModule) IDEInfo(dpInfo *android.IdeInfo) {
+func (b *BootclasspathFragmentModule) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
dpInfo.Deps = append(dpInfo.Deps, b.properties.Contents...)
}
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/core-libraries/Android.bp b/java/core-libraries/Android.bp
index cee7a19..1cca7ad 100644
--- a/java/core-libraries/Android.bp
+++ b/java/core-libraries/Android.bp
@@ -38,6 +38,7 @@
visibility: ["//visibility:public"],
sdk_version: "none",
system_modules: "none",
+ is_stubs_module: true,
}
java_library {
@@ -289,6 +290,7 @@
sdk_version: "none",
system_modules: "none",
patch_module: "java.base",
+ is_stubs_module: true,
}
// Same as legacy.core.platform.api.stubs, but android annotations are
@@ -307,6 +309,7 @@
"legacy.core.platform.api.stubs",
],
patch_module: "java.base",
+ is_stubs_module: true,
}
java_library {
@@ -339,6 +342,7 @@
"stable.core.platform.api.stubs",
],
patch_module: "java.base",
+ is_stubs_module: true,
}
// Used when compiling higher-level code against *.core.platform.api.stubs.
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 63b69d0..7cc06fc 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -192,7 +192,7 @@
// implement the following interface for IDE completion.
var _ android.IDEInfo = (*DeviceHostConverter)(nil)
-func (d *DeviceHostConverter) IDEInfo(ideInfo *android.IdeInfo) {
+func (d *DeviceHostConverter) IDEInfo(ctx android.BaseModuleContext, ideInfo *android.IdeInfo) {
ideInfo.Deps = append(ideInfo.Deps, d.properties.Libs...)
ideInfo.Libs = append(ideInfo.Libs, d.properties.Libs...)
}
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 a38642a..1c63e3f 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -88,18 +88,11 @@
entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
- // Unset LOCAL_SOONG_INSTALLED_MODULE so that this does not default to the primary .apex file
- // Without this, installation of the dexpreopt artifacts get skipped
- entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", "")
},
},
}
}
-func (install dexpreopterInstall) PackageFile(ctx android.ModuleContext) android.PackagingSpec {
- return ctx.PackageFile(install.installDirOnDevice, install.installFileOnDevice, install.outputPathOnHost)
-}
-
type Dexpreopter struct {
dexpreopter
}
@@ -217,15 +210,19 @@
}
})
// Find the apex variant for this module
- _, apexVariantsWithoutTestApexes, _ := android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes)
+ var apexVariantsWithoutTestApexes []string
+ if apexInfo.BaseApexName != "" {
+ // This is a transitive dependency of an override_apex
+ apexVariantsWithoutTestApexes = []string{apexInfo.BaseApexName}
+ } else {
+ _, apexVariantsWithoutTestApexes, _ = android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes)
+ }
disableSource := false
// find the selected apexes
for _, apexVariant := range apexVariantsWithoutTestApexes {
- for _, selected := range psi.GetSelectedModulesForApiDomain(apexVariant) {
- // If the apex_contribution for this api domain contains a prebuilt apex, disable the source variant
- if strings.HasPrefix(selected, "prebuilt_com.google.android") {
- disableSource = true
- }
+ if len(psi.GetSelectedModulesForApiDomain(apexVariant)) > 0 {
+ // If the apex_contribution for this api domain is non-empty, disable the source variant
+ disableSource = true
}
}
return disableSource
@@ -492,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
@@ -583,16 +581,20 @@
// Preopting of boot classpath jars in the ART APEX are handled in
// java/dexpreopt_bootjars.go, and other APEX jars are not preopted.
// The installs will be handled by Make as sub-modules of the java library.
- d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{
+ di := dexpreopterInstall{
name: arch + "-" + installBase,
moduleName: libName,
outputPathOnHost: install.From,
installDirOnDevice: installPath,
installFileOnDevice: installBase,
- })
+ }
+ ctx.InstallFile(di.installDirOnDevice, di.installFileOnDevice, di.outputPathOnHost)
+ d.builtInstalledForApex = append(d.builtInstalledForApex, di)
+
}
} 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/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a81ab83..a2e4734 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -558,6 +558,10 @@
apexVariationOfSelected := append(ctx.Target().Variations(), blueprint.Variation{Mutator: "apex", Variation: apex})
if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, selected) {
ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, selected)
+ } else if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, android.RemoveOptionalPrebuiltPrefix(selected)) {
+ // The prebuilt might have been renamed by prebuilt_rename mutator if the source module does not exist.
+ // Remove the prebuilt_ prefix.
+ ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, android.RemoveOptionalPrebuiltPrefix(selected))
}
}
}
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 73e33f4..07d0595 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -54,6 +54,7 @@
name: "foo",
installable: true,
srcs: ["a.java"],
+ sdk_version: "current",
}`,
enabled: true,
},
@@ -98,6 +99,7 @@
java_library {
name: "foo",
installable: true,
+ sdk_version: "current",
}`,
enabled: false,
},
@@ -107,6 +109,7 @@
java_library {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}`,
enabled: false,
},
@@ -144,6 +147,7 @@
name: "foo",
srcs: ["a.java"],
compile_dex: true,
+ sdk_version: "current",
}`,
enabled: false,
},
@@ -164,6 +168,7 @@
installable: true,
srcs: ["a.java"],
apex_available: ["com.android.apex1"],
+ sdk_version: "current",
}`,
apexVariant: true,
enabled: false,
@@ -176,6 +181,7 @@
installable: true,
srcs: ["a.java"],
apex_available: ["com.android.apex1"],
+ sdk_version: "current",
}`,
moduleName: "service-foo",
apexVariant: true,
@@ -189,6 +195,7 @@
installable: true,
srcs: ["a.java"],
apex_available: ["com.android.apex1"],
+ sdk_version: "current",
}`,
moduleName: "prebuilt_service-foo",
apexVariant: true,
@@ -202,6 +209,7 @@
installable: true,
srcs: ["a.java"],
apex_available: ["com.android.apex1"],
+ sdk_version: "current",
}`,
moduleName: "service-foo",
apexVariant: false,
@@ -311,6 +319,7 @@
installable: true,
srcs: ["a.java"],
apex_available: ["com.android.apex1"],
+ sdk_version: "current",
}`)
ctx := result.TestContext
module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
@@ -342,6 +351,7 @@
name: "foo",
installable: true,
srcs: ["a.java"],
+ sdk_version: "current",
}`)
ctx = result.TestContext
module = ctx.ModuleForTests("foo", "android_common")
@@ -398,6 +408,7 @@
installable: true,
srcs: ["a.java"],
apex_available: ["com.android.apex1"],
+ sdk_version: "current",
}`)
ctx := result.TestContext
module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
@@ -429,6 +440,7 @@
name: "foo",
installable: true,
srcs: ["a.java"],
+ sdk_version: "current",
}`)
ctx = result.TestContext
module = ctx.ModuleForTests("foo", "android_common")
@@ -454,6 +466,7 @@
profile: "art-profile",
},
srcs: ["a.java"],
+ sdk_version: "current",
}`)
ctx := result.TestContext
diff --git a/java/droidstubs.go b/java/droidstubs.go
index d622903..6bcdf85 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -970,6 +970,15 @@
d.apiLintReport = android.PathForModuleOut(ctx, Everything.String(), "api_lint_report.txt")
cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
+ // 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.
+ // 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" &&
d.Name() != "android.car-stubs-docs" {
diff --git a/java/java.go b/java/java.go
index 46344c8..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.
@@ -2404,15 +2404,15 @@
return al.SdkVersion(ctx).ApiLevel
}
-func (al *ApiLibrary) IDEInfo(i *android.IdeInfo) {
- i.Deps = append(i.Deps, al.ideDeps()...)
+func (al *ApiLibrary) IDEInfo(ctx android.BaseModuleContext, i *android.IdeInfo) {
+ i.Deps = append(i.Deps, al.ideDeps(ctx)...)
i.Libs = append(i.Libs, al.properties.Libs...)
i.Static_libs = append(i.Static_libs, al.properties.Static_libs...)
i.SrcJars = append(i.SrcJars, al.stubsSrcJar.String())
}
// deps of java_api_library for module_bp_java_deps.json
-func (al *ApiLibrary) ideDeps() []string {
+func (al *ApiLibrary) ideDeps(ctx android.BaseModuleContext) []string {
ret := []string{}
ret = append(ret, al.properties.Libs...)
ret = append(ret, al.properties.Static_libs...)
@@ -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
})
@@ -2933,7 +2936,7 @@
// Collect information for opening IDE project files in java/jdeps.go.
-func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
+func (j *Import) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
dpInfo.Jars = append(dpInfo.Jars, j.combinedHeaderFile.String())
}
diff --git a/java/jdeps.go b/java/jdeps.go
index e856b37..c2ce503 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -57,27 +57,19 @@
return
}
- ideInfoProvider, ok := module.(android.IDEInfo)
+ ideInfoProvider, ok := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
if !ok {
return
}
- name := ideInfoProvider.BaseModuleName()
+ name := ideInfoProvider.BaseModuleName
ideModuleNameProvider, ok := module.(android.IDECustomizedModuleName)
if ok {
name = ideModuleNameProvider.IDECustomizedModuleName()
}
dpInfo := moduleInfos[name]
- ideInfoProvider.IDEInfo(&dpInfo)
- dpInfo.Deps = android.FirstUniqueStrings(dpInfo.Deps)
- dpInfo.Srcs = android.FirstUniqueStrings(dpInfo.Srcs)
- dpInfo.Aidl_include_dirs = android.FirstUniqueStrings(dpInfo.Aidl_include_dirs)
- dpInfo.Jarjar_rules = android.FirstUniqueStrings(dpInfo.Jarjar_rules)
- dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars)
- dpInfo.SrcJars = android.FirstUniqueStrings(dpInfo.SrcJars)
+ dpInfo = dpInfo.Merge(ideInfoProvider)
dpInfo.Paths = []string{ctx.ModuleDir(module)}
- dpInfo.Static_libs = android.FirstUniqueStrings(dpInfo.Static_libs)
- dpInfo.Libs = android.FirstUniqueStrings(dpInfo.Libs)
moduleInfos[name] = dpInfo
mkProvider, ok := module.(android.AndroidMkDataProvider)
diff --git a/java/jdeps_test.go b/java/jdeps_test.go
index ff54da9..d282f19 100644
--- a/java/jdeps_test.go
+++ b/java/jdeps_test.go
@@ -32,9 +32,7 @@
}
`)
module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
- dpInfo := &android.IdeInfo{}
-
- module.IDEInfo(dpInfo)
+ dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
for _, expected := range []string{"Foo", "Bar"} {
if !android.InList(expected, dpInfo.Deps) {
@@ -54,9 +52,7 @@
}
`)
module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
- dpInfo := &android.IdeInfo{}
-
- module.IDEInfo(dpInfo)
+ dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
for _, expected := range []string{"Foo", "Bar"} {
if !android.InList(expected, dpInfo.Deps) {
@@ -66,26 +62,36 @@
}
func TestCollectJavaLibraryPropertiesAddScrs(t *testing.T) {
- expected := []string{"Foo", "Bar"}
- module := LibraryFactory().(*Library)
- module.expandIDEInfoCompiledSrcs = append(module.expandIDEInfoCompiledSrcs, expected...)
- dpInfo := &android.IdeInfo{}
+ ctx, _ := testJava(t,
+ `
+ java_library {
+ name: "javalib",
+ srcs: ["Foo.java", "Bar.java"],
+ }
+ `)
+ module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
- module.IDEInfo(dpInfo)
-
+ expected := []string{"Foo.java", "Bar.java"}
if !reflect.DeepEqual(dpInfo.Srcs, expected) {
t.Errorf("Library.IDEInfo() Srcs = %v, want %v", dpInfo.Srcs, expected)
}
}
func TestCollectJavaLibraryPropertiesAddAidlIncludeDirs(t *testing.T) {
+ ctx, _ := testJava(t,
+ `
+ java_library {
+ name: "javalib",
+ aidl: {
+ include_dirs: ["Foo", "Bar"],
+ },
+ }
+ `)
+ module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
+
expected := []string{"Foo", "Bar"}
- module := LibraryFactory().(*Library)
- module.deviceProperties.Aidl.Include_dirs = append(module.deviceProperties.Aidl.Include_dirs, expected...)
- dpInfo := &android.IdeInfo{}
-
- module.IDEInfo(dpInfo)
-
if !reflect.DeepEqual(dpInfo.Aidl_include_dirs, expected) {
t.Errorf("Library.IDEInfo() Aidl_include_dirs = %v, want %v", dpInfo.Aidl_include_dirs, expected)
}
@@ -101,9 +107,8 @@
}
`)
module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
- dpInfo := &android.IdeInfo{}
+ dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
- module.IDEInfo(dpInfo)
android.AssertBoolEquals(t, "IdeInfo.Srcs of repackaged library should be empty", true, len(dpInfo.Srcs) == 0)
android.AssertStringEquals(t, "IdeInfo.Jar_rules of repackaged library should not be empty", "jarjar_rules.txt", dpInfo.Jarjar_rules[0])
if !android.SubstringInList(dpInfo.Jars, "soong/.intermediates/javalib/android_common/jarjar/turbine/javalib.jar") {
@@ -125,8 +130,7 @@
}
`)
module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
- dpInfo := &android.IdeInfo{}
+ dpInfo, _ := android.OtherModuleProvider(ctx, module, android.IdeInfoProviderKey)
- module.IDEInfo(dpInfo)
android.AssertStringListContains(t, "IdeInfo.Deps should contain versioned sdk module", dpInfo.Deps, "sdk_public_29_android")
}
diff --git a/java/sdk.go b/java/sdk.go
index dd198ac..4537f19 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -308,10 +308,12 @@
rule.Command().
Text("rm -f").Output(aidl)
+
rule.Command().
BuiltTool("sdkparcelables").
Input(jar).
- Output(aidl)
+ Output(aidl).
+ Flag("--guarantee_stable")
aidls = append(aidls, aidl)
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 2fe629f..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()})
}
@@ -2099,6 +2104,7 @@
props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
props.Dist.Tag = proptools.StringPtr(".jar")
}
+ props.Is_stubs_module = proptools.BoolPtr(true)
return props
}
@@ -3599,8 +3605,8 @@
}
// TODO(b/358613520): This can be removed when modules are no longer allowed to depend on the top-level library.
-func (s *SdkLibrary) IDEInfo(dpInfo *android.IdeInfo) {
- s.Library.IDEInfo(dpInfo)
+func (s *SdkLibrary) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
+ s.Library.IDEInfo(ctx, dpInfo)
if s.implLibraryModule != nil {
dpInfo.Deps = append(dpInfo.Deps, s.implLibraryModule.Name())
} else {
diff --git a/java/system_modules.go b/java/system_modules.go
index 5b00079..f89bf9e 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -307,7 +307,7 @@
// implement the following interface for IDE completion.
var _ android.IDEInfo = (*SystemModules)(nil)
-func (s *SystemModules) IDEInfo(ideInfo *android.IdeInfo) {
+func (s *SystemModules) IDEInfo(ctx android.BaseModuleContext, ideInfo *android.IdeInfo) {
ideInfo.Deps = append(ideInfo.Deps, s.properties.Libs...)
ideInfo.Libs = append(ideInfo.Libs, s.properties.Libs...)
}
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index bad2cf1..924abd4 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -216,6 +216,11 @@
return tag == systemServerClasspathFragmentContentDepTag
}
+// The dexpreopt artifacts of apex system server jars are installed onto system image.
+func (s systemServerClasspathFragmentContentDependencyTag) InstallDepNeeded() bool {
+ return true
+}
+
func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
module := ctx.Module()
_, isSourceModule := module.(*SystemServerClasspathModule)
@@ -234,7 +239,7 @@
}
// Collect information for opening IDE project files in java/jdeps.go.
-func (s *SystemServerClasspathModule) IDEInfo(dpInfo *android.IdeInfo) {
+func (s *SystemServerClasspathModule) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents...)
dpInfo.Deps = append(dpInfo.Deps, s.properties.Standalone_contents...)
}
diff --git a/java/testing.go b/java/testing.go
index 0e85022..03dcee6 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -184,6 +184,10 @@
host_supported: true,
srcs: ["Test.java"],
sdk_version: "current",
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
}
`)),
)
@@ -408,7 +412,6 @@
"core.current.stubs",
"legacy.core.platform.api.stubs",
"stable.core.platform.api.stubs",
-
"android_stubs_current_exportable",
"android_system_stubs_current_exportable",
"android_test_stubs_current_exportable",
@@ -416,13 +419,11 @@
"android_system_server_stubs_current_exportable",
"core.current.stubs.exportable",
"legacy.core.platform.api.stubs.exportable",
-
"kotlin-stdlib",
"kotlin-stdlib-jdk7",
"kotlin-stdlib-jdk8",
"kotlin-annotations",
"stub-annotations",
-
"aconfig-annotations-lib",
"unsupportedappusage",
}
@@ -435,6 +436,7 @@
sdk_version: "none",
system_modules: "stable-core-platform-api-stubs-system-modules",
compile_dex: true,
+ is_stubs_module: true,
}
`, extra)
}
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 533ec62..05b99fd 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -98,6 +98,7 @@
builder.Command().
BuiltTool("conv_linker_config").
Flag("proto").
+ Flag("--force").
FlagWithInput("-s ", input).
FlagWithOutput("-o ", interimOutput)
diff --git a/rust/config/global.go b/rust/config/global.go
index 0c5eb85..990a643 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
var (
pctx = android.NewPackageContext("android/soong/rust/config")
- RustDefaultVersion = "1.79.0"
+ RustDefaultVersion = "1.80.1"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
diff --git a/rust/library.go b/rust/library.go
index 50d5a72..7db8f36 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -70,6 +70,10 @@
// Whether this library is part of the Rust toolchain sysroot.
Sysroot *bool
+
+ // Exclude this rust_ffi target from being included in APEXes.
+ // TODO(b/362509506): remove this once stubs are properly supported by rust_ffi targets.
+ Apex_exclude *bool
}
type LibraryMutatedProperties struct {
@@ -122,6 +126,7 @@
shared() bool
sysroot() bool
source() bool
+ apexExclude() bool
// Returns true if the build options for the module have selected a particular build type
buildRlib() bool
@@ -186,6 +191,10 @@
return library.MutatedProperties.VariantIsSource
}
+func (library *libraryDecorator) apexExclude() bool {
+ return Bool(library.Properties.Apex_exclude)
+}
+
func (library *libraryDecorator) buildRlib() bool {
return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
}
diff --git a/rust/rust.go b/rust/rust.go
index 3402adc..240c221 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -294,6 +294,15 @@
return mod.StaticallyLinked()
}
+func (mod *Module) ApexExclude() bool {
+ if mod.compiler != nil {
+ if library, ok := mod.compiler.(libraryInterface); ok {
+ return library.apexExclude()
+ }
+ }
+ return false
+}
+
func (mod *Module) Object() bool {
// Rust has no modules which produce only object files.
return false
@@ -938,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()})
}
@@ -948,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() {
@@ -1863,6 +1871,10 @@
return false
}
+ if rustDep, ok := dep.(*Module); ok && rustDep.ApexExclude() {
+ return false
+ }
+
return true
}
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 7ee548f..8b994eb 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -338,6 +338,7 @@
shared_library: false,
public: {enabled: true},
min_sdk_version: "2",
+ sdk_version: "current",
}
java_sdk_library {
@@ -348,6 +349,7 @@
public: {enabled: true},
min_sdk_version: "2",
permitted_packages: ["myothersdklibrary"],
+ sdk_version: "current",
}
java_sdk_library {
@@ -357,6 +359,7 @@
compile_dex: true,
public: {enabled: true},
min_sdk_version: "2",
+ sdk_version: "current",
}
`),
).RunTest(t)
@@ -624,6 +627,7 @@
min_sdk_version: "2",
permitted_packages: ["myothersdklibrary"],
compile_dex: true,
+ sdk_version: "current",
}
`),
@@ -655,6 +659,7 @@
shared_library: false,
public: {enabled: true},
min_sdk_version: "2",
+ sdk_version: "current",
}
`),
).RunTest(t)
@@ -877,6 +882,7 @@
public: {enabled: true},
permitted_packages: ["mysdklibrary"],
min_sdk_version: "current",
+ sdk_version: "current",
}
java_sdk_library {
@@ -895,6 +901,7 @@
package_prefixes: ["newlibrary.all.mine"],
single_packages: ["newlibrary.mine"],
},
+ sdk_version: "current",
}
`),
).RunTest(t)
@@ -1080,6 +1087,7 @@
shared_library: false,
public: {enabled: true},
min_sdk_version: "S",
+ sdk_version: "current",
}
java_sdk_library {
@@ -1090,6 +1098,7 @@
public: {enabled: true},
min_sdk_version: "Tiramisu",
permitted_packages: ["mynewsdklibrary"],
+ sdk_version: "current",
}
`),
).RunTest(t)
@@ -1287,6 +1296,7 @@
shared_library: false,
public: {enabled: true},
min_sdk_version: "Tiramisu",
+ sdk_version: "current",
}
java_sdk_library {
name: "mynewsdklibrary",
@@ -1296,6 +1306,7 @@
public: {enabled: true},
min_sdk_version: "Tiramisu",
permitted_packages: ["mynewsdklibrary"],
+ sdk_version: "current",
}
`),
).RunTest(t)
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/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index c1c4ed6..fd6c4e7 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -80,6 +80,7 @@
dex_preopt: {
profile: "art-profile",
},
+ sdk_version: "current",
}
`),
).RunTest(t)
@@ -110,12 +111,14 @@
apex_available: ["myapex"],
srcs: ["Test.java"],
min_sdk_version: "33", // Tiramisu
+ sdk_version: "current",
}
java_sdk_library {
name: "mysdklibrary-future",
apex_available: ["myapex"],
srcs: ["Test.java"],
min_sdk_version: "34", // UpsideDownCake
+ sdk_version: "current",
}
sdk {
name: "mysdk",
@@ -199,6 +202,7 @@
apex_available: ["myapex"],
srcs: ["Test.java"],
min_sdk_version: "34", // UpsideDownCake
+ sdk_version: "current",
}
sdk {
name: "mysdk",
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/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index bbac2db..2bad5a8 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -33,6 +33,7 @@
"kernel/tests/",
"libcore/",
"libnativehelper/",
+ "packages/",
"pdk/",
"prebuilts/",
"sdk/",
diff --git a/ui/build/config.go b/ui/build/config.go
index 64ac1a0..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}) {
@@ -1041,7 +1046,7 @@
func (c *configImpl) UsedEnvFile(tag string) string {
if v, ok := c.environ.Get("TARGET_PRODUCT"); ok {
- return shared.JoinPath(c.SoongOutDir(), usedEnvFile+"."+v+"."+tag)
+ return shared.JoinPath(c.SoongOutDir(), usedEnvFile+"."+v+c.CoverageSuffix()+"."+tag)
}
return shared.JoinPath(c.SoongOutDir(), usedEnvFile+"."+tag)
}
@@ -1149,6 +1154,13 @@
return "", fmt.Errorf("TARGET_PRODUCT is not defined")
}
+func (c *configImpl) CoverageSuffix() string {
+ if v := c.environ.IsEnvTrue("EMMA_INSTRUMENT"); v {
+ return ".coverage"
+ }
+ return ""
+}
+
func (c *configImpl) TargetDevice() string {
return c.targetDevice
}
@@ -1289,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() {
@@ -1520,7 +1545,7 @@
if err != nil {
return filepath.Join(c.SoongOutDir(), "soong.variables")
} else {
- return filepath.Join(c.SoongOutDir(), "soong."+targetProduct+".variables")
+ return filepath.Join(c.SoongOutDir(), "soong."+targetProduct+c.CoverageSuffix()+".variables")
}
}
@@ -1529,7 +1554,7 @@
if err != nil {
return filepath.Join(c.SoongOutDir(), "soong.extra.variables")
} else {
- return filepath.Join(c.SoongOutDir(), "soong."+targetProduct+".extra.variables")
+ return filepath.Join(c.SoongOutDir(), "soong."+targetProduct+c.CoverageSuffix()+".extra.variables")
}
}
@@ -1538,7 +1563,7 @@
if err != nil {
return filepath.Join(c.SoongOutDir(), "build.ninja")
} else {
- return filepath.Join(c.SoongOutDir(), "build."+targetProduct+".ninja")
+ return filepath.Join(c.SoongOutDir(), "build."+targetProduct+c.CoverageSuffix()+".ninja")
}
}
@@ -1550,11 +1575,11 @@
}
func (c *configImpl) SoongAndroidMk() string {
- return filepath.Join(c.SoongOutDir(), "Android-"+c.TargetProduct()+".mk")
+ return filepath.Join(c.SoongOutDir(), "Android-"+c.TargetProduct()+c.CoverageSuffix()+".mk")
}
func (c *configImpl) SoongMakeVarsMk() string {
- return filepath.Join(c.SoongOutDir(), "make_vars-"+c.TargetProduct()+".mk")
+ return filepath.Join(c.SoongOutDir(), "make_vars-"+c.TargetProduct()+c.CoverageSuffix()+".mk")
}
func (c *configImpl) SoongBuildMetrics() string {
@@ -1715,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/kati.go b/ui/build/kati.go
index a0efd2c..5743ff7 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -41,7 +41,7 @@
// arguments.
func genKatiSuffix(ctx Context, config Config) {
// Construct the base suffix.
- katiSuffix := "-" + config.TargetProduct()
+ katiSuffix := "-" + config.TargetProduct() + config.CoverageSuffix()
// Append kati arguments to the suffix.
if args := config.KatiArgs(); len(args) > 0 {
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() {