Merge changes Ib8025019,I7d58d104,I9dd4312c,I995ed389,Iba2a8a5a, ... into rvc-dev
* changes: Allow droidstubs to not generate any stubs Remove conscrypt.module.intra.core.api.stubs from apex white list Ignore PrebuiltDepTag when processing APEX contents Stop requiring apex_available on java_library members of sdks Add dependency tags to apex available errors Extract DepIsInSameApex and RequiredSdks interfaces
This commit is contained in:
committed by
Android (Google) Code Review
commit
416b811742
@@ -19,6 +19,8 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/google/blueprint"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -32,6 +34,14 @@ type ApexInfo struct {
|
|||||||
MinSdkVersion int
|
MinSdkVersion int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
// ApexModule is the interface that a module type is expected to implement if
|
// 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
|
// 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).
|
// is destined for an apex or not (installed to one of the regular partitions).
|
||||||
@@ -49,6 +59,8 @@ type ApexInfo struct {
|
|||||||
// respectively.
|
// respectively.
|
||||||
type ApexModule interface {
|
type ApexModule interface {
|
||||||
Module
|
Module
|
||||||
|
DepIsInSameApex
|
||||||
|
|
||||||
apexModuleBase() *ApexModuleBase
|
apexModuleBase() *ApexModuleBase
|
||||||
|
|
||||||
// Marks that this module should be built for the specified APEXes.
|
// Marks that this module should be built for the specified APEXes.
|
||||||
@@ -88,10 +100,6 @@ type ApexModule interface {
|
|||||||
// Tests if this module is available for the specified APEX or ":platform"
|
// Tests if this module is available for the specified APEX or ":platform"
|
||||||
AvailableFor(what string) bool
|
AvailableFor(what string) bool
|
||||||
|
|
||||||
// DepIsInSameApex tests if the other module 'dep' is installed to the same
|
|
||||||
// APEX as this module
|
|
||||||
DepIsInSameApex(ctx BaseModuleContext, dep Module) bool
|
|
||||||
|
|
||||||
// Returns the highest version which is <= maxSdkVersion.
|
// Returns the highest version which is <= maxSdkVersion.
|
||||||
// For example, with maxSdkVersion is 10 and versionList is [9,11]
|
// For example, with maxSdkVersion is 10 and versionList is [9,11]
|
||||||
// it returns 9 as string
|
// it returns 9 as string
|
||||||
@@ -111,6 +119,15 @@ type ApexProperties struct {
|
|||||||
Info ApexInfo `blueprint:"mutated"`
|
Info ApexInfo `blueprint:"mutated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Marker interface that identifies dependencies that are excluded from APEX
|
||||||
|
// contents.
|
||||||
|
type ExcludeFromApexContentsTag interface {
|
||||||
|
blueprint.DependencyTag
|
||||||
|
|
||||||
|
// Method that differentiates this interface from others.
|
||||||
|
ExcludeFromApexContents()
|
||||||
|
}
|
||||||
|
|
||||||
// Provides default implementation for the ApexModule interface. APEX-aware
|
// Provides default implementation for the ApexModule interface. APEX-aware
|
||||||
// modules are expected to include this struct and call InitApexModule().
|
// modules are expected to include this struct and call InitApexModule().
|
||||||
type ApexModuleBase struct {
|
type ApexModuleBase struct {
|
||||||
|
@@ -128,6 +128,13 @@ type BaseModuleContext interface {
|
|||||||
// and returns a top-down dependency path from a start module to current child module.
|
// and returns a top-down dependency path from a start module to current child module.
|
||||||
GetWalkPath() []Module
|
GetWalkPath() []Module
|
||||||
|
|
||||||
|
// GetTagPath is supposed to be called in visit function passed in WalkDeps()
|
||||||
|
// and returns a top-down dependency tags path from a start module to current child module.
|
||||||
|
// It has one less entry than GetWalkPath() as it contains the dependency tags that
|
||||||
|
// exist between each adjacent pair of modules in the GetWalkPath().
|
||||||
|
// GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
|
||||||
|
GetTagPath() []blueprint.DependencyTag
|
||||||
|
|
||||||
AddMissingDependencies(missingDeps []string)
|
AddMissingDependencies(missingDeps []string)
|
||||||
|
|
||||||
Target() Target
|
Target() Target
|
||||||
@@ -1386,6 +1393,7 @@ type baseModuleContext struct {
|
|||||||
debug bool
|
debug bool
|
||||||
|
|
||||||
walkPath []Module
|
walkPath []Module
|
||||||
|
tagPath []blueprint.DependencyTag
|
||||||
|
|
||||||
strictVisitDeps bool // If true, enforce that all dependencies are enabled
|
strictVisitDeps bool // If true, enforce that all dependencies are enabled
|
||||||
}
|
}
|
||||||
@@ -1675,6 +1683,7 @@ func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, bluep
|
|||||||
|
|
||||||
func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
|
func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
|
||||||
b.walkPath = []Module{b.Module()}
|
b.walkPath = []Module{b.Module()}
|
||||||
|
b.tagPath = []blueprint.DependencyTag{}
|
||||||
b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
|
b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
|
||||||
childAndroidModule, _ := child.(Module)
|
childAndroidModule, _ := child.(Module)
|
||||||
parentAndroidModule, _ := parent.(Module)
|
parentAndroidModule, _ := parent.(Module)
|
||||||
@@ -1682,8 +1691,10 @@ func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
|
|||||||
// record walkPath before visit
|
// record walkPath before visit
|
||||||
for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
|
for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
|
||||||
b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
|
b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
|
||||||
|
b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
|
||||||
}
|
}
|
||||||
b.walkPath = append(b.walkPath, childAndroidModule)
|
b.walkPath = append(b.walkPath, childAndroidModule)
|
||||||
|
b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
|
||||||
return visit(childAndroidModule, parentAndroidModule)
|
return visit(childAndroidModule, parentAndroidModule)
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@@ -1695,6 +1706,10 @@ func (b *baseModuleContext) GetWalkPath() []Module {
|
|||||||
return b.walkPath
|
return b.walkPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
|
||||||
|
return b.tagPath
|
||||||
|
}
|
||||||
|
|
||||||
func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
|
func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
|
||||||
m.bp.VisitAllModuleVariants(func(module blueprint.Module) {
|
m.bp.VisitAllModuleVariants(func(module blueprint.Module) {
|
||||||
visit(module.(Module))
|
visit(module.(Module))
|
||||||
|
@@ -39,6 +39,12 @@ var PrebuiltDepTag prebuiltDependencyTag
|
|||||||
// Mark this tag so dependencies that use it are excluded from visibility enforcement.
|
// Mark this tag so dependencies that use it are excluded from visibility enforcement.
|
||||||
func (t prebuiltDependencyTag) ExcludeFromVisibilityEnforcement() {}
|
func (t prebuiltDependencyTag) ExcludeFromVisibilityEnforcement() {}
|
||||||
|
|
||||||
|
// Mark this tag so dependencies that use it are excluded from APEX contents.
|
||||||
|
func (t prebuiltDependencyTag) ExcludeFromApexContents() {}
|
||||||
|
|
||||||
|
var _ ExcludeFromVisibilityEnforcementTag = PrebuiltDepTag
|
||||||
|
var _ ExcludeFromApexContentsTag = PrebuiltDepTag
|
||||||
|
|
||||||
type PrebuiltProperties struct {
|
type PrebuiltProperties struct {
|
||||||
// When prefer is set to true the prebuilt will be used instead of any source module with
|
// When prefer is set to true the prebuilt will be used instead of any source module with
|
||||||
// a matching name.
|
// a matching name.
|
||||||
|
@@ -22,17 +22,30 @@ import (
|
|||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Extracted from SdkAware to make it easier to define custom subsets of the
|
||||||
|
// SdkAware interface and improve code navigation within the IDE.
|
||||||
|
//
|
||||||
|
// In addition to its use in SdkAware this interface must also be implemented by
|
||||||
|
// APEX to specify the SDKs required by that module and its contents. e.g. APEX
|
||||||
|
// is expected to implement RequiredSdks() by reading its own properties like
|
||||||
|
// `uses_sdks`.
|
||||||
|
type RequiredSdks interface {
|
||||||
|
// The set of SDKs required by an APEX and its contents.
|
||||||
|
RequiredSdks() SdkRefs
|
||||||
|
}
|
||||||
|
|
||||||
// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
|
// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
|
||||||
// built with SDK
|
// built with SDK
|
||||||
type SdkAware interface {
|
type SdkAware interface {
|
||||||
Module
|
Module
|
||||||
|
RequiredSdks
|
||||||
|
|
||||||
sdkBase() *SdkBase
|
sdkBase() *SdkBase
|
||||||
MakeMemberOf(sdk SdkRef)
|
MakeMemberOf(sdk SdkRef)
|
||||||
IsInAnySdk() bool
|
IsInAnySdk() bool
|
||||||
ContainingSdk() SdkRef
|
ContainingSdk() SdkRef
|
||||||
MemberName() string
|
MemberName() string
|
||||||
BuildWithSdks(sdks SdkRefs)
|
BuildWithSdks(sdks SdkRefs)
|
||||||
RequiredSdks() SdkRefs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SdkRef refers to a version of an SDK
|
// SdkRef refers to a version of an SDK
|
||||||
|
56
apex/apex.go
56
apex/apex.go
@@ -18,6 +18,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -121,7 +122,6 @@ func makeApexAvailableWhitelist() map[string][]string {
|
|||||||
"crtbegin_dynamic1",
|
"crtbegin_dynamic1",
|
||||||
"crtbegin_so1",
|
"crtbegin_so1",
|
||||||
"crtbrand",
|
"crtbrand",
|
||||||
"conscrypt.module.intra.core.api.stubs",
|
|
||||||
"dex2oat_headers",
|
"dex2oat_headers",
|
||||||
"dt_fd_forward_export",
|
"dt_fd_forward_export",
|
||||||
"icu4c_extra_headers",
|
"icu4c_extra_headers",
|
||||||
@@ -862,20 +862,28 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cur := mctx.Module().(interface {
|
cur := mctx.Module().(android.DepIsInSameApex)
|
||||||
DepIsInSameApex(android.BaseModuleContext, android.Module) bool
|
|
||||||
})
|
|
||||||
|
|
||||||
mctx.VisitDirectDeps(func(child android.Module) {
|
mctx.VisitDirectDeps(func(child android.Module) {
|
||||||
depName := mctx.OtherModuleName(child)
|
depName := mctx.OtherModuleName(child)
|
||||||
if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() &&
|
if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() &&
|
||||||
cur.DepIsInSameApex(mctx, child) {
|
(cur.DepIsInSameApex(mctx, child) || inAnySdk(child)) {
|
||||||
android.UpdateApexDependency(apexBundles, depName, directDep)
|
android.UpdateApexDependency(apexBundles, depName, directDep)
|
||||||
am.BuildForApexes(apexBundles)
|
am.BuildForApexes(apexBundles)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a module in an APEX depends on a module from an SDK then it needs an APEX
|
||||||
|
// specific variant created for it. Refer to sdk.sdkDepsReplaceMutator.
|
||||||
|
func inAnySdk(module android.Module) bool {
|
||||||
|
if sa, ok := module.(android.SdkAware); ok {
|
||||||
|
return sa.IsInAnySdk()
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Create apex variations if a module is included in APEX(s).
|
// Create apex variations if a module is included in APEX(s).
|
||||||
func apexMutator(mctx android.BottomUpMutatorContext) {
|
func apexMutator(mctx android.BottomUpMutatorContext) {
|
||||||
if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
|
if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
|
||||||
@@ -1809,6 +1817,24 @@ func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) int {
|
|||||||
return intVer
|
return intVer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
|
||||||
|
// a dependency tag.
|
||||||
|
var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:blueprint.BaseDependencyTag{}\E(, )?`)
|
||||||
|
|
||||||
|
func PrettyPrintTag(tag blueprint.DependencyTag) string {
|
||||||
|
// Use tag's custom String() method if available.
|
||||||
|
if stringer, ok := tag.(fmt.Stringer); ok {
|
||||||
|
return stringer.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, get a default string representation of the tag's struct.
|
||||||
|
tagString := fmt.Sprintf("%#v", tag)
|
||||||
|
|
||||||
|
// Remove the boilerplate from BaseDependencyTag as it adds no value.
|
||||||
|
tagString = tagCleaner.ReplaceAllString(tagString, "")
|
||||||
|
return tagString
|
||||||
|
}
|
||||||
|
|
||||||
// Ensures that the dependencies are marked as available for this APEX
|
// Ensures that the dependencies are marked as available for this APEX
|
||||||
func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
|
func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
|
||||||
// Let's be practical. Availability for test, host, and the VNDK apex isn't important
|
// Let's be practical. Availability for test, host, and the VNDK apex isn't important
|
||||||
@@ -1832,12 +1858,23 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
|
|||||||
apexName := ctx.ModuleName()
|
apexName := ctx.ModuleName()
|
||||||
fromName := ctx.OtherModuleName(from)
|
fromName := ctx.OtherModuleName(from)
|
||||||
toName := ctx.OtherModuleName(to)
|
toName := ctx.OtherModuleName(to)
|
||||||
|
|
||||||
|
// If `to` is not actually in the same APEX as `from` then it does not need apex_available and neither
|
||||||
|
// do any of its dependencies.
|
||||||
|
if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
|
||||||
|
// As soon as the dependency graph crosses the APEX boundary, don't go further.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
|
if to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
message := ""
|
message := ""
|
||||||
for _, m := range ctx.GetWalkPath()[1:] {
|
tagPath := ctx.GetTagPath()
|
||||||
message = fmt.Sprintf("%s\n -> %s", message, m.String())
|
// Skip the first module as that will be added at the start of the error message by ctx.ModuleErrorf().
|
||||||
|
walkPath := ctx.GetWalkPath()[1:]
|
||||||
|
for i, m := range walkPath {
|
||||||
|
message = fmt.Sprintf("%s\n via tag %s\n -> %s", message, PrettyPrintTag(tagPath[i]), m.String())
|
||||||
}
|
}
|
||||||
ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, message)
|
ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, message)
|
||||||
// Visit this module's dependencies to check and report any issues with their availability.
|
// Visit this module's dependencies to check and report any issues with their availability.
|
||||||
@@ -1947,6 +1984,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
// TODO(jiyong) do this using walkPayloadDeps
|
// TODO(jiyong) do this using walkPayloadDeps
|
||||||
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
|
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
|
||||||
depTag := ctx.OtherModuleDependencyTag(child)
|
depTag := ctx.OtherModuleDependencyTag(child)
|
||||||
|
if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
depName := ctx.OtherModuleName(child)
|
depName := ctx.OtherModuleName(child)
|
||||||
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
|
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
|
||||||
switch depTag {
|
switch depTag {
|
||||||
@@ -2108,7 +2148,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
|
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
|
||||||
}
|
}
|
||||||
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
|
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
|
||||||
ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
|
ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", PrettyPrintTag(depTag), depName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -141,6 +141,7 @@ func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*andr
|
|||||||
"my_include": nil,
|
"my_include": nil,
|
||||||
"foo/bar/MyClass.java": nil,
|
"foo/bar/MyClass.java": nil,
|
||||||
"prebuilt.jar": nil,
|
"prebuilt.jar": nil,
|
||||||
|
"prebuilt.so": nil,
|
||||||
"vendor/foo/devkeys/test.x509.pem": nil,
|
"vendor/foo/devkeys/test.x509.pem": nil,
|
||||||
"vendor/foo/devkeys/test.pk8": nil,
|
"vendor/foo/devkeys/test.pk8": nil,
|
||||||
"testkey.x509.pem": nil,
|
"testkey.x509.pem": nil,
|
||||||
@@ -342,7 +343,7 @@ func TestBasicApex(t *testing.T) {
|
|||||||
apex_available: [ "myapex" ],
|
apex_available: [ "myapex" ],
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_library {
|
cc_library_shared {
|
||||||
name: "mylib2",
|
name: "mylib2",
|
||||||
srcs: ["mylib.cpp"],
|
srcs: ["mylib.cpp"],
|
||||||
system_shared_libs: [],
|
system_shared_libs: [],
|
||||||
@@ -356,6 +357,16 @@ func TestBasicApex(t *testing.T) {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_prebuilt_library_shared {
|
||||||
|
name: "mylib2",
|
||||||
|
srcs: ["prebuilt.so"],
|
||||||
|
// TODO: remove //apex_available:platform
|
||||||
|
apex_available: [
|
||||||
|
"//apex_available:platform",
|
||||||
|
"myapex",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
cc_library_static {
|
cc_library_static {
|
||||||
name: "libstatic",
|
name: "libstatic",
|
||||||
srcs: ["mylib.cpp"],
|
srcs: ["mylib.cpp"],
|
||||||
@@ -3516,12 +3527,12 @@ func TestApexAvailable_DirectDep(t *testing.T) {
|
|||||||
func TestApexAvailable_IndirectDep(t *testing.T) {
|
func TestApexAvailable_IndirectDep(t *testing.T) {
|
||||||
// libbbaz is an indirect dep
|
// libbbaz is an indirect dep
|
||||||
testApexError(t, `requires "libbaz" that is not available for the APEX. Dependency path:
|
testApexError(t, `requires "libbaz" that is not available for the APEX. Dependency path:
|
||||||
|
.*via tag apex\.dependencyTag.*"sharedLib".*
|
||||||
.*-> libfoo.*link:shared.*
|
.*-> libfoo.*link:shared.*
|
||||||
.*-> libfoo.*link:static.*
|
.*via tag cc\.DependencyTag.*"shared".*
|
||||||
.*-> libbar.*link:shared.*
|
.*-> libbar.*link:shared.*
|
||||||
.*-> libbar.*link:static.*
|
.*via tag cc\.DependencyTag.*"shared".*
|
||||||
.*-> libbaz.*link:shared.*
|
.*-> libbaz.*link:shared.*`, `
|
||||||
.*-> libbaz.*link:static.*`, `
|
|
||||||
apex {
|
apex {
|
||||||
name: "myapex",
|
name: "myapex",
|
||||||
key: "myapex.key",
|
key: "myapex.key",
|
||||||
|
@@ -517,10 +517,21 @@ func (ddoc *Droiddoc) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (dstubs *Droidstubs) AndroidMkEntries() []android.AndroidMkEntries {
|
func (dstubs *Droidstubs) AndroidMkEntries() []android.AndroidMkEntries {
|
||||||
|
// If the stubsSrcJar is not generated (because generate_stubs is false) then
|
||||||
|
// use the api file as the output file to ensure the relevant phony targets
|
||||||
|
// are created in make if only the api txt file is being generated. This is
|
||||||
|
// needed because an invalid output file would prevent the make entries from
|
||||||
|
// being written.
|
||||||
|
// TODO(b/146727827): Revert when we do not need to generate stubs and API separately.
|
||||||
|
distFile := android.OptionalPathForPath(dstubs.apiFile)
|
||||||
|
outputFile := android.OptionalPathForPath(dstubs.stubsSrcJar)
|
||||||
|
if !outputFile.Valid() {
|
||||||
|
outputFile = distFile
|
||||||
|
}
|
||||||
return []android.AndroidMkEntries{android.AndroidMkEntries{
|
return []android.AndroidMkEntries{android.AndroidMkEntries{
|
||||||
Class: "JAVA_LIBRARIES",
|
Class: "JAVA_LIBRARIES",
|
||||||
DistFile: android.OptionalPathForPath(dstubs.apiFile),
|
DistFile: distFile,
|
||||||
OutputFile: android.OptionalPathForPath(dstubs.stubsSrcJar),
|
OutputFile: outputFile,
|
||||||
Include: "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk",
|
Include: "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk",
|
||||||
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
|
||||||
func(entries *android.AndroidMkEntries) {
|
func(entries *android.AndroidMkEntries) {
|
||||||
|
@@ -257,6 +257,11 @@ type DroidstubsProperties struct {
|
|||||||
// if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
|
// if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
|
||||||
Create_doc_stubs *bool
|
Create_doc_stubs *bool
|
||||||
|
|
||||||
|
// if set to false then do not write out stubs. Defaults to true.
|
||||||
|
//
|
||||||
|
// TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
|
||||||
|
Generate_stubs *bool
|
||||||
|
|
||||||
// is set to true, Metalava will allow framework SDK to contain API levels annotations.
|
// is set to true, Metalava will allow framework SDK to contain API levels annotations.
|
||||||
Api_levels_annotations_enabled *bool
|
Api_levels_annotations_enabled *bool
|
||||||
|
|
||||||
@@ -1201,7 +1206,7 @@ func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
|
func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) {
|
||||||
if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
|
if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
|
||||||
apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
|
apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
|
||||||
String(d.properties.Api_filename) != "" {
|
String(d.properties.Api_filename) != "" {
|
||||||
@@ -1227,11 +1232,13 @@ func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuil
|
|||||||
cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
|
cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if Bool(d.properties.Create_doc_stubs) {
|
if stubsDir.Valid() {
|
||||||
cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
|
if Bool(d.properties.Create_doc_stubs) {
|
||||||
} else {
|
cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
|
||||||
cmd.FlagWithArg("--stubs ", stubsDir.String())
|
} else {
|
||||||
cmd.Flag("--exclude-documentation-from-stubs")
|
cmd.FlagWithArg("--stubs ", stubsDir.String())
|
||||||
|
cmd.Flag("--exclude-documentation-from-stubs")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1388,15 +1395,18 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
// Create rule for metalava
|
// Create rule for metalava
|
||||||
|
|
||||||
d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
|
|
||||||
|
|
||||||
srcJarDir := android.PathForModuleOut(ctx, "srcjars")
|
srcJarDir := android.PathForModuleOut(ctx, "srcjars")
|
||||||
stubsDir := android.PathForModuleOut(ctx, "stubsDir")
|
|
||||||
|
|
||||||
rule := android.NewRuleBuilder()
|
rule := android.NewRuleBuilder()
|
||||||
|
|
||||||
rule.Command().Text("rm -rf").Text(stubsDir.String())
|
generateStubs := BoolDefault(d.properties.Generate_stubs, true)
|
||||||
rule.Command().Text("mkdir -p").Text(stubsDir.String())
|
var stubsDir android.OptionalPath
|
||||||
|
if generateStubs {
|
||||||
|
d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
|
||||||
|
stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "stubsDir"))
|
||||||
|
rule.Command().Text("rm -rf").Text(stubsDir.String())
|
||||||
|
rule.Command().Text("mkdir -p").Text(stubsDir.String())
|
||||||
|
}
|
||||||
|
|
||||||
srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
|
srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
|
||||||
|
|
||||||
@@ -1422,13 +1432,15 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
|
cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
|
||||||
}
|
}
|
||||||
|
|
||||||
rule.Command().
|
if generateStubs {
|
||||||
BuiltTool(ctx, "soong_zip").
|
rule.Command().
|
||||||
Flag("-write_if_changed").
|
BuiltTool(ctx, "soong_zip").
|
||||||
Flag("-jar").
|
Flag("-write_if_changed").
|
||||||
FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
|
Flag("-jar").
|
||||||
FlagWithArg("-C ", stubsDir.String()).
|
FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
|
||||||
FlagWithArg("-D ", stubsDir.String())
|
FlagWithArg("-C ", stubsDir.String()).
|
||||||
|
FlagWithArg("-D ", stubsDir.String())
|
||||||
|
}
|
||||||
|
|
||||||
if Bool(d.properties.Write_sdk_values) {
|
if Bool(d.properties.Write_sdk_values) {
|
||||||
d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
|
d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
|
||||||
|
10
java/java.go
10
java/java.go
@@ -1764,11 +1764,6 @@ func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
|
|||||||
if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
|
if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Also, a dependency to an sdk member is also considered as such. This is required because
|
|
||||||
// sdk members should be mutated into APEXes. Refer to sdk.sdkDepsReplaceMutator.
|
|
||||||
if sa, ok := dep.(android.SdkAware); ok && sa.IsInAnySdk() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2508,11 +2503,6 @@ func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
|
|||||||
if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
|
if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Also, a dependency to an sdk member is also considered as such. This is required because
|
|
||||||
// sdk members should be mutated into APEXes. Refer to sdk.sdkDepsReplaceMutator.
|
|
||||||
if sa, ok := dep.(android.SdkAware); ok && sa.IsInAnySdk() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,30 +53,18 @@ func TestBasicSdkWithJavaLibrary(t *testing.T) {
|
|||||||
system_modules: "none",
|
system_modules: "none",
|
||||||
sdk_version: "none",
|
sdk_version: "none",
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
apex_available: [
|
|
||||||
"//apex_available:platform",
|
|
||||||
"//apex_available:anyapex",
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java_import {
|
java_import {
|
||||||
name: "sdkmember_mysdk_1",
|
name: "sdkmember_mysdk_1",
|
||||||
sdk_member_name: "sdkmember",
|
sdk_member_name: "sdkmember",
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
apex_available: [
|
|
||||||
"//apex_available:platform",
|
|
||||||
"//apex_available:anyapex",
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java_import {
|
java_import {
|
||||||
name: "sdkmember_mysdk_2",
|
name: "sdkmember_mysdk_2",
|
||||||
sdk_member_name: "sdkmember",
|
sdk_member_name: "sdkmember",
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
apex_available: [
|
|
||||||
"//apex_available:platform",
|
|
||||||
"//apex_available:anyapex",
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java_library {
|
java_library {
|
||||||
|
20
sdk/sdk.go
20
sdk/sdk.go
@@ -312,7 +312,7 @@ func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
|
|||||||
ctx.BottomUp("SdkMemberInterVersion", memberInterVersionMutator).Parallel()
|
ctx.BottomUp("SdkMemberInterVersion", memberInterVersionMutator).Parallel()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterPostDepshMutators registers post-deps mutators to support modules implementing SdkAware
|
// RegisterPostDepsMutators registers post-deps mutators to support modules implementing SdkAware
|
||||||
// interface and the sdk module type. This function has been made public to be called by tests
|
// interface and the sdk module type. This function has been made public to be called by tests
|
||||||
// outside of the sdk package
|
// outside of the sdk package
|
||||||
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
|
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
|
||||||
@@ -431,23 +431,31 @@ func sdkDepsReplaceMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6: ensure that the dependencies from outside of the APEX are all from the required SDKs
|
// Step 6: ensure that the dependencies outside of the APEX are all from the required SDKs
|
||||||
func sdkRequirementsMutator(mctx android.TopDownMutatorContext) {
|
func sdkRequirementsMutator(mctx android.TopDownMutatorContext) {
|
||||||
if m, ok := mctx.Module().(interface {
|
if m, ok := mctx.Module().(interface {
|
||||||
DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool
|
android.DepIsInSameApex
|
||||||
RequiredSdks() android.SdkRefs
|
android.RequiredSdks
|
||||||
}); ok {
|
}); ok {
|
||||||
requiredSdks := m.RequiredSdks()
|
requiredSdks := m.RequiredSdks()
|
||||||
if len(requiredSdks) == 0 {
|
if len(requiredSdks) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mctx.VisitDirectDeps(func(dep android.Module) {
|
mctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
if mctx.OtherModuleDependencyTag(dep) == android.DefaultsDepTag {
|
tag := mctx.OtherModuleDependencyTag(dep)
|
||||||
|
if tag == android.DefaultsDepTag {
|
||||||
// dependency to defaults is always okay
|
// dependency to defaults is always okay
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the dep is from outside of the APEX, but is not in any of the
|
// Ignore the dependency from the unversioned member to any versioned members as an
|
||||||
|
// apex that depends on the unversioned member will not also be depending on a versioned
|
||||||
|
// member.
|
||||||
|
if _, ok := tag.(sdkMemberVersionedDepTag); ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the dep is outside of the APEX, but is not in any of the
|
||||||
// required SDKs, we know that the dep is a violation.
|
// required SDKs, we know that the dep is a violation.
|
||||||
if sa, ok := dep.(android.SdkAware); ok {
|
if sa, ok := dep.(android.SdkAware); ok {
|
||||||
if !m.DepIsInSameApex(mctx, dep) && !requiredSdks.Contains(sa.ContainingSdk()) {
|
if !m.DepIsInSameApex(mctx, dep) && !requiredSdks.Contains(sa.ContainingSdk()) {
|
||||||
|
Reference in New Issue
Block a user