Merge "Add a tagged output for app's exportPackage"
diff --git a/android/apex.go b/android/apex.go
index 8c06b63..83a7fe1 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -29,11 +29,22 @@
)
type ApexInfo struct {
- // Name of the apex variant that this module is mutated into
- ApexName string
+ // Name of the apex variation that this module is mutated into
+ ApexVariationName string
MinSdkVersion int
Updatable bool
+ RequiredSdks SdkRefs
+
+ InApexes []string
+}
+
+func (i ApexInfo) mergedName() string {
+ name := "apex" + strconv.Itoa(i.MinSdkVersion)
+ for _, sdk := range i.RequiredSdks {
+ name += "_" + sdk.Name + "_" + sdk.Version
+ }
+ return name
}
// Extracted from ApexModule to make it easier to define custom subsets of the
@@ -69,19 +80,22 @@
// Call this before apex.apexMutator is run.
BuildForApex(apex ApexInfo)
- // Returns the APEXes that this module will be built for
- ApexVariations() []ApexInfo
-
- // Returns the name of APEX that this module will be built for. Empty string
- // is returned when 'IsForPlatform() == true'. Note that a module can be
- // included in multiple APEXes, in which case, the module is mutated into
- // multiple modules each of which for an APEX. This method returns the
- // name of the APEX that a variant module is for.
+ // Returns the name of APEX variation that this module will be built for.
+ // Empty string is returned when 'IsForPlatform() == true'. Note that a
+ // module can beincluded in multiple APEXes, in which case, the module
+ // is mutated into one or more variants, each of which is for one or
+ // more APEXes. This method returns the name of the APEX variation of
+ // the module.
// Call this after apex.apexMutator is run.
- ApexName() string
+ ApexVariationName() string
+
+ // Returns the name of the APEX modules that this variant of this module
+ // is present in.
+ // Call this after apex.apexMutator is run.
+ InApexes() []string
// Tests whether this module will be built for the platform or not.
- // This is a shortcut for ApexName() == ""
+ // This is a shortcut for ApexVariationName() == ""
IsForPlatform() bool
// Tests if this module could have APEX variants. APEX variants are
@@ -128,6 +142,15 @@
// Returns nil if this module supports sdkVersion
// Otherwise, returns error with reason
ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion int) error
+
+ // Returns true if this module needs a unique variation per apex, for example if
+ // use_apex_name_macro is set.
+ UniqueApexVariations() bool
+
+ // UpdateUniqueApexVariationsForDeps sets m.uniqueApexVariationsForDeps if any dependencies
+ // that are in the same APEX have unique APEX variations so that the module can link against
+ // the right variant.
+ UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext)
}
type ApexProperties struct {
@@ -144,6 +167,8 @@
Info ApexInfo `blueprint:"mutated"`
NotAvailableForPlatform bool `blueprint:"mutated"`
+
+ UniqueApexVariationsForDeps bool `blueprint:"mutated"`
}
// Marker interface that identifies dependencies that are excluded from APEX
@@ -179,27 +204,43 @@
return nil
}
+func (m *ApexModuleBase) UniqueApexVariations() bool {
+ return false
+}
+
+func (m *ApexModuleBase) UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext) {
+ mctx.VisitDirectDeps(func(dep Module) {
+ if depApexModule, ok := dep.(ApexModule); ok {
+ if depApexModule.DepIsInSameApex(mctx, depApexModule) &&
+ (depApexModule.UniqueApexVariations() ||
+ depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) {
+ m.ApexProperties.UniqueApexVariationsForDeps = true
+ }
+ }
+ })
+}
+
func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
m.apexVariationsLock.Lock()
defer m.apexVariationsLock.Unlock()
for _, v := range m.apexVariations {
- if v.ApexName == apex.ApexName {
+ if v.ApexVariationName == apex.ApexVariationName {
return
}
}
m.apexVariations = append(m.apexVariations, apex)
}
-func (m *ApexModuleBase) ApexVariations() []ApexInfo {
- return m.apexVariations
+func (m *ApexModuleBase) ApexVariationName() string {
+ return m.ApexProperties.Info.ApexVariationName
}
-func (m *ApexModuleBase) ApexName() string {
- return m.ApexProperties.Info.ApexName
+func (m *ApexModuleBase) InApexes() []string {
+ return m.ApexProperties.Info.InApexes
}
func (m *ApexModuleBase) IsForPlatform() bool {
- return m.ApexProperties.Info.ApexName == ""
+ return m.ApexProperties.Info.ApexVariationName == ""
}
func (m *ApexModuleBase) CanHaveApexVariants() bool {
@@ -276,17 +317,48 @@
func (a byApexName) Len() int { return len(a) }
func (a byApexName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a byApexName) Less(i, j int) bool { return a[i].ApexName < a[j].ApexName }
+func (a byApexName) Less(i, j int) bool { return a[i].ApexVariationName < a[j].ApexVariationName }
+
+// mergeApexVariations deduplicates APEX variations that would build identically into a common
+// variation. It returns the reduced list of variations and a list of aliases from the original
+// variation names to the new variation names.
+func mergeApexVariations(apexVariations []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
+ sort.Sort(byApexName(apexVariations))
+ seen := make(map[string]int)
+ for _, apexInfo := range apexVariations {
+ apexName := apexInfo.ApexVariationName
+ mergedName := apexInfo.mergedName()
+ if index, exists := seen[mergedName]; exists {
+ merged[index].InApexes = append(merged[index].InApexes, apexName)
+ merged[index].Updatable = merged[index].Updatable || apexInfo.Updatable
+ } else {
+ seen[mergedName] = len(merged)
+ apexInfo.ApexVariationName = apexInfo.mergedName()
+ apexInfo.InApexes = CopyOf(apexInfo.InApexes)
+ merged = append(merged, apexInfo)
+ }
+ aliases = append(aliases, [2]string{apexName, mergedName})
+ }
+ return merged, aliases
+}
func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Module {
if len(m.apexVariations) > 0 {
m.checkApexAvailableProperty(mctx)
- sort.Sort(byApexName(m.apexVariations))
+ var apexVariations []ApexInfo
+ var aliases [][2]string
+ if !mctx.Module().(ApexModule).UniqueApexVariations() && !m.ApexProperties.UniqueApexVariationsForDeps {
+ apexVariations, aliases = mergeApexVariations(m.apexVariations)
+ } else {
+ apexVariations = m.apexVariations
+ }
+
+ sort.Sort(byApexName(apexVariations))
variations := []string{}
variations = append(variations, "") // Original variation for platform
- for _, apex := range m.apexVariations {
- variations = append(variations, apex.ApexName)
+ for _, apex := range apexVariations {
+ variations = append(variations, apex.ApexVariationName)
}
defaultVariation := ""
@@ -302,9 +374,14 @@
mod.MakeUninstallable()
}
if !platformVariation {
- mod.(ApexModule).apexModuleBase().ApexProperties.Info = m.apexVariations[i-1]
+ mod.(ApexModule).apexModuleBase().ApexProperties.Info = apexVariations[i-1]
}
}
+
+ for _, alias := range aliases {
+ mctx.CreateAliasVariation(alias[0], alias[1])
+ }
+
return modules
}
return nil
@@ -338,7 +415,10 @@
apexesForModule = make(map[string]bool)
apexNamesMap()[moduleName] = apexesForModule
}
- apexesForModule[apex.ApexName] = apexesForModule[apex.ApexName] || directDep
+ apexesForModule[apex.ApexVariationName] = apexesForModule[apex.ApexVariationName] || directDep
+ for _, apexName := range apex.InApexes {
+ apexesForModule[apexName] = apexesForModule[apex.ApexVariationName] || directDep
+ }
}
// TODO(b/146393795): remove this when b/146393795 is fixed
@@ -354,12 +434,26 @@
func DirectlyInApex(apexName string, moduleName string) bool {
apexNamesMapMutex.Lock()
defer apexNamesMapMutex.Unlock()
- if apexNames, ok := apexNamesMap()[moduleName]; ok {
- return apexNames[apexName]
+ if apexNamesForModule, ok := apexNamesMap()[moduleName]; ok {
+ return apexNamesForModule[apexName]
}
return false
}
+// Tests whether a module named moduleName is directly depended on by all APEXes
+// in a list of apexNames.
+func DirectlyInAllApexes(apexNames []string, moduleName string) bool {
+ apexNamesMapMutex.Lock()
+ defer apexNamesMapMutex.Unlock()
+ for _, apexName := range apexNames {
+ apexNamesForModule := apexNamesMap()[moduleName]
+ if !apexNamesForModule[apexName] {
+ return false
+ }
+ }
+ return true
+}
+
type hostContext interface {
Host() bool
}
diff --git a/android/apex_test.go b/android/apex_test.go
new file mode 100644
index 0000000..db02833
--- /dev/null
+++ b/android/apex_test.go
@@ -0,0 +1,111 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "reflect"
+ "testing"
+)
+
+func Test_mergeApexVariations(t *testing.T) {
+ tests := []struct {
+ name string
+ in []ApexInfo
+ wantMerged []ApexInfo
+ wantAliases [][2]string
+ }{
+ {
+ name: "single",
+ in: []ApexInfo{
+ {"foo", 10000, false, nil, []string{"foo"}},
+ },
+ wantMerged: []ApexInfo{
+ {"apex10000", 10000, false, nil, []string{"foo"}},
+ },
+ wantAliases: [][2]string{
+ {"foo", "apex10000"},
+ },
+ },
+ {
+ name: "merge",
+ in: []ApexInfo{
+ {"foo", 10000, false, SdkRefs{{"baz", "1"}}, []string{"foo"}},
+ {"bar", 10000, false, SdkRefs{{"baz", "1"}}, []string{"bar"}},
+ },
+ wantMerged: []ApexInfo{
+ {"apex10000_baz_1", 10000, false, SdkRefs{{"baz", "1"}}, []string{"bar", "foo"}},
+ },
+ wantAliases: [][2]string{
+ {"bar", "apex10000_baz_1"},
+ {"foo", "apex10000_baz_1"},
+ },
+ },
+ {
+ name: "don't merge version",
+ in: []ApexInfo{
+ {"foo", 10000, false, nil, []string{"foo"}},
+ {"bar", 30, false, nil, []string{"bar"}},
+ },
+ wantMerged: []ApexInfo{
+ {"apex30", 30, false, nil, []string{"bar"}},
+ {"apex10000", 10000, false, nil, []string{"foo"}},
+ },
+ wantAliases: [][2]string{
+ {"bar", "apex30"},
+ {"foo", "apex10000"},
+ },
+ },
+ {
+ name: "merge updatable",
+ in: []ApexInfo{
+ {"foo", 10000, false, nil, []string{"foo"}},
+ {"bar", 10000, true, nil, []string{"bar"}},
+ },
+ wantMerged: []ApexInfo{
+ {"apex10000", 10000, true, nil, []string{"bar", "foo"}},
+ },
+ wantAliases: [][2]string{
+ {"bar", "apex10000"},
+ {"foo", "apex10000"},
+ },
+ },
+ {
+ name: "don't merge sdks",
+ in: []ApexInfo{
+ {"foo", 10000, false, SdkRefs{{"baz", "1"}}, []string{"foo"}},
+ {"bar", 10000, false, SdkRefs{{"baz", "2"}}, []string{"bar"}},
+ },
+ wantMerged: []ApexInfo{
+ {"apex10000_baz_2", 10000, false, SdkRefs{{"baz", "2"}}, []string{"bar"}},
+ {"apex10000_baz_1", 10000, false, SdkRefs{{"baz", "1"}}, []string{"foo"}},
+ },
+ wantAliases: [][2]string{
+ {"bar", "apex10000_baz_2"},
+ {"foo", "apex10000_baz_1"},
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ gotMerged, gotAliases := mergeApexVariations(tt.in)
+ if !reflect.DeepEqual(gotMerged, tt.wantMerged) {
+ t.Errorf("mergeApexVariations() gotMerged = %v, want %v", gotMerged, tt.wantMerged)
+ }
+ if !reflect.DeepEqual(gotAliases, tt.wantAliases) {
+ t.Errorf("mergeApexVariations() gotAliases = %v, want %v", gotAliases, tt.wantAliases)
+ }
+ })
+ }
+}
diff --git a/android/module.go b/android/module.go
index 6956167..0eb8bc9 100644
--- a/android/module.go
+++ b/android/module.go
@@ -97,6 +97,8 @@
GlobFiles(globPattern string, excludes []string) Paths
IsSymlink(path Path) bool
Readlink(path Path) string
+
+ Namespace() *Namespace
}
// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
@@ -219,7 +221,6 @@
VisitAllModuleVariants(visit func(Module))
GetMissingDependencies() []string
- Namespace() blueprint.Namespace
}
type Module interface {
@@ -1187,7 +1188,7 @@
var deps Paths
- namespacePrefix := ctx.Namespace().(*Namespace).id
+ namespacePrefix := ctx.Namespace().id
if namespacePrefix != "" {
namespacePrefix = namespacePrefix + "-"
}
@@ -1331,7 +1332,7 @@
suffix = append(suffix, ctx.Arch().ArchType.String())
}
if apex, ok := m.module.(ApexModule); ok && !apex.IsForPlatform() {
- suffix = append(suffix, apex.ApexName())
+ suffix = append(suffix, apex.ApexVariationName())
}
ctx.Variable(pctx, "moduleDesc", desc)
@@ -1498,6 +1499,10 @@
return e.kind == systemExtSpecificModule
}
+func (e *earlyModuleContext) Namespace() *Namespace {
+ return e.EarlyModuleContext.Namespace().(*Namespace)
+}
+
type baseModuleContext struct {
bp blueprint.BaseModuleContext
earlyModuleContext
@@ -1764,6 +1769,9 @@
func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
b.bp.VisitDirectDeps(func(module blueprint.Module) {
+ if module == nil {
+ panic("Unexpected nil module in VisitDirectDeps")
+ }
if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
visit(aModule)
}
diff --git a/android/mutator.go b/android/mutator.go
index b70c4ff..40e61de 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -216,6 +216,7 @@
ReplaceDependencies(string)
ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate)
AliasVariation(variationName string)
+ CreateAliasVariation(fromVariationName, toVariationName string)
}
type bottomUpMutatorContext struct {
@@ -436,3 +437,7 @@
func (b *bottomUpMutatorContext) AliasVariation(variationName string) {
b.bp.AliasVariation(variationName)
}
+
+func (b *bottomUpMutatorContext) CreateAliasVariation(fromVariationName, toVariationName string) {
+ b.bp.CreateAliasVariation(fromVariationName, toVariationName)
+}
diff --git a/android/testing.go b/android/testing.go
index 696efb6..8a9134c 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -119,14 +119,24 @@
if module == nil {
// find all the modules that do exist
- allModuleNames := []string{}
+ var allModuleNames []string
+ var allVariants []string
ctx.VisitAllModules(func(m blueprint.Module) {
- allModuleNames = append(allModuleNames, m.(Module).Name()+"("+ctx.ModuleSubDir(m)+")")
+ allModuleNames = append(allModuleNames, ctx.ModuleName(m))
+ if ctx.ModuleName(m) == name {
+ allVariants = append(allVariants, ctx.ModuleSubDir(m))
+ }
})
sort.Strings(allModuleNames)
+ sort.Strings(allVariants)
- panic(fmt.Errorf("failed to find module %q variant %q. All modules:\n %s",
- name, variant, strings.Join(allModuleNames, "\n ")))
+ if len(allVariants) == 0 {
+ panic(fmt.Errorf("failed to find module %q. All modules:\n %s",
+ name, strings.Join(allModuleNames, "\n ")))
+ } else {
+ panic(fmt.Errorf("failed to find module %q variant %q. All variants:\n %s",
+ name, variant, strings.Join(allVariants, "\n ")))
+ }
}
return TestingModule{module}
@@ -384,7 +394,7 @@
if !found {
t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs))
for i, err := range errs {
- t.Errorf("errs[%d] = %s", i, err)
+ t.Errorf("errs[%d] = %q", i, err)
}
}
}
diff --git a/apex/apex.go b/apex/apex.go
index 9905b79..84a1e75 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -549,7 +549,6 @@
"android.hardware.tetheroffload.config-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
"android.hidl.base-V1.0-java",
- "ipmemorystore-aidl-interfaces-java",
"libcgrouprc",
"libcgrouprc_format",
"libtetherutilsjni",
@@ -670,6 +669,7 @@
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
+ ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
ctx.BottomUp("apex", apexMutator).Parallel()
ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
@@ -687,9 +687,11 @@
return
}
apexInfo := android.ApexInfo{
- ApexName: mctx.ModuleName(),
- MinSdkVersion: a.minSdkVersion(mctx),
- Updatable: a.Updatable(),
+ ApexVariationName: mctx.ModuleName(),
+ MinSdkVersion: a.minSdkVersion(mctx),
+ RequiredSdks: a.RequiredSdks(),
+ Updatable: a.Updatable(),
+ InApexes: []string{mctx.ModuleName()},
}
useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
@@ -722,6 +724,17 @@
})
}
+func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) {
+ if !mctx.Module().Enabled() {
+ return
+ }
+ if am, ok := mctx.Module().(android.ApexModule); ok {
+ // Check if any dependencies use unique apex variations. If so, use unique apex variations
+ // for this module.
+ am.UpdateUniqueApexVariationsForDeps(mctx)
+ }
+}
+
// mark if a module cannot be available to platform. A module cannot be available
// to platform if 1) it is explicitly marked as not available (i.e. "//apex_available:platform"
// is absent) or 2) it depends on another module that isn't (or can't be) available to platform
@@ -1798,7 +1811,7 @@
}
// Check for the indirect dependencies if it is considered as part of the APEX
- if am.ApexName() != "" {
+ if android.InList(ctx.ModuleName(), am.InApexes()) {
return do(ctx, parent, am, false /* externalDep */)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index d13ec5f..93fc39f 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -528,13 +528,13 @@
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
// Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
- ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_myapex")
- ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_apex10000")
// Ensure that apex variant is created for the indirect dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
- ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_apex10000")
// Ensure that both direct and indirect deps are copied into apex
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
@@ -723,10 +723,10 @@
ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned")
// Ensure that APEX variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
// Ensure that APEX variant is created for the indirect dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
// Ensure that both direct and indirect deps are copied into apex
ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so")
@@ -800,7 +800,7 @@
// Ensure that direct stubs dep is included
ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with the latest version of stubs for mylib2
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3/mylib2.so")
@@ -808,9 +808,9 @@
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
// Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
- ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_myapex/mylib3.so")
+ ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex10000/mylib3.so")
// .. and not linking to the stubs variant of mylib3
- ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12_myapex/mylib3.so")
+ ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12/mylib3.so")
// Ensure that stubs libs are built without -include flags
mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
@@ -890,7 +890,7 @@
// Ensure that dependency of stubs is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex2").Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with version 10 of libfoo
ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
@@ -1110,18 +1110,21 @@
testcases := []struct {
name string
minSdkVersion string
+ apexVariant string
shouldLink string
shouldNotLink []string
}{
{
name: "should link to the latest",
minSdkVersion: "",
+ apexVariant: "apex10000",
shouldLink: "30",
shouldNotLink: []string{"29"},
},
{
name: "should link to llndk#29",
minSdkVersion: "min_sdk_version: \"29\",",
+ apexVariant: "apex29",
shouldLink: "29",
shouldNotLink: []string{"30"},
},
@@ -1180,13 +1183,13 @@
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"]
ensureContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
for _, ver := range tc.shouldNotLink {
ensureNotContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+ver+"/libbar.so")
}
- mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
+ mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "__LIBBAR_API__="+tc.shouldLink)
})
}
@@ -1241,9 +1244,9 @@
// Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
- mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
- mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_myapex").Rule("cc").Args["cFlags"]
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
+ mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
+ mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_apex10000").Rule("cc").Args["cFlags"]
// For dependency to libc
// Ensure that mylib is linking with the latest version of stubs
@@ -1256,7 +1259,7 @@
// For dependency to libm
// Ensure that mylib is linking with the non-stub (impl) variant
- ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_myapex/libm.so")
+ ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_apex10000/libm.so")
// ... and not linking to the stub variant
ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29/libm.so")
// ... and is not compiling with the stub
@@ -1270,7 +1273,7 @@
ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28/libdl.so")
ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29/libdl.so")
// ... and not linking to the non-stub (impl) variant
- ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_myapex/libdl.so")
+ ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_apex10000/libdl.so")
// ... Cflags from stub is correctly exported to mylib
ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
@@ -1359,13 +1362,13 @@
// platform liba is linked to non-stub version
expectLink("liba", "shared", "libz", "shared")
// liba in myapex is linked to #28
- expectLink("liba", "shared_myapex", "libz", "shared_28")
- expectNoLink("liba", "shared_myapex", "libz", "shared_30")
- expectNoLink("liba", "shared_myapex", "libz", "shared")
+ expectLink("liba", "shared_apex29", "libz", "shared_28")
+ expectNoLink("liba", "shared_apex29", "libz", "shared_30")
+ expectNoLink("liba", "shared_apex29", "libz", "shared")
// liba in otherapex is linked to #30
- expectLink("liba", "shared_otherapex", "libz", "shared_30")
- expectNoLink("liba", "shared_otherapex", "libz", "shared_28")
- expectNoLink("liba", "shared_otherapex", "libz", "shared")
+ expectLink("liba", "shared_apex30", "libz", "shared_30")
+ expectNoLink("liba", "shared_apex30", "libz", "shared_28")
+ expectNoLink("liba", "shared_apex30", "libz", "shared")
}
func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
@@ -1418,9 +1421,9 @@
// to distinguish them from finalized and future_api(10000)
// In this test, "R" is assumed not finalized yet( listed in Platform_version_active_codenames) and translated into 9000
// (refer android/api_levels.go)
- expectLink("libx", "shared_myapex", "libz", "shared_9000")
- expectNoLink("libx", "shared_myapex", "libz", "shared_29")
- expectNoLink("libx", "shared_myapex", "libz", "shared")
+ expectLink("libx", "shared_apex10000", "libz", "shared_9000")
+ expectNoLink("libx", "shared_apex10000", "libz", "shared_29")
+ expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
@@ -1463,9 +1466,9 @@
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_myapex", "libz", "shared_2")
- expectNoLink("libx", "shared_myapex", "libz", "shared_1")
- expectNoLink("libx", "shared_myapex", "libz", "shared")
+ expectLink("libx", "shared_apex10000", "libz", "shared_2")
+ expectNoLink("libx", "shared_apex10000", "libz", "shared_1")
+ expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
@@ -1549,7 +1552,7 @@
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_hwasan_myapex", "libbar", "shared_30")
+ expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_30")
}
func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
@@ -1575,7 +1578,7 @@
`)
// ensure apex variant of c++ is linked with static unwinder
- cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module)
+ cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_apex29").Module().(*cc.Module)
ensureListContains(t, cm.Properties.AndroidMkStaticLibs, "libgcc_stripped")
// note that platform variant is not.
cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
@@ -1937,8 +1940,8 @@
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("mylib", "shared_myapex", "mylib2", "shared_29")
- expectLink("mylib", "shared_otherapex", "mylib2", "shared_otherapex")
+ expectLink("mylib", "shared_apex29", "mylib2", "shared_29")
+ expectLink("mylib", "shared_apex30", "mylib2", "shared_apex30")
}
func TestFilesInSubDir(t *testing.T) {
@@ -2107,12 +2110,12 @@
inputsString := strings.Join(inputsList, " ")
// ensure that the apex includes vendor variants of the direct and indirect deps
- ensureContains(t, inputsString, "android_vendor.VER_arm64_armv8-a_shared_myapex/mylib.so")
- ensureContains(t, inputsString, "android_vendor.VER_arm64_armv8-a_shared_myapex/mylib2.so")
+ ensureContains(t, inputsString, "android_vendor.VER_arm64_armv8-a_shared_apex10000/mylib.so")
+ ensureContains(t, inputsString, "android_vendor.VER_arm64_armv8-a_shared_apex10000/mylib2.so")
// ensure that the apex does not include core variants
- ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_myapex/mylib.so")
- ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_myapex/mylib2.so")
+ ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_apex10000/mylib.so")
+ ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_apex10000/mylib2.so")
}
func TestUseVendorNotAllowedForSystemApexes(t *testing.T) {
@@ -2250,13 +2253,13 @@
vendorVariant := "android_vendor.VER_arm64_armv8-a"
- ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_myapex").Rule("ld")
+ ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_apex10000").Rule("ld")
libs := names(ldRule.Args["libFlags"])
// VNDK libs(libvndk/libc++) as they are
ensureListContains(t, libs, buildDir+"/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
ensureListContains(t, libs, buildDir+"/.intermediates/libc++/"+vendorVariant+"_shared/libc++.so")
// non-stable Vendor libs as APEX variants
- ensureListContains(t, libs, buildDir+"/.intermediates/libvendor/"+vendorVariant+"_shared_myapex/libvendor.so")
+ ensureListContains(t, libs, buildDir+"/.intermediates/libvendor/"+vendorVariant+"_shared_apex10000/libvendor.so")
// VNDK libs are not included when use_vndk_as_stable: true
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
@@ -2633,7 +2636,21 @@
"myapex",
"otherapex",
],
+ static_libs: ["mylib3"],
+ recovery_available: true,
+ min_sdk_version: "29",
+ }
+ cc_library {
+ name: "mylib3",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [
+ "myapex",
+ "otherapex",
+ ],
use_apex_name_macro: true,
+ recovery_available: true,
min_sdk_version: "29",
}
`)
@@ -2644,19 +2661,43 @@
ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
- mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=10000")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
- mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=29")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
- // When cc_library sets use_apex_name_macro: true
- // apex variants define additional macro to distinguish which apex variant it is built for
+ // When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and
+ // each variant defines additional macros to distinguish which apex variant it is built for
+
+ // non-APEX variant does not have __ANDROID_APEX__ defined
+ mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
+
+ // APEX variant has __ANDROID_APEX__ defined
+ mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
+ ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
+ ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
+
+ // APEX variant has __ANDROID_APEX__ defined
+ mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
+ ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+ ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
+
+ // recovery variant does not set __ANDROID_SDK_VERSION__
+ mylibCFlags = ctx.ModuleForTests("mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
+
+ // When a dependency of a cc_library sets use_apex_name_macro: true each apex gets a unique
+ // variant.
// non-APEX variant does not have __ANDROID_APEX__ defined
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
@@ -2665,17 +2706,17 @@
// APEX variant has __ANDROID_APEX__ defined
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
// APEX variant has __ANDROID_APEX__ defined
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
// recovery variant does not set __ANDROID_SDK_VERSION__
- mylibCFlags = ctx.ModuleForTests("mylib", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ mylibCFlags = ctx.ModuleForTests("mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
}
@@ -3455,7 +3496,7 @@
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
// Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000")
// Ensure that both direct and indirect deps are copied into apex
ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
@@ -3511,7 +3552,7 @@
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
// Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared_apex10000")
// Ensure that both direct and indirect deps are copied into apex
ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so")
@@ -3595,9 +3636,9 @@
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
// Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_myapex")
- ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000")
+ ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
// Ensure that both direct and indirect deps are copied into apex
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
@@ -4062,8 +4103,8 @@
apexRule2 := module2.Rule("apexRule")
copyCmds2 := apexRule2.Args["copy_commands"]
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
- ensureListContains(t, ctx.ModuleVariantsForTests("libcommon"), "android_arm64_armv8-a_shared_commonapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("libcommon"), "android_arm64_armv8-a_shared_apex10000")
ensureContains(t, copyCmds1, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds2, "image.apex/lib64/libcommon.so")
ensureNotContains(t, copyCmds1, "image.apex/lib64/libcommon.so")
@@ -4243,14 +4284,14 @@
ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.apk")
- appZipRule := ctx.ModuleForTests("AppFoo", "android_common_myapex").Description("zip jni libs")
+ appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs")
// JNI libraries are uncompressed
if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") {
t.Errorf("jni libs are not uncompressed for AppFoo")
}
// JNI libraries including transitive deps are
for _, jni := range []string{"libjni", "libfoo"} {
- jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_myapex").Module().(*cc.Module).OutputFile()
+ jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_apex10000").Module().(*cc.Module).OutputFile()
// ... embedded inside APK (jnilibs.zip)
ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
// ... and not directly inside the APEX
@@ -4764,7 +4805,7 @@
// the dependency names directly here but for some reason the names are blank in
// this test.
for _, lib := range []string{"libc++", "mylib"} {
- apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_myapex").Rule("ld").Implicits
+ apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_apex29").Rule("ld").Implicits
nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits
if len(apexImplicits) != len(nonApexImplicits)+1 {
t.Errorf("%q missing unwinder dep", lib)
@@ -4812,8 +4853,8 @@
"etc/permissions/foo.xml",
})
// Permission XML should point to the activated path of impl jar of java_sdk_library
- sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Rule("java_sdk_xml")
- ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\"`)
+ sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_apex10000").Rule("java_sdk_xml")
+ ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/apex10000/javalib/foo.jar\"`)
}
func TestJavaSDKLibrary_WithinApex(t *testing.T) {
@@ -4857,7 +4898,7 @@
})
// The bar library should depend on the implementation jar.
- barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
+ barLibrary := ctx.ModuleForTests("bar", "android_common_apex10000").Rule("javac")
if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
@@ -4987,7 +5028,7 @@
})
// The bar library should depend on the implementation jar.
- barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
+ barLibrary := ctx.ModuleForTests("bar", "android_common_apex10000").Rule("javac")
if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.impl\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
@@ -5616,7 +5657,7 @@
})
t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
- err = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image"
+ err = `module "some-art-lib" from updatable apexes \["com.android.art.something"\] is not allowed in the framework boot image`
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = android.CreateConfiguredJarList(ctx, []string{"com.android.art.something:some-art-lib"})
}
@@ -5624,7 +5665,7 @@
})
t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- err = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image"
+ err = `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the ART boot image`
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"some-updatable-apex:some-updatable-apex-lib"})
}
@@ -5632,7 +5673,7 @@
})
t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- err = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image"
+ err = `module "some-non-updatable-apex-lib" is not allowed in the ART boot image`
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
}
@@ -5640,7 +5681,7 @@
})
t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) {
- err = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
+ err = `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the framework boot image`
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = android.CreateConfiguredJarList(ctx, []string{"some-updatable-apex:some-updatable-apex-lib"})
}
@@ -5671,7 +5712,7 @@
})
t.Run("platform jar in the ART boot image => error", func(t *testing.T) {
- err = "module 'some-platform-lib' is not allowed in the ART boot image"
+ err = `module "some-platform-lib" is not allowed in the ART boot image`
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"platform:some-platform-lib"})
}
diff --git a/cc/binary.go b/cc/binary.go
index 63bbd83..6769fa7 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -445,7 +445,7 @@
// The original path becomes a symlink to the corresponding file in the
// runtime APEX.
translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
- if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !translatedArch && ctx.apexName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() {
+ if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() {
if ctx.Device() && isBionic(ctx.baseModuleName()) {
binary.installSymlinkToRuntimeApex(ctx, file)
}
diff --git a/cc/cc.go b/cc/cc.go
index 9e1c172..9bf9c84 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -344,7 +344,7 @@
isNDKStubLibrary() bool
useClangLld(actx ModuleContext) bool
isForPlatform() bool
- apexName() string
+ apexVariationName() string
apexSdkVersion() int
hasStubsVariants() bool
isStubs() bool
@@ -969,7 +969,7 @@
}
func (c *Module) IsNdk() bool {
- return inList(c.Name(), ndkKnownLibs)
+ return inList(c.BaseModuleName(), ndkKnownLibs)
}
func (c *Module) isLlndk(config android.Config) bool {
@@ -1290,8 +1290,8 @@
return ctx.mod.IsForPlatform()
}
-func (ctx *moduleContextImpl) apexName() string {
- return ctx.mod.ApexName()
+func (ctx *moduleContextImpl) apexVariationName() string {
+ return ctx.mod.ApexVariationName()
}
func (ctx *moduleContextImpl) apexSdkVersion() int {
@@ -2390,7 +2390,7 @@
if ccDep.CcLibrary() && !libDepTag.static() {
depIsStubs := ccDep.BuildStubs()
depHasStubs := VersionVariantAvailable(c) && ccDep.HasStubsVariants()
- depInSameApex := android.DirectlyInApex(c.ApexName(), depName)
+ depInSameApexes := android.DirectlyInAllApexes(c.InApexes(), depName)
depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
var useThisDep bool
@@ -2420,9 +2420,9 @@
}
}
} else {
- // If building for APEX, use stubs only when it is not from
- // the same APEX
- useThisDep = (depInSameApex != depIsStubs)
+ // If building for APEX, use stubs when the parent is in any APEX that
+ // the child is not in.
+ useThisDep = (depInSameApexes != depIsStubs)
}
// when to use (unspecified) stubs, check min_sdk_version and choose the right one
@@ -2446,7 +2446,7 @@
// by default, use current version of LLNDK
versionToUse := ""
versions := stubsVersionsFor(ctx.Config())[depName]
- if c.ApexName() != "" && len(versions) > 0 {
+ if c.ApexVariationName() != "" && len(versions) > 0 {
// if this is for use_vendor apex && dep has stubsVersions
// apply the same rule of apex sdk enforcement to choose right version
var err error
@@ -2895,6 +2895,16 @@
}
}
+func (c *Module) UniqueApexVariations() bool {
+ if u, ok := c.compiler.(interface {
+ uniqueApexVariations() bool
+ }); ok {
+ return u.uniqueApexVariations()
+ } else {
+ return false
+ }
+}
+
// Return true if the module is ever installable.
func (c *Module) EverInstallable() bool {
return c.installer != nil &&
diff --git a/cc/compiler.go b/cc/compiler.go
index d0b5b46..e06243b 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -335,10 +335,10 @@
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RECOVERY__")
}
- if ctx.apexName() != "" {
+ if ctx.apexVariationName() != "" {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
if Bool(compiler.Properties.Use_apex_name_macro) {
- flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexName())+"__")
+ flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexVariationName())+"__")
}
if ctx.Device() {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_SDK_VERSION__="+strconv.Itoa(ctx.apexSdkVersion()))
@@ -556,6 +556,10 @@
return false
}
+func (compiler *baseCompiler) uniqueApexVariations() bool {
+ return Bool(compiler.Properties.Use_apex_name_macro)
+}
+
// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
// For example, com.android.foo => COM_ANDROID_FOO
func makeDefineString(name string) string {
diff --git a/cc/lto.go b/cc/lto.go
index ed3abe7..9868cdf 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -152,9 +152,7 @@
// Do not recurse down non-static dependencies
if isLibTag {
- // TODO(ccross): the staticUnwinder check is there to maintain existing behavior
- // when adding libraryDependencyTag and should be removed.
- if !libTag.static() || libTag.staticUnwinder {
+ if !libTag.static() {
return false
}
} else {
diff --git a/java/app.go b/java/app.go
index 983efeb..fd84223 100755
--- a/java/app.go
+++ b/java/app.go
@@ -845,9 +845,7 @@
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
- // TODO(ccross): The tag == cc.SharedDepTag() check should be cc.IsSharedDepTag(tag) but
- // was left to maintain behavior when adding libraryDependencyTag.
- if IsJniDepTag(tag) || tag == cc.SharedDepTag() {
+ if IsJniDepTag(tag) || cc.IsSharedDepTag(tag) {
if dep, ok := module.(*cc.Module); ok {
if dep.IsNdk() || dep.IsStubs() {
return false
diff --git a/java/config/config.go b/java/config/config.go
index 2f39c99..05da3b5 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -148,9 +148,9 @@
pctx.HostBinToolVariable("DexpreoptGen", "dexpreopt_gen")
pctx.VariableFunc("REJavaPool", remoteexec.EnvOverrideFunc("RBE_JAVA_POOL", "java16"))
- pctx.VariableFunc("REJavacExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAVAC_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
- pctx.VariableFunc("RED8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_D8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
- pctx.VariableFunc("RER8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_R8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+ pctx.VariableFunc("REJavacExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAVAC_EXEC_STRATEGY", remoteexec.RemoteLocalFallbackExecStrategy))
+ pctx.VariableFunc("RED8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_D8_EXEC_STRATEGY", remoteexec.RemoteLocalFallbackExecStrategy))
+ pctx.VariableFunc("RER8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_R8_EXEC_STRATEGY", remoteexec.RemoteLocalFallbackExecStrategy))
pctx.VariableFunc("RETurbineExecStrategy", remoteexec.EnvOverrideFunc("RBE_TURBINE_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.VariableFunc("RESignApkExecStrategy", remoteexec.EnvOverrideFunc("RBE_SIGNAPK_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.VariableFunc("REJarExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAR_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
@@ -163,7 +163,7 @@
pctx.HostBinToolVariable("ManifestMergerCmd", "manifest-merger")
- pctx.HostBinToolVariable("Class2Greylist", "class2greylist")
+ pctx.HostBinToolVariable("Class2NonSdkList", "class2nonsdklist")
pctx.HostBinToolVariable("HiddenAPI", "hiddenapi")
hostBinToolVariableWithSdkToolsPrebuilt("Aapt2Cmd", "aapt2")
diff --git a/java/config/makevars.go b/java/config/makevars.go
index 708a72a..df447a1 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -75,7 +75,7 @@
ctx.Strict("ANDROID_MANIFEST_MERGER", "${ManifestMergerCmd}")
- ctx.Strict("CLASS2GREYLIST", "${Class2Greylist}")
+ ctx.Strict("CLASS2NONSDKLIST", "${Class2NonSdkList}")
ctx.Strict("HIDDENAPI", "${HiddenAPI}")
ctx.Strict("DEX_FLAGS", "${DexFlags}")
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index b445456..3addc1a 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -262,7 +262,7 @@
apex, isApexModule := module.(android.ApexModule)
fromUpdatableApex := isApexModule && apex.Updatable()
if image.name == artBootImageName {
- if isApexModule && strings.HasPrefix(apex.ApexName(), "com.android.art.") {
+ if isApexModule && len(apex.InApexes()) > 0 && allHavePrefix(apex.InApexes(), "com.android.art.") {
// ok: found the jar in the ART apex
} else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) {
// exception (skip and continue): special "hostdex" platform variant
@@ -272,17 +272,17 @@
return -1, nil
} else if fromUpdatableApex {
// error: this jar is part of an updatable apex other than ART
- ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the ART boot image", name, apex.ApexName())
+ ctx.Errorf("module %q from updatable apexes %q is not allowed in the ART boot image", name, apex.InApexes())
} else {
// error: this jar is part of the platform or a non-updatable apex
- ctx.Errorf("module '%s' is not allowed in the ART boot image", name)
+ ctx.Errorf("module %q is not allowed in the ART boot image", name)
}
} else if image.name == frameworkBootImageName {
if !fromUpdatableApex {
// ok: this jar is part of the platform or a non-updatable apex
} else {
// error: this jar is part of an updatable apex
- ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the framework boot image", name, apex.ApexName())
+ ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apex.InApexes())
}
} else {
panic("unknown boot image: " + image.name)
@@ -291,6 +291,15 @@
return index, jar.DexJarBuildPath()
}
+func allHavePrefix(list []string, prefix string) bool {
+ for _, s := range list {
+ if !strings.HasPrefix(s, prefix) {
+ return false
+ }
+ }
+ return true
+}
+
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig {
// Collect dex jar paths for the boot image modules.
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index b5a0217..63b801a 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -23,8 +23,8 @@
)
var hiddenAPIGenerateCSVRule = pctx.AndroidStaticRule("hiddenAPIGenerateCSV", blueprint.RuleParams{
- Command: "${config.Class2Greylist} --stub-api-flags ${stubAPIFlags} $in $outFlag $out",
- CommandDeps: []string{"${config.Class2Greylist}"},
+ Command: "${config.Class2NonSdkList} --stub-api-flags ${stubAPIFlags} $in $outFlag $out",
+ CommandDeps: []string{"${config.Class2NonSdkList}"},
}, "outFlag", "stubAPIFlags")
type hiddenAPI struct {
diff --git a/java/java.go b/java/java.go
index d5375a5..10c6fd3 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1680,7 +1680,7 @@
j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
j.linter.javaLanguageLevel = flags.javaVersion.String()
j.linter.kotlinLanguageLevel = "1.3"
- if j.ApexName() != "" && ctx.Config().UnbundledBuildApps() {
+ if j.ApexVariationName() != "" && ctx.Config().UnbundledBuildApps() {
j.linter.buildModuleReportZip = true
}
j.linter.lint(ctx)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 25f0134..de16173 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1376,22 +1376,22 @@
return android.Paths{jarPath.Path()}
}
-// Get the apex name for module, "" if it is for platform.
-func getApexNameForModule(module android.Module) string {
+// Get the apex names for module, nil if it is for platform.
+func getApexNamesForModule(module android.Module) []string {
if apex, ok := module.(android.ApexModule); ok {
- return apex.ApexName()
+ return apex.InApexes()
}
- return ""
+ return nil
}
-// Check to see if the other module is within the same named APEX as this module.
+// Check to see if the other module is within the same set of named APEXes as this module.
//
// If either this or the other module are on the platform then this will return
// false.
-func withinSameApexAs(module android.ApexModule, other android.Module) bool {
- name := module.ApexName()
- return name != "" && getApexNameForModule(other) == name
+func withinSameApexesAs(module android.ApexModule, other android.Module) bool {
+ names := module.InApexes()
+ return len(names) > 0 && reflect.DeepEqual(names, getApexNamesForModule(other))
}
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
@@ -1410,7 +1410,7 @@
// Only allow access to the implementation library in the following condition:
// * No sdk_version specified on the referencing module.
// * The referencing module is in the same apex as this.
- if sdkVersion.kind == sdkPrivate || withinSameApexAs(module, ctx.Module()) {
+ if sdkVersion.kind == sdkPrivate || withinSameApexesAs(module, ctx.Module()) {
if headerJars {
return module.HeaderJars()
} else {
@@ -1949,7 +1949,7 @@
// For consistency with SdkLibrary make the implementation jar available to libraries that
// are within the same APEX.
implLibraryModule := module.implLibraryModule
- if implLibraryModule != nil && withinSameApexAs(module, ctx.Module()) {
+ if implLibraryModule != nil && withinSameApexesAs(module, ctx.Module()) {
if headerJars {
return implLibraryModule.HeaderJars()
} else {
@@ -2083,8 +2083,8 @@
// File path to the runtime implementation library
func (module *sdkLibraryXml) implPath() string {
implName := proptools.String(module.properties.Lib_name)
- if apexName := module.ApexName(); apexName != "" {
- // TODO(b/146468504): ApexName() is only a soong module name, not apex name.
+ if apexName := module.ApexVariationName(); apexName != "" {
+ // TODO(b/146468504): ApexVariationName() is only a soong module name, not apex name.
// In most cases, this works fine. But when apex_name is set or override_apex is used
// this can be wrong.
return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, implName)
diff --git a/rust/clippy.go b/rust/clippy.go
index e1f567d..6f0ed7f 100644
--- a/rust/clippy.go
+++ b/rust/clippy.go
@@ -19,8 +19,14 @@
)
type ClippyProperties struct {
- // whether to run clippy.
- Clippy *bool
+ // name of the lint set that should be used to validate this module.
+ //
+ // Possible values are "default" (for using a sensible set of lints
+ // depending on the module's location), "android" (for the strictest
+ // lint set that applies to all Android platform code), "vendor" (for a
+ // relaxed set) and "none" (to disable the execution of clippy). The
+ // default value is "default". See also the `lints` property.
+ Clippy_lints *string
}
type clippy struct {
@@ -32,10 +38,10 @@
}
func (c *clippy) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags, PathDeps) {
- if c.Properties.Clippy != nil && !*c.Properties.Clippy {
- return flags, deps
+ enabled, lints, err := config.ClippyLintsForDir(ctx.ModuleDir(), c.Properties.Clippy_lints)
+ if err != nil {
+ ctx.PropertyErrorf("clippy_lints", err.Error())
}
- enabled, lints := config.ClippyLintsForDir(ctx.ModuleDir())
flags.Clippy = enabled
flags.ClippyFlags = append(flags.ClippyFlags, lints)
return flags, deps
diff --git a/rust/clippy_test.go b/rust/clippy_test.go
index 3144173..7815aab 100644
--- a/rust/clippy_test.go
+++ b/rust/clippy_test.go
@@ -16,31 +16,77 @@
import (
"testing"
+
+ "android/soong/android"
)
func TestClippy(t *testing.T) {
- ctx := testRust(t, `
+
+ bp := `
+ // foo uses the default value of clippy_lints
rust_library {
name: "libfoo",
srcs: ["foo.rs"],
crate_name: "foo",
}
+ // bar forces the use of the "android" lint set
+ rust_library {
+ name: "libbar",
+ srcs: ["foo.rs"],
+ crate_name: "bar",
+ clippy_lints: "android",
+ }
+ // foobar explicitly disable clippy
rust_library {
name: "libfoobar",
srcs: ["foo.rs"],
crate_name: "foobar",
- clippy: false,
- }`)
+ clippy_lints: "none",
+ }`
- ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Output("libfoo.dylib.so")
- fooClippy := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
- if fooClippy.Rule.String() != "android/soong/rust.clippy" {
- t.Errorf("Clippy output (default) for libfoo was not generated: %+v", fooClippy)
+ bp = bp + GatherRequiredDepsForTest()
+
+ fs := map[string][]byte{
+ // Reuse the same blueprint file for subdirectories.
+ "external/Android.bp": []byte(bp),
+ "hardware/Android.bp": []byte(bp),
}
- ctx.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").Output("libfoobar.dylib.so")
- foobarClippy := ctx.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
- if foobarClippy.Rule != nil {
- t.Errorf("Clippy output for libfoobar is not empty")
+ var clippyLintTests = []struct {
+ modulePath string
+ fooFlags string
+ }{
+ {"", "${config.ClippyDefaultLints}"},
+ {"external/", ""},
+ {"hardware/", "${config.ClippyVendorLints}"},
+ }
+
+ for _, tc := range clippyLintTests {
+ t.Run("path="+tc.modulePath, func(t *testing.T) {
+
+ config := android.TestArchConfig(buildDir, nil, bp, fs)
+ ctx := CreateTestContext()
+ ctx.Register(config)
+ _, errs := ctx.ParseFileList(".", []string{tc.modulePath + "Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
+
+ r := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ if r.Args["clippyFlags"] != tc.fooFlags {
+ t.Errorf("Incorrect flags for libfoo: %q, want %q", r.Args["clippyFlags"], tc.fooFlags)
+ }
+
+ r = ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ if r.Args["clippyFlags"] != "${config.ClippyDefaultLints}" {
+ t.Errorf("Incorrect flags for libbar: %q, want %q", r.Args["clippyFlags"], "${config.ClippyDefaultLints}")
+ }
+
+ r = ctx.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ if r.Rule != nil {
+ t.Errorf("libfoobar is setup to use clippy when explicitly disabled: clippyFlags=%q", r.Args["clippyFlags"])
+ }
+
+ })
}
}
diff --git a/rust/compiler.go b/rust/compiler.go
index c39a4a1..ef7fb8c 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -32,8 +32,8 @@
compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
}
-func (compiler *baseCompiler) setNoLint() {
- compiler.Properties.No_lint = proptools.BoolPtr(true)
+func (compiler *baseCompiler) disableLints() {
+ compiler.Properties.Lints = proptools.StringPtr("none")
}
func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
@@ -58,8 +58,14 @@
// path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
Srcs []string `android:"path,arch_variant"`
- // whether to suppress the standard lint flags - default to false
- No_lint *bool
+ // name of the lint set that should be used to validate this module.
+ //
+ // Possible values are "default" (for using a sensible set of lints
+ // depending on the module's location), "android" (for the strictest
+ // lint set that applies to all Android platform code), "vendor" (for
+ // a relaxed set) and "none" (for ignoring all lint warnings and
+ // errors). The default value is "default".
+ Lints *string
// flags to pass to rustc
Flags []string `android:"path,arch_variant"`
@@ -159,11 +165,11 @@
func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
- if Bool(compiler.Properties.No_lint) {
- flags.RustFlags = append(flags.RustFlags, config.AllowAllLints)
- } else {
- flags.RustFlags = append(flags.RustFlags, config.RustcLintsForDir(ctx.ModuleDir()))
+ lintFlags, err := config.RustcLintsForDir(ctx.ModuleDir(), compiler.Properties.Lints)
+ if err != nil {
+ ctx.PropertyErrorf("lints", err.Error())
}
+ flags.RustFlags = append(flags.RustFlags, lintFlags)
flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
flags.RustFlags = append(flags.RustFlags, "--edition="+compiler.edition())
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index b853196..8b9fccc 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -17,6 +17,8 @@
import (
"strings"
"testing"
+
+ "android/soong/android"
)
// Test that feature flags are being correctly generated.
@@ -104,3 +106,74 @@
t.Fatalf("unexpected install path for binary: %#v", install_path_bin)
}
}
+
+func TestLints(t *testing.T) {
+
+ bp := `
+ // foo uses the default value of lints
+ rust_library {
+ name: "libfoo",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ }
+ // bar forces the use of the "android" lint set
+ rust_library {
+ name: "libbar",
+ srcs: ["foo.rs"],
+ crate_name: "bar",
+ lints: "android",
+ }
+ // foobar explicitly disable all lints
+ rust_library {
+ name: "libfoobar",
+ srcs: ["foo.rs"],
+ crate_name: "foobar",
+ lints: "none",
+ }`
+
+ bp = bp + GatherRequiredDepsForTest()
+
+ fs := map[string][]byte{
+ // Reuse the same blueprint file for subdirectories.
+ "external/Android.bp": []byte(bp),
+ "hardware/Android.bp": []byte(bp),
+ }
+
+ var lintTests = []struct {
+ modulePath string
+ fooFlags string
+ }{
+ {"", "${config.RustDefaultLints}"},
+ {"external/", "${config.RustAllowAllLints}"},
+ {"hardware/", "${config.RustVendorLints}"},
+ }
+
+ for _, tc := range lintTests {
+ t.Run("path="+tc.modulePath, func(t *testing.T) {
+
+ config := android.TestArchConfig(buildDir, nil, bp, fs)
+ ctx := CreateTestContext()
+ ctx.Register(config)
+ _, errs := ctx.ParseFileList(".", []string{tc.modulePath + "Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
+
+ r := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ if !strings.Contains(r.Args["rustcFlags"], tc.fooFlags) {
+ t.Errorf("Incorrect flags for libfoo: %q, want %q", r.Args["rustcFlags"], tc.fooFlags)
+ }
+
+ r = ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ if !strings.Contains(r.Args["rustcFlags"], "${config.RustDefaultLints}") {
+ t.Errorf("Incorrect flags for libbar: %q, want %q", r.Args["rustcFlags"], "${config.RustDefaultLints}")
+ }
+
+ r = ctx.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ if !strings.Contains(r.Args["rustcFlags"], "${config.RustAllowAllLints}") {
+ t.Errorf("Incorrect flags for libfoobar: %q, want %q", r.Args["rustcFlags"], "${config.RustAllowAllLints}")
+ }
+
+ })
+ }
+}
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 22a0e63..ed9f90b 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -6,6 +6,7 @@
"external/rust",
"external/crosvm",
"external/adhd",
+ "frameworks/native/libs/binder/rust",
"prebuilts/rust",
"system/extras/profcollectd",
"system/security",
diff --git a/rust/config/lints.go b/rust/config/lints.go
index e24ffac..06bb668 100644
--- a/rust/config/lints.go
+++ b/rust/config/lints.go
@@ -15,6 +15,7 @@
package config
import (
+ "fmt"
"strings"
"android/soong/android"
@@ -24,18 +25,21 @@
// The Android build system tries to avoid reporting warnings during the build.
// Therefore, by default, we upgrade warnings to denials. For some of these
// lints, an allow exception is setup, using the variables below.
-// There are different default lints depending on the repository location (see
-// DefaultLocalClippyChecks).
+//
// The lints are split into two categories. The first one contains the built-in
// lints (https://doc.rust-lang.org/rustc/lints/index.html). The second is
// specific to Clippy lints (https://rust-lang.github.io/rust-clippy/master/).
//
-// When developing a module, it is possible to use the `no_lint` property to
-// disable the built-in lints configuration. It is also possible to set
-// `clippy` to false to disable the clippy verification. Expect some
-// questioning during review if you enable one of these options. For external/
-// code, if you need to use them, it is likely a bug. Otherwise, it may be
-// useful to add an exception (that is, move a lint from deny to allow).
+// For both categories, there are 3 levels of linting possible:
+// - "android", for the strictest lints that applies to all Android platform code.
+// - "vendor", for relaxed rules.
+// - "none", to disable the linting.
+// There is a fourth option ("default") which automatically selects the linting level
+// based on the module's location. See defaultLintSetForPath.
+//
+// When developing a module, you may set `lints = "none"` and `clippy_lints =
+// "none"` to disable all the linting. Expect some questioning during code review
+// if you enable one of these options.
var (
// Default Rust lints that applies to Google-authored modules.
defaultRustcLints = []string{
@@ -102,13 +106,6 @@
pctx.StaticVariable("RustAllowAllLints", strings.Join(allowAllLints, " "))
}
-type PathBasedClippyConfig struct {
- PathPrefix string
- RustcConfig string
- ClippyEnabled bool
- ClippyConfig string
-}
-
const noLint = ""
const rustcDefault = "${config.RustDefaultLints}"
const rustcVendor = "${config.RustVendorLints}"
@@ -116,36 +113,78 @@
const clippyDefault = "${config.ClippyDefaultLints}"
const clippyVendor = "${config.ClippyVendorLints}"
-// This is a map of local path prefixes to a set of parameters for the linting:
-// - a string for the lints to apply to rustc.
-// - a boolean to indicate if clippy should be executed.
-// - a string for the lints to apply to clippy.
-// The first entry matching will be used.
-var DefaultLocalClippyChecks = []PathBasedClippyConfig{
- {"external/", rustcAllowAll, false, noLint},
- {"hardware/", rustcVendor, true, clippyVendor},
- {"prebuilts/", rustcAllowAll, false, noLint},
- {"vendor/google", rustcDefault, true, clippyDefault},
- {"vendor/", rustcVendor, true, clippyVendor},
+// lintConfig defines a set of lints and clippy configuration.
+type lintConfig struct {
+ rustcConfig string // for the lints to apply to rustc.
+ clippyEnabled bool // to indicate if clippy should be executed.
+ clippyConfig string // for the lints to apply to clippy.
}
-var AllowAllLints = rustcAllowAll
+
+const (
+ androidLints = "android"
+ vendorLints = "vendor"
+ noneLints = "none"
+)
+
+// lintSets defines the categories of linting for Android and their mapping to lintConfigs.
+var lintSets = map[string]lintConfig{
+ androidLints: {rustcDefault, true, clippyDefault},
+ vendorLints: {rustcVendor, true, clippyVendor},
+ noneLints: {rustcAllowAll, false, noLint},
+}
+
+type pathLintSet struct {
+ prefix string
+ set string
+}
+
+// This is a map of local path prefixes to a lint set. The first entry
+// matching will be used. If no entry matches, androidLints ("android") will be
+// used.
+var defaultLintSetForPath = []pathLintSet{
+ {"external", noneLints},
+ {"hardware", vendorLints},
+ {"prebuilts", noneLints},
+ {"vendor/google", androidLints},
+ {"vendor", vendorLints},
+}
// ClippyLintsForDir returns a boolean if Clippy should be executed and if so, the lints to be used.
-func ClippyLintsForDir(dir string) (bool, string) {
- for _, pathCheck := range DefaultLocalClippyChecks {
- if strings.HasPrefix(dir, pathCheck.PathPrefix) {
- return pathCheck.ClippyEnabled, pathCheck.ClippyConfig
+func ClippyLintsForDir(dir string, clippyLintsProperty *string) (bool, string, error) {
+ if clippyLintsProperty != nil {
+ set, ok := lintSets[*clippyLintsProperty]
+ if ok {
+ return set.clippyEnabled, set.clippyConfig, nil
+ }
+ if *clippyLintsProperty != "default" {
+ return false, "", fmt.Errorf("unknown value for `clippy_lints`: %v, valid options are: default, android, vendor or none", *clippyLintsProperty)
}
}
- return true, clippyDefault
+ for _, p := range defaultLintSetForPath {
+ if strings.HasPrefix(dir, p.prefix) {
+ setConfig := lintSets[p.set]
+ return setConfig.clippyEnabled, setConfig.clippyConfig, nil
+ }
+ }
+ return true, clippyDefault, nil
}
// RustcLintsForDir returns the standard lints to be used for a repository.
-func RustcLintsForDir(dir string) string {
- for _, pathCheck := range DefaultLocalClippyChecks {
- if strings.HasPrefix(dir, pathCheck.PathPrefix) {
- return pathCheck.RustcConfig
+func RustcLintsForDir(dir string, lintProperty *string) (string, error) {
+ if lintProperty != nil {
+ set, ok := lintSets[*lintProperty]
+ if ok {
+ return set.rustcConfig, nil
+ }
+ if *lintProperty != "default" {
+ return "", fmt.Errorf("unknown value for `lints`: %v, valid options are: default, android, vendor or none", *lintProperty)
+ }
+
+ }
+ for _, p := range defaultLintSetForPath {
+ if strings.HasPrefix(dir, p.prefix) {
+ return lintSets[p.set].rustcConfig, nil
}
}
- return rustcDefault
+ return rustcDefault, nil
}
diff --git a/rust/rust.go b/rust/rust.go
index 54b2285..b697869 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1046,9 +1046,9 @@
return name
}
-func (mod *Module) setClippy(clippy bool) {
+func (mod *Module) disableClippy() {
if mod.clippy != nil {
- mod.clippy.Properties.Clippy = proptools.BoolPtr(clippy)
+ mod.clippy.Properties.Clippy_lints = proptools.StringPtr("none")
}
}
diff --git a/rust/source_provider.go b/rust/source_provider.go
index 76679c2..e168718 100644
--- a/rust/source_provider.go
+++ b/rust/source_provider.go
@@ -73,8 +73,8 @@
module.compiler = library
if !enableLints {
- library.setNoLint()
- module.setClippy(false)
+ library.disableLints()
+ module.disableClippy()
}
return module
diff --git a/scripts/build-aml-prebuilts.sh b/scripts/build-aml-prebuilts.sh
index c60eaa1..ef5565d 100755
--- a/scripts/build-aml-prebuilts.sh
+++ b/scripts/build-aml-prebuilts.sh
@@ -84,6 +84,8 @@
"CrossHostArch": "x86_64",
"Aml_abis": true,
+ "Allow_missing_dependencies": ${SOONG_ALLOW_MISSING_DEPENDENCIES:-false},
+ "Unbundled_build": ${TARGET_BUILD_UNBUNDLED:-false},
"UseGoma": ${USE_GOMA}
}
EOF
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 9501d88..b8ffc11 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -265,11 +265,11 @@
}
`)
- sdkMemberV1 := result.ModuleForTests("sdkmember_mysdk_1", "android_arm64_armv8-a_shared_myapex").Rule("toc").Output
- sdkMemberV2 := result.ModuleForTests("sdkmember_mysdk_2", "android_arm64_armv8-a_shared_myapex2").Rule("toc").Output
+ sdkMemberV1 := result.ModuleForTests("sdkmember_mysdk_1", "android_arm64_armv8-a_shared_apex10000_mysdk_1").Rule("toc").Output
+ sdkMemberV2 := result.ModuleForTests("sdkmember_mysdk_2", "android_arm64_armv8-a_shared_apex10000_mysdk_2").Rule("toc").Output
- cpplibForMyApex := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_shared_myapex")
- cpplibForMyApex2 := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_shared_myapex2")
+ cpplibForMyApex := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_shared_apex10000_mysdk_1")
+ cpplibForMyApex2 := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_shared_apex10000_mysdk_2")
// Depending on the uses_sdks value, different libs are linked
ensureListContains(t, pathsToStrings(cpplibForMyApex.Rule("ld").Implicits), sdkMemberV1.String())
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 931ca3c..5911c71 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -207,8 +207,8 @@
sdkMemberV1 := result.ctx.ModuleForTests("sdkmember_mysdk_1", "android_common").Rule("combineJar").Output
sdkMemberV2 := result.ctx.ModuleForTests("sdkmember_mysdk_2", "android_common").Rule("combineJar").Output
- javalibForMyApex := result.ctx.ModuleForTests("myjavalib", "android_common_myapex")
- javalibForMyApex2 := result.ctx.ModuleForTests("myjavalib", "android_common_myapex2")
+ javalibForMyApex := result.ctx.ModuleForTests("myjavalib", "android_common_apex10000_mysdk_1")
+ javalibForMyApex2 := result.ctx.ModuleForTests("myjavalib", "android_common_apex10000_mysdk_2")
// Depending on the uses_sdks value, different libs are linked
ensureListContains(t, pathsToStrings(javalibForMyApex.Rule("javac").Implicits), sdkMemberV1.String())
diff --git a/ui/build/rbe.go b/ui/build/rbe.go
index 99107e3..6a26063 100644
--- a/ui/build/rbe.go
+++ b/ui/build/rbe.go
@@ -53,11 +53,14 @@
func getRBEVars(ctx Context, config Config) map[string]string {
rand.Seed(time.Now().UnixNano())
vars := map[string]string{
- "RBE_server_address": fmt.Sprintf("unix://%v/reproxy_%v.sock", absPath(ctx, config.TempDir()), rand.Intn(1000)),
- "RBE_log_path": config.rbeLogPath(),
- "RBE_re_proxy": config.rbeReproxy(),
- "RBE_exec_root": config.rbeExecRoot(),
- "RBE_output_dir": config.rbeStatsOutputDir(),
+ "RBE_log_path": config.rbeLogPath(),
+ "RBE_log_dir": config.logDir(),
+ "RBE_re_proxy": config.rbeReproxy(),
+ "RBE_exec_root": config.rbeExecRoot(),
+ "RBE_output_dir": config.rbeStatsOutputDir(),
+ }
+ if config.StartRBE() {
+ vars["RBE_server_address"] = fmt.Sprintf("unix://%v/reproxy_%v.sock", absPath(ctx, config.TempDir()), rand.Intn(1000))
}
k, v := config.rbeAuth()
vars[k] = v