Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability almost always use identical command line arguments to build but with different intermediates directories. This causes unnecessary build time and disk space for duplicated work. Deduplicate APEX variants that would build identically. Create aliases from the per-APEX variations to the new shared variations so that the APEX modules can continue to depend on them via the APEX name as the variation. This has one significant change in behavior. Before this change, if an APEX had two libraries in its direct dependencies and one of those libraries depended on the other, and the second library had stubs, then the first library would depend on the implementation of the second library and not the stubs. After this change, if the first library is also present in a second APEX but the second library is not, then the common variant shared between the two APEXes would use the stubs, not the implementation. In a correctly configured set of build rules this change will be irrelevant, because if the compilation worked for the second APEX using stubs then it will work for the common variant using stubs. However, if an incorrect change to the build rules is made this could lead to confusing errors, as a previously-working common variant could suddenly stop building when a module is added to a new APEX without its dependencies that require implementation APIs to compile. This change reduces the number of modules in an AOSP arm64-userdebug build by 3% (52242 to 50586), reduces the number of variants of the libcutils module from 74 to 53, and reduces the number of variants of the massive libart[d] modules from 44 to 32. Bug: 164216768 Test: go test ./build/soong/apex/... Change-Id: I0529837476a253c32b3dfb98dcccf107427c742c
This commit is contained in:
parent
8cb67e4358
commit
d6b2525b00
126
android/apex.go
126
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 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 {
|
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,22 @@ func (m *ApexModuleBase) TestFor() []string {
|
||||||
return nil
|
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) {
|
func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
|
||||||
m.apexVariationsLock.Lock()
|
m.apexVariationsLock.Lock()
|
||||||
defer m.apexVariationsLock.Unlock()
|
defer m.apexVariationsLock.Unlock()
|
||||||
|
@ -190,14 +231,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 +319,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 +374,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 +416,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 +434,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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1769,6 +1769,9 @@ func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module
|
||||||
|
|
||||||
func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
|
func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
|
||||||
b.bp.VisitDirectDeps(func(module blueprint.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 {
|
if aModule := b.validateAndroidModule(module, b.strictVisitDeps); aModule != nil {
|
||||||
visit(aModule)
|
visit(aModule)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -4812,8 +4853,8 @@ func TestJavaSDKLibrary(t *testing.T) {
|
||||||
"etc/permissions/foo.xml",
|
"etc/permissions/foo.xml",
|
||||||
})
|
})
|
||||||
// Permission XML should point to the activated path of impl jar of java_sdk_library
|
// 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")
|
sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_apex10000").Rule("java_sdk_xml")
|
||||||
ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\"`)
|
ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/apex10000/javalib/foo.jar\"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJavaSDKLibrary_WithinApex(t *testing.T) {
|
func TestJavaSDKLibrary_WithinApex(t *testing.T) {
|
||||||
|
@ -4857,7 +4898,7 @@ func TestJavaSDKLibrary_WithinApex(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// The bar library should depend on the implementation jar.
|
// 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) {
|
if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
|
||||||
t.Errorf("expected %q, found %#q", expected, actual)
|
t.Errorf("expected %q, found %#q", expected, actual)
|
||||||
}
|
}
|
||||||
|
@ -4987,7 +5028,7 @@ func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// The bar library should depend on the implementation jar.
|
// 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) {
|
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)
|
t.Errorf("expected %q, found %#q", expected, actual)
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
|
|
@ -1376,22 +1376,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 {
|
||||||
|
@ -1410,7 +1410,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 {
|
||||||
|
@ -1949,7 +1949,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 {
|
||||||
|
|
|
@ -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())
|
||||||
|
|
Loading…
Reference in New Issue