Currently, non-apex variants of modules that are in apexes are not exported to make unless they're apex_available to the platform. This means that you can't `m` those modules directly. However, there is a workaround in the apex androidmk implementation that emits make rules for the removed modules, but just redirects them to build the apex itself. We want to remove that, but one of the problems with doing so is that you can no longer `m` many modules afterwards. To fix that, unhide the apex's dependencies from make. To ensure they're not installed, call SkipInstall() on them, and update SkipInstall() to be more strict by setting `LOCAL_UNINSTALLABLE_MODULE := true`. Bug: 254205429 Test: Presubmits Change-Id: Ib971981559f3b642ce6be8890679e994e1b44be0
441 lines
8.5 KiB
Go
441 lines
8.5 KiB
Go
// Copyright 2020 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package android
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/google/blueprint"
|
|
"github.com/google/blueprint/proptools"
|
|
)
|
|
|
|
// Module to be packaged
|
|
type componentTestModule struct {
|
|
ModuleBase
|
|
props struct {
|
|
Deps []string
|
|
Skip_install *bool
|
|
}
|
|
|
|
builtFile Path
|
|
}
|
|
|
|
// dep tag used in this test. All dependencies are considered as installable.
|
|
type installDepTag struct {
|
|
blueprint.BaseDependencyTag
|
|
InstallAlwaysNeededDependencyTag
|
|
}
|
|
|
|
func componentTestModuleFactory() Module {
|
|
m := &componentTestModule{}
|
|
m.AddProperties(&m.props)
|
|
InitAndroidArchModule(m, HostAndDeviceSupported, MultilibBoth)
|
|
return m
|
|
}
|
|
|
|
func (m *componentTestModule) DepsMutator(ctx BottomUpMutatorContext) {
|
|
ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
|
|
}
|
|
|
|
func (m *componentTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|
m.builtFile = PathForModuleOut(ctx, m.Name())
|
|
dir := ctx.Target().Arch.ArchType.Multilib
|
|
installDir := PathForModuleInstall(ctx, dir)
|
|
if proptools.Bool(m.props.Skip_install) {
|
|
m.SkipInstall()
|
|
}
|
|
ctx.InstallFile(installDir, m.Name(), m.builtFile)
|
|
}
|
|
|
|
func (m *componentTestModule) AndroidMkEntries() []AndroidMkEntries {
|
|
return []AndroidMkEntries{
|
|
{
|
|
OutputFile: OptionalPathForPath(m.builtFile),
|
|
},
|
|
}
|
|
}
|
|
|
|
// Module that itself is a package
|
|
type packageTestModule struct {
|
|
ModuleBase
|
|
PackagingBase
|
|
properties struct {
|
|
Install_deps []string `android:`
|
|
}
|
|
entries []string
|
|
}
|
|
|
|
func packageMultiTargetTestModuleFactory() Module {
|
|
module := &packageTestModule{}
|
|
InitPackageModule(module)
|
|
InitAndroidMultiTargetsArchModule(module, DeviceSupported, MultilibCommon)
|
|
module.AddProperties(&module.properties)
|
|
return module
|
|
}
|
|
|
|
func packageTestModuleFactory() Module {
|
|
module := &packageTestModule{}
|
|
InitPackageModule(module)
|
|
InitAndroidArchModule(module, DeviceSupported, MultilibBoth)
|
|
module.AddProperties(&module.properties)
|
|
return module
|
|
}
|
|
|
|
type packagingDepTag struct {
|
|
blueprint.BaseDependencyTag
|
|
PackagingItemAlwaysDepTag
|
|
}
|
|
|
|
func (m *packageTestModule) DepsMutator(ctx BottomUpMutatorContext) {
|
|
m.AddDeps(ctx, packagingDepTag{})
|
|
ctx.AddDependency(ctx.Module(), installDepTag{}, m.properties.Install_deps...)
|
|
}
|
|
|
|
func (m *packageTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|
zipFile := PathForModuleOut(ctx, "myzip.zip")
|
|
m.entries = m.CopyDepsToZip(ctx, m.GatherPackagingSpecs(ctx), zipFile)
|
|
}
|
|
|
|
func runPackagingTest(t *testing.T, multitarget bool, bp string, expected []string) {
|
|
t.Helper()
|
|
|
|
var archVariant string
|
|
var moduleFactory ModuleFactory
|
|
if multitarget {
|
|
archVariant = "android_common"
|
|
moduleFactory = packageMultiTargetTestModuleFactory
|
|
} else {
|
|
archVariant = "android_arm64_armv8-a"
|
|
moduleFactory = packageTestModuleFactory
|
|
}
|
|
|
|
result := GroupFixturePreparers(
|
|
PrepareForTestWithArchMutator,
|
|
FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
|
ctx.RegisterModuleType("component", componentTestModuleFactory)
|
|
ctx.RegisterModuleType("package_module", moduleFactory)
|
|
}),
|
|
FixtureWithRootAndroidBp(bp),
|
|
).RunTest(t)
|
|
|
|
p := result.Module("package", archVariant).(*packageTestModule)
|
|
actual := p.entries
|
|
actual = SortedUniqueStrings(actual)
|
|
expected = SortedUniqueStrings(expected)
|
|
AssertDeepEquals(t, "package entries", expected, actual)
|
|
}
|
|
|
|
func TestPackagingBaseMultiTarget(t *testing.T) {
|
|
multiTarget := true
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
}
|
|
`, []string{"lib64/foo"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
deps: ["bar"],
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
}
|
|
`, []string{"lib64/foo", "lib64/bar"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
deps: ["bar"],
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
compile_multilib: "both",
|
|
}
|
|
`, []string{"lib32/foo", "lib32/bar", "lib64/foo", "lib64/bar"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
compile_multilib: "32",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
multilib: {
|
|
lib32: {
|
|
deps: ["bar"],
|
|
},
|
|
},
|
|
compile_multilib: "both",
|
|
}
|
|
`, []string{"lib32/foo", "lib32/bar", "lib64/foo"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
multilib: {
|
|
first: {
|
|
deps: ["bar"],
|
|
},
|
|
},
|
|
compile_multilib: "both",
|
|
}
|
|
`, []string{"lib32/foo", "lib64/foo", "lib64/bar"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
}
|
|
|
|
component {
|
|
name: "baz",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
arch: {
|
|
arm64: {
|
|
deps: ["bar"],
|
|
},
|
|
x86_64: {
|
|
deps: ["baz"],
|
|
},
|
|
},
|
|
compile_multilib: "both",
|
|
}
|
|
`, []string{"lib32/foo", "lib64/foo", "lib64/bar"})
|
|
}
|
|
|
|
func TestSkipInstallProducesLocalUninstallableModule(t *testing.T) {
|
|
result := GroupFixturePreparers(
|
|
PrepareForTestWithArchMutator,
|
|
FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
|
ctx.RegisterModuleType("component", componentTestModuleFactory)
|
|
ctx.RegisterModuleType("package_module", packageTestModuleFactory)
|
|
}),
|
|
FixtureWithRootAndroidBp(`
|
|
component {
|
|
name: "foo",
|
|
skip_install: true,
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
}
|
|
`),
|
|
).RunTest(t)
|
|
module := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*componentTestModule)
|
|
entries := AndroidMkEntriesForTest(t, result.TestContext, module)
|
|
builder := &strings.Builder{}
|
|
entries[0].write(builder)
|
|
androidMkString := builder.String()
|
|
if !strings.Contains(androidMkString, "LOCAL_UNINSTALLABLE_MODULE := true") {
|
|
t.Errorf("Expected android mk entries to contain \"LOCAL_UNINSTALLABLE_MODULE := true\", got: \n%s", androidMkString)
|
|
}
|
|
}
|
|
|
|
func TestPackagingBaseSingleTarget(t *testing.T) {
|
|
multiTarget := false
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
}
|
|
`, []string{"lib64/foo"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
deps: ["bar"],
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
}
|
|
`, []string{"lib64/foo", "lib64/bar"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
compile_multilib: "32",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
multilib: {
|
|
lib32: {
|
|
deps: ["bar"],
|
|
},
|
|
},
|
|
}
|
|
`, []string{"lib64/foo"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
multilib: {
|
|
lib64: {
|
|
deps: ["bar"],
|
|
},
|
|
},
|
|
}
|
|
`, []string{"lib64/foo", "lib64/bar"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
}
|
|
|
|
component {
|
|
name: "baz",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
arch: {
|
|
arm64: {
|
|
deps: ["bar"],
|
|
},
|
|
x86_64: {
|
|
deps: ["baz"],
|
|
},
|
|
},
|
|
}
|
|
`, []string{"lib64/foo", "lib64/bar"})
|
|
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
install_deps: ["bar"],
|
|
}
|
|
`, []string{"lib64/foo"})
|
|
}
|
|
|
|
func TestPackagingWithSkipInstallDeps(t *testing.T) {
|
|
// package -[dep]-> foo -[dep]-> bar -[dep]-> baz
|
|
// OK SKIPPED
|
|
multiTarget := false
|
|
runPackagingTest(t, multiTarget,
|
|
`
|
|
component {
|
|
name: "foo",
|
|
deps: ["bar"],
|
|
}
|
|
|
|
component {
|
|
name: "bar",
|
|
deps: ["baz"],
|
|
skip_install: true,
|
|
}
|
|
|
|
component {
|
|
name: "baz",
|
|
}
|
|
|
|
package_module {
|
|
name: "package",
|
|
deps: ["foo"],
|
|
}
|
|
`, []string{"lib64/foo"})
|
|
}
|