Merge "Install sdk variants in unbundled builds and package uninstallable variants"
This commit is contained in:
@@ -34,10 +34,10 @@ func (i InstallAlwaysNeededDependencyTag) InstallDepNeeded() bool {
|
||||
|
||||
var _ InstallNeededDependencyTag = InstallAlwaysNeededDependencyTag{}
|
||||
|
||||
// IsInstallDepNeeded returns true if the dependency tag implements the InstallNeededDependencyTag
|
||||
// IsInstallDepNeededTag returns true if the dependency tag implements the InstallNeededDependencyTag
|
||||
// interface and the InstallDepNeeded returns true, meaning that the installed files of the parent
|
||||
// should depend on the installed files of the child.
|
||||
func IsInstallDepNeeded(tag blueprint.DependencyTag) bool {
|
||||
func IsInstallDepNeededTag(tag blueprint.DependencyTag) bool {
|
||||
if i, ok := tag.(InstallNeededDependencyTag); ok {
|
||||
return i.InstallDepNeeded()
|
||||
}
|
||||
|
@@ -74,7 +74,7 @@ func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) {
|
||||
if ctx.OtherModuleHasProvider(dep, LicenseMetadataProvider) {
|
||||
info := ctx.OtherModuleProvider(dep, LicenseMetadataProvider).(*LicenseMetadataInfo)
|
||||
allDepMetadataFiles = append(allDepMetadataFiles, info.LicenseMetadataPath)
|
||||
if isContainer || IsInstallDepNeeded(ctx.OtherModuleDependencyTag(dep)) {
|
||||
if isContainer || isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
|
||||
allDepMetadataDepSets = append(allDepMetadataDepSets, info.LicenseMetadataDepSet)
|
||||
}
|
||||
|
||||
|
@@ -925,6 +925,12 @@ type commonProperties struct {
|
||||
// and don't create a rule to install the file.
|
||||
SkipInstall bool `blueprint:"mutated"`
|
||||
|
||||
// UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
|
||||
// mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
|
||||
// is used to avoid adding install or packaging dependencies into libraries provided
|
||||
// by apexes.
|
||||
UninstallableApexPlatformVariant bool `blueprint:"mutated"`
|
||||
|
||||
// Whether the module has been replaced by a prebuilt
|
||||
ReplacedByPrebuilt bool `blueprint:"mutated"`
|
||||
|
||||
@@ -2009,6 +2015,7 @@ func (m *ModuleBase) IsSkipInstall() bool {
|
||||
// have other side effects, in particular when it adds a NOTICE file target,
|
||||
// which other install targets might depend on.
|
||||
func (m *ModuleBase) MakeUninstallable() {
|
||||
m.commonProperties.UninstallableApexPlatformVariant = true
|
||||
m.HideFromMake()
|
||||
}
|
||||
|
||||
@@ -2038,13 +2045,19 @@ func (m *ModuleBase) EffectiveLicenseFiles() Paths {
|
||||
}
|
||||
|
||||
// computeInstallDeps finds the installed paths of all dependencies that have a dependency
|
||||
// tag that is annotated as needing installation via the IsInstallDepNeeded method.
|
||||
// tag that is annotated as needing installation via the isInstallDepNeeded method.
|
||||
func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*installPathsDepSet, []*packagingSpecsDepSet) {
|
||||
var installDeps []*installPathsDepSet
|
||||
var packagingSpecs []*packagingSpecsDepSet
|
||||
ctx.VisitDirectDeps(func(dep Module) {
|
||||
if IsInstallDepNeeded(ctx.OtherModuleDependencyTag(dep)) && !dep.IsHideFromMake() && !dep.IsSkipInstall() {
|
||||
installDeps = append(installDeps, dep.base().installFilesDepSet)
|
||||
if isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) {
|
||||
// Installation is still handled by Make, so anything hidden from Make is not
|
||||
// installable.
|
||||
if !dep.IsHideFromMake() && !dep.IsSkipInstall() {
|
||||
installDeps = append(installDeps, dep.base().installFilesDepSet)
|
||||
}
|
||||
// Add packaging deps even when the dependency is not installed so that uninstallable
|
||||
// modules can still be packaged. Often the package will be installed instead.
|
||||
packagingSpecs = append(packagingSpecs, dep.base().packagingSpecsDepSet)
|
||||
}
|
||||
})
|
||||
@@ -2052,6 +2065,17 @@ func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*installPathsDepSe
|
||||
return installDeps, packagingSpecs
|
||||
}
|
||||
|
||||
// isInstallDepNeeded returns true if installing the output files of the current module
|
||||
// should also install the output files of the given dependency and dependency tag.
|
||||
func isInstallDepNeeded(dep Module, tag blueprint.DependencyTag) bool {
|
||||
// Don't add a dependency from the platform to a library provided by an apex.
|
||||
if dep.base().commonProperties.UninstallableApexPlatformVariant {
|
||||
return false
|
||||
}
|
||||
// Only install modules if the dependency tag is an InstallDepNeeded tag.
|
||||
return IsInstallDepNeededTag(tag)
|
||||
}
|
||||
|
||||
func (m *ModuleBase) FilesToInstall() InstallPaths {
|
||||
return m.installFiles
|
||||
}
|
||||
|
@@ -373,7 +373,7 @@ func TestPackagingBaseSingleTarget(t *testing.T) {
|
||||
|
||||
func TestPackagingWithSkipInstallDeps(t *testing.T) {
|
||||
// package -[dep]-> foo -[dep]-> bar -[dep]-> baz
|
||||
// OK SKIPPED
|
||||
// Packaging should continue transitively through modules that are not installed.
|
||||
multiTarget := false
|
||||
runPackagingTest(t, multiTarget,
|
||||
`
|
||||
@@ -396,5 +396,5 @@ func TestPackagingWithSkipInstallDeps(t *testing.T) {
|
||||
name: "package",
|
||||
deps: ["foo"],
|
||||
}
|
||||
`, []string{"lib64/foo"})
|
||||
`, []string{"lib64/foo", "lib64/bar", "lib64/baz"})
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@ import (
|
||||
"android/soong/cc"
|
||||
"android/soong/dexpreopt"
|
||||
prebuilt_etc "android/soong/etc"
|
||||
"android/soong/filesystem"
|
||||
"android/soong/java"
|
||||
"android/soong/rust"
|
||||
"android/soong/sh"
|
||||
@@ -10378,3 +10379,54 @@ func TestStubLibrariesMultipleApexViolation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileSystemShouldSkipApexLibraries(t *testing.T) {
|
||||
context := android.GroupFixturePreparers(
|
||||
android.PrepareForIntegrationTestWithAndroid,
|
||||
cc.PrepareForIntegrationTestWithCc,
|
||||
PrepareForTestWithApexBuildComponents,
|
||||
prepareForTestWithMyapex,
|
||||
filesystem.PrepareForTestWithFilesystemBuildComponents,
|
||||
)
|
||||
result := context.RunTestWithBp(t, `
|
||||
android_system_image {
|
||||
name: "myfilesystem",
|
||||
deps: [
|
||||
"libfoo",
|
||||
],
|
||||
linker_config_src: "linker.config.json",
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libfoo",
|
||||
shared_libs: [
|
||||
"libbar",
|
||||
],
|
||||
stl: "none",
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libbar",
|
||||
stl: "none",
|
||||
apex_available: ["myapex"],
|
||||
}
|
||||
|
||||
apex {
|
||||
name: "myapex",
|
||||
native_shared_libs: ["libbar"],
|
||||
key: "myapex.key",
|
||||
updatable: false,
|
||||
}
|
||||
|
||||
apex_key {
|
||||
name: "myapex.key",
|
||||
public_key: "testkey.avbpubkey",
|
||||
private_key: "testkey.pem",
|
||||
}
|
||||
`)
|
||||
|
||||
inputs := result.ModuleForTests("myfilesystem", "android_common").Output("deps.zip").Implicits
|
||||
android.AssertStringListDoesNotContain(t, "filesystem should not have libbar",
|
||||
inputs.Strings(),
|
||||
"out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so")
|
||||
}
|
||||
|
@@ -124,17 +124,14 @@ func (c *Module) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.Properties.IsSdkVariant {
|
||||
if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake {
|
||||
// Make the SDK variant uninstallable so that there are not two rules to install
|
||||
// to the same location.
|
||||
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
|
||||
|
||||
if c.Properties.SdkAndPlatformVariantVisibleToMake {
|
||||
// Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite
|
||||
// dependencies to the .sdk suffix when building a module that uses the SDK.
|
||||
entries.SetString("SOONG_SDK_VARIANT_MODULES",
|
||||
"$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))")
|
||||
}
|
||||
// Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite
|
||||
// dependencies to the .sdk suffix when building a module that uses the SDK.
|
||||
entries.SetString("SOONG_SDK_VARIANT_MODULES",
|
||||
"$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))")
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@@ -47,16 +47,16 @@ func sdkMutator(ctx android.BottomUpMutatorContext) {
|
||||
|
||||
// Mark the SDK variant.
|
||||
modules[1].(*Module).Properties.IsSdkVariant = true
|
||||
// SDK variant is not supposed to be installed
|
||||
modules[1].(*Module).Properties.PreventInstall = true
|
||||
|
||||
if ctx.Config().UnbundledBuildApps() {
|
||||
// For an unbundled apps build, hide the platform variant from Make.
|
||||
modules[0].(*Module).Properties.HideFromMake = true
|
||||
modules[0].(*Module).Properties.PreventInstall = true
|
||||
} else {
|
||||
// For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
|
||||
// exposed to Make.
|
||||
modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
|
||||
modules[1].(*Module).Properties.PreventInstall = true
|
||||
}
|
||||
ctx.AliasVariation("")
|
||||
} else if isCcModule && ccModule.isImportedApiLibrary() {
|
||||
@@ -74,8 +74,8 @@ func sdkMutator(ctx android.BottomUpMutatorContext) {
|
||||
if apiLibrary.hasApexStubs() {
|
||||
// For an unbundled apps build, hide the platform variant from Make.
|
||||
modules[1].(*Module).Properties.HideFromMake = true
|
||||
modules[1].(*Module).Properties.PreventInstall = true
|
||||
}
|
||||
modules[1].(*Module).Properties.PreventInstall = true
|
||||
} else {
|
||||
// For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
|
||||
// exposed to Make.
|
||||
|
@@ -101,95 +101,3 @@ func TestSdkMutator(t *testing.T) {
|
||||
assertDep(t, libsdkNDK, libcxxNDK)
|
||||
assertDep(t, libsdkPlatform, libcxxPlatform)
|
||||
}
|
||||
|
||||
func TestMakeModuleNameForSdkVariant(t *testing.T) {
|
||||
bp := `
|
||||
cc_library {
|
||||
name: "libfoo",
|
||||
srcs: ["main_test.cpp"],
|
||||
sdk_version: "current",
|
||||
stl: "none",
|
||||
}
|
||||
`
|
||||
platformVariant := "android_arm64_armv8-a_shared"
|
||||
sdkVariant := "android_arm64_armv8-a_sdk_shared"
|
||||
testCases := []struct {
|
||||
name string
|
||||
unbundledApps []string
|
||||
variant string
|
||||
skipInstall bool // soong skips install
|
||||
hideFromMake bool // no make entry
|
||||
makeUninstallable bool // make skips install
|
||||
makeModuleName string
|
||||
}{
|
||||
{
|
||||
name: "platform variant in normal builds",
|
||||
unbundledApps: nil,
|
||||
variant: platformVariant,
|
||||
// installable in soong
|
||||
skipInstall: false,
|
||||
// visiable in Make as "libfoo"
|
||||
hideFromMake: false,
|
||||
makeModuleName: "libfoo",
|
||||
// installable in Make
|
||||
makeUninstallable: false,
|
||||
},
|
||||
{
|
||||
name: "sdk variant in normal builds",
|
||||
unbundledApps: nil,
|
||||
variant: sdkVariant,
|
||||
// soong doesn't install
|
||||
skipInstall: true,
|
||||
// visible in Make as "libfoo.sdk"
|
||||
hideFromMake: false,
|
||||
makeModuleName: "libfoo.sdk",
|
||||
// but not installed
|
||||
makeUninstallable: true,
|
||||
},
|
||||
{
|
||||
name: "platform variant in unbunded builds",
|
||||
unbundledApps: []string{"bar"},
|
||||
variant: platformVariant,
|
||||
// installable in soong
|
||||
skipInstall: false,
|
||||
// hidden from make
|
||||
hideFromMake: true,
|
||||
},
|
||||
{
|
||||
name: "sdk variant in unbunded builds",
|
||||
unbundledApps: []string{"bar"},
|
||||
variant: sdkVariant,
|
||||
// soong doesn't install
|
||||
skipInstall: true,
|
||||
// visible in Make as "libfoo"
|
||||
hideFromMake: false,
|
||||
makeModuleName: "libfoo",
|
||||
// but not installed
|
||||
makeUninstallable: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fixture := android.GroupFixturePreparers(prepareForCcTest,
|
||||
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||
variables.Unbundled_build_apps = tc.unbundledApps
|
||||
}),
|
||||
)
|
||||
ctx := fixture.RunTestWithBp(t, bp).TestContext
|
||||
module := ctx.ModuleForTests("libfoo", tc.variant).Module().(*Module)
|
||||
android.AssertBoolEquals(t, "IsSkipInstall", tc.skipInstall, module.IsSkipInstall())
|
||||
android.AssertBoolEquals(t, "HideFromMake", tc.hideFromMake, module.HiddenFromMake())
|
||||
if !tc.hideFromMake {
|
||||
entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
|
||||
android.AssertStringEquals(t, "LOCAL_MODULE",
|
||||
tc.makeModuleName, entries.EntryMap["LOCAL_MODULE"][0])
|
||||
actualUninstallable := false
|
||||
if actual, ok := entries.EntryMap["LOCAL_UNINSTALLABLE_MODULE"]; ok {
|
||||
actualUninstallable = "true" == actual[0]
|
||||
}
|
||||
android.AssertBoolEquals(t, "LOCAL_UNINSTALLABLE_MODULE",
|
||||
tc.makeUninstallable, actualUninstallable)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user