Exclude source->prebuilt deps from visibility enforcement

When both prebuilt and source versions of a module are present in the
build an implicit dependency is added from source -> prebuilt. This
change excludes that dependency from visibility enforcement as it
provides no value and would otherwise require an sdk snapshot to
rewrite the visibility of the generated prebuilt modules which would
be complicated.

The rewriting would include:
* Detecting //visibility:public and just passing that straight through.
* Detecting //visibility:private and replacing that with the location
  of the source.
* Otherwise, adding the location of the source to the visibility
  property.

This adds a general mechanism to allow any dependency to be excluded
from visibility enforcement by simply using a tag that implements
the ExcludeFromVisibilityEnforcementTag interface.

Bug: 142940300
Test: m nothing
Change-Id: I0668ff5aa798152d17faf3aac1bb8eff8d6350c3
This commit is contained in:
Paul Duffin 2020-01-14 12:42:08 +00:00
parent c132742c96
commit 78ac5b962e
4 changed files with 76 additions and 3 deletions

View File

@ -36,6 +36,9 @@ type prebuiltDependencyTag struct {
var PrebuiltDepTag prebuiltDependencyTag
// Mark this tag so dependencies that use it are excluded from visibility enforcement.
func (t prebuiltDependencyTag) ExcludeFromVisibilityEnforcement() {}
type PrebuiltProperties struct {
// When prefer is set to true the prebuilt will be used instead of any source module with
// a matching name.

View File

@ -141,10 +141,8 @@ func TestPrebuilts(t *testing.T) {
config := TestConfig(buildDir, nil, bp, fs)
ctx := NewTestContext()
RegisterPrebuiltMutators(ctx)
registerTestPrebuiltBuildComponents(ctx)
ctx.RegisterModuleType("filegroup", FileGroupFactory)
ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
ctx.RegisterModuleType("source", newSourceModule)
ctx.Register(config)
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
@ -212,6 +210,13 @@ func TestPrebuilts(t *testing.T) {
}
}
func registerTestPrebuiltBuildComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
ctx.RegisterModuleType("source", newSourceModule)
RegisterPrebuiltMutators(ctx)
}
type prebuiltModule struct {
ModuleBase
prebuilt Prebuilt

View File

@ -19,6 +19,8 @@ import (
"regexp"
"strings"
"sync"
"github.com/google/blueprint"
)
// Enforces visibility rules between modules.
@ -190,6 +192,15 @@ func moduleToVisibilityRuleMap(ctx BaseModuleContext) *sync.Map {
}).(*sync.Map)
}
// Marker interface that identifies dependencies that are excluded from visibility
// enforcement.
type ExcludeFromVisibilityEnforcementTag interface {
blueprint.DependencyTag
// Method that differentiates this interface from others.
ExcludeFromVisibilityEnforcement()
}
// The rule checker needs to be registered before defaults expansion to correctly check that
// //visibility:xxx isn't combined with other packages in the same list in any one module.
func RegisterVisibilityRuleChecker(ctx RegisterMutatorsContext) {
@ -389,6 +400,12 @@ func visibilityRuleEnforcer(ctx TopDownMutatorContext) {
// Visit all the dependencies making sure that this module has access to them all.
ctx.VisitDirectDeps(func(dep Module) {
// Ignore dependencies that have an ExcludeFromVisibilityEnforcementTag
tag := ctx.OtherModuleDependencyTag(dep)
if _, ok := tag.(ExcludeFromVisibilityEnforcementTag); ok {
return
}
depName := ctx.OtherModuleName(dep)
depDir := ctx.OtherModuleDir(dep)
depQualified := qualifiedModuleName{depDir, depName}

View File

@ -853,6 +853,51 @@ var visibilityTests = []struct {
` not visible to this module`,
},
},
{
name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
fs: map[string][]byte{
"prebuilts/Blueprints": []byte(`
prebuilt {
name: "module",
visibility: ["//top/other"],
}`),
"top/sources/source_file": nil,
"top/sources/Blueprints": []byte(`
source {
name: "module",
visibility: ["//top/other"],
}`),
"top/other/source_file": nil,
"top/other/Blueprints": []byte(`
source {
name: "other",
deps: [":module"],
}`),
},
},
{
name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
fs: map[string][]byte{
"prebuilts/Blueprints": []byte(`
prebuilt {
name: "module",
visibility: ["//top/other"],
prefer: true,
}`),
"top/sources/source_file": nil,
"top/sources/Blueprints": []byte(`
source {
name: "module",
visibility: ["//top/other"],
}`),
"top/other/source_file": nil,
"top/other/Blueprints": []byte(`
source {
name: "other",
deps: [":module"],
}`),
},
},
}
func TestVisibility(t *testing.T) {
@ -873,7 +918,10 @@ func testVisibility(buildDir string, fs map[string][]byte) (*TestContext, []erro
ctx := NewTestArchContext()
ctx.RegisterModuleType("mock_library", newMockLibraryModule)
ctx.RegisterModuleType("mock_defaults", defaultsFactory)
// Order of the following method calls is significant.
RegisterPackageBuildComponents(ctx)
registerTestPrebuiltBuildComponents(ctx)
ctx.PreArchMutators(RegisterVisibilityRuleChecker)
ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(RegisterVisibilityRuleGatherer)