Merge "Disable "__builtin_func" when converting mk to bp" into main
diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go
index 392e819..d29e312 100644
--- a/aconfig/aconfig_declarations.go
+++ b/aconfig/aconfig_declarations.go
@@ -137,18 +137,22 @@
inputFiles := make([]android.Path, len(declarationFiles))
copy(inputFiles, declarationFiles)
inputFiles = append(inputFiles, valuesFiles...)
+ args := map[string]string{
+ "release_version": ctx.Config().ReleaseVersion(),
+ "package": module.properties.Package,
+ "declarations": android.JoinPathsWithPrefix(declarationFiles, "--declarations "),
+ "values": joinAndPrefix(" --values ", module.properties.Values),
+ "default-permission": optionalVariable(" --default-permission ", defaultPermission),
+ }
+ if len(module.properties.Container) > 0 {
+ args["container"] = "--container " + module.properties.Container
+ }
ctx.Build(pctx, android.BuildParams{
Rule: aconfigRule,
Output: intermediateCacheFilePath,
Inputs: inputFiles,
Description: "aconfig_declarations",
- Args: map[string]string{
- "release_version": ctx.Config().ReleaseVersion(),
- "package": module.properties.Package,
- "declarations": android.JoinPathsWithPrefix(declarationFiles, "--declarations "),
- "values": joinAndPrefix(" --values ", module.properties.Values),
- "default-permission": optionalVariable(" --default-permission ", defaultPermission),
- },
+ Args: args,
})
intermediateDumpFilePath := android.PathForModuleOut(ctx, "intermediate.txt")
diff --git a/aconfig/aconfig_declarations_test.go b/aconfig/aconfig_declarations_test.go
index 1fe3c86..5201fed 100644
--- a/aconfig/aconfig_declarations_test.go
+++ b/aconfig/aconfig_declarations_test.go
@@ -69,3 +69,38 @@
depData, _ := android.SingletonModuleProvider(result, module, android.AconfigDeclarationsProviderKey)
android.AssertBoolEquals(t, "exportable", depData.Exportable, false)
}
+
+func TestAconfigDeclarationsWithContainer(t *testing.T) {
+ bp := `
+ aconfig_declarations {
+ name: "module_name",
+ package: "com.example.package",
+ container: "com.android.foo",
+ srcs: [
+ "foo.aconfig",
+ ],
+ }
+ `
+ result := runTest(t, android.FixtureExpectsNoErrors, bp)
+
+ module := result.ModuleForTests("module_name", "")
+ rule := module.Rule("aconfig")
+ android.AssertStringEquals(t, "rule must contain container", rule.Args["container"], "--container com.android.foo")
+}
+
+func TestAconfigDeclarationsWithoutContainer(t *testing.T) {
+ bp := `
+ aconfig_declarations {
+ name: "module_name",
+ package: "com.example.package",
+ srcs: [
+ "foo.aconfig",
+ ],
+ }
+ `
+ result := runTest(t, android.FixtureExpectsNoErrors, bp)
+
+ module := result.ModuleForTests("module_name", "")
+ rule := module.Rule("aconfig")
+ android.AssertIntEquals(t, "rule must not contain container", len(rule.Args["container"]), 0)
+}
diff --git a/aconfig/init.go b/aconfig/init.go
index 4625128..4655467 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -28,6 +28,7 @@
blueprint.RuleParams{
Command: `${aconfig} create-cache` +
` --package ${package}` +
+ ` ${container}` +
` ${declarations}` +
` ${values}` +
` ${default-permission}` +
@@ -38,7 +39,7 @@
"${aconfig}",
},
Restat: true,
- }, "release_version", "package", "declarations", "values", "default-permission")
+ }, "release_version", "package", "container", "declarations", "values", "default-permission")
// For create-device-config-sysprops: Generate aconfig flag value map text file
aconfigTextRule = pctx.AndroidStaticRule("aconfig_text",
diff --git a/android/api_levels.go b/android/api_levels.go
index 1130c3e..fab5fc7 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -289,6 +289,8 @@
var ApiLevelR = uncheckedFinalApiLevel(30)
+var ApiLevelUpsideDownCake = uncheckedFinalApiLevel(34)
+
// ReplaceFinalizedCodenames returns the API level number associated with that API level
// if the `raw` input is the codename of an API level has been finalized.
// If the input is *not* a finalized codename, the input is returned unmodified.
diff --git a/android/base_module_context.go b/android/base_module_context.go
index dd38a4e..9be3fad 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -305,6 +305,12 @@
AllowDisabledModuleDependency(target Module) bool
}
+type AlwaysAllowDisabledModuleDependencyTag struct{}
+
+func (t AlwaysAllowDisabledModuleDependencyTag) AllowDisabledModuleDependency(Module) bool {
+ return true
+}
+
func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool, ignoreBlueprint bool) Module {
aModule, _ := module.(Module)
diff --git a/android/config.go b/android/config.go
index 567ebd8..10c30d4 100644
--- a/android/config.go
+++ b/android/config.go
@@ -168,7 +168,10 @@
// Thus, verify_overlaps is disabled when RELEASE_DEFAULT_MODULE_BUILD_FROM_SOURCE is set to false.
// TODO(b/308174018): Re-enable verify_overlaps for both builr from source/mainline prebuilts.
func (c Config) DisableVerifyOverlaps() bool {
- return c.IsEnvTrue("DISABLE_VERIFY_OVERLAPS") || !c.ReleaseDefaultModuleBuildFromSource()
+ if c.IsEnvFalse("DISABLE_VERIFY_OVERLAPS") && c.ReleaseDisableVerifyOverlaps() {
+ panic("The current release configuration does not support verify_overlaps. DISABLE_VERIFY_OVERLAPS cannot be set to false")
+ }
+ return c.IsEnvTrue("DISABLE_VERIFY_OVERLAPS") || c.ReleaseDisableVerifyOverlaps() || !c.ReleaseDefaultModuleBuildFromSource()
}
// MaxPageSizeSupported returns the max page size supported by the device. This
@@ -209,6 +212,10 @@
Bool(c.config.productVariables.ReleaseDefaultModuleBuildFromSource)
}
+func (c Config) ReleaseDisableVerifyOverlaps() bool {
+ return c.config.productVariables.GetBuildFlagBool("RELEASE_DISABLE_VERIFY_OVERLAPS_CHECK")
+}
+
// Enables flagged apis annotated with READ_WRITE aconfig flags to be included in the stubs
// and hiddenapi flags so that they are accessible at runtime
func (c Config) ReleaseExportRuntimeApis() bool {
diff --git a/android/filegroup.go b/android/filegroup.go
index bc881ed..86d7b4b 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -15,6 +15,7 @@
package android
import (
+ "maps"
"strings"
"github.com/google/blueprint"
@@ -97,6 +98,25 @@
}
SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: fg.srcs.Strings()})
CollectDependencyAconfigFiles(ctx, &fg.mergedAconfigFiles)
+
+ var aconfigDeclarations []string
+ var intermediateCacheOutputPaths Paths
+ var srcjars Paths
+ modeInfos := make(map[string]ModeInfo)
+ ctx.VisitDirectDeps(func(module Module) {
+ if dep, ok := OtherModuleProvider(ctx, module, CodegenInfoProvider); ok {
+ aconfigDeclarations = append(aconfigDeclarations, dep.AconfigDeclarations...)
+ intermediateCacheOutputPaths = append(intermediateCacheOutputPaths, dep.IntermediateCacheOutputPaths...)
+ srcjars = append(srcjars, dep.Srcjars...)
+ maps.Copy(modeInfos, dep.ModeInfos)
+ }
+ })
+ SetProvider(ctx, CodegenInfoProvider, CodegenInfo{
+ AconfigDeclarations: aconfigDeclarations,
+ IntermediateCacheOutputPaths: intermediateCacheOutputPaths,
+ Srcjars: srcjars,
+ ModeInfos: modeInfos,
+ })
}
func (fg *fileGroup) Srcs() Paths {
diff --git a/android/license_metadata.go b/android/license_metadata.go
index 463fd07..eabb1b1 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -77,6 +77,11 @@
if ctx.OtherModuleDependencyTag(dep) == DefaultsDepTag {
return
}
+ // The required dependencies just say modules A and B should be installed together.
+ // It doesn't mean that one is built using the other.
+ if ctx.OtherModuleDependencyTag(dep) == RequiredDepTag {
+ return
+ }
if info, ok := OtherModuleProvider(ctx, dep, LicenseMetadataProvider); ok {
allDepMetadataFiles = append(allDepMetadataFiles, info.LicenseMetadataPath)
diff --git a/android/module.go b/android/module.go
index 000476c..cce4fa6 100644
--- a/android/module.go
+++ b/android/module.go
@@ -542,6 +542,15 @@
var teamDepTag = TeamDepTagType{}
+// Dependency tag for required, host_required, and target_required modules.
+var RequiredDepTag = struct {
+ blueprint.BaseDependencyTag
+ InstallAlwaysNeededDependencyTag
+ // Requiring disabled module has been supported (as a side effect of this being implemented
+ // in Make). We may want to make it an error, but for now, let's keep the existing behavior.
+ AlwaysAllowDisabledModuleDependencyTag
+}{}
+
// CommonTestOptions represents the common `test_options` properties in
// Android.bp.
type CommonTestOptions struct {
@@ -1007,6 +1016,87 @@
if m.Team() != "" {
ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
}
+
+ // TODO(jiyong): remove below case. This is to work around build errors happening
+ // on branches with reduced manifest like aosp_kernel-build-tools.
+ // In the branch, a build error occurs as follows.
+ // 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
+ // projects like external/bouncycastle
+ // 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
+ // the top-level build goal (in the shell file that invokes Soong).
+ // 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
+ // 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of
+ // ALLOW_MISSING_DEPENDENCIES didn't cause a problem.
+ // 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
+ // absence of external/bouncycastle fails the build.
+ //
+ // Unfortunately, there's no way for Soong to correctly determine if it's running in a
+ // reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
+ // a strong signal, because that's very common across reduced manifest branches.
+ pv := ctx.Config().productVariables
+ fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
+ if fullManifest {
+ m.addRequiredDeps(ctx)
+ }
+}
+
+// addRequiredDeps adds required, target_required, and host_required as dependencies.
+func (m *ModuleBase) addRequiredDeps(ctx BottomUpMutatorContext) {
+ addDep := func(target Target, depName string) {
+ if !ctx.OtherModuleExists(depName) {
+ if ctx.Config().AllowMissingDependencies() {
+ return
+ }
+ }
+
+ // If Android native module requires another Android native module, ensure that
+ // they have the same bitness. This mimics the policy in select-bitness-of-required-modules
+ // in build/make/core/main.mk.
+ // TODO(jiyong): the Make-side does this only when the required module is a shared
+ // library or a native test.
+ bothInAndroid := m.Device() && target.Os.Class == Device
+ nativeArch := m.Arch().ArchType.Multilib != string(MultilibCommon)
+ sameBitness := m.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
+ if bothInAndroid && nativeArch && !sameBitness {
+ return
+ }
+
+ variation := target.Variations()
+ if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
+ ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
+ }
+ }
+
+ if m.Device() {
+ for _, depName := range m.RequiredModuleNames() {
+ for _, target := range ctx.Config().Targets[Android] {
+ addDep(target, depName)
+ }
+ }
+ for _, depName := range m.HostRequiredModuleNames() {
+ for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] {
+ addDep(target, depName)
+ }
+ }
+ }
+
+ if m.Host() {
+ for _, depName := range m.RequiredModuleNames() {
+ for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] {
+ // When a host module requires another host module, don't make a
+ // dependency if they have different OSes (i.e. hostcross).
+ if m.Target().HostCross != target.HostCross {
+ continue
+ }
+ addDep(target, depName)
+ }
+ }
+ for _, depName := range m.TargetRequiredModuleNames() {
+ for _, target := range ctx.Config().Targets[Android] {
+ addDep(target, depName)
+ }
+ }
+ }
}
// AddProperties "registers" the provided props
diff --git a/android/singleton.go b/android/singleton.go
index ccddeaf..5f93996 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -251,7 +251,7 @@
func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name string) []Module {
// get module reference for visibility enforcement
- qualified := createVisibilityModuleReference(s.ModuleName(referer), s.ModuleDir(referer), s.ModuleType(referer))
+ qualified := createVisibilityModuleReference(s.ModuleName(referer), s.ModuleDir(referer), referer)
modules := s.SingletonContext.ModuleVariantsFromName(referer, name)
result := make([]Module, 0, len(modules))
diff --git a/android/visibility.go b/android/visibility.go
index 79a534f..89c0adc 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -58,19 +58,14 @@
var visibilityRuleRegexp = regexp.MustCompile(visibilityRulePattern)
type visibilityModuleReference struct {
- name qualifiedModuleName
- isPartitionModule bool
+ name qualifiedModuleName
+ module Module
}
-func createVisibilityModuleReference(name, dir, typ string) visibilityModuleReference {
- isPartitionModule := false
- switch typ {
- case "android_filesystem", "android_system_image":
- isPartitionModule = true
- }
+func createVisibilityModuleReference(name, dir string, module Module) visibilityModuleReference {
return visibilityModuleReference{
- name: createQualifiedModuleName(name, dir),
- isPartitionModule: isPartitionModule,
+ name: createQualifiedModuleName(name, dir),
+ module: module,
}
}
@@ -214,21 +209,37 @@
return "//visibility:private"
}
+var anyPartitionRegex = regexp.MustCompile("^any_(system|system_ext|vendor|product|data|odm)_partition$")
+
// visibilityRule for //visibility:any_partition
-type anyPartitionRule struct{}
+type anyPartitionRule struct {
+ partitionType string
+}
var _ visibilityRule = anyPartitionRule{}
+type PartitionTypeInterface interface {
+ PartitionType() string
+}
+
func (r anyPartitionRule) matches(m visibilityModuleReference) bool {
- return m.isPartitionModule
+ if m2, ok := m.module.(PartitionTypeInterface); ok {
+ return m2.PartitionType() == r.partitionType
+ }
+ return false
}
func (r anyPartitionRule) String() string {
- return "//visibility:any_partition"
+ return "//visibility:any_" + r.partitionType + "_partition"
}
var visibilityRuleMap = NewOnceKey("visibilityRuleMap")
+type visibilityRulesForModule struct {
+ rule compositeRule
+ implicitPartitionRules compositeRule
+}
+
// The map from qualifiedModuleName to visibilityRule.
func moduleToVisibilityRuleMap(config Config) *sync.Map {
return config.Once(visibilityRuleMap, func() interface{} {
@@ -304,9 +315,6 @@
if pkg == "visibility" {
switch name {
case "private", "public":
- case "any_partition":
- // any_partition can be used with another visibility fields
- continue
case "legacy_public":
ctx.PropertyErrorf(property, "//visibility:legacy_public must not be used")
continue
@@ -314,6 +322,10 @@
// This keyword does not create a rule so pretend it does not exist.
ruleCount -= 1
default:
+ if anyPartitionRegex.MatchString(name) {
+ // any_*_partition can be used with another visibility fields
+ continue
+ }
ctx.PropertyErrorf(property, "unrecognized visibility rule %q", v)
continue
}
@@ -352,15 +364,20 @@
// Parse the visibility rules that control access to the module and store them by id
// for use when enforcing the rules.
+ var rule compositeRule
primaryProperty := m.base().primaryVisibilityProperty
if primaryProperty != nil {
if visibility := primaryProperty.getStrings(); visibility != nil {
- rule := parseRules(ctx, currentPkg, primaryProperty.getName(), visibility)
- if rule != nil {
- moduleToVisibilityRuleMap(ctx.Config()).Store(qualifiedModuleId, rule)
- }
+ rule = parseRules(ctx, currentPkg, primaryProperty.getName(), visibility)
}
}
+ ipr := implicitPartitionRules(ctx)
+ if rule != nil || ipr != nil {
+ moduleToVisibilityRuleMap(ctx.Config()).Store(qualifiedModuleId, visibilityRulesForModule{
+ rule: rule,
+ implicitPartitionRules: ipr,
+ })
+ }
}
func parseRules(ctx BaseModuleContext, currentPkg, property string, visibility []string) compositeRule {
@@ -392,8 +409,13 @@
hasNonPrivateRule = false
// This does not actually create a rule so continue onto the next rule.
continue
- case "any_partition":
- r = anyPartitionRule{}
+ default:
+ match := anyPartitionRegex.FindStringSubmatch(name)
+ if match != nil {
+ r = anyPartitionRule{
+ partitionType: match[1],
+ }
+ }
}
} else {
switch name {
@@ -432,6 +454,22 @@
return rules
}
+func implicitPartitionRules(ctx BaseModuleContext) compositeRule {
+ var result compositeRule
+ if ctx.SocSpecific() {
+ result = append(result, anyPartitionRule{partitionType: "vendor"})
+ } else if ctx.ProductSpecific() {
+ result = append(result, anyPartitionRule{partitionType: "product"})
+ } else if ctx.Module().InstallInData() {
+ result = append(result, anyPartitionRule{partitionType: "data"})
+ } else if ctx.SystemExtSpecific() {
+ result = append(result, anyPartitionRule{partitionType: "system_ext"})
+ } else if ctx.DeviceSpecific() {
+ result = append(result, anyPartitionRule{partitionType: "odm"})
+ }
+ return result
+}
+
func isAllowedFromOutsideVendor(pkg string, name string) bool {
if pkg == "vendor" {
return name == "__subpackages__"
@@ -470,7 +508,7 @@
}
func visibilityRuleEnforcer(ctx TopDownMutatorContext) {
- qualified := createVisibilityModuleReference(ctx.ModuleName(), ctx.ModuleDir(), ctx.ModuleType())
+ qualified := createVisibilityModuleReference(ctx.ModuleName(), ctx.ModuleDir(), ctx.Module())
// Visit all the dependencies making sure that this module has access to them all.
ctx.VisitDirectDeps(func(dep Module) {
@@ -505,10 +543,13 @@
// which is currently //visibility:public.
func effectiveVisibilityRules(config Config, qualified qualifiedModuleName) compositeRule {
moduleToVisibilityRule := moduleToVisibilityRuleMap(config)
- value, ok := moduleToVisibilityRule.Load(qualified)
+ value := visibilityRulesForModule{}
+ if valueRaw, ok := moduleToVisibilityRule.Load(qualified); ok {
+ value = valueRaw.(visibilityRulesForModule)
+ }
var rule compositeRule
- if ok {
- rule = value.(compositeRule)
+ if value.rule != nil {
+ rule = value.rule
} else {
rule = packageDefaultVisibility(moduleToVisibilityRule, qualified)
}
@@ -518,6 +559,20 @@
if rule == nil {
rule = defaultVisibility
}
+
+ // If a partition rule wasn't specified, add implicit partition visibility
+ // rules based on the partition properties like vendor: true.
+ foundPartitionRule := false
+ for _, r := range rule {
+ if _, ok := r.(anyPartitionRule); ok {
+ foundPartitionRule = true
+ break
+ }
+ }
+ if !foundPartitionRule {
+ rule = append(rule, value.implicitPartitionRules...)
+ }
+
return rule
}
@@ -531,7 +586,7 @@
for {
value, ok := moduleToVisibilityRule.Load(packageQualifiedId)
if ok {
- return value.(compositeRule)
+ return value.(visibilityRulesForModule).rule
}
if packageQualifiedId.isRootPackage() {
@@ -605,7 +660,7 @@
rule := effectiveVisibilityRules(ctx.Config(), qualified)
- currentModule := createVisibilityModuleReference(moduleName, dir, ctx.OtherModuleType(module))
+ currentModule := createVisibilityModuleReference(moduleName, dir, module)
// Modules are implicitly visible to other modules in the same package,
// without checking the visibility rules. Here we need to add that visibility
diff --git a/android/visibility_test.go b/android/visibility_test.go
index bb43b1f..1a2eeca 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -1905,7 +1905,7 @@
},
},
{
- name: "any_partition visibility works",
+ name: "any_system_partition visibility works",
fs: MockFS{
"top/Android.bp": []byte(`
android_filesystem {
@@ -1916,12 +1916,12 @@
package(default_visibility=["//visibility:private"])
mock_library {
name: "bar",
- visibility: ["//visibility:any_partition"],
+ visibility: ["//visibility:any_system_partition"],
}`),
},
},
{
- name: "any_partition visibility works with the other visibility",
+ name: "any_system_partition visibility works with the other visibility",
fs: MockFS{
"top/Android.bp": []byte(`
android_filesystem {
@@ -1935,13 +1935,13 @@
name: "bar",
visibility: [
"//top2",
- "//visibility:any_partition"
+ "//visibility:any_system_partition"
],
}`),
},
},
{
- name: "any_partition visibility doesn't work for non-partitions",
+ name: "any_system_partition visibility doesn't work for non-partitions",
fs: MockFS{
"top/Android.bp": []byte(`
mock_library {
@@ -1951,11 +1951,77 @@
"top/nested/Android.bp": []byte(`
mock_library {
name: "bar",
- visibility: ["//visibility:any_partition"],
+ visibility: ["//visibility:any_system_partition"],
}`),
},
expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
},
+ {
+ name: "any_system_partition visibility doesn't work for vendor partitions",
+ fs: MockFS{
+ "top/Android.bp": []byte(`
+ android_filesystem {
+ name: "foo",
+ partition_type: "vendor",
+ deps: ["bar"],
+ }`),
+ "top/nested/Android.bp": []byte(`
+ package(default_visibility=["//visibility:private"])
+ mock_library {
+ name: "bar",
+ visibility: ["//visibility:any_system_partition"],
+ }`),
+ },
+ expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
+ },
+ {
+ name: "Vendor modules are visible to any vendor partition by default",
+ fs: MockFS{
+ "top/Android.bp": []byte(`
+ android_filesystem {
+ name: "foo",
+ partition_type: "vendor",
+ deps: ["bar"],
+ }`),
+ "top/nested/Android.bp": []byte(`
+ package(default_visibility=["//visibility:private"])
+ mock_library {
+ name: "bar",
+ vendor: true,
+ }`),
+ },
+ },
+ {
+ name: "Not visible to vendor partitions when using any_system_partiton, even if vendor: true",
+ fs: MockFS{
+ "top/Android.bp": []byte(`
+ android_filesystem {
+ name: "foo",
+ partition_type: "vendor",
+ deps: ["bar"],
+ }`),
+ "top/nested/Android.bp": []byte(`
+ package(default_visibility=["//visibility:private"])
+ mock_library {
+ name: "bar",
+ vendor: true,
+ visibility: ["//visibility:any_system_partition"],
+ }`),
+ },
+ expectedErrors: []string{`module "foo" variant "android_common": depends on //top/nested:bar which is not visible to this module`},
+ },
+ {
+ name: "unknown any_partition specs throw errors",
+ fs: MockFS{
+ "top/nested/Android.bp": []byte(`
+ package(default_visibility=["//visibility:private"])
+ mock_library {
+ name: "bar",
+ visibility: ["//visibility:any_unknown_partition"],
+ }`),
+ },
+ expectedErrors: []string{`unrecognized visibility rule "//visibility:any_unknown_partition"`},
+ },
}
func TestVisibility(t *testing.T) {
@@ -1977,8 +2043,7 @@
ctx.RegisterModuleType("mock_library", newMockLibraryModule)
ctx.RegisterModuleType("mock_parent", newMockParentFactory)
ctx.RegisterModuleType("mock_defaults", defaultsFactory)
- // For testing //visibility:any_partition. The module type doesn't matter, just that it's registered under the name "android_filesystem"
- ctx.RegisterModuleType("android_filesystem", newMockLibraryModule)
+ ctx.RegisterModuleType("android_filesystem", newMockFilesystemModule)
}),
prepareForTestWithFakePrebuiltModules,
// Add additional files to the mock filesystem
@@ -2032,6 +2097,37 @@
func (p *mockLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
}
+type mockFilesystemModuleProperties struct {
+ Partition_type *string
+ Deps []string
+}
+
+type mockFilesystemModule struct {
+ ModuleBase
+ properties mockFilesystemModuleProperties
+}
+
+func (j *mockFilesystemModule) DepsMutator(ctx BottomUpMutatorContext) {
+ ctx.AddVariationDependencies(nil, dependencyTag{name: "mockdeps"}, j.properties.Deps...)
+}
+
+func (p *mockFilesystemModule) GenerateAndroidBuildActions(ModuleContext) {
+}
+
+func (p *mockFilesystemModule) PartitionType() string {
+ if p.properties.Partition_type == nil {
+ return "system"
+ }
+ return *p.properties.Partition_type
+}
+
+func newMockFilesystemModule() Module {
+ m := &mockFilesystemModule{}
+ m.AddProperties(&m.properties)
+ InitAndroidArchModule(m, DeviceSupported, MultilibCommon)
+ return m
+}
+
type mockDefaults struct {
ModuleBase
DefaultsModuleBase
diff --git a/androidmk/parser/parser.go b/androidmk/parser/parser.go
index fb6be38..8a20bb0 100644
--- a/androidmk/parser/parser.go
+++ b/androidmk/parser/parser.go
@@ -413,6 +413,9 @@
p.accept('\t')
newLine = false
continue loop
+ } else if p.tok == '\n' {
+ p.accept('\n')
+ continue loop
} else if p.parseDirective() {
newLine = false
continue
diff --git a/androidmk/parser/parser_test.go b/androidmk/parser/parser_test.go
index 9efebf8..db3313d 100644
--- a/androidmk/parser/parser_test.go
+++ b/androidmk/parser/parser_test.go
@@ -84,6 +84,22 @@
},
},
},
+ {
+ name: "Blank line in rule's command",
+ in: `all:
+ echo first line
+
+ echo second line`,
+ out: []Node{
+ &Rule{
+ Target: SimpleMakeString("all", NoPos),
+ RecipePos: NoPos,
+ Recipe: "echo first line\necho second line",
+ Prerequisites: SimpleMakeString("", NoPos),
+ },
+ },
+ },
+
}
func TestParse(t *testing.T) {
diff --git a/apex/aconfig_test.go b/apex/aconfig_test.go
index be98d45..a179dbf 100644
--- a/apex/aconfig_test.go
+++ b/apex/aconfig_test.go
@@ -193,6 +193,70 @@
mode: "exported",
}`,
},
+ {
+ name: "Rust lib passes for exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ native_shared_libs: ["libmy_rust_library"],
+ binaries: ["my_rust_binary"],
+ updatable: false,
+ }
+ rust_library {
+ name: "libflags_rust", // test mock
+ crate_name: "flags_rust",
+ srcs: ["lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblazy_static", // test mock
+ crate_name: "lazy_static",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_ffi_shared {
+ name: "libmy_rust_library",
+ srcs: ["src/lib.rs"],
+ rustlibs: ["libmy_rust_aconfig_library_foo"],
+ crate_name: "my_rust_library",
+ apex_available: ["myapex"],
+ }
+ rust_binary {
+ name: "my_rust_binary",
+ srcs: ["foo/bar/MyClass.rs"],
+ rustlibs: ["libmy_rust_aconfig_library_bar"],
+ apex_available: ["myapex"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["foo.aconfig"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_bar",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["bar.aconfig"],
+ }
+ rust_aconfig_library {
+ name: "libmy_rust_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ crate_name: "my_rust_aconfig_library_foo",
+ apex_available: ["myapex"],
+ mode: "exported",
+ }
+ rust_aconfig_library {
+ name: "libmy_rust_aconfig_library_bar",
+ aconfig_declarations: "my_aconfig_declarations_bar",
+ crate_name: "my_rust_aconfig_library_bar",
+ apex_available: ["myapex"],
+ mode: "exported",
+ }`,
+ },
}
for _, test := range testCases {
t.Run(test.name, func(t *testing.T) {
@@ -394,6 +458,93 @@
expectedError: `.*my_cc_binary_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`,
},
{
+ name: "Rust lib fails for non-exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ native_shared_libs: ["libmy_rust_library"],
+ updatable: false,
+ }
+ rust_library {
+ name: "libflags_rust", // test mock
+ crate_name: "flags_rust",
+ srcs: ["lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblazy_static", // test mock
+ crate_name: "lazy_static",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_ffi_shared {
+ name: "libmy_rust_library",
+ srcs: ["src/lib.rs"],
+ rustlibs: ["libmy_rust_aconfig_library_foo"],
+ crate_name: "my_rust_library",
+ apex_available: ["myapex"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["foo.aconfig"],
+ }
+ rust_aconfig_library {
+ name: "libmy_rust_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ crate_name: "my_rust_aconfig_library_foo",
+ apex_available: ["myapex"],
+ }`,
+ expectedError: `.*libmy_rust_aconfig_library_foo/myapex depends on libmy_rust_aconfig_library_foo/otherapex/production across containers`,
+ },
+ {
+ name: "Rust binary fails for non-exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ binaries: ["my_rust_binary"],
+ updatable: false,
+ }
+ rust_library {
+ name: "libflags_rust", // test mock
+ crate_name: "flags_rust",
+ srcs: ["lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblazy_static", // test mock
+ crate_name: "lazy_static",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_binary {
+ name: "my_rust_binary",
+ srcs: ["foo/bar/MyClass.rs"],
+ rustlibs: ["libmy_rust_aconfig_library_bar"],
+ apex_available: ["myapex"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_bar",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["bar.aconfig"],
+ }
+ rust_aconfig_library {
+ name: "libmy_rust_aconfig_library_bar",
+ aconfig_declarations: "my_aconfig_declarations_bar",
+ crate_name: "my_rust_aconfig_library_bar",
+ apex_available: ["myapex"],
+ }`,
+ expectedError: `.*libmy_rust_aconfig_library_bar/myapex depends on libmy_rust_aconfig_library_bar/otherapex/production across containers`,
+ },
+ {
name: "Aconfig validation propagate along sourceOrOutputDependencyTag",
bp: apex_default_bp + `
apex {
diff --git a/apex/apex.go b/apex/apex.go
index 32a3638..bc91407 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1648,10 +1648,9 @@
return af
}
-func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile {
+func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, outputFile android.Path) apexFile {
dirInApex := filepath.Join(prebuilt.BaseDir(), prebuilt.SubDir())
- fileToCopy := prebuilt.OutputFile()
- return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt)
+ return newApexFile(ctx, outputFile, outputFile.Base(), dirInApex, etc, prebuilt)
}
func apexFileForCompatConfig(ctx android.BaseModuleContext, config java.PlatformCompatConfigIntf, depName string) apexFile {
@@ -1821,6 +1820,9 @@
if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
return false
}
+ if depTag == android.RequiredDepTag {
+ return false
+ }
ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
@@ -2120,7 +2122,10 @@
}
case prebuiltTag:
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
+ filesToCopy, _ := prebuilt.OutputFiles("")
+ 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)
@@ -2263,7 +2268,10 @@
// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
} else if java.IsXmlPermissionsFileDepTag(depTag) {
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
- vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
+ filesToCopy, _ := prebuilt.OutputFiles("")
+ for _, etcFile := range filesToCopy {
+ vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
+ }
}
} else if rust.IsDylibDepTag(depTag) {
if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
@@ -2314,6 +2322,8 @@
// nothing
} else if depTag == android.DarwinUniversalVariantTag {
// nothing
+ } else if depTag == android.RequiredDepTag {
+ // nothing
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 19b9d16..b7362b2 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -10047,7 +10047,6 @@
key: "myapex.key",
updatable: false,
java_libs: ["foo"],
- required: ["otherapex"],
}
apex_key {
@@ -11022,7 +11021,7 @@
}
`)
- inputs := result.ModuleForTests("myfilesystem", "android_common").Output("deps.zip").Implicits
+ inputs := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img").Implicits
android.AssertStringListDoesNotContain(t, "filesystem should not have libbar",
inputs.Strings(),
"out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so")
diff --git a/cc/cc.go b/cc/cc.go
index 0fa3457..90185ea 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2980,6 +2980,9 @@
if depTag == stubImplDepTag {
return false
}
+ if depTag == android.RequiredDepTag {
+ return false
+ }
// Even if target lib has no vendor variant, keep checking dependency
// graph in case it depends on vendor_available or product_available
@@ -3157,6 +3160,10 @@
return
}
+ if depTag == android.RequiredDepTag {
+ return
+ }
+
if dep.Target().Os != ctx.Os() {
ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
return
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 0de9e05..10342a3 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -49,7 +49,6 @@
}
arm64Ldflags = []string{
- "-Wl,--hash-style=gnu",
"-Wl,-z,separate-code",
"-Wl,-z,separate-loadable-segments",
}
diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go
index 335ad56..f7d190b 100644
--- a/cc/config/arm64_linux_host.go
+++ b/cc/config/arm64_linux_host.go
@@ -42,7 +42,6 @@
"-Wl,-z,now",
"-Wl,--build-id=md5",
"-Wl,--fatal-warnings",
- "-Wl,--hash-style=gnu",
"-Wl,--no-undefined-version",
}
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 603bc6d..3284e4b 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -38,7 +38,6 @@
}
armLdflags = []string{
- "-Wl,--hash-style=gnu",
"-Wl,-m,armelf",
// Revert this after b/322359235 is fixed
"-Wl,-mllvm", "-Wl,-enable-shrink-wrap=false",
diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go
index 6a84fee..47f0de1 100644
--- a/cc/config/riscv64_device.go
+++ b/cc/config/riscv64_device.go
@@ -23,24 +23,29 @@
var (
riscv64Cflags = []string{
- // Help catch common 32/64-bit errors.
+ // Help catch common 32/64-bit errors. (This is duplicated in all 64-bit
+ // architectures' cflags.)
"-Werror=implicit-function-declaration",
+ // This is already the driver's Android default, but duplicated here (and
+ // below) for ease of experimentation with additional extensions.
"-march=rv64gcv_zba_zbb_zbs",
- "-munaligned-access",
- // Until https://gitlab.com/qemu-project/qemu/-/issues/1976 is fixed...
+ // TODO: move to driver (https://github.com/google/android-riscv64/issues/111)
+ "-mno-strict-align",
+ // TODO: remove when qemu V works (https://gitlab.com/qemu-project/qemu/-/issues/1976)
+ // (Note that we'll probably want to wait for berberis to be good enough
+ // that most people don't care about qemu's V performance either!)
"-mno-implicit-float",
- // (https://github.com/google/android-riscv64/issues/124)
+ // TODO: remove when clang default changed (https://github.com/google/android-riscv64/issues/124)
"-mllvm -jump-is-expensive=false",
}
riscv64ArchVariantCflags = map[string][]string{}
riscv64Ldflags = []string{
- "-Wl,--hash-style=gnu",
+ // This is already the driver's Android default, but duplicated here (and
+ // above) for ease of experimentation with additional extensions.
"-march=rv64gcv_zba_zbb_zbs",
- "-munaligned-access",
- // We should change the default for this in clang, but for now...
- // (https://github.com/google/android-riscv64/issues/124)
+ // TODO: remove when clang default changed (https://github.com/google/android-riscv64/issues/124)
"-Wl,-mllvm -Wl,-jump-is-expensive=false",
}
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index 12119a7..ca2c2b7 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -30,7 +30,6 @@
x86_64Cppflags = []string{}
x86_64Ldflags = []string{
- "-Wl,--hash-style=gnu",
"-Wl,-z,separate-loadable-segments",
}
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index 2faa670..60b8339 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -33,9 +33,7 @@
x86Cppflags = []string{}
- x86Ldflags = []string{
- "-Wl,--hash-style=gnu",
- }
+ x86Ldflags = []string{}
x86ArchVariantCflags = map[string][]string{
"": []string{
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index f80be99..99d4ebb 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -46,7 +46,6 @@
"-Wl,-z,now",
"-Wl,--build-id=md5",
"-Wl,--fatal-warnings",
- "-Wl,--hash-style=gnu",
"-Wl,--no-undefined-version",
// Use the device gcc toolchain
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index 05c644f..0896206 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -210,3 +210,47 @@
t.Errorf(`expected product variant, but does not exist in %v`, variants)
}
}
+
+// cc_genrule is initialized to android.InitAndroidArchModule
+// that is an architecture-specific Android module.
+// So testing properties tagged with `android:"arch_variant"`
+// for cc_genrule.
+func TestMultilibGenruleOut(t *testing.T) {
+ bp := `
+ cc_genrule {
+ name: "gen",
+ cmd: "cp $(in) $(out)",
+ srcs: ["foo"],
+ multilib: {
+ lib32: {
+ out: [
+ "subdir32/external-module32",
+ ],
+ },
+ lib64: {
+ out: [
+ "subdir64/external-module64",
+ ],
+ },
+ },
+ }
+ `
+ result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp)
+ gen_32bit := result.ModuleForTests("gen", "android_arm_armv7-a-neon").OutputFiles(t, "")
+ android.AssertPathsEndWith(t,
+ "genrule_out",
+ []string{
+ "subdir32/external-module32",
+ },
+ gen_32bit,
+ )
+
+ gen_64bit := result.ModuleForTests("gen", "android_arm64_armv8-a").OutputFiles(t, "")
+ android.AssertPathsEndWith(t,
+ "genrule_out",
+ []string{
+ "subdir64/external-module64",
+ },
+ gen_64bit,
+ )
+}
diff --git a/cc/linker.go b/cc/linker.go
index 2c50db2..9686697 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -530,13 +530,6 @@
flags.Global.LdFlags = append(flags.Global.LdFlags, RpathFlags(ctx)...)
}
- if ctx.useSdk() {
- // The bionic linker now has support gnu style hashes (which are much faster!), but shipping
- // to older devices requires the old style hash. Fortunately, we can build with both and
- // it'll work anywhere.
- flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--hash-style=both")
- }
-
flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainLdflags())
// Version_script is not needed when linking stubs lib where the version
diff --git a/cc/lto.go b/cc/lto.go
index 05fa8ee..a084db7 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -90,10 +90,6 @@
} else if ctx.testBinary() || ctx.testLibrary() {
// Do not enable LTO for tests for better debugging.
ltoEnabled = false
- } else if ctx.isVndk() {
- // FIXME: ThinLTO for VNDK produces different output.
- // b/169217596
- ltoEnabled = false
}
lto.Properties.LtoDefault = ltoDefault
diff --git a/cmd/symbols_map/Android.bp b/cmd/symbols_map/Android.bp
index 0ba3b07..e3ae6ed 100644
--- a/cmd/symbols_map/Android.bp
+++ b/cmd/symbols_map/Android.bp
@@ -5,17 +5,16 @@
blueprint_go_binary {
name: "symbols_map",
srcs: [
- "elf.go",
"r8.go",
"symbols_map.go",
],
testSrcs: [
- "elf_test.go",
"r8_test.go",
],
deps: [
"blueprint-pathtools",
"golang-protobuf-encoding-prototext",
+ "soong-elf",
"soong-response",
"symbols_map_proto",
],
diff --git a/cmd/symbols_map/symbols_map.go b/cmd/symbols_map/symbols_map.go
index 938446d..c56cf93 100644
--- a/cmd/symbols_map/symbols_map.go
+++ b/cmd/symbols_map/symbols_map.go
@@ -22,6 +22,7 @@
"strings"
"android/soong/cmd/symbols_map/symbols_map_proto"
+ "android/soong/elf"
"android/soong/response"
"github.com/google/blueprint/pathtools"
@@ -116,7 +117,7 @@
if *elfFile != "" {
typ = symbols_map_proto.Mapping_ELF
location = *elfFile
- identifier, err = elfIdentifier(*elfFile, true)
+ identifier, err = elf.Identifier(*elfFile, true)
if err != nil {
fmt.Fprintf(os.Stderr, "error reading elf identifier: %s\n", err)
os.Exit(1)
diff --git a/elf/Android.bp b/elf/Android.bp
new file mode 100644
index 0000000..6450be1
--- /dev/null
+++ b/elf/Android.bp
@@ -0,0 +1,28 @@
+// Copyright 2016 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-elf",
+ pkgPath: "android/soong/elf",
+ srcs: [
+ "elf.go",
+ ],
+ testSrcs: [
+ "elf_test.go",
+ ],
+}
diff --git a/cmd/symbols_map/elf.go b/elf/elf.go
similarity index 94%
rename from cmd/symbols_map/elf.go
rename to elf/elf.go
index 950e3b2..e84a8ae 100644
--- a/cmd/symbols_map/elf.go
+++ b/elf/elf.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package elf
import (
"debug/elf"
@@ -26,9 +26,9 @@
const gnuBuildID = "GNU\x00"
-// elfIdentifier extracts the elf build ID from an elf file. If allowMissing is true it returns
+// Identifier extracts the elf build ID from an elf file. If allowMissing is true it returns
// an empty identifier if the file exists but the build ID note does not.
-func elfIdentifier(filename string, allowMissing bool) (string, error) {
+func Identifier(filename string, allowMissing bool) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", fmt.Errorf("failed to open %s: %w", filename, err)
diff --git a/cmd/symbols_map/elf_test.go b/elf/elf_test.go
similarity index 99%
rename from cmd/symbols_map/elf_test.go
rename to elf/elf_test.go
index a94c87f..a220770 100644
--- a/cmd/symbols_map/elf_test.go
+++ b/elf/elf_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package elf
import (
"bytes"
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 7642378..a42c576 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -71,10 +71,15 @@
type prebuiltEtcProperties struct {
// Source file of this prebuilt. Can reference a genrule type module with the ":module" syntax.
+ // Mutually exclusive with srcs.
Src *string `android:"path,arch_variant"`
+ // Source files of this prebuilt. Can reference a genrule type module with the ":module" syntax.
+ // Mutually exclusive with src. When used, filename_from_src is set to true.
+ Srcs []string `android:"path,arch_variant"`
+
// Optional name for the installed file. If unspecified, name of the module is used as the file
- // name.
+ // name. Only available when using a single source (src).
Filename *string `android:"arch_variant"`
// When set to true, and filename property is not set, the name for the installed file
@@ -127,9 +132,9 @@
// Returns the sub install directory relative to BaseDir().
SubDir() string
- // Returns an android.OutputPath to the intermeidate file, which is the renamed prebuilt source
+ // Returns an android.OutputPath to the intermediate file, which is the renamed prebuilt source
// file.
- OutputFile() android.OutputPath
+ OutputFiles(tag string) (android.Paths, error)
}
type PrebuiltEtc struct {
@@ -142,8 +147,8 @@
properties prebuiltEtcProperties
subdirProperties prebuiltSubdirProperties
- sourceFilePath android.Path
- outputFilePath android.OutputPath
+ sourceFilePaths android.Paths
+ outputFilePaths android.OutputPaths
// The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
installDirBase string
installDirBase64 string
@@ -246,6 +251,9 @@
}
func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
+ if len(p.properties.Srcs) > 0 {
+ panic(fmt.Errorf("SourceFilePath not available on multi-source prebuilt %q", p.Name()))
+ }
return android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
}
@@ -260,7 +268,10 @@
}
func (p *PrebuiltEtc) OutputFile() android.OutputPath {
- return p.outputFilePath
+ if len(p.properties.Srcs) > 0 {
+ panic(fmt.Errorf("OutputFile not available on multi-source prebuilt %q", p.Name()))
+ }
+ return p.outputFilePaths[0]
}
var _ android.OutputFileProducer = (*PrebuiltEtc)(nil)
@@ -268,7 +279,7 @@
func (p *PrebuiltEtc) OutputFiles(tag string) (android.Paths, error) {
switch tag {
case "":
- return android.Paths{p.outputFilePath}, nil
+ return p.outputFilePaths.Paths(), nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -301,50 +312,7 @@
return false
}
-func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- filename := proptools.String(p.properties.Filename)
- filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
- if p.properties.Src != nil {
- p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
-
- // Determine the output file basename.
- // If Filename is set, use the name specified by the property.
- // If Filename_from_src is set, use the source file name.
- // Otherwise use the module name.
- if filename != "" {
- if filenameFromSrc {
- ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
- return
- }
- } else if filenameFromSrc {
- filename = p.sourceFilePath.Base()
- } else {
- filename = ctx.ModuleName()
- }
- } else if ctx.Config().AllowMissingDependencies() {
- // If no srcs was set and AllowMissingDependencies is enabled then
- // mark the module as missing dependencies and set a fake source path
- // and file name.
- ctx.AddMissingDependencies([]string{"MISSING_PREBUILT_SRC_FILE"})
- p.sourceFilePath = android.PathForModuleSrc(ctx)
- if filename == "" {
- filename = ctx.ModuleName()
- }
- } else {
- ctx.PropertyErrorf("src", "missing prebuilt source file")
- return
- }
-
- if strings.Contains(filename, "/") {
- ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
- return
- }
-
- // Check that `sub_dir` and `relative_install_path` are not set at the same time.
- if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil {
- ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir")
- }
-
+func (p *PrebuiltEtc) installBaseDir(ctx android.ModuleContext) string {
// If soc install dir was specified and SOC specific is set, set the installDirPath to the
// specified socInstallDirBase.
installBaseDir := p.installDirBase
@@ -357,47 +325,138 @@
if p.installAvoidMultilibConflict && !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
installBaseDir = filepath.Join(installBaseDir, ctx.Arch().ArchType.String())
}
+ return installBaseDir
+}
- p.installDirPath = android.PathForModuleInstall(ctx, installBaseDir, p.SubDir())
+func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ var installs []installProperties
- // Call InstallFile even when uninstallable to make the module included in the package
- ip := installProperties{
- installable: p.Installable(),
- filename: filename,
- sourceFilePath: p.sourceFilePath,
- symlinks: p.properties.Symlinks,
+ if p.properties.Src != nil && len(p.properties.Srcs) > 0 {
+ ctx.PropertyErrorf("src", "src is set. Cannot set srcs")
}
- p.addInstallRules(ctx, ip)
+
+ // Check that `sub_dir` and `relative_install_path` are not set at the same time.
+ if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil {
+ ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir")
+ }
+ p.installDirPath = android.PathForModuleInstall(ctx, p.installBaseDir(ctx), p.SubDir())
+
+ filename := proptools.String(p.properties.Filename)
+ filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
+ if p.properties.Src != nil {
+ p.sourceFilePaths = android.PathsForModuleSrc(ctx, []string{proptools.String(p.properties.Src)})
+ // If the source was not found, set a fake source path to
+ // support AllowMissingDependencies executions.
+ if len(p.sourceFilePaths) == 0 {
+ p.sourceFilePaths = android.Paths{android.PathForModuleSrc(ctx)}
+ }
+
+ // Determine the output file basename.
+ // If Filename is set, use the name specified by the property.
+ // If Filename_from_src is set, use the source file name.
+ // Otherwise use the module name.
+ if filename != "" {
+ if filenameFromSrc {
+ ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
+ return
+ }
+ } else if filenameFromSrc {
+ filename = p.sourceFilePaths[0].Base()
+ } else {
+ filename = ctx.ModuleName()
+ }
+ if strings.Contains(filename, "/") {
+ ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
+ return
+ }
+ p.outputFilePaths = android.OutputPaths{android.PathForModuleOut(ctx, filename).OutputPath}
+
+ ip := installProperties{
+ filename: filename,
+ sourceFilePath: p.sourceFilePaths[0],
+ outputFilePath: p.outputFilePaths[0],
+ installDirPath: p.installDirPath,
+ symlinks: p.properties.Symlinks,
+ }
+ installs = append(installs, ip)
+ } else if len(p.properties.Srcs) > 0 {
+ if filename != "" {
+ ctx.PropertyErrorf("filename", "filename cannot be set when using srcs")
+ }
+ if len(p.properties.Symlinks) > 0 {
+ ctx.PropertyErrorf("symlinks", "symlinks cannot be set when using srcs")
+ }
+ if p.properties.Filename_from_src != nil {
+ ctx.PropertyErrorf("filename_from_src", "filename_from_src is implicitly set to true when using srcs")
+ }
+ p.sourceFilePaths = android.PathsForModuleSrc(ctx, p.properties.Srcs)
+ for _, src := range p.sourceFilePaths {
+ filename := src.Base()
+ output := android.PathForModuleOut(ctx, filename).OutputPath
+ ip := installProperties{
+ filename: filename,
+ sourceFilePath: src,
+ outputFilePath: output,
+ installDirPath: p.installDirPath,
+ }
+ p.outputFilePaths = append(p.outputFilePaths, output)
+ installs = append(installs, ip)
+ }
+ } else if ctx.Config().AllowMissingDependencies() {
+ // If no srcs was set and AllowMissingDependencies is enabled then
+ // mark the module as missing dependencies and set a fake source path
+ // and file name.
+ ctx.AddMissingDependencies([]string{"MISSING_PREBUILT_SRC_FILE"})
+ p.sourceFilePaths = android.Paths{android.PathForModuleSrc(ctx)}
+ if filename == "" {
+ filename = ctx.ModuleName()
+ }
+ p.outputFilePaths = android.OutputPaths{android.PathForModuleOut(ctx, filename).OutputPath}
+ ip := installProperties{
+ filename: filename,
+ sourceFilePath: p.sourceFilePaths[0],
+ outputFilePath: p.outputFilePaths[0],
+ installDirPath: p.installDirPath,
+ }
+ installs = append(installs, ip)
+ } else {
+ ctx.PropertyErrorf("src", "missing prebuilt source file")
+ return
+ }
+
+ // Call InstallFile even when uninstallable to make the module included in the package.
+ if !p.Installable() {
+ p.SkipInstall()
+ }
+ for _, ip := range installs {
+ ip.addInstallRules(ctx)
+ }
android.CollectDependencyAconfigFiles(ctx, &p.mergedAconfigFiles)
}
type installProperties struct {
- installable bool
filename string
sourceFilePath android.Path
+ outputFilePath android.OutputPath
+ installDirPath android.InstallPath
symlinks []string
}
// utility function to add install rules to the build graph.
// Reduces code duplication between Soong and Mixed build analysis
-func (p *PrebuiltEtc) addInstallRules(ctx android.ModuleContext, ip installProperties) {
- if !ip.installable {
- p.SkipInstall()
- }
-
+func (ip *installProperties) addInstallRules(ctx android.ModuleContext) {
// Copy the file from src to a location in out/ with the correct `filename`
// This ensures that outputFilePath has the correct name for others to
// use, as the source file may have a different name.
- p.outputFilePath = android.PathForModuleOut(ctx, ip.filename).OutputPath
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
- Output: p.outputFilePath,
+ Output: ip.outputFilePath,
Input: ip.sourceFilePath,
})
- installPath := ctx.InstallFile(p.installDirPath, ip.filename, p.outputFilePath)
+ installPath := ctx.InstallFile(ip.installDirPath, ip.filename, ip.outputFilePath)
for _, sl := range ip.symlinks {
- ctx.InstallSymlink(p.installDirPath, sl, installPath)
+ ctx.InstallSymlink(ip.installDirPath, sl, installPath)
}
}
@@ -421,15 +480,15 @@
class = "ETC"
}
- return []android.AndroidMkEntries{android.AndroidMkEntries{
+ return []android.AndroidMkEntries{{
Class: class,
SubName: nameSuffix,
- OutputFile: android.OptionalPathForPath(p.outputFilePath),
+ OutputFile: android.OptionalPathForPath(p.outputFilePaths[0]),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_TAGS", "optional")
entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
- entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
+ entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePaths[0].Base())
if len(p.properties.Symlinks) > 0 {
entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...)
}
@@ -700,7 +759,11 @@
targetArch := "arch-" + m.Target().Arch.ArchType.String()
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "etc", m.BaseModuleName())
- snapshotOutputs = append(snapshotOutputs, copyFile(ctx, m.OutputFile(), snapshotLibOut, s.Fake))
+ outputs, _ := m.OutputFiles("")
+ for _, output := range outputs {
+ cp := copyFile(ctx, output, snapshotLibOut, s.Fake)
+ snapshotOutputs = append(snapshotOutputs, cp)
+ }
prop := snapshot.SnapshotJsonFlags{}
propOut := snapshotLibOut + ".json"
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index df11709..1d9aa8e 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -96,7 +96,7 @@
`)
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
- android.AssertStringEquals(t, "output file path", "foo.installed.conf", p.outputFilePath.Base())
+ android.AssertStringEquals(t, "output file path", "foo.installed.conf", p.outputFilePaths[0].Base())
}
func TestPrebuiltEtcGlob(t *testing.T) {
@@ -113,10 +113,24 @@
`)
p := result.Module("my_foo", "android_arm64_armv8-a").(*PrebuiltEtc)
- android.AssertStringEquals(t, "my_foo output file path", "my_foo", p.outputFilePath.Base())
+ android.AssertStringEquals(t, "my_foo output file path", "my_foo", p.outputFilePaths[0].Base())
p = result.Module("my_bar", "android_arm64_armv8-a").(*PrebuiltEtc)
- android.AssertStringEquals(t, "my_bar output file path", "bar.conf", p.outputFilePath.Base())
+ android.AssertStringEquals(t, "my_bar output file path", "bar.conf", p.outputFilePaths[0].Base())
+}
+
+func TestPrebuiltEtcMultipleSrcs(t *testing.T) {
+ result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo",
+ srcs: ["*.conf"],
+ }
+ `)
+
+ p := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
+ android.AssertStringEquals(t, "output file path", "bar.conf", p.outputFilePaths[0].Base())
+ android.AssertStringEquals(t, "output file path", "baz.conf", p.outputFilePaths[1].Base())
+ android.AssertStringEquals(t, "output file path", "foo.conf", p.outputFilePaths[2].Base())
}
func TestPrebuiltEtcAndroidMk(t *testing.T) {
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 795a0aa..efc889c 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -19,6 +19,7 @@
"fmt"
"io"
"path/filepath"
+ "slices"
"strings"
"android/soong/android"
@@ -87,6 +88,10 @@
// is ext4.
Type *string
+ // Identifies which partition this is for //visibility:any_system_image (and others) visibility
+ // checks, and will be used in the future for API surface checks.
+ Partition_type *string
+
// file_contexts file to make image. Currently, only ext4 is supported.
File_contexts *string `android:"path"`
@@ -109,6 +114,12 @@
// Mount point for this image. Default is "/"
Mount_point *string
+
+ // If set to the name of a partition ("system", "vendor", etc), this filesystem module
+ // will also include the contents of the make-built staging directories. If any soong
+ // modules would be installed to the same location as a make module, they will overwrite
+ // the make version.
+ Include_make_built_files string
}
// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
@@ -168,6 +179,9 @@
var pctx = android.NewPackageContext("android/soong/filesystem")
func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if !android.InList(f.PartitionType(), validPartitions) {
+ ctx.PropertyErrorf("partition_type", "partition_type must be one of %s, found: %s", validPartitions, f.PartitionType())
+ }
switch f.fsType(ctx) {
case ext4Type:
f.output = f.buildImageUsingBuildImage(ctx)
@@ -183,13 +197,9 @@
ctx.InstallFile(f.installDir, f.installFileName(), f.output)
}
-// root zip will contain extra files/dirs that are not from the `deps` property.
-func (f *filesystem) buildRootZip(ctx android.ModuleContext) android.OutputPath {
- rootDir := android.PathForModuleGen(ctx, "root").OutputPath
- builder := android.NewRuleBuilder(pctx, ctx)
- builder.Command().Text("rm -rf").Text(rootDir.String())
- builder.Command().Text("mkdir -p").Text(rootDir.String())
-
+// Copy extra files/dirs that are not from the `deps` property to `rootDir`, checking for conflicts with files
+// already in `rootDir`.
+func (f *filesystem) buildNonDepsFiles(ctx android.ModuleContext, builder *android.RuleBuilder, rootDir android.OutputPath) {
// create dirs and symlinks
for _, dir := range f.properties.Dirs {
// OutputPath.Join verifies dir
@@ -212,65 +222,43 @@
// OutputPath.Join verifies name. don't need to verify target.
dst := rootDir.Join(ctx, name)
-
+ builder.Command().Textf("(! [ -e %s -o -L %s ] || (echo \"%s already exists from an earlier stage of the build\" && exit 1))", dst, dst, dst)
builder.Command().Text("mkdir -p").Text(filepath.Dir(dst.String()))
builder.Command().Text("ln -sf").Text(proptools.ShellEscape(target)).Text(dst.String())
}
// create extra files if there's any
- rootForExtraFiles := android.PathForModuleGen(ctx, "root-extra").OutputPath
- var extraFiles android.OutputPaths
if f.buildExtraFiles != nil {
- extraFiles = f.buildExtraFiles(ctx, rootForExtraFiles)
+ rootForExtraFiles := android.PathForModuleGen(ctx, "root-extra").OutputPath
+ extraFiles := f.buildExtraFiles(ctx, rootForExtraFiles)
for _, f := range extraFiles {
- rel, _ := filepath.Rel(rootForExtraFiles.String(), f.String())
- if strings.HasPrefix(rel, "..") {
- panic(fmt.Errorf("%q is not under %q\n", f, rootForExtraFiles))
+ rel, err := filepath.Rel(rootForExtraFiles.String(), f.String())
+ if err != nil || strings.HasPrefix(rel, "..") {
+ ctx.ModuleErrorf("can't make %q relative to %q", f, rootForExtraFiles)
}
}
- }
-
- // Zip them all
- zipOut := android.PathForModuleGen(ctx, "root.zip").OutputPath
- zipCommand := builder.Command().BuiltTool("soong_zip")
- zipCommand.FlagWithOutput("-o ", zipOut).
- FlagWithArg("-C ", rootDir.String()).
- Flag("-L 0"). // no compression because this will be unzipped soon
- FlagWithArg("-D ", rootDir.String()).
- Flag("-d") // include empty directories
- if len(extraFiles) > 0 {
- zipCommand.FlagWithArg("-C ", rootForExtraFiles.String())
- for _, f := range extraFiles {
- zipCommand.FlagWithInput("-f ", f)
+ if len(extraFiles) > 0 {
+ builder.Command().BuiltTool("merge_directories").
+ Implicits(extraFiles.Paths()).
+ Text(rootDir.String()).
+ Text(rootForExtraFiles.String())
}
}
-
- builder.Command().Text("rm -rf").Text(rootDir.String())
-
- builder.Build("zip_root", fmt.Sprintf("zipping root contents for %s", ctx.ModuleName()))
- return zipOut
}
func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) android.OutputPath {
- depsZipFile := android.PathForModuleOut(ctx, "deps.zip").OutputPath
- f.entries = f.CopyDepsToZip(ctx, f.gatherFilteredPackagingSpecs(ctx), depsZipFile)
-
- builder := android.NewRuleBuilder(pctx, ctx)
- depsBase := proptools.StringDefault(f.properties.Base_dir, ".")
- rebasedDepsZip := android.PathForModuleOut(ctx, "rebased_deps.zip").OutputPath
- builder.Command().
- BuiltTool("zip2zip").
- FlagWithInput("-i ", depsZipFile).
- FlagWithOutput("-o ", rebasedDepsZip).
- Text("**/*:" + proptools.ShellEscape(depsBase)) // zip2zip verifies depsBase
-
rootDir := android.PathForModuleOut(ctx, "root").OutputPath
- rootZip := f.buildRootZip(ctx)
- builder.Command().
- BuiltTool("zipsync").
- FlagWithArg("-d ", rootDir.String()). // zipsync wipes this. No need to clear.
- Input(rootZip).
- Input(rebasedDepsZip)
+ rebasedDir := rootDir
+ if f.properties.Base_dir != nil {
+ rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
+ }
+ builder := android.NewRuleBuilder(pctx, ctx)
+ // Wipe the root dir to get rid of leftover files from prior builds
+ builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
+ f.entries = f.CopySpecsToDir(ctx, builder, f.gatherFilteredPackagingSpecs(ctx), rebasedDir)
+
+ f.buildNonDepsFiles(ctx, builder, rootDir)
+ f.addMakeBuiltFiles(ctx, builder, rootDir)
// run host_init_verifier
// Ideally we should have a concept of pluggable linters that verify the generated image.
@@ -388,25 +376,21 @@
ctx.PropertyErrorf("file_contexts", "file_contexts is not supported for compressed cpio image.")
}
- depsZipFile := android.PathForModuleOut(ctx, "deps.zip").OutputPath
- f.entries = f.CopyDepsToZip(ctx, f.gatherFilteredPackagingSpecs(ctx), depsZipFile)
-
- builder := android.NewRuleBuilder(pctx, ctx)
- depsBase := proptools.StringDefault(f.properties.Base_dir, ".")
- rebasedDepsZip := android.PathForModuleOut(ctx, "rebased_deps.zip").OutputPath
- builder.Command().
- BuiltTool("zip2zip").
- FlagWithInput("-i ", depsZipFile).
- FlagWithOutput("-o ", rebasedDepsZip).
- Text("**/*:" + proptools.ShellEscape(depsBase)) // zip2zip verifies depsBase
+ if f.properties.Include_make_built_files != "" {
+ ctx.PropertyErrorf("include_make_built_files", "include_make_built_files is not supported for compressed cpio image.")
+ }
rootDir := android.PathForModuleOut(ctx, "root").OutputPath
- rootZip := f.buildRootZip(ctx)
- builder.Command().
- BuiltTool("zipsync").
- FlagWithArg("-d ", rootDir.String()). // zipsync wipes this. No need to clear.
- Input(rootZip).
- Input(rebasedDepsZip)
+ rebasedDir := rootDir
+ if f.properties.Base_dir != nil {
+ rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
+ }
+ builder := android.NewRuleBuilder(pctx, ctx)
+ // Wipe the root dir to get rid of leftover files from prior builds
+ builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
+ f.entries = f.CopySpecsToDir(ctx, builder, f.gatherFilteredPackagingSpecs(ctx), rebasedDir)
+
+ f.buildNonDepsFiles(ctx, builder, rootDir)
output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
cmd := builder.Command().
@@ -429,6 +413,45 @@
return output
}
+var validPartitions = []string{
+ "system",
+ "userdata",
+ "cache",
+ "system_other",
+ "vendor",
+ "product",
+ "system_ext",
+ "odm",
+ "vendor_dlkm",
+ "odm_dlkm",
+ "system_dlkm",
+}
+
+func (f *filesystem) addMakeBuiltFiles(ctx android.ModuleContext, builder *android.RuleBuilder, rootDir android.Path) {
+ partition := f.properties.Include_make_built_files
+ if partition == "" {
+ return
+ }
+ if !slices.Contains(validPartitions, partition) {
+ ctx.PropertyErrorf("include_make_built_files", "Expected one of %#v, found %q", validPartitions, partition)
+ return
+ }
+ stampFile := fmt.Sprintf("target/product/%s/obj/PACKAGING/%s_intermediates/staging_dir.stamp", ctx.Config().DeviceName(), partition)
+ fileListFile := fmt.Sprintf("target/product/%s/obj/PACKAGING/%s_intermediates/file_list.txt", ctx.Config().DeviceName(), partition)
+ stagingDir := fmt.Sprintf("target/product/%s/%s", ctx.Config().DeviceName(), partition)
+
+ builder.Command().BuiltTool("merge_directories").
+ Implicit(android.PathForArbitraryOutput(ctx, stampFile)).
+ Text("--ignore-duplicates").
+ FlagWithInput("--file-list", android.PathForArbitraryOutput(ctx, fileListFile)).
+ Text(rootDir.String()).
+ Text(android.PathForArbitraryOutput(ctx, stagingDir).String())
+}
+
+func (f *filesystem) PartitionType() string {
+ return proptools.StringDefault(f.properties.Partition_type, "system")
+}
+
var _ android.AndroidMkEntriesProvider = (*filesystem)(nil)
// Implements android.AndroidMkEntriesProvider
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index c448105..74c79e3 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -16,6 +16,7 @@
import (
"os"
+ "path/filepath"
"testing"
"android/soong/android"
@@ -75,6 +76,11 @@
cc_library {
name: "libbar",
+ required: ["libbaz"],
+ }
+
+ cc_library {
+ name: "libbaz",
}
`)
@@ -86,6 +92,7 @@
"bin/foo",
"lib/libbar.so",
"lib64/libbar.so",
+ "lib64/libbaz.so",
"etc/bpf/bpf.o",
}
for _, e := range expected {
@@ -93,6 +100,22 @@
}
}
+func TestIncludeMakeBuiltFiles(t *testing.T) {
+ result := fixture.RunTestWithBp(t, `
+ android_filesystem {
+ name: "myfilesystem",
+ include_make_built_files: "system",
+ }
+ `)
+
+ output := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img")
+
+ stampFile := filepath.Join(result.Config.OutDir(), "target/product/test_device/obj/PACKAGING/system_intermediates/staging_dir.stamp")
+ fileListFile := filepath.Join(result.Config.OutDir(), "target/product/test_device/obj/PACKAGING/system_intermediates/file_list.txt")
+ android.AssertStringListContains(t, "deps of filesystem must include the staging dir stamp file", output.Implicits.Strings(), stampFile)
+ android.AssertStringListContains(t, "deps of filesystem must include the staging dir file list", output.Implicits.Strings(), fileListFile)
+}
+
func TestFileSystemFillsLinkerConfigWithStubLibs(t *testing.T) {
result := fixture.RunTestWithBp(t, `
android_system_image {
@@ -270,7 +293,7 @@
}
`)
- inputs := result.ModuleForTests("myfilesystem", "android_common").Output("deps.zip").Implicits
+ inputs := result.ModuleForTests("myfilesystem", "android_common").Output("myfilesystem.img").Implicits
android.AssertStringListContains(t, "filesystem should have libbar even for unbundled build",
inputs.Strings(),
"out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so")
@@ -314,7 +337,7 @@
`)
filesystem := result.ModuleForTests("myfilesystem", "android_common_cov")
- inputs := filesystem.Output("deps.zip").Implicits
+ inputs := filesystem.Output("myfilesystem.img").Implicits
android.AssertStringListContains(t, "filesystem should have libfoo(cov)",
inputs.Strings(),
"out/soong/.intermediates/libfoo/android_arm64_armv8-a_shared_cov/libfoo.so")
diff --git a/filesystem/system_image.go b/filesystem/system_image.go
index 34f4ffb..5028a49 100644
--- a/filesystem/system_image.go
+++ b/filesystem/system_image.go
@@ -43,6 +43,9 @@
}
func (s *systemImage) buildExtraFiles(ctx android.ModuleContext, root android.OutputPath) android.OutputPaths {
+ if s.filesystem.properties.Partition_type != nil {
+ ctx.PropertyErrorf("partition_type", "partition_type must be unset on an android_system_image module. It is assumed to be 'system'.")
+ }
lc := s.buildLinkerConfigFile(ctx, root)
// Add more files if needed
return []android.OutputPath{lc}
@@ -53,19 +56,40 @@
output := root.Join(ctx, "system", "etc", "linker.config.pb")
// we need "Module"s for packaging items
- var otherModules []android.Module
+ modulesInPackageByModule := make(map[android.Module]bool)
+ modulesInPackageByName := make(map[string]bool)
+
deps := s.gatherFilteredPackagingSpecs(ctx)
ctx.WalkDeps(func(child, parent android.Module) bool {
for _, ps := range child.PackagingSpecs() {
if _, ok := deps[ps.RelPathInPackage()]; ok {
- otherModules = append(otherModules, child)
+ modulesInPackageByModule[child] = true
+ modulesInPackageByName[child.Name()] = true
+ return true
}
}
return true
})
+ provideModules := make([]android.Module, 0, len(modulesInPackageByModule))
+ for mod := range modulesInPackageByModule {
+ provideModules = append(provideModules, mod)
+ }
+
+ var requireModules []android.Module
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ _, parentInPackage := modulesInPackageByModule[parent]
+ _, childInPackageName := modulesInPackageByName[child.Name()]
+
+ // When parent is in the package, and child (or its variant) is not, this can be from an interface.
+ if parentInPackage && !childInPackageName {
+ requireModules = append(requireModules, child)
+ }
+ return true
+ })
+
builder := android.NewRuleBuilder(pctx, ctx)
- linkerconfig.BuildLinkerConfig(ctx, builder, input, otherModules, output)
+ linkerconfig.BuildLinkerConfig(ctx, builder, input, provideModules, requireModules, output)
builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String())
return output
}
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index 60b1366..7c71b77 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -21,9 +21,4 @@
"com.google.pixel.camera.hal.manifest",
// go/keep-sorted end
}
-
- SandboxingDenyPathList = []string{
- // go/keep-sorted start
- // go/keep-sorted end
- }
)
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 6f66088..43f4fe5 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -317,7 +317,17 @@
// required relative locations of the tool and its dependencies, use those
// instead. They will be copied to those relative locations in the sbox
// sandbox.
- packagedTools = append(packagedTools, specs...)
+ // Care must be taken since TransitivePackagingSpec may return device-side
+ // paths via the required property. Filter them out.
+ for i, ps := range specs {
+ if ps.Partition() != "" {
+ if i == 0 {
+ panic("first PackagingSpec is assumed to be the host-side tool")
+ }
+ continue
+ }
+ packagedTools = append(packagedTools, ps)
+ }
// Assume that the first PackagingSpec of the module is the tool.
addLocationLabel(tag.label, packagedToolLocation{specs[0]})
} else {
@@ -808,7 +818,7 @@
type genRuleProperties struct {
// names of the output files that will be generated
- Out []string
+ Out []string `android:"arch_variant"`
}
var Bool = proptools.Bool
@@ -842,19 +852,15 @@
type sandboxingAllowlistSets struct {
sandboxingDenyModuleSet map[string]bool
- sandboxingDenyPathSet map[string]bool
}
func getSandboxingAllowlistSets(ctx android.PathContext) *sandboxingAllowlistSets {
return ctx.Config().Once(sandboxingAllowlistKey, func() interface{} {
sandboxingDenyModuleSet := map[string]bool{}
- sandboxingDenyPathSet := map[string]bool{}
android.AddToStringSet(sandboxingDenyModuleSet, SandboxingDenyModuleList)
- android.AddToStringSet(sandboxingDenyPathSet, SandboxingDenyPathList)
return &sandboxingAllowlistSets{
sandboxingDenyModuleSet: sandboxingDenyModuleSet,
- sandboxingDenyPathSet: sandboxingDenyPathSet,
}
}).(*sandboxingAllowlistSets)
}
@@ -864,8 +870,7 @@
return r.SandboxTools()
}
sandboxingAllowlistSets := getSandboxingAllowlistSets(ctx)
- if sandboxingAllowlistSets.sandboxingDenyPathSet[ctx.ModuleDir()] ||
- sandboxingAllowlistSets.sandboxingDenyModuleSet[ctx.ModuleName()] {
+ if sandboxingAllowlistSets.sandboxingDenyModuleSet[ctx.ModuleName()] {
return r.SandboxTools()
}
return r.SandboxInputs()
diff --git a/java/aar.go b/java/aar.go
index 27dd38b..1734da9 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -104,6 +104,9 @@
// Filter only specified product and ignore other products
Filter_product *string `blueprint:"mutated"`
+
+ // Names of aconfig_declarations modules that specify aconfig flags that the module depends on.
+ Flags_packages []string
}
type aapt struct {
@@ -348,6 +351,7 @@
classLoaderContexts dexpreopt.ClassLoaderContextMap
excludedLibs []string
enforceDefaultTargetSdkVersion bool
+ forceNonFinalResourceIDs bool
extraLinkFlags []string
aconfigTextFiles android.Paths
}
@@ -383,11 +387,6 @@
// Add additional manifest files to transitive manifests.
additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
- // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
- // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
- // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
- // android_library_import modules. If this is fixed, staticManifestsDepSet can be dropped completely in favor of
- // staticResourcesNodesDepSet.manifests()
transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
@@ -541,7 +540,8 @@
if a.useResourceProcessorBusyBox(ctx) {
rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
- resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags)
+ resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags,
+ opts.forceNonFinalResourceIDs)
aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
transitiveRJars = append(transitiveRJars, rJar)
a.rJar = rJar
@@ -605,7 +605,8 @@
// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
// supports producing classes for static dependencies that only include resources from that dependency.
func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
- rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool, aaptFlags []string) {
+ rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool, aaptFlags []string,
+ forceNonFinalIds bool) {
var args []string
var deps android.Paths
@@ -615,6 +616,9 @@
// to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
// package.
args, deps = transitiveDeps.resourceProcessorDeps()
+ if forceNonFinalIds {
+ args = append(args, "--finalFields=false")
+ }
} else {
// When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
// library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
@@ -754,7 +758,8 @@
// reverse later.
// NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
// dependencies) the highest priority dependency is listed first, but for resources the highest priority
- // dependency has to be listed last.
+ // dependency has to be listed last. This is also inconsistent with the way manifests from the same
+ // transitive dependencies are merged.
staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
android.ReverseSliceInPlace(staticResourcesNodeDepSets))
sharedResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
@@ -804,6 +809,10 @@
a.aapt.deps(ctx, sdkDep)
}
a.usesLibrary.deps(ctx, false)
+
+ for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
+ ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
+ }
}
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -817,13 +826,14 @@
sdkContext: android.SdkContext(a),
classLoaderContexts: a.classLoaderContexts,
enforceDefaultTargetSdkVersion: false,
+ aconfigTextFiles: getAconfigFilePaths(ctx),
},
)
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
a.hideApexVariantFromMake = !apexInfo.IsForPlatform()
- a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
+ a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
ctx.CheckbuildFile(a.aapt.exportPackage)
@@ -964,7 +974,8 @@
properties AARImportProperties
- classpathFile android.WritablePath
+ headerJarFile android.WritablePath
+ implementationJarFile android.WritablePath
proguardFlags android.WritablePath
exportPackage android.WritablePath
transitiveAaptResourcePackagesFile android.Path
@@ -985,6 +996,9 @@
sdkVersion android.SdkSpec
minSdkVersion android.ApiLevel
+ usesLibrary
+ classLoaderContexts dexpreopt.ClassLoaderContextMap
+
// Single aconfig "cache file" merged from this module and all dependencies.
mergedAconfigFiles map[string]android.Paths
}
@@ -997,7 +1011,7 @@
case ".aar":
return []android.Path{a.aarPath}, nil
case "":
- return []android.Path{a.classpathFile}, nil
+ return []android.Path{a.implementationJarFile}, nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -1080,6 +1094,8 @@
ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
+
+ a.usesLibrary.deps(ctx, false)
}
type JniPackageInfo struct {
@@ -1138,7 +1154,7 @@
}
extractedAARDir := android.PathForModuleOut(ctx, "aar")
- a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
+ classpathFile := extractedAARDir.Join(ctx, "classes-combined.jar")
a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
a.rTxt = extractedAARDir.Join(ctx, "R.txt")
a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
@@ -1154,11 +1170,11 @@
ctx.Build(pctx, android.BuildParams{
Rule: unzipAAR,
Input: a.aarPath,
- Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt},
+ Outputs: android.WritablePaths{classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt},
Description: "unzip AAR",
Args: map[string]string{
"outDir": extractedAARDir.String(),
- "combinedClassesJar": a.classpathFile.String(),
+ "combinedClassesJar": classpathFile.String(),
"assetsPackage": a.assetsPackage.String(),
},
})
@@ -1213,7 +1229,7 @@
linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)
a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
- resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true, nil)
+ resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true, nil, false)
aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
@@ -1231,13 +1247,7 @@
a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
- // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
- // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
- // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
- // android_library_import modules. If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped
- // completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest
- //manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests)
- _ = staticManifestsDepSet
+ manifestDepSetBuilder.Transitive(staticManifestsDepSet)
a.manifestsDepSet = manifestDepSetBuilder.Build()
transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
@@ -1249,12 +1259,45 @@
a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
a.collectTransitiveHeaderJars(ctx)
+
+ a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
+
+ var staticJars android.Paths
+ var staticHeaderJars android.Paths
+ ctx.VisitDirectDeps(func(module android.Module) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
+ tag := ctx.OtherModuleDependencyTag(module)
+ switch tag {
+ case staticLibTag:
+ staticJars = append(staticJars, dep.ImplementationJars...)
+ staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
+ }
+ }
+ addCLCFromDep(ctx, module, a.classLoaderContexts)
+ })
+
+ if len(staticJars) > 0 {
+ combineJars := append(android.Paths{classpathFile}, staticJars...)
+ a.implementationJarFile = android.PathForModuleOut(ctx, "combined", ctx.ModuleName()+".jar")
+ TransformJarsToJar(ctx, a.implementationJarFile, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
+ } else {
+ a.implementationJarFile = classpathFile
+ }
+
+ if len(staticHeaderJars) > 0 {
+ combineJars := append(android.Paths{classpathFile}, staticHeaderJars...)
+ a.headerJarFile = android.PathForModuleOut(ctx, "turbine-combined", ctx.ModuleName()+".jar")
+ TransformJarsToJar(ctx, a.headerJarFile, "combine header jars", combineJars, android.OptionalPath{}, false, nil, nil)
+ } else {
+ a.headerJarFile = classpathFile
+ }
+
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
- HeaderJars: android.PathsIfNonNil(a.classpathFile),
+ HeaderJars: android.PathsIfNonNil(a.headerJarFile),
TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars,
TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
- ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
- ImplementationJars: android.PathsIfNonNil(a.classpathFile),
+ ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationJarFile),
+ ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
@@ -1287,15 +1330,15 @@
}
func (a *AARImport) HeaderJars() android.Paths {
- return android.Paths{a.classpathFile}
+ return android.Paths{a.headerJarFile}
}
func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
- return android.Paths{a.classpathFile}
+ return android.Paths{a.implementationJarFile}
}
-func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) android.Path {
- return nil
+func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
+ return OptionalDexJarPath{}
}
func (a *AARImport) DexJarInstallPath() android.Path {
@@ -1303,9 +1346,11 @@
}
func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
- return nil
+ return a.classLoaderContexts
}
+var _ UsesLibraryDependency = (*AARImport)(nil)
+
var _ android.ApexModule = (*AARImport)(nil)
// Implements android.ApexModule
@@ -1314,7 +1359,7 @@
}
// Implements android.ApexModule
-func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
+func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
return nil
}
@@ -1328,7 +1373,10 @@
func AARImportFactory() android.Module {
module := &AARImport{}
- module.AddProperties(&module.properties)
+ module.AddProperties(
+ &module.properties,
+ &module.usesLibrary.usesLibraryProperties,
+ )
android.InitPrebuiltModule(module, &module.properties.Aars)
android.InitApexModule(module)
diff --git a/java/aar_test.go b/java/aar_test.go
index 4d4e5d0..6bd53f2 100644
--- a/java/aar_test.go
+++ b/java/aar_test.go
@@ -81,3 +81,50 @@
})
}
}
+
+func TestLibraryFlagsPackages(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ android_library {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ flags_packages: [
+ "bar",
+ "baz",
+ ],
+ }
+ aconfig_declarations {
+ name: "bar",
+ package: "com.example.package.bar",
+ srcs: [
+ "bar.aconfig",
+ ],
+ }
+ aconfig_declarations {
+ name: "baz",
+ package: "com.example.package.baz",
+ srcs: [
+ "baz.aconfig",
+ ],
+ }
+ `)
+
+ foo := result.ModuleForTests("foo", "android_common")
+
+ // android_library module depends on aconfig_declarations listed in flags_packages
+ android.AssertBoolEquals(t, "foo expected to depend on bar", true,
+ CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"))
+
+ android.AssertBoolEquals(t, "foo expected to depend on baz", true,
+ CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "baz"))
+
+ aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
+ linkInFlags := aapt2LinkRule.Args["inFlags"]
+ android.AssertStringDoesContain(t,
+ "aapt2 link command expected to pass feature flags arguments",
+ linkInFlags,
+ "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ )
+}
diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go
index 5909b1e..7c91884 100644
--- a/java/android_manifest_test.go
+++ b/java/android_manifest_test.go
@@ -92,10 +92,9 @@
"out/soong/.intermediates/transitive/android_common/manifest_fixer/AndroidManifest.xml",
"transitive/AndroidManifest2.xml",
"out/soong/.intermediates/transitive_import/android_common/aar/AndroidManifest.xml",
+ "out/soong/.intermediates/transitive_import_dep/android_common/aar/AndroidManifest.xml",
"out/soong/.intermediates/direct_import/android_common/aar/AndroidManifest.xml",
- // TODO(b/288358614): Soong has historically not merged manifests from dependencies of
- // android_library_import modules.
-
+ "out/soong/.intermediates/direct_import_dep/android_common/aar/AndroidManifest.xml",
},
manifestMergerRule.Implicits)
}
diff --git a/java/androidmk.go b/java/androidmk.go
index 498962f..a52d439 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -211,7 +211,7 @@
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
OverrideName: prebuilt.BaseModuleName(),
- OutputFile: android.OptionalPathForPath(prebuilt.combinedClasspathFile),
+ OutputFile: android.OptionalPathForPath(prebuilt.combinedImplementationFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
@@ -219,8 +219,8 @@
if prebuilt.dexJarFile.IsSet() {
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path())
}
- entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile)
- entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile)
+ entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedHeaderFile)
+ entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedImplementationFile)
entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String())
entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem())
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
@@ -262,13 +262,13 @@
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
- OutputFile: android.OptionalPathForPath(prebuilt.classpathFile),
+ OutputFile: android.OptionalPathForPath(prebuilt.implementationJarFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
- entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.classpathFile)
- entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.classpathFile)
+ entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.headerJarFile)
+ entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.implementationJarFile)
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", prebuilt.exportPackage)
entries.SetPath("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", prebuilt.transitiveAaptResourcePackagesFile)
entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags)
diff --git a/java/app.go b/java/app.go
index 4f6f1f3..2abc451 100755
--- a/java/app.go
+++ b/java/app.go
@@ -169,9 +169,6 @@
// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
// from PRODUCT_PACKAGES.
Overrides []string
-
- // Names of aconfig_declarations modules that specify aconfig flags that the app depends on.
- Flags_packages []string
}
type AndroidApp struct {
@@ -290,6 +287,10 @@
}
a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
+
+ for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
+ ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
+ }
}
func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
@@ -317,10 +318,6 @@
`must be names of android_app_certificate modules in the form ":module"`)
}
}
-
- for _, aconfig_declaration := range a.overridableAppProperties.Flags_packages {
- ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
- }
}
func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -457,6 +454,21 @@
return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true)
}
+func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
+ ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) {
+ if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
+ aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
+ } else {
+ ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
+ "flags_packages property, but %s is not aconfig_declarations module type",
+ dep.Name(),
+ )
+ }
+ })
+
+ return aconfigTextFilePaths
+}
+
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
usePlatformAPI := proptools.Bool(a.Module.deviceProperties.Platform_apis)
if ctx.Module().(android.SdkContext).SdkVersion(ctx).Kind == android.SdkModule {
@@ -507,26 +519,17 @@
a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
}
- var aconfigTextFilePaths android.Paths
- ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) {
- if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
- aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath)
- } else {
- ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+
- "flags_packages property, but %s is not aconfig_declarations module type",
- dep.Name(),
- )
- }
- })
-
+ // Use non final ids if we are doing optimized shrinking and are using R8.
+ nonFinalIds := Bool(a.dexProperties.Optimize.Optimized_shrink_resources) && a.dexer.effectiveOptimizeEnabled()
a.aapt.buildActions(ctx,
aaptBuildActionOptions{
sdkContext: android.SdkContext(a),
classLoaderContexts: a.classLoaderContexts,
excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
+ forceNonFinalResourceIDs: nonFinalIds,
extraLinkFlags: aaptLinkFlags,
- aconfigTextFiles: aconfigTextFilePaths,
+ aconfigTextFiles: getAconfigFilePaths(ctx),
},
)
@@ -547,7 +550,13 @@
staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
- a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
+ if !Bool(a.dexProperties.Optimize.Optimized_shrink_resources) {
+ // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
+ // live for code references and (transitively) mark these as live.
+ // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
+ // dead code alive)
+ a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
+ }
}
func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
@@ -580,7 +589,7 @@
var packageResources = a.exportPackage
if ctx.ModuleName() != "framework-res" {
- if Bool(a.dexProperties.Optimize.Shrink_resources) {
+ if a.dexProperties.resourceShrinkingEnabled() {
protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
aapt2Convert(ctx, protoFile, packageResources, "proto")
a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
@@ -603,7 +612,7 @@
}
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
- if Bool(a.dexProperties.Optimize.Shrink_resources) {
+ if a.dexProperties.resourceShrinkingEnabled() {
binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
packageResources = binaryResources
@@ -755,7 +764,7 @@
// Unlike installApkName, a.stem should respect base module name for override_android_app.
// Therefore, use ctx.ModuleName() instead of a.Name().
- a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
+ a.stem = proptools.StringDefault(a.overridableProperties.Stem, ctx.ModuleName())
// Check if the install APK name needs to be overridden.
// Both android_app and override_android_app module are expected to possess
@@ -763,7 +772,7 @@
// from the base module. Therefore, use a.Name() which represents
// the module name for both android_app and override_android_app.
a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(
- proptools.StringDefault(a.overridableDeviceProperties.Stem, a.Name()))
+ proptools.StringDefault(a.overridableProperties.Stem, a.Name()))
if ctx.ModuleName() == "framework-res" {
// framework-res.apk is installed as system/framework/framework-res.apk
@@ -1507,7 +1516,7 @@
func OverrideAndroidAppModuleFactory() android.Module {
m := &OverrideAndroidApp{}
m.AddProperties(
- &OverridableDeviceProperties{},
+ &OverridableProperties{},
&overridableAppProperties{},
)
diff --git a/java/app_test.go b/java/app_test.go
index 5d7b048..ca9d317 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -829,12 +829,12 @@
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
directResources: nil,
@@ -849,12 +849,12 @@
directClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -928,13 +928,13 @@
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
directResources: nil,
@@ -953,12 +953,12 @@
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -1034,13 +1034,13 @@
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/app/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
dontVerifyDirect: true,
@@ -1075,12 +1075,12 @@
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
directResources: nil,
@@ -1098,12 +1098,12 @@
"out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
},
dontVerifyTransitive: true,
@@ -1137,12 +1137,12 @@
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar",
"out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar",
},
appCombined: []string{
"out/soong/.intermediates/app/android_common/javac/app.jar",
"out/soong/.intermediates/direct/android_common/combined/direct.jar",
- "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar",
},
directResources: nil,
@@ -1157,12 +1157,12 @@
directClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar",
},
directCombined: []string{
"out/soong/.intermediates/direct/android_common/javac/direct.jar",
"out/soong/.intermediates/transitive/android_common/javac/transitive.jar",
- "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
+ "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar",
},
transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"},
@@ -4401,3 +4401,20 @@
dexpreopt := result.ModuleForTests("app", "android_common").MaybeRule("dexpreopt").Rule
android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil)
}
+
+func TestAppStem(t *testing.T) {
+ ctx := testApp(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ stem: "foo-new",
+ sdk_version: "current",
+ }`)
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ outputs := fmt.Sprint(foo.AllOutputs())
+ if !strings.Contains(outputs, "foo-new.apk") {
+ t.Errorf("Module output does not contain expected apk %s", "foo-new.apk")
+ }
+}
diff --git a/java/base.go b/java/base.go
index 69f88be..be286fe 100644
--- a/java/base.go
+++ b/java/base.go
@@ -305,8 +305,8 @@
HiddenAPIFlagFileProperties
}
-// Device properties that can be overridden by overriding module (e.g. override_android_app)
-type OverridableDeviceProperties struct {
+// Properties that can be overridden by overriding module (e.g. override_android_app)
+type OverridableProperties struct {
// set the name of the output. If not set, `name` is used.
// To override a module with this property set, overriding module might need to set this as well.
// Otherwise, both the overridden and the overriding modules will have the same output name, which
@@ -434,7 +434,7 @@
protoProperties android.ProtoProperties
deviceProperties DeviceProperties
- overridableDeviceProperties OverridableDeviceProperties
+ overridableProperties OverridableProperties
// jar file containing header classes including static library dependencies, suitable for
// inserting into the bootclasspath/classpath of another compile
@@ -616,6 +616,7 @@
func (j *Module) addHostProperties() {
j.AddProperties(
&j.properties,
+ &j.overridableProperties,
&j.protoProperties,
&j.usesLibraryProperties,
)
@@ -625,7 +626,6 @@
j.addHostProperties()
j.AddProperties(
&j.deviceProperties,
- &j.overridableDeviceProperties,
&j.dexer.dexProperties,
&j.dexpreoptProperties,
&j.linter.properties,
@@ -1219,14 +1219,15 @@
}
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
- HeaderJars: android.PathsIfNonNil(j.headerJarFile),
- TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
- TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
- AidlIncludeDirs: j.exportAidlIncludeDirs,
- ExportedPlugins: j.exportedPluginJars,
- ExportedPluginClasses: j.exportedPluginClasses,
- ExportedPluginDisableTurbine: j.exportedDisableTurbine,
- StubsLinkType: j.stubsLinkType,
+ HeaderJars: android.PathsIfNonNil(j.headerJarFile),
+ TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
+ TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
+ AidlIncludeDirs: j.exportAidlIncludeDirs,
+ ExportedPlugins: j.exportedPluginJars,
+ ExportedPluginClasses: j.exportedPluginClasses,
+ ExportedPluginDisableTurbine: j.exportedDisableTurbine,
+ StubsLinkType: j.stubsLinkType,
+ AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
})
j.outputFile = j.headerJarFile
@@ -1729,22 +1730,23 @@
android.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles)
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
- HeaderJars: android.PathsIfNonNil(j.headerJarFile),
- RepackagedHeaderJars: android.PathsIfNonNil(j.repackagedHeaderJarFile),
- TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
- TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
- ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
- ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
- ResourceJars: android.PathsIfNonNil(j.resourceJar),
- AidlIncludeDirs: j.exportAidlIncludeDirs,
- SrcJarArgs: j.srcJarArgs,
- SrcJarDeps: j.srcJarDeps,
- TransitiveSrcFiles: j.transitiveSrcFiles,
- ExportedPlugins: j.exportedPluginJars,
- ExportedPluginClasses: j.exportedPluginClasses,
- ExportedPluginDisableTurbine: j.exportedDisableTurbine,
- JacocoReportClassesFile: j.jacocoReportClassesFile,
- StubsLinkType: j.stubsLinkType,
+ HeaderJars: android.PathsIfNonNil(j.headerJarFile),
+ RepackagedHeaderJars: android.PathsIfNonNil(j.repackagedHeaderJarFile),
+ TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
+ TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
+ ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
+ ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
+ ResourceJars: android.PathsIfNonNil(j.resourceJar),
+ AidlIncludeDirs: j.exportAidlIncludeDirs,
+ SrcJarArgs: j.srcJarArgs,
+ SrcJarDeps: j.srcJarDeps,
+ TransitiveSrcFiles: j.transitiveSrcFiles,
+ ExportedPlugins: j.exportedPluginJars,
+ ExportedPluginClasses: j.exportedPluginClasses,
+ ExportedPluginDisableTurbine: j.exportedDisableTurbine,
+ JacocoReportClassesFile: j.jacocoReportClassesFile,
+ StubsLinkType: j.stubsLinkType,
+ AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -2295,6 +2297,7 @@
// annotation processor that generates API is incompatible with the turbine
// optimization.
deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
case pluginTag:
if plugin, ok := module.(*Plugin); ok {
if plugin.pluginProperties.Processor_class != nil {
@@ -2353,6 +2356,8 @@
deps.staticJars = append(deps.staticJars, dep.Srcs()...)
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
}
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
} else {
switch tag {
case bootClasspathTag:
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 7c45d30..cc3da76 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -77,7 +77,7 @@
return javaSdkLibrarySdkMemberType
}
- return javaBootLibsSdkMemberType
+ return JavaBootLibsSdkMemberType
}
func (b bootclasspathFragmentContentDependencyTag) ExportMember() bool {
diff --git a/java/dex.go b/java/dex.go
index 4474c63..6caaa7f 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -66,6 +66,12 @@
// If true, optimize for size by removing unused resources. Defaults to false.
Shrink_resources *bool
+ // If true, use optimized resource shrinking in R8, overriding the
+ // Shrink_resources setting. Defaults to false.
+ // Optimized shrinking means that R8 will trace and treeshake resources together with code
+ // and apply additional optimizations. This implies non final fields in the R classes.
+ Optimized_shrink_resources *bool
+
// Flags to pass to proguard.
Proguard_flags []string
@@ -105,6 +111,10 @@
return BoolDefault(d.dexProperties.Optimize.Enabled, d.dexProperties.Optimize.EnabledByDefault)
}
+func (d *DexProperties) resourceShrinkingEnabled() bool {
+ return BoolDefault(d.Optimize.Optimized_shrink_resources, Bool(d.Optimize.Shrink_resources))
+}
+
var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -351,10 +361,14 @@
r8Flags = append(r8Flags, "-ignorewarnings")
}
+ // resourcesInput is empty when we don't use resource shrinking, if on, pass these to R8
if d.resourcesInput.Valid() {
r8Flags = append(r8Flags, "--resource-input", d.resourcesInput.Path().String())
r8Deps = append(r8Deps, d.resourcesInput.Path())
r8Flags = append(r8Flags, "--resource-output", d.resourcesOutput.Path().String())
+ if Bool(opt.Optimized_shrink_resources) {
+ r8Flags = append(r8Flags, "--optimized-resource-shrinking")
+ }
}
return r8Flags, r8Deps
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 76c8d88..9556e95 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -368,7 +368,7 @@
ret, err = nil, fmt.Errorf("api file path not supported for the stub type %s", stubsType.String())
}
if ret == nil && err == nil {
- err = fmt.Errorf("stubs srcjar is null for the stub type %s", stubsType.String())
+ err = fmt.Errorf("api file is null for the stub type %s", stubsType.String())
}
return ret, err
}
@@ -478,34 +478,41 @@
}
func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath, stubsType StubsType, checkApi bool) {
- if checkApi || String(d.properties.Api_filename) != "" {
- filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
- uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
- cmd.FlagWithOutput("--api ", uncheckedApiFile)
+ apiFileName := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt")
+ uncheckedApiFile := android.PathForModuleOut(ctx, stubsType.String(), apiFileName)
+ cmd.FlagWithOutput("--api ", uncheckedApiFile)
+ if checkApi || String(d.properties.Api_filename) != "" {
if stubsType == Everything {
d.apiFile = uncheckedApiFile
} else if stubsType == Exportable {
d.exportableApiFile = uncheckedApiFile
}
} else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" {
- // If check api is disabled then make the source file available for export.
- d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
+ if stubsType == Everything {
+ // If check api is disabled then make the source file available for export.
+ d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile)
+ } else if stubsType == Exportable {
+ d.exportableApiFile = uncheckedApiFile
+ }
}
+ removedApiFileName := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
+ uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), removedApiFileName)
+ cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
if checkApi || String(d.properties.Removed_api_filename) != "" {
- filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt")
- uncheckedRemovedFile := android.PathForModuleOut(ctx, stubsType.String(), filename)
- cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile)
-
if stubsType == Everything {
d.removedApiFile = uncheckedRemovedFile
} else if stubsType == Exportable {
d.exportableRemovedApiFile = uncheckedRemovedFile
}
} else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" {
- // If check api is disabled then make the source removed api file available for export.
- d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
+ if stubsType == Everything {
+ // If check api is disabled then make the source removed api file available for export.
+ d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile)
+ } else if stubsType == Exportable {
+ d.exportableRemovedApiFile = uncheckedRemovedFile
+ }
}
if stubsDir.Valid() {
diff --git a/java/java.go b/java/java.go
index e606993..72536cd 100644
--- a/java/java.go
+++ b/java/java.go
@@ -21,6 +21,7 @@
import (
"fmt"
"path/filepath"
+ "slices"
"sort"
"strings"
@@ -82,8 +83,8 @@
// Register sdk member types.
android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
android.RegisterSdkMemberType(javaLibsSdkMemberType)
- android.RegisterSdkMemberType(javaBootLibsSdkMemberType)
- android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType)
+ android.RegisterSdkMemberType(JavaBootLibsSdkMemberType)
+ android.RegisterSdkMemberType(JavaSystemserverLibsSdkMemberType)
android.RegisterSdkMemberType(javaTestSdkMemberType)
}
@@ -154,7 +155,7 @@
// either java_libs, or java_header_libs would end up exporting more information than was strictly
// necessary. The java_boot_libs property to allow those modules to be exported as part of the
// sdk/module_exports without exposing any unnecessary information.
- javaBootLibsSdkMemberType = &librarySdkMemberType{
+ JavaBootLibsSdkMemberType = &librarySdkMemberType{
android.SdkMemberTypeBase{
PropertyName: "java_boot_libs",
SupportsSdk: true,
@@ -193,7 +194,7 @@
// either java_libs, or java_header_libs would end up exporting more information than was strictly
// necessary. The java_systemserver_libs property to allow those modules to be exported as part of
// the sdk/module_exports without exposing any unnecessary information.
- javaSystemserverLibsSdkMemberType = &librarySdkMemberType{
+ JavaSystemserverLibsSdkMemberType = &librarySdkMemberType{
android.SdkMemberTypeBase{
PropertyName: "java_systemserver_libs",
SupportsSdk: true,
@@ -309,6 +310,10 @@
// implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
// and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...)
StubsLinkType StubsLinkType
+
+ // AconfigIntermediateCacheOutputPaths is a path to the cache files collected from the
+ // java_aconfig_library modules that are statically linked to this module.
+ AconfigIntermediateCacheOutputPaths android.Paths
}
var JavaInfoProvider = blueprint.NewProvider[JavaInfo]()
@@ -897,7 +902,7 @@
}
}
- j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
+ j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())
proguardSpecInfo := j.collectProguardSpecInfo(ctx)
android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo)
@@ -1694,7 +1699,7 @@
}
func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
+ j.stem = proptools.StringDefault(j.overridableProperties.Stem, ctx.ModuleName())
if ctx.Arch().ArchType == android.Common {
// Compile the jar
@@ -2333,6 +2338,9 @@
// List of shared java libs that this module has dependencies to
Libs []string
+ // List of static java libs that this module has dependencies to
+ Static_libs []string
+
// List of files to remove from the jar file(s)
Exclude_files []string
@@ -2385,9 +2393,10 @@
dexJarFileErr error
dexJarInstallFile android.Path
- combinedClasspathFile android.Path
- classLoaderContexts dexpreopt.ClassLoaderContextMap
- exportAidlIncludeDirs android.Paths
+ combinedImplementationFile android.Path
+ combinedHeaderFile android.Path
+ classLoaderContexts dexpreopt.ClassLoaderContextMap
+ exportAidlIncludeDirs android.Paths
hideApexVariantFromMake bool
@@ -2471,6 +2480,7 @@
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
+ ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
if ctx.Device() && Bool(j.dexProperties.Compile_dex) {
sdkDeps(ctx, android.SdkContext(j), j.dexer)
@@ -2500,23 +2510,13 @@
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.commonBuildActions(ctx)
- jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
-
- jarName := j.Stem() + ".jar"
- outputFile := android.PathForModuleOut(ctx, "combined", jarName)
- TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
- false, j.properties.Exclude_files, j.properties.Exclude_dirs)
- if Bool(j.properties.Jetifier) {
- inputFile := outputFile
- outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
- TransformJetifier(ctx, outputFile, inputFile)
- }
- j.combinedClasspathFile = outputFile
j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
var flags javaBuilderFlags
j.collectTransitiveHeaderJars(ctx)
+ var staticJars android.Paths
+ var staticHeaderJars android.Paths
ctx.VisitDirectDeps(func(module android.Module) {
tag := ctx.OtherModuleDependencyTag(module)
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
@@ -2526,6 +2526,8 @@
flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...)
case staticLibTag:
flags.classpath = append(flags.classpath, dep.HeaderJars...)
+ staticJars = append(staticJars, dep.ImplementationAndResourcesJars...)
+ staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
case bootClasspathTag:
flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)
}
@@ -2539,6 +2541,46 @@
addCLCFromDep(ctx, module, j.classLoaderContexts)
})
+ jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
+ jarName := j.Stem() + ".jar"
+
+ // Always pass the input jars to TransformJarsToJar, even if there is only a single jar, we need the output
+ // file of the module to be named jarName.
+ outputFile := android.PathForModuleOut(ctx, "combined", jarName)
+ implementationJars := append(slices.Clone(jars), staticJars...)
+ TransformJarsToJar(ctx, outputFile, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{},
+ false, j.properties.Exclude_files, j.properties.Exclude_dirs)
+
+ // If no dependencies have separate header jars then there is no need to create a separate
+ // header jar for this module.
+ reuseImplementationJarAsHeaderJar := slices.Equal(staticJars, staticHeaderJars)
+
+ var headerOutputFile android.WritablePath
+ if reuseImplementationJarAsHeaderJar {
+ headerOutputFile = outputFile
+ } else {
+ headerJars := append(slices.Clone(jars), staticHeaderJars...)
+ headerOutputFile = android.PathForModuleOut(ctx, "turbine-combined", jarName)
+ TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{},
+ false, j.properties.Exclude_files, j.properties.Exclude_dirs)
+ }
+
+ if Bool(j.properties.Jetifier) {
+ inputFile := outputFile
+ outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
+ TransformJetifier(ctx, outputFile, inputFile)
+
+ if !reuseImplementationJarAsHeaderJar {
+ headerInputFile := headerOutputFile
+ headerOutputFile = android.PathForModuleOut(ctx, "jetifier-headers", jarName)
+ TransformJetifier(ctx, headerOutputFile, headerInputFile)
+ } else {
+ headerOutputFile = outputFile
+ }
+ }
+ j.combinedHeaderFile = headerOutputFile
+ j.combinedImplementationFile = outputFile
+
j.maybeInstall(ctx, jarName, outputFile)
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
@@ -2622,11 +2664,11 @@
}
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
- HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile),
+ HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
- ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
- ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile),
+ ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile),
+ ImplementationJars: android.PathsIfNonNil(j.combinedImplementationFile),
AidlIncludeDirs: j.exportAidlIncludeDirs,
StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
@@ -2654,7 +2696,7 @@
func (j *Import) OutputFiles(tag string) (android.Paths, error) {
switch tag {
case "", ".jar":
- return android.Paths{j.combinedClasspathFile}, nil
+ return android.Paths{j.combinedImplementationFile}, nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -2663,17 +2705,11 @@
var _ android.OutputFileProducer = (*Import)(nil)
func (j *Import) HeaderJars() android.Paths {
- if j.combinedClasspathFile == nil {
- return nil
- }
- return android.Paths{j.combinedClasspathFile}
+ return android.PathsIfNonNil(j.combinedHeaderFile)
}
func (j *Import) ImplementationAndResourcesJars() android.Paths {
- if j.combinedClasspathFile == nil {
- return nil
- }
- return android.Paths{j.combinedClasspathFile}
+ return android.PathsIfNonNil(j.combinedImplementationFile)
}
func (j *Import) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
@@ -3005,7 +3041,7 @@
module.AddProperties(
&CommonProperties{},
&DeviceProperties{},
- &OverridableDeviceProperties{},
+ &OverridableProperties{},
&DexProperties{},
&DexpreoptProperties{},
&android.ProtoProperties{},
diff --git a/java/java_test.go b/java/java_test.go
index 2f3ccb9..2676aa5 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -588,10 +588,11 @@
javac := fooModule.Rule("javac")
combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
barModule := ctx.ModuleForTests("bar", "android_common")
- barJar := barModule.Rule("combineJar").Output
+ barJar := barModule.Output("combined/bar.jar").Output
bazModule := ctx.ModuleForTests("baz", "android_common")
bazJar := bazModule.Rule("combineJar").Output
- sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
+ sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").
+ Output("combined/sdklib.stubs.jar").Output
fooLibrary := fooModule.Module().(*Library)
assertDeepEquals(t, "foo unique sources incorrect",
@@ -1035,7 +1036,7 @@
}
}
-func TestJavaLibrary(t *testing.T) {
+func TestJavaLibraryOutputFiles(t *testing.T) {
testJavaWithFS(t, "", map[string][]byte{
"libcore/Android.bp": []byte(`
java_library {
@@ -1052,7 +1053,7 @@
})
}
-func TestJavaImport(t *testing.T) {
+func TestJavaImportOutputFiles(t *testing.T) {
testJavaWithFS(t, "", map[string][]byte{
"libcore/Android.bp": []byte(`
java_import {
@@ -1068,6 +1069,85 @@
})
}
+func TestJavaImport(t *testing.T) {
+ bp := `
+ java_library {
+ name: "source_library",
+ srcs: ["source.java"],
+ }
+
+ java_import {
+ name: "import_with_no_deps",
+ jars: ["no_deps.jar"],
+ }
+
+ java_import {
+ name: "import_with_source_deps",
+ jars: ["source_deps.jar"],
+ static_libs: ["source_library"],
+ }
+
+ java_import {
+ name: "import_with_import_deps",
+ jars: ["import_deps.jar"],
+ static_libs: ["import_with_no_deps"],
+ }
+ `
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, bp)
+
+ source := ctx.ModuleForTests("source_library", "android_common")
+ sourceJar := source.Output("javac/source_library.jar")
+ sourceHeaderJar := source.Output("turbine-combined/source_library.jar")
+ sourceJavaInfo, _ := android.SingletonModuleProvider(ctx, source.Module(), JavaInfoProvider)
+
+ // The source library produces separate implementation and header jars
+ android.AssertPathsRelativeToTopEquals(t, "source library implementation jar",
+ []string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars)
+ android.AssertPathsRelativeToTopEquals(t, "source library header jar",
+ []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars)
+
+ importWithNoDeps := ctx.ModuleForTests("import_with_no_deps", "android_common")
+ importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar")
+ importWithNoDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider)
+
+ // An import with no deps produces a single jar used as both the header and implementation jar.
+ android.AssertPathsRelativeToTopEquals(t, "import with no deps implementation jar",
+ []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.ImplementationAndResourcesJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar",
+ []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs",
+ []string{"no_deps.jar"}, importWithNoDepsJar.Inputs)
+
+ importWithSourceDeps := ctx.ModuleForTests("import_with_source_deps", "android_common")
+ importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar")
+ importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar")
+ importWithSourceDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider)
+
+ // An import with source deps produces separate header and implementation jars.
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps implementation jar",
+ []string{importWithSourceDepsJar.Output.String()}, importWithSourceDepsJavaInfo.ImplementationAndResourcesJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar",
+ []string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs",
+ []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs)
+ android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs",
+ []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs)
+
+ importWithImportDeps := ctx.ModuleForTests("import_with_import_deps", "android_common")
+ importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar")
+ importWithImportDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider)
+
+ // An import with only import deps produces a single jar used as both the header and implementation jar.
+ android.AssertPathsRelativeToTopEquals(t, "import with import deps implementation jar",
+ []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.ImplementationAndResourcesJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar",
+ []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars)
+ android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs",
+ []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs)
+}
+
var compilerFlagsTestCases = []struct {
in string
out bool
@@ -2643,6 +2723,70 @@
}
}
+func TestMultiplePlatformCompatConfigPrebuilts(t *testing.T) {
+ bp := `
+ // multiple variations of platform_compat_config
+ // source
+ platform_compat_config {
+ name: "myconfig",
+ }
+ // prebuilt "v1"
+ prebuilt_platform_compat_config {
+ name: "myconfig",
+ metadata: "myconfig.xml",
+ }
+ // prebuilt "v2"
+ prebuilt_platform_compat_config {
+ name: "myconfig.v2",
+ source_module_name: "myconfig", // without source_module_name, the singleton will merge two .xml files
+ metadata: "myconfig.v2.xml",
+ }
+
+ // selectors
+ apex_contributions {
+ name: "myapex_contributions",
+ contents: ["%v"],
+ }
+ `
+ testCases := []struct {
+ desc string
+ selectedDependencyName string
+ expectedPlatformCompatConfigXml string
+ }{
+ {
+ desc: "Source platform_compat_config is selected using apex_contributions",
+ selectedDependencyName: "myconfig",
+ expectedPlatformCompatConfigXml: "out/soong/.intermediates/myconfig/android_common/myconfig_meta.xml",
+ },
+ {
+ desc: "Prebuilt platform_compat_config v1 is selected using apex_contributions",
+ selectedDependencyName: "prebuilt_myconfig",
+ expectedPlatformCompatConfigXml: "myconfig.xml",
+ },
+ {
+ desc: "Prebuilt platform_compat_config v2 is selected using apex_contributions",
+ selectedDependencyName: "prebuilt_myconfig.v2",
+ expectedPlatformCompatConfigXml: "myconfig.v2.xml",
+ },
+ }
+
+ for _, tc := range testCases {
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithPlatformCompatConfig,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions",
+ }
+ }),
+ ).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
+
+ mergedGlobalConfig := ctx.SingletonForTests("platform_compat_config_singleton").Output("compat_config/merged_compat_config.xml")
+ android.AssertIntEquals(t, "The merged compat config file should only have a single dependency", 1, len(mergedGlobalConfig.Implicits))
+ android.AssertStringEquals(t, "The merged compat config file is missing the appropriate platform compat config", mergedGlobalConfig.Implicits[0].String(), tc.expectedPlatformCompatConfigXml)
+ }
+}
+
func TestApiLibraryAconfigDeclarations(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
@@ -2693,3 +2837,38 @@
cmdline := String(android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest).Commands[0].Command)
android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
}
+
+func TestJavaLibHostWithStem(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library_host {
+ name: "foo",
+ srcs: ["a.java"],
+ stem: "foo-new",
+ }
+ `)
+
+ buildOS := ctx.Config().BuildOS.String()
+ foo := ctx.ModuleForTests("foo", buildOS+"_common")
+
+ outputs := fmt.Sprint(foo.AllOutputs())
+ if !strings.Contains(outputs, "foo-new.jar") {
+ t.Errorf("Module output does not contain expected jar %s", "foo-new.jar")
+ }
+}
+
+func TestJavaLibWithStem(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ stem: "foo-new",
+ }
+ `)
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ outputs := fmt.Sprint(foo.AllOutputs())
+ if !strings.Contains(outputs, "foo-new.jar") {
+ t.Errorf("Module output does not contain expected jar %s", "foo-new.jar")
+ }
+}
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 2197304..2fc6c02 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -20,6 +20,7 @@
"android/soong/android"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
func init() {
@@ -184,6 +185,11 @@
type prebuiltCompatConfigProperties struct {
Metadata *string `android:"path"`
+
+ // Name of the source soong module that gets shadowed by this prebuilt
+ // If unspecified, follows the naming convention that the source module of
+ // the prebuilt is Name() without "prebuilt_" prefix
+ Source_module_name *string
}
func (module *prebuiltCompatConfigModule) Prebuilt() *android.Prebuilt {
@@ -198,6 +204,10 @@
return module.metadataFile
}
+func (module *prebuiltCompatConfigModule) BaseModuleName() string {
+ return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name())
+}
+
var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil)
func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 94e9c6c..6a79e58 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -158,6 +158,21 @@
mctx.CreateModule(genrule.GenRuleFactory, &genruleProps)
}
+func createCombinedApiFilegroupModule(mctx android.LoadHookContext, name string, srcs []string) {
+ filegroupProps := struct {
+ Name *string
+ Srcs []string
+ }{}
+ filegroupProps.Name = proptools.StringPtr(name)
+
+ var transformedSrcs []string
+ for _, src := range srcs {
+ transformedSrcs = append(transformedSrcs, ":"+src)
+ }
+ filegroupProps.Srcs = transformedSrcs
+ mctx.CreateModule(android.FileGroupFactory, &filegroupProps)
+}
+
func createLatestApiModuleExtensionVersionFile(mctx android.LoadHookContext, name string, version string) {
genruleProps := struct {
Name *string
@@ -252,6 +267,10 @@
return module + ".api." + scope + "." + version
}
+func PrebuiltApiCombinedModuleName(module, scope, version string) string {
+ return module + ".api.combined." + scope + "." + version
+}
+
func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
// <apiver>/<scope>/api/<module>.txt
apiLevelFiles := globApiDirs(mctx, p, "api/*.txt")
@@ -307,7 +326,9 @@
}
// Sort the keys in order to make build.ninja stable
- for _, k := range android.SortedKeys(latest) {
+ sortedLatestKeys := android.SortedKeys(latest)
+
+ for _, k := range sortedLatestKeys {
info := latest[k]
name := PrebuiltApiModuleName(info.module, info.scope, "latest")
latestExtensionVersionModuleName := PrebuiltApiModuleName(info.module, info.scope, "latest.extension_version")
@@ -333,11 +354,25 @@
}
}
// Create empty incompatibilities files for remaining modules
- for _, k := range android.SortedKeys(latest) {
+ // If the incompatibility module has been created, create a corresponding combined module
+ for _, k := range sortedLatestKeys {
if _, ok := incompatibilities[k]; !ok {
createEmptyFile(mctx, PrebuiltApiModuleName(latest[k].module+"-incompatibilities", latest[k].scope, "latest"))
}
}
+
+ // Create combined latest api and removed api files modules.
+ // The combined modules list all api files of the api scope and its subset api scopes.
+ for _, k := range sortedLatestKeys {
+ info := latest[k]
+ name := PrebuiltApiCombinedModuleName(info.module, info.scope, "latest")
+
+ var srcs []string
+ currentApiScope := scopeByName[info.scope]
+ srcs = append(srcs, PrebuiltApiModuleName(info.module, currentApiScope.name, "latest"))
+
+ createCombinedApiFilegroupModule(mctx, name, srcs)
+ }
}
func createPrebuiltApiModules(mctx android.LoadHookContext) {
diff --git a/java/rro.go b/java/rro.go
index 3e0f8e9..72170fc 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -122,6 +122,10 @@
ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...)
ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...)
+
+ for _, aconfig_declaration := range r.aaptProperties.Flags_packages {
+ ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
+ }
}
func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -151,6 +155,7 @@
sdkContext: r,
enforceDefaultTargetSdkVersion: false,
extraLinkFlags: aaptLinkFlags,
+ aconfigTextFiles: getAconfigFilePaths(ctx),
},
)
diff --git a/java/rro_test.go b/java/rro_test.go
index c4a4d04..d697ec6 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -405,3 +405,49 @@
android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
}
}
+
+func TestRuntimeResourceOverlayFlagsPackages(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ runtime_resource_overlay {
+ name: "foo",
+ sdk_version: "current",
+ flags_packages: [
+ "bar",
+ "baz",
+ ],
+ }
+ aconfig_declarations {
+ name: "bar",
+ package: "com.example.package.bar",
+ srcs: [
+ "bar.aconfig",
+ ],
+ }
+ aconfig_declarations {
+ name: "baz",
+ package: "com.example.package.baz",
+ srcs: [
+ "baz.aconfig",
+ ],
+ }
+ `)
+
+ foo := result.ModuleForTests("foo", "android_common")
+
+ // runtime_resource_overlay module depends on aconfig_declarations listed in flags_packages
+ android.AssertBoolEquals(t, "foo expected to depend on bar", true,
+ CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "bar"))
+
+ android.AssertBoolEquals(t, "foo expected to depend on baz", true,
+ CheckModuleHasDependency(t, result.TestContext, "foo", "android_common", "baz"))
+
+ aapt2LinkRule := foo.Rule("android/soong/java.aapt2Link")
+ linkInFlags := aapt2LinkRule.Args["inFlags"]
+ android.AssertStringDoesContain(t,
+ "aapt2 link command expected to pass feature flags arguments",
+ linkInFlags,
+ "--feature-flags @out/soong/.intermediates/bar/intermediate.txt --feature-flags @out/soong/.intermediates/baz/intermediate.txt",
+ )
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index cdd0448..5ddc675 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -30,6 +30,7 @@
"android/soong/android"
"android/soong/dexpreopt"
+ "android/soong/etc"
)
const (
@@ -1672,12 +1673,16 @@
return PrebuiltApiModuleName(name, apiScope.name, "latest")
}
+func latestPrebuiltApiCombinedModuleName(name string, apiScope *apiScope) string {
+ return PrebuiltApiCombinedModuleName(name, apiScope.name, "latest")
+}
+
func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string {
return ":" + module.latestApiModuleName(apiScope)
}
func (module *SdkLibrary) latestApiModuleName(apiScope *apiScope) string {
- return latestPrebuiltApiModuleName(module.distStem(), apiScope)
+ return latestPrebuiltApiCombinedModuleName(module.distStem(), apiScope)
}
func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope *apiScope) string {
@@ -1685,7 +1690,7 @@
}
func (module *SdkLibrary) latestRemovedApiModuleName(apiScope *apiScope) string {
- return latestPrebuiltApiModuleName(module.distStem()+"-removed", apiScope)
+ return latestPrebuiltApiCombinedModuleName(module.distStem()+"-removed", apiScope)
}
func (module *SdkLibrary) latestIncompatibilitiesFilegroupName(apiScope *apiScope) string {
@@ -1993,20 +1998,25 @@
if !Bool(module.sdkLibraryProperties.No_dist) {
// Dist the api txt and removed api txt artifacts for sdk builds.
distDir := proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
+ stubsTypeTagPrefix := ""
+ if mctx.Config().ReleaseHiddenApiExportableStubs() {
+ stubsTypeTagPrefix = ".exportable"
+ }
for _, p := range []struct {
tag string
pattern string
}{
// "exportable" api files are copied to the dist directory instead of the
- // "everything" api files.
- {tag: ".exportable.api.txt", pattern: "%s.txt"},
- {tag: ".exportable.removed-api.txt", pattern: "%s-removed.txt"},
+ // "everything" api files when "RELEASE_HIDDEN_API_EXPORTABLE_STUBS" build flag
+ // is set. Otherwise, the "everything" api files are copied to the dist directory.
+ {tag: "%s.api.txt", pattern: "%s.txt"},
+ {tag: "%s.removed-api.txt", pattern: "%s-removed.txt"},
} {
props.Dists = append(props.Dists, android.Dist{
Targets: []string{"sdk", "win_sdk"},
Dir: distDir,
Dest: proptools.StringPtr(fmt.Sprintf(p.pattern, module.distStem())),
- Tag: proptools.StringPtr(p.tag),
+ Tag: proptools.StringPtr(fmt.Sprintf(p.tag, stubsTypeTagPrefix)),
})
}
}
@@ -2079,7 +2089,7 @@
mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
-func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
+func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope, doDist bool) libraryProperties {
props := libraryProperties{}
props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
@@ -2095,13 +2105,22 @@
}
props.Compile_dex = compileDex
+ if !Bool(module.sdkLibraryProperties.No_dist) && doDist {
+ props.Dist.Targets = []string{"sdk", "win_sdk"}
+ props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
+ props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
+ props.Dist.Tag = proptools.StringPtr(".jar")
+ }
+
return props
}
func (module *SdkLibrary) createTopLevelStubsLibrary(
mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) {
- props := module.topLevelStubsLibraryProps(mctx, apiScope)
+ // Dist the "everything" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is false
+ doDist := !mctx.Config().ReleaseHiddenApiExportableStubs()
+ props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
// Add the stub compiling java_library/java_api_library as static lib based on build config
@@ -2117,18 +2136,11 @@
func (module *SdkLibrary) createTopLevelExportableStubsLibrary(
mctx android.DefaultableHookContext, apiScope *apiScope) {
- props := module.topLevelStubsLibraryProps(mctx, apiScope)
+ // Dist the "exportable" stubs when the RELEASE_HIDDEN_API_EXPORTABLE_STUBS build flag is true
+ doDist := mctx.Config().ReleaseHiddenApiExportableStubs()
+ props := module.topLevelStubsLibraryProps(mctx, apiScope, doDist)
props.Name = proptools.StringPtr(module.exportableStubsLibraryModuleName(apiScope))
- // Dist the class jar artifact for sdk builds.
- // "exportable" stubs are copied to dist for sdk builds instead of the "everything" stubs.
- if !Bool(module.sdkLibraryProperties.No_dist) {
- props.Dist.Targets = []string{"sdk", "win_sdk"}
- props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
- props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
- props.Dist.Tag = proptools.StringPtr(".jar")
- }
-
staticLib := module.exportableSourceStubsLibraryModuleName(apiScope)
props.Static_libs = append(props.Static_libs, staticLib)
@@ -3163,10 +3175,12 @@
}
// from android.PrebuiltEtcModule
-func (module *sdkLibraryXml) OutputFile() android.OutputPath {
- return module.outputFilePath
+func (module *sdkLibraryXml) OutputFiles(tag string) (android.Paths, error) {
+ return android.OutputPaths{module.outputFilePath}.Paths(), nil
}
+var _ etc.PrebuiltEtcModule = (*sdkLibraryXml)(nil)
+
// from android.ApexModule
func (module *sdkLibraryXml) AvailableFor(what string) bool {
return true
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 93ef408..fb584c5 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -139,10 +139,10 @@
exportedComponentsInfo, _ := android.SingletonModuleProvider(result, foo.Module(), android.ExportedComponentsInfoProvider)
expectedFooExportedComponents := []string{
- "foo-removed.api.public.latest",
- "foo-removed.api.system.latest",
- "foo.api.public.latest",
- "foo.api.system.latest",
+ "foo-removed.api.combined.public.latest",
+ "foo-removed.api.combined.system.latest",
+ "foo.api.combined.public.latest",
+ "foo.api.combined.system.latest",
"foo.stubs",
"foo.stubs.exportable",
"foo.stubs.exportable.system",
@@ -556,8 +556,8 @@
CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
`dex2oatd`,
- `sdklib-removed.api.public.latest`,
- `sdklib.api.public.latest`,
+ `sdklib-removed.api.combined.public.latest`,
+ `sdklib.api.combined.public.latest`,
`sdklib.impl`,
`sdklib.stubs`,
`sdklib.stubs.exportable`,
@@ -960,8 +960,8 @@
CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
`dex2oatd`,
`prebuilt_sdklib`,
- `sdklib-removed.api.public.latest`,
- `sdklib.api.public.latest`,
+ `sdklib-removed.api.combined.public.latest`,
+ `sdklib.api.combined.public.latest`,
`sdklib.impl`,
`sdklib.stubs`,
`sdklib.stubs.exportable`,
@@ -1039,8 +1039,8 @@
CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{
`prebuilt_sdklib`,
- `sdklib-removed.api.public.latest`,
- `sdklib.api.public.latest`,
+ `sdklib-removed.api.combined.public.latest`,
+ `sdklib.api.combined.public.latest`,
`sdklib.impl`,
`sdklib.stubs`,
`sdklib.stubs.exportable`,
@@ -1393,6 +1393,11 @@
"sdklib_group_foo",
"sdklib_owner_foo",
"foo"),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_HIDDEN_API_EXPORTABLE_STUBS": "true",
+ }
+ }),
).RunTestWithBp(t, `
java_sdk_library {
name: "sdklib_no_group",
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index 59c5466..b291e70 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -189,7 +189,7 @@
return javaSdkLibrarySdkMemberType
}
- return javaSystemserverLibsSdkMemberType
+ return JavaSystemserverLibsSdkMemberType
}
func (b systemServerClasspathFragmentContentDependencyTag) ExportMember() bool {
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 78b62d9..98aa408 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -89,7 +89,7 @@
output := android.PathForModuleOut(ctx, "linker.config.pb").OutputPath
builder := android.NewRuleBuilder(pctx, ctx)
- BuildLinkerConfig(ctx, builder, input, nil, output)
+ BuildLinkerConfig(ctx, builder, input, nil, nil, output)
builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String())
l.outputFilePath = output
@@ -101,7 +101,7 @@
}
func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
- input android.Path, otherModules []android.Module, output android.OutputPath) {
+ input android.Path, provideModules []android.Module, requireModules []android.Module, output android.OutputPath) {
// First, convert the input json to protobuf format
interimOutput := android.PathForModuleOut(ctx, "temp.pb")
@@ -111,9 +111,9 @@
FlagWithInput("-s ", input).
FlagWithOutput("-o ", interimOutput)
- // Secondly, if there's provideLibs gathered from otherModules, append them
+ // Secondly, if there's provideLibs gathered from provideModules, append them
var provideLibs []string
- for _, m := range otherModules {
+ for _, m := range provideModules {
if c, ok := m.(*cc.Module); ok && cc.IsStubTarget(c) {
for _, ps := range c.PackagingSpecs() {
provideLibs = append(provideLibs, ps.FileName())
@@ -122,18 +122,45 @@
}
provideLibs = android.FirstUniqueStrings(provideLibs)
sort.Strings(provideLibs)
+
+ var requireLibs []string
+ for _, m := range requireModules {
+ if c, ok := m.(*cc.Module); ok && c.HasStubsVariants() && !c.Host() {
+ requireLibs = append(requireLibs, c.ImplementationModuleName(ctx)+".so")
+ }
+ }
+
+ requireLibs = android.FirstUniqueStrings(requireLibs)
+ sort.Strings(requireLibs)
+
if len(provideLibs) > 0 {
+ prevOutput := interimOutput
+ interimOutput = android.PathForModuleOut(ctx, "temp_provideLibs.pb")
builder.Command().
BuiltTool("conv_linker_config").
Flag("append").
- FlagWithInput("-s ", interimOutput).
- FlagWithOutput("-o ", output).
+ FlagWithInput("-s ", prevOutput).
+ FlagWithOutput("-o ", interimOutput).
FlagWithArg("--key ", "provideLibs").
FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(provideLibs, " ")))
- } else {
- // If nothing to add, just cp to the final output
- builder.Command().Text("cp").Input(interimOutput).Output(output)
+ builder.Temporary(prevOutput)
}
+ if len(requireLibs) > 0 {
+ prevOutput := interimOutput
+ interimOutput = android.PathForModuleOut(ctx, "temp_requireLibs.pb")
+ builder.Command().
+ BuiltTool("conv_linker_config").
+ Flag("append").
+ FlagWithInput("-s ", prevOutput).
+ FlagWithOutput("-o ", interimOutput).
+ FlagWithArg("--key ", "requireLibs").
+ FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(requireLibs, " ")))
+ builder.Temporary(prevOutput)
+ }
+
+ // cp to the final output
+ builder.Command().Text("cp").Input(interimOutput).Output(output)
+
builder.Temporary(interimOutput)
builder.DeleteTemporaryFiles()
}
diff --git a/rust/compiler.go b/rust/compiler.go
index c1bdbeb..03fdf2b 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -75,6 +75,8 @@
strippedOutputFilePath() android.OptionalPath
checkedCrateRootPath() (android.Path, error)
+
+ Aliases() map[string]string
}
func (compiler *baseCompiler) edition() string {
@@ -140,6 +142,12 @@
// flags to pass to the linker
Ld_flags []string `android:"arch_variant"`
+ // Rust crate dependencies to rename. Each entry should be a string of the form "dependencyname:alias".
+ //
+ // "dependencyname" here should be the name of the crate, not the Android module. This is
+ // equivalent to writing `alias = { package = "dependencyname" }` in a `Cargo.toml`.
+ Aliases []string
+
// list of rust rlib crate dependencies
Rlibs []string `android:"arch_variant"`
@@ -281,6 +289,18 @@
return Bool(compiler.Properties.Prefer_rlib)
}
+func (compiler *baseCompiler) Aliases() map[string]string {
+ aliases := map[string]string{}
+ for _, entry := range compiler.Properties.Aliases {
+ dep, alias, found := strings.Cut(entry, ":")
+ if !found {
+ panic(fmt.Errorf("invalid aliases entry %q missing ':'", entry))
+ }
+ aliases[dep] = alias
+ }
+ return aliases
+}
+
func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
// For devices, we always link stdlibs in as dylibs by default.
if compiler.preferRlib() {
diff --git a/rust/config/global.go b/rust/config/global.go
index 418eca4..e28dbaa 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -25,7 +25,7 @@
pctx = android.NewPackageContext("android/soong/rust/config")
ExportedVars = android.NewExportedVariables(pctx)
- RustDefaultVersion = "1.75.0"
+ RustDefaultVersion = "1.76.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
diff --git a/rust/library.go b/rust/library.go
index 7f004fc..3560d73 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -54,9 +54,13 @@
Shared VariantLibraryProperties `android:"arch_variant"`
Static VariantLibraryProperties `android:"arch_variant"`
- // path to include directories to pass to cc_* modules, only relevant for static/shared variants.
+ // TODO: Remove this when all instances of Include_dirs have been removed from rust_ffi modules.
+ // path to include directories to pass to cc_* modules, only relevant for static/shared variants (deprecated, use export_include_dirs instead).
Include_dirs []string `android:"path,arch_variant"`
+ // path to include directories to export to cc_* modules, only relevant for static/shared variants.
+ Export_include_dirs []string `android:"path,arch_variant"`
+
// Whether this library is part of the Rust toolchain sysroot.
Sysroot *bool
}
@@ -465,6 +469,7 @@
flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
if library.shared() || library.static() {
library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
+ library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)...)
}
if library.shared() {
if ctx.Darwin() {
diff --git a/rust/library_test.go b/rust/library_test.go
index e03074d..7275b66 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -403,3 +403,22 @@
}
}
+
+func TestRustFFIExportedIncludes(t *testing.T) {
+ ctx := testRust(t, `
+ rust_ffi {
+ name: "libbar",
+ srcs: ["foo.rs"],
+ crate_name: "bar",
+ export_include_dirs: ["rust_includes"],
+ host_supported: true,
+ }
+ cc_library_static {
+ name: "libfoo",
+ srcs: ["foo.cpp"],
+ shared_libs: ["libbar"],
+ host_supported: true,
+ }`)
+ libfooStatic := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_static").Rule("cc")
+ android.AssertStringDoesContain(t, "cFlags for lib module", libfooStatic.Args["cFlags"], " -Irust_includes ")
+}
diff --git a/rust/rust.go b/rust/rust.go
index 245ed2e..7d81c72 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1063,6 +1063,12 @@
return nil
}
+func (d dependencyTag) PropagateAconfigValidation() bool {
+ return d == rlibDepTag || d == sourceDepTag
+}
+
+var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{}
+
var _ android.LicenseAnnotationsDependencyTag = dependencyTag{}
var (
@@ -1136,6 +1142,7 @@
}
}
}
+
func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
@@ -1427,16 +1434,29 @@
mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
var rlibDepFiles RustLibraries
+ aliases := mod.compiler.Aliases()
for _, dep := range directRlibDeps {
- rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
+ crateName := dep.CrateName()
+ if alias, aliased := aliases[crateName]; aliased {
+ crateName = alias
+ }
+ rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
}
var dylibDepFiles RustLibraries
for _, dep := range directDylibDeps {
- dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
+ crateName := dep.CrateName()
+ if alias, aliased := aliases[crateName]; aliased {
+ crateName = alias
+ }
+ dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
}
var procMacroDepFiles RustLibraries
for _, dep := range directProcMacroDeps {
- procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
+ crateName := dep.CrateName()
+ if alias, aliased := aliases[crateName]; aliased {
+ crateName = alias
+ }
+ procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
}
var staticLibDepFiles android.Paths
diff --git a/rust/rust_test.go b/rust/rust_test.go
index d609c2f..295a734 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -470,6 +470,35 @@
m.Output("libwaldo.dylib.so.bloaty.csv")
}
+// Test that aliases are respected.
+func TestRustAliases(t *testing.T) {
+ ctx := testRust(t, `
+ rust_library {
+ name: "libbar",
+ crate_name: "bar",
+ srcs: ["src/lib.rs"],
+ }
+ rust_library {
+ name: "libbaz",
+ crate_name: "baz",
+ srcs: ["src/lib.rs"],
+ }
+ rust_binary {
+ name: "foo",
+ srcs: ["src/main.rs"],
+ rustlibs: ["libbar", "libbaz"],
+ aliases: ["bar:bar_renamed"],
+ }`)
+
+ fooRustc := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+ if !strings.Contains(fooRustc.Args["libFlags"], "--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
+ t.Errorf("--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+ }
+ if !strings.Contains(fooRustc.Args["libFlags"], "--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so") {
+ t.Errorf("--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+ }
+}
+
func assertString(t *testing.T, got, expected string) {
t.Helper()
if got != expected {
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
index 7ebe66b..a6ed0e5 100644
--- a/rust/vendor_snapshot_test.go
+++ b/rust/vendor_snapshot_test.go
@@ -32,7 +32,7 @@
crate_name: "ffivendor_available",
srcs: ["lib.rs"],
vendor_available: true,
- include_dirs: ["rust_headers/"],
+ export_include_dirs: ["rust_headers/"],
}
rust_ffi {
@@ -40,7 +40,7 @@
crate_name: "ffivendor",
srcs: ["lib.rs"],
vendor: true,
- include_dirs: ["rust_headers/"],
+ export_include_dirs: ["rust_headers/"],
}
rust_library {
diff --git a/scripts/Android.bp b/scripts/Android.bp
index e2fd59f..f36329b 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -292,3 +292,16 @@
name: "keep-flagged-apis",
src: "keep-flagged-apis.sh",
}
+
+python_binary_host {
+ name: "merge_directories",
+ main: "merge_directories.py",
+ srcs: [
+ "merge_directories.py",
+ ],
+ version: {
+ py3: {
+ embedded_launcher: true,
+ },
+ },
+}
diff --git a/scripts/merge_directories.py b/scripts/merge_directories.py
new file mode 100755
index 0000000..3f8631b
--- /dev/null
+++ b/scripts/merge_directories.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+import argparse
+import os
+import shutil
+import sys
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Given a list of directories, this script will copy the contents of all of "
+ "them into the first directory, erroring out if any duplicate files are found."
+ )
+ parser.add_argument(
+ "--ignore-duplicates",
+ action="store_true",
+ help="Don't error out on duplicate files, just skip them. The file from the earliest "
+ "directory listed on the command line will be the winner."
+ )
+ parser.add_argument(
+ "--file-list",
+ help="Path to a text file containing paths relative to in_dir. Only these paths will be "
+ "copied out of in_dir."
+ )
+ parser.add_argument("out_dir")
+ parser.add_argument("in_dir")
+ args = parser.parse_args()
+
+ if not os.path.isdir(args.out_dir):
+ sys.exit(f"error: {args.out_dir} must be a directory")
+ if not os.path.isdir(args.in_dir):
+ sys.exit(f"error: {args.in_dir} must be a directory")
+
+ file_list = None
+ if args.file_list:
+ with open(file_list_file, "r") as f:
+ file_list = f.read().strip().splitlines()
+
+ in_dir = args.in_dir
+ for root, dirs, files in os.walk(in_dir):
+ rel_root = os.path.relpath(root, in_dir)
+ dst_root = os.path.join(args.out_dir, rel_root)
+ made_parent_dirs = False
+ for f in files:
+ src = os.path.join(root, f)
+ dst = os.path.join(dst_root, f)
+ p = os.path.normpath(os.path.join(rel_root, f))
+ if file_list is not None and p not in file_list:
+ continue
+ if os.path.lexists(dst):
+ if args.ignore_duplicates:
+ continue
+ sys.exit(f"error: {p} exists in both {args.out_dir} and {in_dir}")
+
+ if not made_parent_dirs:
+ os.makedirs(dst_root, exist_ok=True)
+ made_parent_dirs = True
+
+ shutil.copy2(src, dst, follow_symlinks=False)
+
+if __name__ == "__main__":
+ main()
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 5d41958..8d3bbfa 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -152,6 +152,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [],
+}
+
prebuilt_bootclasspath_fragment {
name: "art-bootclasspath-fragment",
prefer: false,
@@ -187,6 +192,7 @@
apex_available: ["com.android.art"],
jars: ["java_boot_libs/snapshot/jars/are/invalid/core2.jar"],
}
+
`),
checkAllCopyRules(`
.intermediates/art-bootclasspath-fragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv
@@ -353,6 +359,15 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [
+ "prebuilt_myothersdklibrary",
+ "prebuilt_mysdklibrary",
+ "prebuilt_mycoreplatform",
+ ],
+}
+
prebuilt_bootclasspath_fragment {
name: "mybootclasspathfragment",
prefer: false,
@@ -642,6 +657,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mysdklibrary"],
+}
+
prebuilt_bootclasspath_fragment {
name: "mybootclasspathfragment",
prefer: false,
@@ -881,6 +901,14 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [
+ "prebuilt_mynewlibrary",
+ "prebuilt_mysdklibrary",
+ ],
+}
+
prebuilt_bootclasspath_fragment {
name: "mybootclasspathfragment",
prefer: false,
@@ -1008,6 +1036,9 @@
android.FixtureMergeEnv(map[string]string{
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": targetBuildRelease,
}),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_version_active_codenames = []string{"VanillaIceCream"}
+ }),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.BuildFlags = map[string]string{
@@ -1226,6 +1257,9 @@
android.FixtureMergeEnv(map[string]string{
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S",
}),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_version_active_codenames = []string{"VanillaIceCream"}
+ }),
android.FixtureWithRootAndroidBp(`
sdk {
name: "mysdk",
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 265579a..9490d12 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -123,6 +123,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_sdkmember"],
+}
+
cc_prebuilt_library_shared {
name: "sdkmember",
prefer: false,
@@ -226,6 +231,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_crtobj"],
+}
+
cc_prebuilt_object {
name: "crtobj",
prefer: false,
@@ -333,6 +343,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_shared {
name: "mynativelib",
prefer: false,
@@ -406,6 +421,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_shared {
name: "mynativelib",
prefer: false,
@@ -465,6 +485,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mymodule_exports.contributions",
+ contents: ["prebuilt_mynativebinary"],
+}
+
cc_prebuilt_binary {
name: "mynativebinary",
prefer: false,
@@ -523,6 +548,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_mynativebinary"],
+}
+
cc_prebuilt_binary {
name: "mynativebinary",
prefer: false,
@@ -621,6 +651,14 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: [
+ "prebuilt_mynativebinary",
+ "prebuilt_mynativelib",
+ ],
+}
+
cc_prebuilt_binary {
name: "mynativebinary",
prefer: false,
@@ -696,6 +734,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mymodule_exports.contributions",
+ contents: ["prebuilt_linker"],
+}
+
cc_prebuilt_binary {
name: "linker",
prefer: false,
@@ -755,6 +798,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_shared {
name: "mynativelib",
prefer: false,
@@ -856,6 +904,15 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [
+ "prebuilt_mynativelib",
+ "prebuilt_myothernativelib",
+ "prebuilt_mysystemnativelib",
+ ],
+}
+
cc_prebuilt_library_shared {
name: "mynativelib",
prefer: false,
@@ -953,6 +1010,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_shared {
name: "mynativelib",
prefer: false,
@@ -1029,6 +1091,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_shared {
name: "mynativelib",
prefer: false,
@@ -1095,6 +1162,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_static {
name: "mynativelib",
prefer: false,
@@ -1158,6 +1230,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_static {
name: "mynativelib",
prefer: false,
@@ -1222,6 +1299,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library {
name: "mynativelib",
prefer: false,
@@ -1298,6 +1380,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library {
name: "mynativelib",
prefer: false,
@@ -1394,6 +1481,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library {
name: "mynativelib",
prefer: false,
@@ -1520,6 +1612,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_static {
name: "mynativelib",
prefer: false,
@@ -1572,6 +1669,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativeheaders"],
+}
+
cc_prebuilt_library_headers {
name: "mynativeheaders",
prefer: false,
@@ -1594,6 +1696,9 @@
PrepareForTestWithSdkBuildComponents,
ccTestFs.AddToFixture(),
prepareForTestWithNativeBridgeTarget,
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ android.RegisterApexContributionsBuildComponents(ctx)
+ }),
).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -1616,6 +1721,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativeheaders"],
+}
+
cc_prebuilt_library_headers {
name: "mynativeheaders",
prefer: false,
@@ -1679,6 +1789,9 @@
cc.PrepareForTestWithCcDefaultModules,
PrepareForTestWithSdkBuildComponents,
ccTestFs.AddToFixture(),
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ android.RegisterApexContributionsBuildComponents(ctx)
+ }),
).RunTestWithBp(t, fmt.Sprintf(`
sdk {
name: "mysdk",
@@ -1701,6 +1814,11 @@
checkAndroidBpContents(fmt.Sprintf(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativeheaders"],
+}
+
cc_prebuilt_library_headers {
name: "mynativeheaders",
prefer: false,
@@ -1750,6 +1868,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativeheaders"],
+}
+
cc_prebuilt_library_headers {
name: "mynativeheaders",
prefer: false,
@@ -1807,6 +1930,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativeheaders"],
+}
+
cc_prebuilt_library_headers {
name: "mynativeheaders",
prefer: false,
@@ -1870,6 +1998,15 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [
+ "prebuilt_sslnil",
+ "prebuilt_sslempty",
+ "prebuilt_sslnonempty",
+ ],
+}
+
cc_prebuilt_library_shared {
name: "sslnil",
prefer: false,
@@ -1943,6 +2080,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_sslvariants"],
+}
+
cc_prebuilt_library_shared {
name: "sslvariants",
prefer: false,
@@ -2002,6 +2144,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_stubslib"],
+}
+
cc_prebuilt_library_shared {
name: "stubslib",
prefer: false,
@@ -2056,6 +2203,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_stubslib"],
+}
+
cc_prebuilt_library_shared {
name: "stubslib",
prefer: false,
@@ -2114,6 +2266,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mylib"],
+}
+
cc_prebuilt_library_shared {
name: "mylib",
prefer: false,
@@ -2178,6 +2335,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mynativelib"],
+}
+
cc_prebuilt_library_shared {
name: "mynativelib",
prefer: false,
diff --git a/sdk/compat_config_sdk_test.go b/sdk/compat_config_sdk_test.go
index 45e8e0e..75b5229 100644
--- a/sdk/compat_config_sdk_test.go
+++ b/sdk/compat_config_sdk_test.go
@@ -36,6 +36,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myconfig"],
+}
+
prebuilt_platform_compat_config {
name: "myconfig",
prefer: false,
diff --git a/sdk/exports_test.go b/sdk/exports_test.go
index 2605fd1..9d0a242 100644
--- a/sdk/exports_test.go
+++ b/sdk/exports_test.go
@@ -46,6 +46,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 1b2b0f1..275860f 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -108,6 +108,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -154,6 +159,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -193,6 +203,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -245,6 +260,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -291,6 +311,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -313,6 +338,9 @@
android.FixtureMergeEnv(map[string]string{
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": targetBuildRelease,
}),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_version_active_codenames = []string{"VanillaIceCream"}
+ }),
).RunTestWithBp(t, `
sdk {
name: "mysdk",
@@ -395,6 +423,11 @@
checkAndroidBpContents(fmt.Sprintf(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mylib"],
+}
+
java_import {
name: "mylib",
prefer: false,
@@ -459,6 +492,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: [],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -504,6 +542,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -542,6 +585,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_myjavatests"],
+}
+
java_test_import {
name: "myjavatests",
prefer: false,
@@ -582,6 +630,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: ["prebuilt_myjavatests"],
+}
+
java_test_import {
name: "myjavatests",
prefer: false,
@@ -661,6 +714,15 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [
+ "prebuilt_exported-system-module",
+ "prebuilt_myjavalib",
+ "prebuilt_my-system-modules",
+ ],
+}
+
java_import {
name: "exported-system-module",
prefer: false,
@@ -790,6 +852,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_my-system-modules"],
+}
+
java_import {
name: "mysdk_system-module",
prefer: false,
@@ -854,6 +921,15 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "myexports.contributions",
+ contents: [
+ "prebuilt_hostjavalib",
+ "prebuilt_androidjavalib",
+ "prebuilt_myjavalib",
+ ],
+}
+
java_import {
name: "hostjavalib",
prefer: false,
@@ -920,6 +996,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -993,6 +1074,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib-foo"],
+}
+
java_sdk_library_import {
name: "myjavalib-foo",
prefer: false,
@@ -1046,6 +1132,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1093,6 +1184,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1147,6 +1243,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1204,6 +1305,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1272,6 +1378,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1320,6 +1431,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1371,6 +1487,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1436,6 +1557,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1509,6 +1635,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1569,6 +1700,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
@@ -1626,6 +1762,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_sdk_library_import {
name: "myjavalib",
prefer: false,
diff --git a/sdk/license_sdk_test.go b/sdk/license_sdk_test.go
index 829edf1..754f019 100644
--- a/sdk/license_sdk_test.go
+++ b/sdk/license_sdk_test.go
@@ -69,6 +69,11 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
diff --git a/sdk/member_trait_test.go b/sdk/member_trait_test.go
index 99caf13..673d6fb 100644
--- a/sdk/member_trait_test.go
+++ b/sdk/member_trait_test.go
@@ -137,6 +137,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -202,6 +207,17 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [
+ "prebuilt_myjavalib",
+ "prebuilt_myjavalib_extra",
+ "prebuilt_myjavalib_special",
+ "prebuilt_anotherjavalib",
+ "prebuilt_anotherjavalib_special",
+ ],
+}
+
java_test_import {
name: "myjavalib",
prefer: false,
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index c4df146..f9d49d9 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -118,6 +118,16 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: [
+ "prebuilt_myjavalib",
+ "prebuilt_mypublicjavalib",
+ "prebuilt_mydefaultedjavalib",
+ "prebuilt_myprivatejavalib",
+ ],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -398,6 +408,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_myjavalib"],
+}
+
java_import {
name: "myjavalib",
prefer: false,
@@ -453,6 +468,11 @@
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mysdklibrary"],
+}
+
prebuilt_bootclasspath_fragment {
name: "mybootclasspathfragment",
prefer: false,
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index 3c0b8ae..c1c4ed6 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -34,6 +34,9 @@
env["SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE"] = targetBuildRelease
}
}),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_version_active_codenames = []string{"VanillaIceCream"}
+ }),
prepareForSdkTestWithApex,
android.FixtureWithRootAndroidBp(sdk+`
@@ -242,6 +245,11 @@
expectedLatestSnapshot := `
// This is auto-generated. DO NOT EDIT.
+apex_contributions_defaults {
+ name: "mysdk.contributions",
+ contents: ["prebuilt_mysdklibrary"],
+}
+
java_sdk_library_import {
name: "mysdklibrary",
prefer: false,
diff --git a/sdk/update.go b/sdk/update.go
index a731414..b8ae38a 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -24,6 +24,7 @@
"android/soong/apex"
"android/soong/cc"
+ "android/soong/java"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -388,6 +389,7 @@
// Create the prebuilt modules for each of the member modules.
traits := s.gatherTraits()
+ memberNames := []string{} // soong module names of the members. contains the prebuilt_ prefix.
for _, member := range members {
memberType := member.memberType
if !memberType.ArePrebuiltsRequired() {
@@ -409,6 +411,38 @@
prebuiltModule := memberType.AddPrebuiltModule(memberCtx, member)
s.createMemberSnapshot(memberCtx, member, prebuiltModule.(*bpModule))
+
+ if member.memberType != android.LicenseModuleSdkMemberType && !builder.isInternalMember(member.name) {
+ // More exceptions
+ // 1. Skip BCP and SCCP fragments
+ // 2. Skip non-sdk contents of BCP and SCCP fragments
+ //
+ // The non-sdk contents of BCP/SSCP fragments should only be used for dexpreopt and hiddenapi,
+ // and are not available to the rest of the build.
+ if android.InList(member.memberType,
+ []android.SdkMemberType{
+ // bcp
+ java.BootclasspathFragmentSdkMemberType,
+ java.JavaBootLibsSdkMemberType,
+ // sscp
+ java.SystemServerClasspathFragmentSdkMemberType,
+ java.JavaSystemserverLibsSdkMemberType,
+ },
+ ) {
+ continue
+ }
+
+ memberNames = append(memberNames, android.PrebuiltNameFromSource(member.name))
+ }
+ }
+
+ // create an apex_contributions_defaults for this module's sdk.
+ // this module type is supported in V and above.
+ if targetApiLevel.GreaterThan(android.ApiLevelUpsideDownCake) {
+ ac := newModule("apex_contributions_defaults")
+ ac.AddProperty("name", s.Name()+".contributions")
+ ac.AddProperty("contents", memberNames)
+ bpFile.AddModule(ac)
}
// Create a transformer that will transform a module by replacing any references
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 698aaf2..b9b68be 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -54,15 +54,13 @@
}
type syspropRustGenRule struct {
- android.ModuleBase
+ *rust.BaseSourceProvider
- properties syspropGenProperties
-
- genSrcs android.Paths
+ properties rustLibraryProperties
}
var _ android.OutputFileProducer = (*syspropJavaGenRule)(nil)
-var _ android.OutputFileProducer = (*syspropRustGenRule)(nil)
+var _ rust.SourceProvider = (*syspropRustGenRule)(nil)
var (
syspropJava = pctx.AndroidStaticRule("syspropJava",
@@ -144,7 +142,7 @@
// syspropRustGenRule module generates rust source files containing generated rust APIs.
// It also depends on check api rule, so api check has to pass to use sysprop_library.
-func (g *syspropRustGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (g *syspropRustGenRule) GenerateSource(ctx rust.ModuleContext, deps rust.PathDeps) android.Path {
var checkApiFileTimeStamp android.WritablePath
ctx.VisitDirectDeps(func(dep android.Module) {
@@ -153,25 +151,47 @@
}
})
- for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Srcs) {
- syspropDir := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcrust")
- outputDir := syspropDir.Join(ctx, "src")
- libPath := syspropDir.Join(ctx, "src", "lib.rs")
+ outputDir := android.PathForModuleOut(ctx, "src")
+ libFile := outputDir.Join(ctx, "lib.rs")
+ g.BaseSourceProvider.OutputFiles = append(g.BaseSourceProvider.OutputFiles, libFile)
+ libFileLines := []string{"//! Autogenerated system property accessors."}
+
+ for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Sysprop_srcs) {
+ moduleName := syspropPathToRustModule(syspropFile)
+ moduleDir := outputDir.Join(ctx, moduleName)
+ modulePath := moduleDir.Join(ctx, "mod.rs")
ctx.Build(pctx, android.BuildParams{
Rule: syspropRust,
Description: "sysprop_rust " + syspropFile.Rel(),
- Outputs: android.WritablePaths{libPath},
+ Output: modulePath,
Input: syspropFile,
Implicit: checkApiFileTimeStamp,
Args: map[string]string{
"scope": g.properties.Scope,
- "out_dir": outputDir.String(),
+ "out_dir": moduleDir.String(),
},
})
- g.genSrcs = append(g.genSrcs, libPath)
+ g.BaseSourceProvider.OutputFiles = append(g.BaseSourceProvider.OutputFiles, modulePath)
+ libFileLines = append(libFileLines, fmt.Sprintf("pub mod %s;", moduleName))
}
+
+ libFileSource := strings.Join(libFileLines, "\n")
+ android.WriteFileRule(ctx, libFile, libFileSource)
+
+ return libFile
+}
+
+func (g *syspropRustGenRule) SourceProviderProps() []interface{} {
+ return append(g.BaseSourceProvider.SourceProviderProps(), &g.Properties)
+}
+
+// syspropPathToRustModule takes a path to a .sysprop file and returns the name to use for the
+// corresponding Rust module.
+func syspropPathToRustModule(syspropFilename android.Path) string {
+ filenameBase := strings.TrimSuffix(syspropFilename.Base(), ".sysprop")
+ return strings.ToLower(filenameBase)
}
func (g *syspropRustGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -180,15 +200,13 @@
ctx.AddFarVariationDependencies(nil, nil, proptools.String(g.properties.Check_api))
}
-func (g *syspropRustGenRule) OutputFiles(_ string) (android.Paths, error) {
- return g.genSrcs, nil
-}
-
func syspropRustGenFactory() android.Module {
- g := &syspropRustGenRule{}
- g.AddProperties(&g.properties)
- android.InitAndroidModule(g)
- return g
+ g := &syspropRustGenRule{
+ BaseSourceProvider: rust.NewSourceProvider(),
+ }
+ sourceProvider := rust.NewSourceProviderModule(android.DeviceSupported, g, false, false)
+ sourceProvider.AddProperties(&g.properties)
+ return sourceProvider.Init()
}
type syspropLibrary struct {
@@ -308,10 +326,6 @@
return m.BaseModuleName() + "_java_gen_public"
}
-func (m *syspropLibrary) rustGenModuleName() string {
- return m.rustCrateName() + "_rust_gen"
-}
-
func (m *syspropLibrary) rustGenStubName() string {
return "lib" + m.rustCrateName() + "_rust"
}
@@ -528,6 +542,9 @@
type rustLibraryProperties struct {
Name *string
+ Sysprop_srcs []string `android:"path"`
+ Scope string
+ Check_api *string
Srcs []string
Installable *bool
Crate_name string
@@ -667,18 +684,15 @@
}
// Generate a Rust implementation library.
- ctx.CreateModule(syspropRustGenFactory, &syspropGenProperties{
- Srcs: m.properties.Srcs,
- Scope: scope,
- Name: proptools.StringPtr(m.rustGenModuleName()),
- Check_api: proptools.StringPtr(ctx.ModuleName()),
- })
rustProps := rustLibraryProperties{
- Name: proptools.StringPtr(m.rustGenStubName()),
- Srcs: []string{":" + m.rustGenModuleName()},
- Installable: proptools.BoolPtr(false),
- Crate_name: m.rustCrateName(),
+ Name: proptools.StringPtr(m.rustGenStubName()),
+ Sysprop_srcs: m.properties.Srcs,
+ Scope: scope,
+ Check_api: proptools.StringPtr(ctx.ModuleName()),
+ Installable: proptools.BoolPtr(false),
+ Crate_name: m.rustCrateName(),
Rustlibs: []string{
+ "liblog_rust",
"librustutils",
},
Vendor_available: m.properties.Vendor_available,
@@ -686,7 +700,7 @@
Apex_available: m.ApexProperties.Apex_available,
Min_sdk_version: proptools.StringPtr("29"),
}
- ctx.CreateModule(rust.RustLibraryFactory, &rustProps)
+ ctx.CreateModule(syspropRustGenFactory, &rustProps)
// syspropLibraries will be used by property_contexts to check types.
// Record absolute paths of sysprop_library to prevent soong_namespace problem.
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 9dd696f..dfbbe7d 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -72,6 +72,15 @@
vendor_available: true,
min_sdk_version: "29",
}
+
+ rust_library {
+ name: "liblog_rust",
+ crate_name: "log",
+ srcs: ["log/src/lib.rs"],
+ product_available: true,
+ vendor_available: true,
+ min_sdk_version: "29",
+ }
`
mockFS := android.MockFS{
@@ -115,6 +124,7 @@
"com/android2/OdmProperties.sysprop": nil,
"librustutils/lib.rs": nil,
+ "log/src/lib.rs": nil,
}
result := android.GroupFixturePreparers(
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 2f25a8c..81c678d 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -94,7 +94,6 @@
"gcert": Allowed,
"gcertstatus": Allowed,
"gcloud": Allowed,
- "getopt": Allowed,
"git": Allowed,
"hexdump": Allowed,
"jar": Allowed,