Merge "Reland: Deduplicate APEX variants that would build identically"
This commit is contained in:
151
android/apex.go
151
android/apex.go
@@ -34,6 +34,17 @@ type ApexInfo struct {
|
|||||||
|
|
||||||
MinSdkVersion int
|
MinSdkVersion int
|
||||||
Updatable bool
|
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
|
// Extracted from ApexModule to make it easier to define custom subsets of the
|
||||||
@@ -69,17 +80,20 @@ type ApexModule interface {
|
|||||||
// Call this before apex.apexMutator is run.
|
// Call this before apex.apexMutator is run.
|
||||||
BuildForApex(apex ApexInfo)
|
BuildForApex(apex ApexInfo)
|
||||||
|
|
||||||
// Returns the APEXes that this module will be built for
|
|
||||||
ApexVariations() []ApexInfo
|
|
||||||
|
|
||||||
// Returns the name of APEX variation that this module will be built for.
|
// Returns the name of APEX variation that this module will be built for.
|
||||||
//Empty string is returned when 'IsForPlatform() == true'. Note that a
|
// Empty string is returned when 'IsForPlatform() == true'. Note that a
|
||||||
// module can be included in multiple APEXes, in which case, the module
|
// module can beincluded in multiple APEXes, in which case, the module
|
||||||
// is mutated into multiple modules each of which for an APEX. This method
|
// is mutated into one or more variants, each of which is for one or
|
||||||
// returns the name of the APEX that a variant module is for.
|
// more APEXes. This method returns the name of the APEX variation of
|
||||||
|
// the module.
|
||||||
// Call this after apex.apexMutator is run.
|
// Call this after apex.apexMutator is run.
|
||||||
ApexVariationName() 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.
|
// Tests whether this module will be built for the platform or not.
|
||||||
// This is a shortcut for ApexVariationName() == ""
|
// This is a shortcut for ApexVariationName() == ""
|
||||||
IsForPlatform() bool
|
IsForPlatform() bool
|
||||||
@@ -128,6 +142,15 @@ type ApexModule interface {
|
|||||||
// Returns nil if this module supports sdkVersion
|
// Returns nil if this module supports sdkVersion
|
||||||
// Otherwise, returns error with reason
|
// Otherwise, returns error with reason
|
||||||
ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion int) error
|
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 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 {
|
type ApexProperties struct {
|
||||||
@@ -144,6 +167,8 @@ type ApexProperties struct {
|
|||||||
Info ApexInfo `blueprint:"mutated"`
|
Info ApexInfo `blueprint:"mutated"`
|
||||||
|
|
||||||
NotAvailableForPlatform bool `blueprint:"mutated"`
|
NotAvailableForPlatform bool `blueprint:"mutated"`
|
||||||
|
|
||||||
|
UniqueApexVariationsForDeps bool `blueprint:"mutated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marker interface that identifies dependencies that are excluded from APEX
|
// Marker interface that identifies dependencies that are excluded from APEX
|
||||||
@@ -179,6 +204,47 @@ func (m *ApexModuleBase) TestFor() []string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ApexModuleBase) UniqueApexVariations() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ApexModuleBase) UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext) {
|
||||||
|
// anyInSameApex returns true if the two ApexInfo lists contain any values in an InApexes list
|
||||||
|
// in common. It is used instead of DepIsInSameApex because it needs to determine if the dep
|
||||||
|
// is in the same APEX due to being directly included, not only if it is included _because_ it
|
||||||
|
// is a dependency.
|
||||||
|
anyInSameApex := func(a, b []ApexInfo) bool {
|
||||||
|
collectApexes := func(infos []ApexInfo) []string {
|
||||||
|
var ret []string
|
||||||
|
for _, info := range infos {
|
||||||
|
ret = append(ret, info.InApexes...)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
aApexes := collectApexes(a)
|
||||||
|
bApexes := collectApexes(b)
|
||||||
|
sort.Strings(bApexes)
|
||||||
|
for _, aApex := range aApexes {
|
||||||
|
index := sort.SearchStrings(bApexes, aApex)
|
||||||
|
if index < len(bApexes) && bApexes[index] == aApex {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
mctx.VisitDirectDeps(func(dep Module) {
|
||||||
|
if depApexModule, ok := dep.(ApexModule); ok {
|
||||||
|
if anyInSameApex(depApexModule.apexModuleBase().apexVariations, m.apexVariations) &&
|
||||||
|
(depApexModule.UniqueApexVariations() ||
|
||||||
|
depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) {
|
||||||
|
m.ApexProperties.UniqueApexVariationsForDeps = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
|
func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
|
||||||
m.apexVariationsLock.Lock()
|
m.apexVariationsLock.Lock()
|
||||||
defer m.apexVariationsLock.Unlock()
|
defer m.apexVariationsLock.Unlock()
|
||||||
@@ -190,14 +256,14 @@ func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
|
|||||||
m.apexVariations = append(m.apexVariations, apex)
|
m.apexVariations = append(m.apexVariations, apex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ApexModuleBase) ApexVariations() []ApexInfo {
|
|
||||||
return m.apexVariations
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ApexModuleBase) ApexVariationName() string {
|
func (m *ApexModuleBase) ApexVariationName() string {
|
||||||
return m.ApexProperties.Info.ApexVariationName
|
return m.ApexProperties.Info.ApexVariationName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ApexModuleBase) InApexes() []string {
|
||||||
|
return m.ApexProperties.Info.InApexes
|
||||||
|
}
|
||||||
|
|
||||||
func (m *ApexModuleBase) IsForPlatform() bool {
|
func (m *ApexModuleBase) IsForPlatform() bool {
|
||||||
return m.ApexProperties.Info.ApexVariationName == ""
|
return m.ApexProperties.Info.ApexVariationName == ""
|
||||||
}
|
}
|
||||||
@@ -278,14 +344,45 @@ 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) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
func (a byApexName) Less(i, j int) bool { return a[i].ApexVariationName < a[j].ApexVariationName }
|
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 {
|
func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Module {
|
||||||
if len(m.apexVariations) > 0 {
|
if len(m.apexVariations) > 0 {
|
||||||
m.checkApexAvailableProperty(mctx)
|
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 := []string{}
|
||||||
variations = append(variations, "") // Original variation for platform
|
variations = append(variations, "") // Original variation for platform
|
||||||
for _, apex := range m.apexVariations {
|
for _, apex := range apexVariations {
|
||||||
variations = append(variations, apex.ApexVariationName)
|
variations = append(variations, apex.ApexVariationName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,9 +399,14 @@ func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Mod
|
|||||||
mod.MakeUninstallable()
|
mod.MakeUninstallable()
|
||||||
}
|
}
|
||||||
if !platformVariation {
|
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 modules
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -339,6 +441,9 @@ func UpdateApexDependency(apex ApexInfo, moduleName string, directDep bool) {
|
|||||||
apexNamesMap()[moduleName] = apexesForModule
|
apexNamesMap()[moduleName] = apexesForModule
|
||||||
}
|
}
|
||||||
apexesForModule[apex.ApexVariationName] = apexesForModule[apex.ApexVariationName] || 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
|
// TODO(b/146393795): remove this when b/146393795 is fixed
|
||||||
@@ -354,12 +459,26 @@ func ClearApexDependency() {
|
|||||||
func DirectlyInApex(apexName string, moduleName string) bool {
|
func DirectlyInApex(apexName string, moduleName string) bool {
|
||||||
apexNamesMapMutex.Lock()
|
apexNamesMapMutex.Lock()
|
||||||
defer apexNamesMapMutex.Unlock()
|
defer apexNamesMapMutex.Unlock()
|
||||||
if apexNames, ok := apexNamesMap()[moduleName]; ok {
|
if apexNamesForModule, ok := apexNamesMap()[moduleName]; ok {
|
||||||
return apexNames[apexName]
|
return apexNamesForModule[apexName]
|
||||||
}
|
}
|
||||||
return false
|
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 {
|
type hostContext interface {
|
||||||
Host() bool
|
Host() bool
|
||||||
}
|
}
|
||||||
|
111
android/apex_test.go
Normal file
111
android/apex_test.go
Normal file
@@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@@ -394,7 +394,7 @@ func FailIfNoMatchingErrors(t *testing.T, pattern string, errs []error) {
|
|||||||
if !found {
|
if !found {
|
||||||
t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs))
|
t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs))
|
||||||
for i, err := range errs {
|
for i, err := range errs {
|
||||||
t.Errorf("errs[%d] = %s", i, err)
|
t.Errorf("errs[%d] = %q", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
apex/apex.go
16
apex/apex.go
@@ -669,6 +669,7 @@ func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
|
|||||||
|
|
||||||
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
|
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
|
||||||
ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
|
ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
|
||||||
|
ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
|
||||||
ctx.BottomUp("apex", apexMutator).Parallel()
|
ctx.BottomUp("apex", apexMutator).Parallel()
|
||||||
ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
|
ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
|
||||||
ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
|
ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
|
||||||
@@ -688,7 +689,9 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) {
|
|||||||
apexInfo := android.ApexInfo{
|
apexInfo := android.ApexInfo{
|
||||||
ApexVariationName: mctx.ModuleName(),
|
ApexVariationName: mctx.ModuleName(),
|
||||||
MinSdkVersion: a.minSdkVersion(mctx),
|
MinSdkVersion: a.minSdkVersion(mctx),
|
||||||
|
RequiredSdks: a.RequiredSdks(),
|
||||||
Updatable: a.Updatable(),
|
Updatable: a.Updatable(),
|
||||||
|
InApexes: []string{mctx.ModuleName()},
|
||||||
}
|
}
|
||||||
|
|
||||||
useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
|
useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
|
||||||
@@ -721,6 +724,17 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// 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"
|
// 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
|
// is absent) or 2) it depends on another module that isn't (or can't be) available to platform
|
||||||
@@ -1797,7 +1811,7 @@ func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.Paylo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for the indirect dependencies if it is considered as part of the APEX
|
// Check for the indirect dependencies if it is considered as part of the APEX
|
||||||
if am.ApexVariationName() != "" {
|
if android.InList(ctx.ModuleName(), am.InApexes()) {
|
||||||
return do(ctx, parent, am, false /* externalDep */)
|
return do(ctx, parent, am, false /* externalDep */)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -528,13 +528,13 @@ func TestBasicApex(t *testing.T) {
|
|||||||
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
|
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
|
||||||
|
|
||||||
// Ensure that apex variant is created for the direct dep
|
// 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")
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_myapex")
|
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_apex10000")
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_myapex")
|
ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_apex10000")
|
||||||
|
|
||||||
// Ensure that apex variant is created for the indirect dep
|
// 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")
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_myapex")
|
ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_apex10000")
|
||||||
|
|
||||||
// Ensure that both direct and indirect deps are copied into apex
|
// Ensure that both direct and indirect deps are copied into apex
|
||||||
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
|
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
|
||||||
@@ -723,10 +723,10 @@ func TestBasicZipApex(t *testing.T) {
|
|||||||
ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned")
|
ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned")
|
||||||
|
|
||||||
// Ensure that APEX variant is created for the direct dep
|
// 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
|
// 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
|
// Ensure that both direct and indirect deps are copied into apex
|
||||||
ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so")
|
ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so")
|
||||||
@@ -800,7 +800,7 @@ func TestApexWithStubs(t *testing.T) {
|
|||||||
// Ensure that direct stubs dep is included
|
// Ensure that direct stubs dep is included
|
||||||
ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
|
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
|
// 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")
|
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3/mylib2.so")
|
||||||
@@ -808,9 +808,9 @@ func TestApexWithStubs(t *testing.T) {
|
|||||||
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
|
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)
|
// 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
|
// .. 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
|
// Ensure that stubs libs are built without -include flags
|
||||||
mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
|
mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
|
||||||
@@ -890,7 +890,7 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||||||
// Ensure that dependency of stubs is not included
|
// Ensure that dependency of stubs is not included
|
||||||
ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
|
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
|
// Ensure that mylib is linking with version 10 of libfoo
|
||||||
ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
|
ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
|
||||||
@@ -1110,18 +1110,21 @@ func TestApexDependsOnLLNDKTransitively(t *testing.T) {
|
|||||||
testcases := []struct {
|
testcases := []struct {
|
||||||
name string
|
name string
|
||||||
minSdkVersion string
|
minSdkVersion string
|
||||||
|
apexVariant string
|
||||||
shouldLink string
|
shouldLink string
|
||||||
shouldNotLink []string
|
shouldNotLink []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "should link to the latest",
|
name: "should link to the latest",
|
||||||
minSdkVersion: "",
|
minSdkVersion: "",
|
||||||
|
apexVariant: "apex10000",
|
||||||
shouldLink: "30",
|
shouldLink: "30",
|
||||||
shouldNotLink: []string{"29"},
|
shouldNotLink: []string{"29"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "should link to llndk#29",
|
name: "should link to llndk#29",
|
||||||
minSdkVersion: "min_sdk_version: \"29\",",
|
minSdkVersion: "min_sdk_version: \"29\",",
|
||||||
|
apexVariant: "apex29",
|
||||||
shouldLink: "29",
|
shouldLink: "29",
|
||||||
shouldNotLink: []string{"30"},
|
shouldNotLink: []string{"30"},
|
||||||
},
|
},
|
||||||
@@ -1180,13 +1183,13 @@ func TestApexDependsOnLLNDKTransitively(t *testing.T) {
|
|||||||
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
|
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
|
||||||
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
|
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")
|
ensureContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
|
||||||
for _, ver := range tc.shouldNotLink {
|
for _, ver := range tc.shouldNotLink {
|
||||||
ensureNotContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+ver+"/libbar.so")
|
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)
|
ensureContains(t, mylibCFlags, "__LIBBAR_API__="+tc.shouldLink)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1241,9 +1244,9 @@ func TestApexWithSystemLibsStubs(t *testing.T) {
|
|||||||
// Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
|
// 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")
|
ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.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"]
|
||||||
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"]
|
||||||
mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_myapex").Rule("cc").Args["cFlags"]
|
mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_apex10000").Rule("cc").Args["cFlags"]
|
||||||
|
|
||||||
// For dependency to libc
|
// For dependency to libc
|
||||||
// Ensure that mylib is linking with the latest version of stubs
|
// Ensure that mylib is linking with the latest version of stubs
|
||||||
@@ -1256,7 +1259,7 @@ func TestApexWithSystemLibsStubs(t *testing.T) {
|
|||||||
|
|
||||||
// For dependency to libm
|
// For dependency to libm
|
||||||
// Ensure that mylib is linking with the non-stub (impl) variant
|
// 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
|
// ... and not linking to the stub variant
|
||||||
ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29/libm.so")
|
ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29/libm.so")
|
||||||
// ... and is not compiling with the stub
|
// ... and is not compiling with the stub
|
||||||
@@ -1270,7 +1273,7 @@ func TestApexWithSystemLibsStubs(t *testing.T) {
|
|||||||
ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28/libdl.so")
|
ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28/libdl.so")
|
||||||
ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29/libdl.so")
|
ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29/libdl.so")
|
||||||
// ... and not linking to the non-stub (impl) variant
|
// ... 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
|
// ... Cflags from stub is correctly exported to mylib
|
||||||
ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
|
ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
|
||||||
ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
|
ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
|
||||||
@@ -1359,13 +1362,13 @@ func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T)
|
|||||||
// platform liba is linked to non-stub version
|
// platform liba is linked to non-stub version
|
||||||
expectLink("liba", "shared", "libz", "shared")
|
expectLink("liba", "shared", "libz", "shared")
|
||||||
// liba in myapex is linked to #28
|
// liba in myapex is linked to #28
|
||||||
expectLink("liba", "shared_myapex", "libz", "shared_28")
|
expectLink("liba", "shared_apex29", "libz", "shared_28")
|
||||||
expectNoLink("liba", "shared_myapex", "libz", "shared_30")
|
expectNoLink("liba", "shared_apex29", "libz", "shared_30")
|
||||||
expectNoLink("liba", "shared_myapex", "libz", "shared")
|
expectNoLink("liba", "shared_apex29", "libz", "shared")
|
||||||
// liba in otherapex is linked to #30
|
// liba in otherapex is linked to #30
|
||||||
expectLink("liba", "shared_otherapex", "libz", "shared_30")
|
expectLink("liba", "shared_apex30", "libz", "shared_30")
|
||||||
expectNoLink("liba", "shared_otherapex", "libz", "shared_28")
|
expectNoLink("liba", "shared_apex30", "libz", "shared_28")
|
||||||
expectNoLink("liba", "shared_otherapex", "libz", "shared")
|
expectNoLink("liba", "shared_apex30", "libz", "shared")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
|
func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
|
||||||
@@ -1418,9 +1421,9 @@ func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
|
|||||||
// to distinguish them from finalized and future_api(10000)
|
// 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
|
// In this test, "R" is assumed not finalized yet( listed in Platform_version_active_codenames) and translated into 9000
|
||||||
// (refer android/api_levels.go)
|
// (refer android/api_levels.go)
|
||||||
expectLink("libx", "shared_myapex", "libz", "shared_9000")
|
expectLink("libx", "shared_apex10000", "libz", "shared_9000")
|
||||||
expectNoLink("libx", "shared_myapex", "libz", "shared_29")
|
expectNoLink("libx", "shared_apex10000", "libz", "shared_29")
|
||||||
expectNoLink("libx", "shared_myapex", "libz", "shared")
|
expectNoLink("libx", "shared_apex10000", "libz", "shared")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
|
func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
|
||||||
@@ -1463,9 +1466,9 @@ func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
|
|||||||
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
|
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")
|
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
|
||||||
}
|
}
|
||||||
expectLink("libx", "shared_myapex", "libz", "shared_2")
|
expectLink("libx", "shared_apex10000", "libz", "shared_2")
|
||||||
expectNoLink("libx", "shared_myapex", "libz", "shared_1")
|
expectNoLink("libx", "shared_apex10000", "libz", "shared_1")
|
||||||
expectNoLink("libx", "shared_myapex", "libz", "shared")
|
expectNoLink("libx", "shared_apex10000", "libz", "shared")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
|
func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
|
||||||
@@ -1549,7 +1552,7 @@ func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) {
|
|||||||
libFlags := ld.Args["libFlags"]
|
libFlags := ld.Args["libFlags"]
|
||||||
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
|
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) {
|
func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
|
||||||
@@ -1575,7 +1578,7 @@ func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
|
|||||||
`)
|
`)
|
||||||
|
|
||||||
// ensure apex variant of c++ is linked with static unwinder
|
// 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")
|
ensureListContains(t, cm.Properties.AndroidMkStaticLibs, "libgcc_stripped")
|
||||||
// note that platform variant is not.
|
// note that platform variant is not.
|
||||||
cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
|
cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
|
||||||
@@ -1937,8 +1940,8 @@ func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion
|
|||||||
libFlags := ld.Args["libFlags"]
|
libFlags := ld.Args["libFlags"]
|
||||||
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
|
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
|
||||||
}
|
}
|
||||||
expectLink("mylib", "shared_myapex", "mylib2", "shared_29")
|
expectLink("mylib", "shared_apex29", "mylib2", "shared_29")
|
||||||
expectLink("mylib", "shared_otherapex", "mylib2", "shared_otherapex")
|
expectLink("mylib", "shared_apex30", "mylib2", "shared_apex30")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilesInSubDir(t *testing.T) {
|
func TestFilesInSubDir(t *testing.T) {
|
||||||
@@ -2107,12 +2110,12 @@ func TestUseVendor(t *testing.T) {
|
|||||||
inputsString := strings.Join(inputsList, " ")
|
inputsString := strings.Join(inputsList, " ")
|
||||||
|
|
||||||
// ensure that the apex includes vendor variants of the direct and indirect deps
|
// 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_apex10000/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/mylib2.so")
|
||||||
|
|
||||||
// ensure that the apex does not include core variants
|
// 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_apex10000/mylib.so")
|
||||||
ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_myapex/mylib2.so")
|
ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_apex10000/mylib2.so")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUseVendorNotAllowedForSystemApexes(t *testing.T) {
|
func TestUseVendorNotAllowedForSystemApexes(t *testing.T) {
|
||||||
@@ -2250,13 +2253,13 @@ func TestVendorApex_use_vndk_as_stable(t *testing.T) {
|
|||||||
|
|
||||||
vendorVariant := "android_vendor.VER_arm64_armv8-a"
|
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"])
|
libs := names(ldRule.Args["libFlags"])
|
||||||
// VNDK libs(libvndk/libc++) as they are
|
// VNDK libs(libvndk/libc++) as they are
|
||||||
ensureListContains(t, libs, buildDir+"/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
|
ensureListContains(t, libs, buildDir+"/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
|
||||||
ensureListContains(t, libs, buildDir+"/.intermediates/libc++/"+vendorVariant+"_shared/libc++.so")
|
ensureListContains(t, libs, buildDir+"/.intermediates/libc++/"+vendorVariant+"_shared/libc++.so")
|
||||||
// non-stable Vendor libs as APEX variants
|
// 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
|
// VNDK libs are not included when use_vndk_as_stable: true
|
||||||
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
|
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
|
||||||
@@ -2633,7 +2636,21 @@ func TestMacro(t *testing.T) {
|
|||||||
"myapex",
|
"myapex",
|
||||||
"otherapex",
|
"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,
|
use_apex_name_macro: true,
|
||||||
|
recovery_available: true,
|
||||||
min_sdk_version: "29",
|
min_sdk_version: "29",
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
@@ -2644,19 +2661,43 @@ func TestMacro(t *testing.T) {
|
|||||||
ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
|
ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
|
||||||
|
|
||||||
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
|
// 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_APEX__")
|
||||||
ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=10000")
|
ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=10000")
|
||||||
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
|
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
|
||||||
|
|
||||||
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
|
// 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_APEX__")
|
||||||
ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=29")
|
ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=29")
|
||||||
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
|
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
|
||||||
|
|
||||||
// When cc_library sets use_apex_name_macro: true
|
// When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and
|
||||||
// apex variants define additional macro to distinguish which apex variant it is built for
|
// 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
|
// non-APEX variant does not have __ANDROID_APEX__ defined
|
||||||
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
|
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
|
||||||
@@ -2665,17 +2706,17 @@ func TestMacro(t *testing.T) {
|
|||||||
// APEX variant has __ANDROID_APEX__ defined
|
// APEX variant has __ANDROID_APEX__ defined
|
||||||
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
|
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__")
|
||||||
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
|
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
|
||||||
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
|
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
|
||||||
|
|
||||||
// APEX variant has __ANDROID_APEX__ defined
|
// APEX variant has __ANDROID_APEX__ defined
|
||||||
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
|
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
|
||||||
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
|
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
|
||||||
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
|
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__
|
// 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_APEX__")
|
||||||
ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
|
ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
|
||||||
}
|
}
|
||||||
@@ -3455,7 +3496,7 @@ func TestNonTestApex(t *testing.T) {
|
|||||||
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
|
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
|
||||||
|
|
||||||
// Ensure that apex variant is created for the direct dep
|
// 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
|
// Ensure that both direct and indirect deps are copied into apex
|
||||||
ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
|
ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
|
||||||
@@ -3511,7 +3552,7 @@ func TestTestApex(t *testing.T) {
|
|||||||
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
|
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
|
||||||
|
|
||||||
// Ensure that apex variant is created for the direct dep
|
// 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
|
// Ensure that both direct and indirect deps are copied into apex
|
||||||
ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so")
|
ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so")
|
||||||
@@ -3595,9 +3636,9 @@ func TestApexWithTarget(t *testing.T) {
|
|||||||
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
|
ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
|
||||||
|
|
||||||
// Ensure that apex variant is created for the direct dep
|
// 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")
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_myapex")
|
ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000")
|
||||||
ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
|
ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
|
||||||
|
|
||||||
// Ensure that both direct and indirect deps are copied into apex
|
// Ensure that both direct and indirect deps are copied into apex
|
||||||
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
|
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
|
||||||
@@ -4062,8 +4103,8 @@ func TestApexUsesOtherApex(t *testing.T) {
|
|||||||
apexRule2 := module2.Rule("apexRule")
|
apexRule2 := module2.Rule("apexRule")
|
||||||
copyCmds2 := apexRule2.Args["copy_commands"]
|
copyCmds2 := apexRule2.Args["copy_commands"]
|
||||||
|
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
|
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("libcommon"), "android_arm64_armv8-a_shared_commonapex")
|
ensureListContains(t, ctx.ModuleVariantsForTests("libcommon"), "android_arm64_armv8-a_shared_apex10000")
|
||||||
ensureContains(t, copyCmds1, "image.apex/lib64/mylib.so")
|
ensureContains(t, copyCmds1, "image.apex/lib64/mylib.so")
|
||||||
ensureContains(t, copyCmds2, "image.apex/lib64/libcommon.so")
|
ensureContains(t, copyCmds2, "image.apex/lib64/libcommon.so")
|
||||||
ensureNotContains(t, copyCmds1, "image.apex/lib64/libcommon.so")
|
ensureNotContains(t, copyCmds1, "image.apex/lib64/libcommon.so")
|
||||||
@@ -4243,14 +4284,14 @@ func TestApexWithApps(t *testing.T) {
|
|||||||
ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
|
ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
|
||||||
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.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
|
// JNI libraries are uncompressed
|
||||||
if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") {
|
if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") {
|
||||||
t.Errorf("jni libs are not uncompressed for AppFoo")
|
t.Errorf("jni libs are not uncompressed for AppFoo")
|
||||||
}
|
}
|
||||||
// JNI libraries including transitive deps are
|
// JNI libraries including transitive deps are
|
||||||
for _, jni := range []string{"libjni", "libfoo"} {
|
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)
|
// ... embedded inside APK (jnilibs.zip)
|
||||||
ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
|
ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
|
||||||
// ... and not directly inside the APEX
|
// ... and not directly inside the APEX
|
||||||
@@ -4764,7 +4805,7 @@ func TestLegacyAndroid10Support(t *testing.T) {
|
|||||||
// the dependency names directly here but for some reason the names are blank in
|
// the dependency names directly here but for some reason the names are blank in
|
||||||
// this test.
|
// this test.
|
||||||
for _, lib := range []string{"libc++", "mylib"} {
|
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
|
nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits
|
||||||
if len(apexImplicits) != len(nonApexImplicits)+1 {
|
if len(apexImplicits) != len(nonApexImplicits)+1 {
|
||||||
t.Errorf("%q missing unwinder dep", lib)
|
t.Errorf("%q missing unwinder dep", lib)
|
||||||
@@ -5616,7 +5657,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
|
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) {
|
transform = func(config *dexpreopt.GlobalConfig) {
|
||||||
config.BootJars = android.CreateConfiguredJarList(ctx, []string{"com.android.art.something:some-art-lib"})
|
config.BootJars = android.CreateConfiguredJarList(ctx, []string{"com.android.art.something:some-art-lib"})
|
||||||
}
|
}
|
||||||
@@ -5624,7 +5665,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
|
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) {
|
transform = func(config *dexpreopt.GlobalConfig) {
|
||||||
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"some-updatable-apex:some-updatable-apex-lib"})
|
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"some-updatable-apex:some-updatable-apex-lib"})
|
||||||
}
|
}
|
||||||
@@ -5632,7 +5673,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
|
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) {
|
transform = func(config *dexpreopt.GlobalConfig) {
|
||||||
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
|
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
|
||||||
}
|
}
|
||||||
@@ -5640,7 +5681,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) {
|
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) {
|
transform = func(config *dexpreopt.GlobalConfig) {
|
||||||
config.BootJars = android.CreateConfiguredJarList(ctx, []string{"some-updatable-apex:some-updatable-apex-lib"})
|
config.BootJars = android.CreateConfiguredJarList(ctx, []string{"some-updatable-apex:some-updatable-apex-lib"})
|
||||||
}
|
}
|
||||||
@@ -5671,7 +5712,7 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("platform jar in the ART boot image => error", func(t *testing.T) {
|
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) {
|
transform = func(config *dexpreopt.GlobalConfig) {
|
||||||
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"platform:some-platform-lib"})
|
config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"platform:some-platform-lib"})
|
||||||
}
|
}
|
||||||
|
18
cc/cc.go
18
cc/cc.go
@@ -2390,7 +2390,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
if ccDep.CcLibrary() && !libDepTag.static() {
|
if ccDep.CcLibrary() && !libDepTag.static() {
|
||||||
depIsStubs := ccDep.BuildStubs()
|
depIsStubs := ccDep.BuildStubs()
|
||||||
depHasStubs := VersionVariantAvailable(c) && ccDep.HasStubsVariants()
|
depHasStubs := VersionVariantAvailable(c) && ccDep.HasStubsVariants()
|
||||||
depInSameApex := android.DirectlyInApex(c.ApexVariationName(), depName)
|
depInSameApexes := android.DirectlyInAllApexes(c.InApexes(), depName)
|
||||||
depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
|
depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
|
||||||
|
|
||||||
var useThisDep bool
|
var useThisDep bool
|
||||||
@@ -2420,9 +2420,9 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If building for APEX, use stubs only when it is not from
|
// If building for APEX, use stubs when the parent is in any APEX that
|
||||||
// the same APEX
|
// the child is not in.
|
||||||
useThisDep = (depInSameApex != depIsStubs)
|
useThisDep = (depInSameApexes != depIsStubs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// when to use (unspecified) stubs, check min_sdk_version and choose the right one
|
// when to use (unspecified) stubs, check min_sdk_version and choose the right one
|
||||||
@@ -2895,6 +2895,16 @@ func (c *Module) TestFor() []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
// Return true if the module is ever installable.
|
||||||
func (c *Module) EverInstallable() bool {
|
func (c *Module) EverInstallable() bool {
|
||||||
return c.installer != nil &&
|
return c.installer != nil &&
|
||||||
|
@@ -556,6 +556,10 @@ func (compiler *baseCompiler) hasSrcExt(ext string) bool {
|
|||||||
return false
|
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
|
// 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
|
// For example, com.android.foo => COM_ANDROID_FOO
|
||||||
func makeDefineString(name string) string {
|
func makeDefineString(name string) string {
|
||||||
|
@@ -262,7 +262,7 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
|
|||||||
apex, isApexModule := module.(android.ApexModule)
|
apex, isApexModule := module.(android.ApexModule)
|
||||||
fromUpdatableApex := isApexModule && apex.Updatable()
|
fromUpdatableApex := isApexModule && apex.Updatable()
|
||||||
if image.name == artBootImageName {
|
if image.name == artBootImageName {
|
||||||
if isApexModule && strings.HasPrefix(apex.ApexVariationName(), "com.android.art.") {
|
if isApexModule && len(apex.InApexes()) > 0 && allHavePrefix(apex.InApexes(), "com.android.art.") {
|
||||||
// ok: found the jar in the ART apex
|
// ok: found the jar in the ART apex
|
||||||
} else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) {
|
} else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) {
|
||||||
// exception (skip and continue): special "hostdex" platform variant
|
// exception (skip and continue): special "hostdex" platform variant
|
||||||
@@ -272,17 +272,17 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
|
|||||||
return -1, nil
|
return -1, nil
|
||||||
} else if fromUpdatableApex {
|
} else if fromUpdatableApex {
|
||||||
// error: this jar is part of an updatable apex other than ART
|
// 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.ApexVariationName())
|
ctx.Errorf("module %q from updatable apexes %q is not allowed in the ART boot image", name, apex.InApexes())
|
||||||
} else {
|
} else {
|
||||||
// error: this jar is part of the platform or a non-updatable apex
|
// 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 {
|
} else if image.name == frameworkBootImageName {
|
||||||
if !fromUpdatableApex {
|
if !fromUpdatableApex {
|
||||||
// ok: this jar is part of the platform or a non-updatable apex
|
// ok: this jar is part of the platform or a non-updatable apex
|
||||||
} else {
|
} else {
|
||||||
// error: this jar is part of an updatable apex
|
// 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.ApexVariationName())
|
ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apex.InApexes())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic("unknown boot image: " + image.name)
|
panic("unknown boot image: " + image.name)
|
||||||
@@ -291,6 +291,15 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
|
|||||||
return index, jar.DexJarBuildPath()
|
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.
|
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
|
||||||
func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig {
|
func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig {
|
||||||
// Collect dex jar paths for the boot image modules.
|
// Collect dex jar paths for the boot image modules.
|
||||||
|
@@ -1375,22 +1375,22 @@ func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) and
|
|||||||
return android.Paths{jarPath.Path()}
|
return android.Paths{jarPath.Path()}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the apex name for module, "" if it is for platform.
|
// Get the apex names for module, nil if it is for platform.
|
||||||
func getApexNameForModule(module android.Module) string {
|
func getApexNamesForModule(module android.Module) []string {
|
||||||
if apex, ok := module.(android.ApexModule); ok {
|
if apex, ok := module.(android.ApexModule); ok {
|
||||||
return apex.ApexVariationName()
|
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
|
// If either this or the other module are on the platform then this will return
|
||||||
// false.
|
// false.
|
||||||
func withinSameApexAs(module android.ApexModule, other android.Module) bool {
|
func withinSameApexesAs(module android.ApexModule, other android.Module) bool {
|
||||||
name := module.ApexVariationName()
|
names := module.InApexes()
|
||||||
return name != "" && getApexNameForModule(other) == name
|
return len(names) > 0 && reflect.DeepEqual(names, getApexNamesForModule(other))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
|
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
|
||||||
@@ -1409,7 +1409,7 @@ func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkS
|
|||||||
// Only allow access to the implementation library in the following condition:
|
// Only allow access to the implementation library in the following condition:
|
||||||
// * No sdk_version specified on the referencing module.
|
// * No sdk_version specified on the referencing module.
|
||||||
// * The referencing module is in the same apex as this.
|
// * 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 {
|
if headerJars {
|
||||||
return module.HeaderJars()
|
return module.HeaderJars()
|
||||||
} else {
|
} else {
|
||||||
@@ -1948,7 +1948,7 @@ func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersio
|
|||||||
// For consistency with SdkLibrary make the implementation jar available to libraries that
|
// For consistency with SdkLibrary make the implementation jar available to libraries that
|
||||||
// are within the same APEX.
|
// are within the same APEX.
|
||||||
implLibraryModule := module.implLibraryModule
|
implLibraryModule := module.implLibraryModule
|
||||||
if implLibraryModule != nil && withinSameApexAs(module, ctx.Module()) {
|
if implLibraryModule != nil && withinSameApexesAs(module, ctx.Module()) {
|
||||||
if headerJars {
|
if headerJars {
|
||||||
return implLibraryModule.HeaderJars()
|
return implLibraryModule.HeaderJars()
|
||||||
} else {
|
} else {
|
||||||
@@ -2064,6 +2064,12 @@ func sdkLibraryXmlFactory() android.Module {
|
|||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (module *sdkLibraryXml) UniqueApexVariations() bool {
|
||||||
|
// sdkLibraryXml needs a unique variation per APEX because the generated XML file contains the path to the
|
||||||
|
// mounted APEX, which contains the name of the APEX.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// from android.PrebuiltEtcModule
|
// from android.PrebuiltEtcModule
|
||||||
func (module *sdkLibraryXml) SubDir() string {
|
func (module *sdkLibraryXml) SubDir() string {
|
||||||
return "permissions"
|
return "permissions"
|
||||||
|
@@ -265,11 +265,11 @@ func TestBasicSdkWithCc(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
sdkMemberV1 := result.ModuleForTests("sdkmember_mysdk_1", "android_arm64_armv8-a_shared_myapex").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_myapex2").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")
|
cpplibForMyApex := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_shared_apex10000_mysdk_1")
|
||||||
cpplibForMyApex2 := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_shared_myapex2")
|
cpplibForMyApex2 := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_shared_apex10000_mysdk_2")
|
||||||
|
|
||||||
// Depending on the uses_sdks value, different libs are linked
|
// Depending on the uses_sdks value, different libs are linked
|
||||||
ensureListContains(t, pathsToStrings(cpplibForMyApex.Rule("ld").Implicits), sdkMemberV1.String())
|
ensureListContains(t, pathsToStrings(cpplibForMyApex.Rule("ld").Implicits), sdkMemberV1.String())
|
||||||
|
@@ -207,8 +207,8 @@ func TestBasicSdkWithJavaLibrary(t *testing.T) {
|
|||||||
sdkMemberV1 := result.ctx.ModuleForTests("sdkmember_mysdk_1", "android_common").Rule("combineJar").Output
|
sdkMemberV1 := result.ctx.ModuleForTests("sdkmember_mysdk_1", "android_common").Rule("combineJar").Output
|
||||||
sdkMemberV2 := result.ctx.ModuleForTests("sdkmember_mysdk_2", "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")
|
javalibForMyApex := result.ctx.ModuleForTests("myjavalib", "android_common_apex10000_mysdk_1")
|
||||||
javalibForMyApex2 := result.ctx.ModuleForTests("myjavalib", "android_common_myapex2")
|
javalibForMyApex2 := result.ctx.ModuleForTests("myjavalib", "android_common_apex10000_mysdk_2")
|
||||||
|
|
||||||
// Depending on the uses_sdks value, different libs are linked
|
// Depending on the uses_sdks value, different libs are linked
|
||||||
ensureListContains(t, pathsToStrings(javalibForMyApex.Rule("javac").Implicits), sdkMemberV1.String())
|
ensureListContains(t, pathsToStrings(javalibForMyApex.Rule("javac").Implicits), sdkMemberV1.String())
|
||||||
|
Reference in New Issue
Block a user