2018-10-02 17:38:19 +02:00
|
|
|
// Copyright 2018 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
|
|
|
|
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
import (
|
2020-02-26 14:45:42 +01:00
|
|
|
"fmt"
|
2019-06-04 00:07:03 +02:00
|
|
|
"sort"
|
2020-02-26 14:45:42 +01:00
|
|
|
"strconv"
|
2020-04-27 18:08:37 +02:00
|
|
|
"strings"
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
"sync"
|
2020-04-07 16:25:44 +02:00
|
|
|
|
|
|
|
"github.com/google/blueprint"
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
)
|
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
|
|
|
|
2020-07-23 07:32:17 +02:00
|
|
|
var (
|
|
|
|
SdkVersion_Android10 = uncheckedFinalApiLevel(29)
|
2020-03-12 10:37:20 +01:00
|
|
|
)
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// ApexInfo describes the metadata common to all modules in an apexBundle.
|
2020-02-13 02:13:25 +01:00
|
|
|
type ApexInfo struct {
|
2020-09-16 03:30:11 +02:00
|
|
|
// Name of the apex variation that this module is mutated into, or "" for
|
|
|
|
// a platform variant. Note that a module can be included in multiple APEXes,
|
|
|
|
// in which case, the module is mutated into one or more variants, each of
|
|
|
|
// which is for one or more APEXes.
|
2020-08-13 20:24:56 +02:00
|
|
|
ApexVariationName string
|
2020-02-13 02:13:25 +01:00
|
|
|
|
2020-07-23 07:32:17 +02:00
|
|
|
// Serialized ApiLevel. Use via MinSdkVersion() method. Cannot be stored in
|
|
|
|
// its struct form because this is cloned into properties structs, and
|
|
|
|
// ApiLevel has private members.
|
|
|
|
MinSdkVersionStr string
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// True if the module comes from an updatable APEX.
|
|
|
|
Updatable bool
|
|
|
|
RequiredSdks SdkRefs
|
|
|
|
|
|
|
|
InApexes []string
|
|
|
|
ApexContents []*ApexContents
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
var ApexInfoProvider = blueprint.NewMutatorProvider(ApexInfo{}, "apex")
|
|
|
|
|
2020-10-02 19:26:04 +02:00
|
|
|
func (i ApexInfo) mergedName(ctx PathContext) string {
|
2020-07-23 07:32:17 +02:00
|
|
|
name := "apex" + strconv.Itoa(i.MinSdkVersion(ctx).FinalOrFutureInt())
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
for _, sdk := range i.RequiredSdks {
|
|
|
|
name += "_" + sdk.Name + "_" + sdk.Version
|
|
|
|
}
|
|
|
|
return name
|
2020-02-13 02:13:25 +01:00
|
|
|
}
|
|
|
|
|
2020-10-02 19:26:04 +02:00
|
|
|
func (this *ApexInfo) MinSdkVersion(ctx PathContext) ApiLevel {
|
2020-07-23 07:32:17 +02:00
|
|
|
return ApiLevelOrPanic(ctx, this.MinSdkVersionStr)
|
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
func (i ApexInfo) IsForPlatform() bool {
|
|
|
|
return i.ApexVariationName == ""
|
|
|
|
}
|
|
|
|
|
2020-10-28 20:20:06 +01:00
|
|
|
func (i ApexInfo) InApex(apex string) bool {
|
|
|
|
for _, a := range i.InApexes {
|
|
|
|
if a == apex {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// ApexTestForInfo stores the contents of APEXes for which this module is a test and thus has
|
|
|
|
// access to APEX internals.
|
|
|
|
type ApexTestForInfo struct {
|
|
|
|
ApexContents []*ApexContents
|
|
|
|
}
|
|
|
|
|
|
|
|
var ApexTestForInfoProvider = blueprint.NewMutatorProvider(ApexTestForInfo{}, "apex_test_for")
|
|
|
|
|
2020-03-30 16:33:32 +02:00
|
|
|
// Extracted from ApexModule to make it easier to define custom subsets of the
|
|
|
|
// ApexModule interface and improve code navigation within the IDE.
|
|
|
|
type DepIsInSameApex interface {
|
|
|
|
// DepIsInSameApex tests if the other module 'dep' is installed to the same
|
|
|
|
// APEX as this module
|
|
|
|
DepIsInSameApex(ctx BaseModuleContext, dep Module) bool
|
|
|
|
}
|
|
|
|
|
2018-10-02 17:38:19 +02:00
|
|
|
// ApexModule is the interface that a module type is expected to implement if
|
|
|
|
// the module has to be built differently depending on whether the module
|
|
|
|
// is destined for an apex or not (installed to one of the regular partitions).
|
|
|
|
//
|
|
|
|
// Native shared libraries are one such module type; when it is built for an
|
|
|
|
// APEX, it should depend only on stable interfaces such as NDK, stable AIDL,
|
|
|
|
// or C APIs from other APEXs.
|
|
|
|
//
|
|
|
|
// A module implementing this interface will be mutated into multiple
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
// variations by apex.apexMutator if it is directly or indirectly included
|
2018-10-02 17:38:19 +02:00
|
|
|
// in one or more APEXs. Specifically, if a module is included in apex.foo and
|
|
|
|
// apex.bar then three apex variants are created: platform, apex.foo and
|
|
|
|
// apex.bar. The platform variant is for the regular partitions
|
|
|
|
// (e.g., /system or /vendor, etc.) while the other two are for the APEXs,
|
|
|
|
// respectively.
|
|
|
|
type ApexModule interface {
|
|
|
|
Module
|
2020-03-30 16:33:32 +02:00
|
|
|
DepIsInSameApex
|
|
|
|
|
2018-10-02 17:38:19 +02:00
|
|
|
apexModuleBase() *ApexModuleBase
|
|
|
|
|
2020-07-22 08:17:19 +02:00
|
|
|
// Marks that this module should be built for the specified APEX.
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
// Call this before apex.apexMutator is run.
|
2020-07-22 08:17:19 +02:00
|
|
|
BuildForApex(apex ApexInfo)
|
apexDepsMutator is a top-down mutator
apex { name: ["myapex"], native_shared_libs: ["libX", "libY"] }
cc_library { name: "libX", shared_libs: ["libY"] }
cc_library { name: "libY", shared_libs: ["libZ"], stubs: {...} }
apexDepsMutator was a bottom up mutator and it uses WalkDeps to traverse
the dependency tree rooted at myapex in a depth-first order. While
traversing the tree, if calls BuildForApex for a module that will be
part of the APEX.
libY is visited twice. Once via libX and once via myapex. If the visit
from libX was before the visit from myapex (since this is a depth-first
traversing), BuildForApex is not called for libY and its dependency
libZ, because libY provides a stub. And then when libY is again visited
via myapex, BuildForApex is correctly called for the module, but not for
its dependencies libZ because the paths from libY to libZ was already
visited.
As a result, the apex variant of libY has a dependency to the non-apex
variant of libZ.
Fixing the problem by changing the mutator a top-down one.
Bug: 148645937
Test: m
Change-Id: Ib2cb28852087c63a568b3fd036504e9261cf0782
2020-02-11 23:53:12 +01:00
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// Returns true if this module is present in any APEXes
|
|
|
|
// directly or indirectly.
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
// Call this after apex.apexMutator is run.
|
2020-09-16 03:30:11 +02:00
|
|
|
InAnyApex() bool
|
2018-10-02 17:38:19 +02:00
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// Returns true if this module is directly in any APEXes.
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
// Call this after apex.apexMutator is run.
|
2020-09-16 03:30:11 +02:00
|
|
|
DirectlyInAnyApex() bool
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// Returns true if any variant of this module is directly in any APEXes.
|
|
|
|
// Call this after apex.apexMutator is run.
|
|
|
|
AnyVariantDirectlyInAnyApex() bool
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
|
|
|
|
// Tests if this module could have APEX variants. APEX variants are
|
2018-10-02 17:38:19 +02:00
|
|
|
// created only for the modules that returns true here. This is useful
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
// for not creating APEX variants for certain types of shared libraries
|
|
|
|
// such as NDK stubs.
|
2018-10-02 17:38:19 +02:00
|
|
|
CanHaveApexVariants() bool
|
|
|
|
|
|
|
|
// Tests if this module can be installed to APEX as a file. For example,
|
|
|
|
// this would return true for shared libs while return false for static
|
|
|
|
// libs.
|
|
|
|
IsInstallableToApex() bool
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
// Tests if this module is available for the specified APEX or ":platform"
|
|
|
|
AvailableFor(what string) bool
|
2019-10-15 08:20:07 +02:00
|
|
|
|
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
|
|
|
// Return true if this module is not available to platform (i.e. apex_available
|
|
|
|
// property doesn't have "//apex_available:platform"), or shouldn't be available
|
|
|
|
// to platform, which is the case when this module depends on other module that
|
|
|
|
// isn't available to platform.
|
|
|
|
NotAvailableForPlatform() bool
|
|
|
|
|
|
|
|
// Mark that this module is not available to platform. Set by the
|
|
|
|
// check-platform-availability mutator in the apex package.
|
|
|
|
SetNotAvailableForPlatform()
|
|
|
|
|
2020-04-13 09:19:48 +02:00
|
|
|
// List of APEXes that this module tests. The module has access to
|
|
|
|
// the private part of the listed APEXes even when it is not included in the
|
|
|
|
// APEXes.
|
|
|
|
TestFor() []string
|
2020-04-15 04:03:39 +02:00
|
|
|
|
|
|
|
// Returns nil if this module supports sdkVersion
|
|
|
|
// Otherwise, returns error with reason
|
2020-07-23 07:32:17 +02:00
|
|
|
ShouldSupportSdkVersion(ctx BaseModuleContext, sdkVersion ApiLevel) error
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
|
|
|
|
// Returns true if this module needs a unique variation per apex, for example if
|
|
|
|
// use_apex_name_macro is set.
|
|
|
|
UniqueApexVariations() bool
|
2018-10-02 17:38:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type ApexProperties struct {
|
2020-01-17 14:02:56 +01:00
|
|
|
// Availability of this module in APEXes. Only the listed APEXes can contain
|
|
|
|
// this module. If the module has stubs then other APEXes and the platform may
|
|
|
|
// access it through them (subject to visibility).
|
|
|
|
//
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
// "//apex_available:anyapex" is a pseudo APEX name that matches to any APEX.
|
|
|
|
// "//apex_available:platform" refers to non-APEX partitions like "system.img".
|
2020-07-29 02:37:46 +02:00
|
|
|
// "com.android.gki.*" matches any APEX module name with the prefix "com.android.gki.".
|
2020-02-12 18:30:45 +01:00
|
|
|
// Default is ["//apex_available:platform"].
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
Apex_available []string
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// AnyVariantDirectlyInAnyApex is true in the primary variant of a module if _any_ variant
|
|
|
|
// of the module is directly in any apex. This includes host, arch, asan, etc. variants.
|
|
|
|
// It is unused in any variant that is not the primary variant.
|
|
|
|
// Ideally this wouldn't be used, as it incorrectly mixes arch variants if only one arch
|
|
|
|
// is in an apex, but a few places depend on it, for example when an ASAN variant is
|
|
|
|
// created before the apexMutator.
|
|
|
|
AnyVariantDirectlyInAnyApex bool `blueprint:"mutated"`
|
|
|
|
|
|
|
|
// DirectlyInAnyApex is true if any APEX variant (including the "" variant used for the
|
|
|
|
// platform) of this module is directly in any APEX.
|
|
|
|
DirectlyInAnyApex bool `blueprint:"mutated"`
|
|
|
|
|
|
|
|
// DirectlyInAnyApex is true if any APEX variant (including the "" variant used for the
|
|
|
|
// platform) of this module is directly or indirectly in any APEX.
|
|
|
|
InAnyApex bool `blueprint:"mutated"`
|
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
|
|
|
|
|
|
|
NotAvailableForPlatform bool `blueprint:"mutated"`
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
|
|
|
|
UniqueApexVariationsForDeps bool `blueprint:"mutated"`
|
2018-10-02 17:38:19 +02:00
|
|
|
}
|
|
|
|
|
2020-04-07 16:25:44 +02:00
|
|
|
// Marker interface that identifies dependencies that are excluded from APEX
|
|
|
|
// contents.
|
|
|
|
type ExcludeFromApexContentsTag interface {
|
|
|
|
blueprint.DependencyTag
|
|
|
|
|
|
|
|
// Method that differentiates this interface from others.
|
|
|
|
ExcludeFromApexContents()
|
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// Marker interface that identifies dependencies that should inherit the DirectlyInAnyApex
|
|
|
|
// state from the parent to the child. For example, stubs libraries are marked as
|
|
|
|
// DirectlyInAnyApex if their implementation is in an apex.
|
|
|
|
type CopyDirectlyInAnyApexTag interface {
|
|
|
|
blueprint.DependencyTag
|
|
|
|
|
|
|
|
CopyDirectlyInAnyApex()
|
|
|
|
}
|
|
|
|
|
2018-10-02 17:38:19 +02:00
|
|
|
// Provides default implementation for the ApexModule interface. APEX-aware
|
|
|
|
// modules are expected to include this struct and call InitApexModule().
|
|
|
|
type ApexModuleBase struct {
|
|
|
|
ApexProperties ApexProperties
|
|
|
|
|
|
|
|
canHaveApexVariants bool
|
2019-06-04 00:07:03 +02:00
|
|
|
|
|
|
|
apexVariationsLock sync.Mutex // protects apexVariations during parallel apexDepsMutator
|
2020-02-13 02:13:25 +01:00
|
|
|
apexVariations []ApexInfo
|
2018-10-02 17:38:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ApexModuleBase) apexModuleBase() *ApexModuleBase {
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
2020-03-04 15:22:45 +01:00
|
|
|
func (m *ApexModuleBase) ApexAvailable() []string {
|
|
|
|
return m.ApexProperties.Apex_available
|
|
|
|
}
|
|
|
|
|
2020-04-13 09:19:48 +02:00
|
|
|
func (m *ApexModuleBase) TestFor() []string {
|
|
|
|
// To be implemented by concrete types inheriting ApexModuleBase
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
func (m *ApexModuleBase) UniqueApexVariations() bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-07-22 08:17:19 +02:00
|
|
|
func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
|
2019-06-04 00:07:03 +02:00
|
|
|
m.apexVariationsLock.Lock()
|
|
|
|
defer m.apexVariationsLock.Unlock()
|
2020-07-22 08:17:19 +02:00
|
|
|
for _, v := range m.apexVariations {
|
2020-08-13 20:24:56 +02:00
|
|
|
if v.ApexVariationName == apex.ApexVariationName {
|
2020-07-22 08:17:19 +02:00
|
|
|
return
|
apexDepsMutator is a top-down mutator
apex { name: ["myapex"], native_shared_libs: ["libX", "libY"] }
cc_library { name: "libX", shared_libs: ["libY"] }
cc_library { name: "libY", shared_libs: ["libZ"], stubs: {...} }
apexDepsMutator was a bottom up mutator and it uses WalkDeps to traverse
the dependency tree rooted at myapex in a depth-first order. While
traversing the tree, if calls BuildForApex for a module that will be
part of the APEX.
libY is visited twice. Once via libX and once via myapex. If the visit
from libX was before the visit from myapex (since this is a depth-first
traversing), BuildForApex is not called for libY and its dependency
libZ, because libY provides a stub. And then when libY is again visited
via myapex, BuildForApex is correctly called for the module, but not for
its dependencies libZ because the paths from libY to libZ was already
visited.
As a result, the apex variant of libY has a dependency to the non-apex
variant of libZ.
Fixing the problem by changing the mutator a top-down one.
Bug: 148645937
Test: m
Change-Id: Ib2cb28852087c63a568b3fd036504e9261cf0782
2020-02-11 23:53:12 +01:00
|
|
|
}
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
}
|
2020-07-22 08:17:19 +02:00
|
|
|
m.apexVariations = append(m.apexVariations, apex)
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
func (m *ApexModuleBase) DirectlyInAnyApex() bool {
|
|
|
|
return m.ApexProperties.DirectlyInAnyApex
|
2018-10-02 17:38:19 +02:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
func (m *ApexModuleBase) AnyVariantDirectlyInAnyApex() bool {
|
|
|
|
return m.ApexProperties.AnyVariantDirectlyInAnyApex
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
func (m *ApexModuleBase) InAnyApex() bool {
|
|
|
|
return m.ApexProperties.InAnyApex
|
2018-10-02 17:38:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ApexModuleBase) CanHaveApexVariants() bool {
|
|
|
|
return m.canHaveApexVariants
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ApexModuleBase) IsInstallableToApex() bool {
|
|
|
|
// should be overriden if needed
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
const (
|
2019-12-02 16:43:57 +01:00
|
|
|
AvailableToPlatform = "//apex_available:platform"
|
2020-03-06 13:30:13 +01:00
|
|
|
AvailableToAnyApex = "//apex_available:anyapex"
|
2020-07-29 02:37:46 +02:00
|
|
|
AvailableToGkiApex = "com.android.gki.*"
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
)
|
|
|
|
|
2019-10-07 08:47:24 +02:00
|
|
|
func CheckAvailableForApex(what string, apex_available []string) bool {
|
|
|
|
if len(apex_available) == 0 {
|
2020-01-10 16:12:39 +01:00
|
|
|
// apex_available defaults to ["//apex_available:platform"],
|
|
|
|
// which means 'available to the platform but no apexes'.
|
|
|
|
return what == AvailableToPlatform
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
}
|
2019-10-07 08:47:24 +02:00
|
|
|
return InList(what, apex_available) ||
|
2020-07-29 02:37:46 +02:00
|
|
|
(what != AvailableToPlatform && InList(AvailableToAnyApex, apex_available)) ||
|
|
|
|
(strings.HasPrefix(what, "com.android.gki.") && InList(AvailableToGkiApex, apex_available))
|
2019-10-07 08:47:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ApexModuleBase) AvailableFor(what string) bool {
|
|
|
|
return CheckAvailableForApex(what, m.ApexProperties.Apex_available)
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
}
|
|
|
|
|
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
|
|
|
func (m *ApexModuleBase) NotAvailableForPlatform() bool {
|
|
|
|
return m.ApexProperties.NotAvailableForPlatform
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *ApexModuleBase) SetNotAvailableForPlatform() {
|
|
|
|
m.ApexProperties.NotAvailableForPlatform = true
|
|
|
|
}
|
|
|
|
|
2019-10-15 08:20:07 +02:00
|
|
|
func (m *ApexModuleBase) DepIsInSameApex(ctx BaseModuleContext, dep Module) bool {
|
|
|
|
// By default, if there is a dependency from A to B, we try to include both in the same APEX,
|
|
|
|
// unless B is explicitly from outside of the APEX (i.e. a stubs lib). Thus, returning true.
|
|
|
|
// This is overridden by some module types like apex.ApexBundle, cc.Module, java.Module, etc.
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
|
|
|
|
for _, n := range m.ApexProperties.Apex_available {
|
2020-07-29 02:37:46 +02:00
|
|
|
if n == AvailableToPlatform || n == AvailableToAnyApex || n == AvailableToGkiApex {
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
continue
|
|
|
|
}
|
2019-10-08 11:40:51 +02:00
|
|
|
if !mctx.OtherModuleExists(n) && !mctx.Config().AllowMissingDependencies() {
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
mctx.PropertyErrorf("apex_available", "%q is not a valid module name", n)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-13 02:13:25 +01:00
|
|
|
type byApexName []ApexInfo
|
|
|
|
|
|
|
|
func (a byApexName) Len() int { return len(a) }
|
|
|
|
func (a byApexName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
2020-08-13 20:24:56 +02:00
|
|
|
func (a byApexName) Less(i, j int) bool { return a[i].ApexVariationName < a[j].ApexVariationName }
|
2020-02-13 02:13:25 +01:00
|
|
|
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
// 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.
|
2020-10-02 19:26:04 +02:00
|
|
|
func mergeApexVariations(ctx PathContext, apexVariations []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
sort.Sort(byApexName(apexVariations))
|
|
|
|
seen := make(map[string]int)
|
|
|
|
for _, apexInfo := range apexVariations {
|
|
|
|
apexName := apexInfo.ApexVariationName
|
2020-07-23 07:32:17 +02:00
|
|
|
mergedName := apexInfo.mergedName(ctx)
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
if index, exists := seen[mergedName]; exists {
|
|
|
|
merged[index].InApexes = append(merged[index].InApexes, apexName)
|
2020-09-16 03:30:11 +02:00
|
|
|
merged[index].ApexContents = append(merged[index].ApexContents, apexInfo.ApexContents...)
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
merged[index].Updatable = merged[index].Updatable || apexInfo.Updatable
|
|
|
|
} else {
|
|
|
|
seen[mergedName] = len(merged)
|
2020-07-23 07:32:17 +02:00
|
|
|
apexInfo.ApexVariationName = apexInfo.mergedName(ctx)
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
apexInfo.InApexes = CopyOf(apexInfo.InApexes)
|
2020-09-16 03:30:11 +02:00
|
|
|
apexInfo.ApexContents = append([]*ApexContents(nil), apexInfo.ApexContents...)
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
merged = append(merged, apexInfo)
|
|
|
|
}
|
|
|
|
aliases = append(aliases, [2]string{apexName, mergedName})
|
|
|
|
}
|
|
|
|
return merged, aliases
|
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
func CreateApexVariations(mctx BottomUpMutatorContext, module ApexModule) []Module {
|
|
|
|
base := module.apexModuleBase()
|
|
|
|
if len(base.apexVariations) > 0 {
|
|
|
|
base.checkApexAvailableProperty(mctx)
|
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
|
|
|
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
var apexVariations []ApexInfo
|
|
|
|
var aliases [][2]string
|
2020-09-16 03:30:11 +02:00
|
|
|
if !mctx.Module().(ApexModule).UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
|
|
|
|
apexVariations, aliases = mergeApexVariations(mctx, base.apexVariations)
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
} else {
|
2020-09-16 03:30:11 +02:00
|
|
|
apexVariations = base.apexVariations
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
}
|
2020-09-16 03:30:11 +02:00
|
|
|
// base.apexVariations is only needed to propagate the list of apexes from
|
|
|
|
// apexDepsMutator to apexMutator. It is no longer accurate after
|
|
|
|
// mergeApexVariations, and won't be copied to all but the first created
|
|
|
|
// variant. Clear it so it doesn't accidentally get used later.
|
|
|
|
base.apexVariations = nil
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
|
|
|
|
sort.Sort(byApexName(apexVariations))
|
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
|
|
|
variations := []string{}
|
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
|
|
|
variations = append(variations, "") // Original variation for platform
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
for _, apex := range apexVariations {
|
2020-08-13 20:24:56 +02:00
|
|
|
variations = append(variations, apex.ApexVariationName)
|
2020-02-13 02:13:25 +01:00
|
|
|
}
|
2018-12-26 08:32:21 +01:00
|
|
|
|
2019-12-27 06:11:47 +01:00
|
|
|
defaultVariation := ""
|
|
|
|
mctx.SetDefaultDependencyVariation(&defaultVariation)
|
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
var inApex ApexMembership
|
|
|
|
for _, a := range apexVariations {
|
|
|
|
for _, apexContents := range a.ApexContents {
|
|
|
|
inApex = inApex.merge(apexContents.contents[mctx.ModuleName()])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
base.ApexProperties.InAnyApex = true
|
|
|
|
base.ApexProperties.DirectlyInAnyApex = inApex == directlyInApex
|
|
|
|
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
modules := mctx.CreateVariations(variations...)
|
2020-02-13 02:13:25 +01:00
|
|
|
for i, mod := range modules {
|
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
|
|
|
platformVariation := i == 0
|
2020-02-13 02:13:25 +01:00
|
|
|
if platformVariation && !mctx.Host() && !mod.(ApexModule).AvailableFor(AvailableToPlatform) {
|
2020-08-06 23:34:42 +02:00
|
|
|
// Do not install the module for platform, but still allow it to output
|
|
|
|
// uninstallable AndroidMk entries in certain cases when they have
|
|
|
|
// side effects.
|
|
|
|
mod.MakeUninstallable()
|
2020-02-13 02:13:25 +01:00
|
|
|
}
|
|
|
|
if !platformVariation {
|
2020-09-16 03:30:11 +02:00
|
|
|
mctx.SetVariationProvider(mod, ApexInfoProvider, apexVariations[i-1])
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
}
|
|
|
|
}
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
|
|
|
|
for _, alias := range aliases {
|
|
|
|
mctx.CreateAliasVariation(alias[0], alias[1])
|
|
|
|
}
|
|
|
|
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
return modules
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// 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.
|
|
|
|
func UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext, am ApexModule) {
|
|
|
|
// 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
|
|
|
|
}
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
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
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
}
|
2020-09-16 03:30:11 +02:00
|
|
|
|
|
|
|
mctx.VisitDirectDeps(func(dep Module) {
|
|
|
|
if depApexModule, ok := dep.(ApexModule); ok {
|
|
|
|
if anyInSameApex(depApexModule.apexModuleBase().apexVariations, am.apexModuleBase().apexVariations) &&
|
|
|
|
(depApexModule.UniqueApexVariations() ||
|
|
|
|
depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) {
|
|
|
|
am.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// UpdateDirectlyInAnyApex uses the final module to store if any variant of this
|
|
|
|
// module is directly in any APEX, and then copies the final value to all the modules.
|
|
|
|
// It also copies the DirectlyInAnyApex value to any direct dependencies with a
|
|
|
|
// CopyDirectlyInAnyApexTag dependency tag.
|
|
|
|
func UpdateDirectlyInAnyApex(mctx BottomUpMutatorContext, am ApexModule) {
|
|
|
|
base := am.apexModuleBase()
|
|
|
|
// Copy DirectlyInAnyApex and InAnyApex from any direct dependencies with a
|
|
|
|
// CopyDirectlyInAnyApexTag dependency tag.
|
|
|
|
mctx.VisitDirectDeps(func(dep Module) {
|
|
|
|
if _, ok := mctx.OtherModuleDependencyTag(dep).(CopyDirectlyInAnyApexTag); ok {
|
|
|
|
depBase := dep.(ApexModule).apexModuleBase()
|
|
|
|
base.ApexProperties.DirectlyInAnyApex = depBase.ApexProperties.DirectlyInAnyApex
|
|
|
|
base.ApexProperties.InAnyApex = depBase.ApexProperties.InAnyApex
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
if base.ApexProperties.DirectlyInAnyApex {
|
|
|
|
// Variants of a module are always visited sequentially in order, so it is safe to
|
|
|
|
// write to another variant of this module.
|
|
|
|
// For a BottomUpMutator the PrimaryModule() is visited first and FinalModule() is
|
|
|
|
// visited last.
|
|
|
|
mctx.FinalModule().(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex = true
|
2019-12-17 04:47:13 +01:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// If this is the FinalModule (last visited module) copy AnyVariantDirectlyInAnyApex to
|
|
|
|
// all the other variants
|
|
|
|
if am == mctx.FinalModule().(ApexModule) {
|
|
|
|
mctx.VisitAllModuleVariants(func(variant Module) {
|
|
|
|
variant.(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex =
|
|
|
|
base.ApexProperties.AnyVariantDirectlyInAnyApex
|
|
|
|
})
|
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
type ApexMembership int
|
|
|
|
|
|
|
|
const (
|
|
|
|
notInApex ApexMembership = 0
|
|
|
|
indirectlyInApex = iota
|
|
|
|
directlyInApex
|
|
|
|
)
|
|
|
|
|
|
|
|
// Each apexBundle has an apexContents, and modules in that apex have a provider containing the
|
|
|
|
// apexContents of each apexBundle they are part of.
|
|
|
|
type ApexContents struct {
|
|
|
|
ApexName string
|
|
|
|
contents map[string]ApexMembership
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewApexContents(name string, contents map[string]ApexMembership) *ApexContents {
|
|
|
|
return &ApexContents{
|
|
|
|
ApexName: name,
|
|
|
|
contents: contents,
|
Reland: 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.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
func (i ApexMembership) Add(direct bool) ApexMembership {
|
|
|
|
if direct || i == directlyInApex {
|
|
|
|
return directlyInApex
|
|
|
|
}
|
|
|
|
return indirectlyInApex
|
2019-01-15 20:53:23 +01:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
func (i ApexMembership) merge(other ApexMembership) ApexMembership {
|
|
|
|
if other == directlyInApex || i == directlyInApex {
|
|
|
|
return directlyInApex
|
2019-01-15 20:53:23 +01:00
|
|
|
}
|
2020-09-16 03:30:11 +02:00
|
|
|
|
|
|
|
if other == indirectlyInApex || i == indirectlyInApex {
|
|
|
|
return indirectlyInApex
|
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
|
|
|
}
|
2020-09-16 03:30:11 +02:00
|
|
|
return notInApex
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ac *ApexContents) DirectlyInApex(name string) bool {
|
|
|
|
return ac.contents[name] == directlyInApex
|
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
func (ac *ApexContents) InApex(name string) bool {
|
|
|
|
return ac.contents[name] != notInApex
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
}
|
|
|
|
|
2020-09-16 03:30:11 +02:00
|
|
|
// Tests whether a module named moduleName is directly depended on by all APEXes
|
|
|
|
// in an ApexInfo.
|
|
|
|
func DirectlyInAllApexes(apexInfo ApexInfo, moduleName string) bool {
|
|
|
|
for _, contents := range apexInfo.ApexContents {
|
|
|
|
if !contents.DirectlyInApex(moduleName) {
|
|
|
|
return false
|
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
|
|
|
}
|
|
|
|
}
|
2020-09-16 03:30:11 +02:00
|
|
|
return true
|
2018-12-07 15:08:36 +01:00
|
|
|
}
|
|
|
|
|
2018-10-02 17:38:19 +02:00
|
|
|
func InitApexModule(m ApexModule) {
|
|
|
|
base := m.apexModuleBase()
|
|
|
|
base.canHaveApexVariants = true
|
|
|
|
|
|
|
|
m.AddProperties(&base.ApexProperties)
|
|
|
|
}
|
2020-04-27 18:08:37 +02:00
|
|
|
|
|
|
|
// A dependency info for a single ApexModule, either direct or transitive.
|
|
|
|
type ApexModuleDepInfo struct {
|
|
|
|
// Name of the dependency
|
|
|
|
To string
|
|
|
|
// List of dependencies To belongs to. Includes APEX itself, if a direct dependency.
|
|
|
|
From []string
|
|
|
|
// Whether the dependency belongs to the final compiled APEX.
|
|
|
|
IsExternal bool
|
2020-04-27 19:53:18 +02:00
|
|
|
// min_sdk_version of the ApexModule
|
|
|
|
MinSdkVersion string
|
2020-04-27 18:08:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// A map of a dependency name to its ApexModuleDepInfo
|
|
|
|
type DepNameToDepInfoMap map[string]ApexModuleDepInfo
|
|
|
|
|
|
|
|
type ApexBundleDepsInfo struct {
|
2020-05-14 00:44:03 +02:00
|
|
|
flatListPath OutputPath
|
|
|
|
fullListPath OutputPath
|
2020-04-27 18:08:37 +02:00
|
|
|
}
|
|
|
|
|
2020-04-28 15:57:42 +02:00
|
|
|
type ApexBundleDepsInfoIntf interface {
|
|
|
|
Updatable() bool
|
2020-04-27 19:07:06 +02:00
|
|
|
FlatListPath() Path
|
2020-04-27 18:08:37 +02:00
|
|
|
FullListPath() Path
|
|
|
|
}
|
|
|
|
|
2020-04-27 19:07:06 +02:00
|
|
|
func (d *ApexBundleDepsInfo) FlatListPath() Path {
|
|
|
|
return d.flatListPath
|
|
|
|
}
|
|
|
|
|
2020-04-27 18:08:37 +02:00
|
|
|
func (d *ApexBundleDepsInfo) FullListPath() Path {
|
|
|
|
return d.fullListPath
|
|
|
|
}
|
|
|
|
|
2020-04-27 19:07:06 +02:00
|
|
|
// Generate two module out files:
|
|
|
|
// 1. FullList with transitive deps and their parents in the dep graph
|
|
|
|
// 2. FlatList with a flat list of transitive deps
|
2020-04-27 19:53:18 +02:00
|
|
|
func (d *ApexBundleDepsInfo) BuildDepsInfoLists(ctx ModuleContext, minSdkVersion string, depInfos DepNameToDepInfoMap) {
|
2020-04-27 19:07:06 +02:00
|
|
|
var fullContent strings.Builder
|
|
|
|
var flatContent strings.Builder
|
|
|
|
|
2020-05-14 16:15:01 +02:00
|
|
|
fmt.Fprintf(&fullContent, "%s(minSdkVersion:%s):\\n", ctx.ModuleName(), minSdkVersion)
|
2020-04-27 18:08:37 +02:00
|
|
|
for _, key := range FirstUniqueStrings(SortedStringKeys(depInfos)) {
|
|
|
|
info := depInfos[key]
|
2020-04-27 19:53:18 +02:00
|
|
|
toName := fmt.Sprintf("%s(minSdkVersion:%s)", info.To, info.MinSdkVersion)
|
2020-04-27 18:08:37 +02:00
|
|
|
if info.IsExternal {
|
|
|
|
toName = toName + " (external)"
|
|
|
|
}
|
2020-05-14 16:15:01 +02:00
|
|
|
fmt.Fprintf(&fullContent, " %s <- %s\\n", toName, strings.Join(SortedUniqueStrings(info.From), ", "))
|
|
|
|
fmt.Fprintf(&flatContent, "%s\\n", toName)
|
2020-04-27 18:08:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
d.fullListPath = PathForModuleOut(ctx, "depsinfo", "fulllist.txt").OutputPath
|
|
|
|
ctx.Build(pctx, BuildParams{
|
|
|
|
Rule: WriteFile,
|
|
|
|
Description: "Full Dependency Info",
|
|
|
|
Output: d.fullListPath,
|
|
|
|
Args: map[string]string{
|
2020-04-27 19:07:06 +02:00
|
|
|
"content": fullContent.String(),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
d.flatListPath = PathForModuleOut(ctx, "depsinfo", "flatlist.txt").OutputPath
|
|
|
|
ctx.Build(pctx, BuildParams{
|
|
|
|
Rule: WriteFile,
|
|
|
|
Description: "Flat Dependency Info",
|
|
|
|
Output: d.flatListPath,
|
|
|
|
Args: map[string]string{
|
|
|
|
"content": flatContent.String(),
|
2020-04-27 18:08:37 +02:00
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
2020-04-15 04:03:39 +02:00
|
|
|
|
|
|
|
// TODO(b/158059172): remove minSdkVersion allowlist
|
2020-07-23 07:32:17 +02:00
|
|
|
var minSdkVersionAllowlist = func(apiMap map[string]int) map[string]ApiLevel {
|
|
|
|
list := make(map[string]ApiLevel, len(apiMap))
|
|
|
|
for name, finalApiInt := range apiMap {
|
|
|
|
list[name] = uncheckedFinalApiLevel(finalApiInt)
|
|
|
|
}
|
|
|
|
return list
|
|
|
|
}(map[string]int{
|
2020-04-15 04:03:39 +02:00
|
|
|
"adbd": 30,
|
|
|
|
"android.net.ipsec.ike": 30,
|
|
|
|
"androidx-constraintlayout_constraintlayout-solver": 30,
|
|
|
|
"androidx.annotation_annotation": 28,
|
|
|
|
"androidx.arch.core_core-common": 28,
|
|
|
|
"androidx.collection_collection": 28,
|
|
|
|
"androidx.lifecycle_lifecycle-common": 28,
|
|
|
|
"apache-commons-compress": 29,
|
|
|
|
"bouncycastle_ike_digests": 30,
|
|
|
|
"brotli-java": 29,
|
|
|
|
"captiveportal-lib": 28,
|
|
|
|
"flatbuffer_headers": 30,
|
|
|
|
"framework-permission": 30,
|
|
|
|
"framework-statsd": 30,
|
|
|
|
"gemmlowp_headers": 30,
|
|
|
|
"ike-internals": 30,
|
|
|
|
"kotlinx-coroutines-android": 28,
|
|
|
|
"kotlinx-coroutines-core": 28,
|
|
|
|
"libadb_crypto": 30,
|
|
|
|
"libadb_pairing_auth": 30,
|
|
|
|
"libadb_pairing_connection": 30,
|
|
|
|
"libadb_pairing_server": 30,
|
|
|
|
"libadb_protos": 30,
|
|
|
|
"libadb_tls_connection": 30,
|
|
|
|
"libadbconnection_client": 30,
|
|
|
|
"libadbconnection_server": 30,
|
|
|
|
"libadbd_core": 30,
|
|
|
|
"libadbd_services": 30,
|
|
|
|
"libadbd": 30,
|
|
|
|
"libapp_processes_protos_lite": 30,
|
|
|
|
"libasyncio": 30,
|
|
|
|
"libbrotli": 30,
|
|
|
|
"libbuildversion": 30,
|
|
|
|
"libcrypto_static": 30,
|
|
|
|
"libcrypto_utils": 30,
|
|
|
|
"libdiagnose_usb": 30,
|
|
|
|
"libeigen": 30,
|
|
|
|
"liblz4": 30,
|
|
|
|
"libmdnssd": 30,
|
|
|
|
"libneuralnetworks_common": 30,
|
|
|
|
"libneuralnetworks_headers": 30,
|
|
|
|
"libneuralnetworks": 30,
|
|
|
|
"libprocpartition": 30,
|
|
|
|
"libprotobuf-java-lite": 30,
|
|
|
|
"libprotoutil": 30,
|
|
|
|
"libqemu_pipe": 30,
|
|
|
|
"libstats_jni": 30,
|
|
|
|
"libstatslog_statsd": 30,
|
|
|
|
"libstatsmetadata": 30,
|
|
|
|
"libstatspull": 30,
|
|
|
|
"libstatssocket": 30,
|
|
|
|
"libsync": 30,
|
|
|
|
"libtextclassifier_hash_headers": 30,
|
|
|
|
"libtextclassifier_hash_static": 30,
|
|
|
|
"libtflite_kernel_utils": 30,
|
|
|
|
"libwatchdog": 29,
|
|
|
|
"libzstd": 30,
|
|
|
|
"metrics-constants-protos": 28,
|
|
|
|
"net-utils-framework-common": 29,
|
|
|
|
"permissioncontroller-statsd": 28,
|
|
|
|
"philox_random_headers": 30,
|
|
|
|
"philox_random": 30,
|
|
|
|
"service-permission": 30,
|
|
|
|
"service-statsd": 30,
|
|
|
|
"statsd-aidl-ndk_platform": 30,
|
|
|
|
"statsd": 30,
|
|
|
|
"tensorflow_headers": 30,
|
|
|
|
"xz-java": 29,
|
2020-07-23 07:32:17 +02:00
|
|
|
})
|
2020-04-15 04:03:39 +02:00
|
|
|
|
|
|
|
// Function called while walking an APEX's payload dependencies.
|
|
|
|
//
|
|
|
|
// Return true if the `to` module should be visited, false otherwise.
|
|
|
|
type PayloadDepsCallback func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool
|
|
|
|
|
|
|
|
// UpdatableModule represents updatable APEX/APK
|
|
|
|
type UpdatableModule interface {
|
|
|
|
Module
|
|
|
|
WalkPayloadDeps(ctx ModuleContext, do PayloadDepsCallback)
|
|
|
|
}
|
|
|
|
|
|
|
|
// CheckMinSdkVersion checks if every dependency of an updatable module sets min_sdk_version accordingly
|
2020-07-23 07:32:17 +02:00
|
|
|
func CheckMinSdkVersion(m UpdatableModule, ctx ModuleContext, minSdkVersion ApiLevel) {
|
2020-04-15 04:03:39 +02:00
|
|
|
// do not enforce min_sdk_version for host
|
|
|
|
if ctx.Host() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// do not enforce for coverage build
|
|
|
|
if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || ctx.DeviceConfig().NativeCoverageEnabled() || ctx.DeviceConfig().ClangCoverageEnabled() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// do not enforce deps.min_sdk_version if APEX/APK doesn't set min_sdk_version or
|
|
|
|
// min_sdk_version is not finalized (e.g. current or codenames)
|
2020-07-23 07:32:17 +02:00
|
|
|
if minSdkVersion.IsCurrent() {
|
2020-04-15 04:03:39 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
m.WalkPayloadDeps(ctx, func(ctx ModuleContext, from blueprint.Module, to ApexModule, externalDep bool) bool {
|
|
|
|
if externalDep {
|
|
|
|
// external deps are outside the payload boundary, which is "stable" interface.
|
|
|
|
// We don't have to check min_sdk_version for external dependencies.
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if am, ok := from.(DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil {
|
|
|
|
toName := ctx.OtherModuleName(to)
|
2020-07-23 07:32:17 +02:00
|
|
|
if ver, ok := minSdkVersionAllowlist[toName]; !ok || ver.GreaterThan(minSdkVersion) {
|
2020-04-15 04:03:39 +02:00
|
|
|
ctx.OtherModuleErrorf(to, "should support min_sdk_version(%v) for %q: %v. Dependency path: %s",
|
|
|
|
minSdkVersion, ctx.ModuleName(), err.Error(), ctx.GetPathString(false))
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
}
|