Add required, host_required, and target_required as dependencies
So far, the installation of required modules were handled by Make. This prevents us from implementing the module installation and packaging entirely in Soong. This CL is the first step towards that goal. Soong now correctly tracks the dependencies and they are correctly returned by TransitivePackagingSpecs(), which is used by packaging modules like android_system_image. Bug: 321626681 Test: build Change-Id: I9192b5333ceaa0b7d1c5c4abeec2af62febcd976
This commit is contained in:
parent
8fb0e9734c
commit
8bcf3c64f1
7 changed files with 119 additions and 1 deletions
|
@ -305,6 +305,12 @@ type AllowDisabledModuleDependency interface {
|
|||
AllowDisabledModuleDependency(target Module) bool
|
||||
}
|
||||
|
||||
type AlwaysAllowDisabledModuleDependencyTag struct{}
|
||||
|
||||
func (t AlwaysAllowDisabledModuleDependencyTag) AllowDisabledModuleDependency(Module) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool, ignoreBlueprint bool) Module {
|
||||
aModule, _ := module.(Module)
|
||||
|
||||
|
|
|
@ -77,6 +77,11 @@ func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) {
|
|||
if ctx.OtherModuleDependencyTag(dep) == DefaultsDepTag {
|
||||
return
|
||||
}
|
||||
// The required dependencies just say modules A and B should be installed together.
|
||||
// It doesn't mean that one is built using the other.
|
||||
if ctx.OtherModuleDependencyTag(dep) == RequiredDepTag {
|
||||
return
|
||||
}
|
||||
|
||||
if info, ok := OtherModuleProvider(ctx, dep, LicenseMetadataProvider); ok {
|
||||
allDepMetadataFiles = append(allDepMetadataFiles, info.LicenseMetadataPath)
|
||||
|
|
|
@ -542,6 +542,15 @@ type TeamDepTagType struct {
|
|||
|
||||
var teamDepTag = TeamDepTagType{}
|
||||
|
||||
// Dependency tag for required, host_required, and target_required modules.
|
||||
var RequiredDepTag = struct {
|
||||
blueprint.BaseDependencyTag
|
||||
InstallAlwaysNeededDependencyTag
|
||||
// Requiring disabled module has been supported (as a side effect of this being implemented
|
||||
// in Make). We may want to make it an error, but for now, let's keep the existing behavior.
|
||||
AlwaysAllowDisabledModuleDependencyTag
|
||||
}{}
|
||||
|
||||
// CommonTestOptions represents the common `test_options` properties in
|
||||
// Android.bp.
|
||||
type CommonTestOptions struct {
|
||||
|
@ -1007,6 +1016,87 @@ func (m *ModuleBase) baseDepsMutator(ctx BottomUpMutatorContext) {
|
|||
if m.Team() != "" {
|
||||
ctx.AddDependency(ctx.Module(), teamDepTag, m.Team())
|
||||
}
|
||||
|
||||
// TODO(jiyong): remove below case. This is to work around build errors happening
|
||||
// on branches with reduced manifest like aosp_kernel-build-tools.
|
||||
// In the branch, a build error occurs as follows.
|
||||
// 1. aosp_kernel-build-tools is a reduced manifest branch. It doesn't have some git
|
||||
// projects like external/bouncycastle
|
||||
// 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
|
||||
// the top-level build goal (in the shell file that invokes Soong).
|
||||
// 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
|
||||
// 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of
|
||||
// ALLOW_MISSING_DEPENDENCIES didn't cause a problem.
|
||||
// 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
|
||||
// absence of external/bouncycastle fails the build.
|
||||
//
|
||||
// Unfortunately, there's no way for Soong to correctly determine if it's running in a
|
||||
// reduced manifest branch. Instead, here, we use the absence of DeviceArch or DeviceName as
|
||||
// a strong signal, because that's very common across reduced manifest branches.
|
||||
pv := ctx.Config().productVariables
|
||||
fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
|
||||
if fullManifest {
|
||||
m.addRequiredDeps(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// addRequiredDeps adds required, target_required, and host_required as dependencies.
|
||||
func (m *ModuleBase) addRequiredDeps(ctx BottomUpMutatorContext) {
|
||||
addDep := func(target Target, depName string) {
|
||||
if !ctx.OtherModuleExists(depName) {
|
||||
if ctx.Config().AllowMissingDependencies() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// If Android native module requires another Android native module, ensure that
|
||||
// they have the same bitness. This mimics the policy in select-bitness-of-required-modules
|
||||
// in build/make/core/main.mk.
|
||||
// TODO(jiyong): the Make-side does this only when the required module is a shared
|
||||
// library or a native test.
|
||||
bothInAndroid := m.Device() && target.Os.Class == Device
|
||||
nativeArch := m.Arch().ArchType.Multilib != string(MultilibCommon)
|
||||
sameBitness := m.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
|
||||
if bothInAndroid && nativeArch && !sameBitness {
|
||||
return
|
||||
}
|
||||
|
||||
variation := target.Variations()
|
||||
if ctx.OtherModuleFarDependencyVariantExists(variation, depName) {
|
||||
ctx.AddFarVariationDependencies(variation, RequiredDepTag, depName)
|
||||
}
|
||||
}
|
||||
|
||||
if m.Device() {
|
||||
for _, depName := range m.RequiredModuleNames() {
|
||||
for _, target := range ctx.Config().Targets[Android] {
|
||||
addDep(target, depName)
|
||||
}
|
||||
}
|
||||
for _, depName := range m.HostRequiredModuleNames() {
|
||||
for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] {
|
||||
addDep(target, depName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if m.Host() {
|
||||
for _, depName := range m.RequiredModuleNames() {
|
||||
for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] {
|
||||
// When a host module requires another host module, don't make a
|
||||
// dependency if they have different OSes (i.e. hostcross).
|
||||
if m.Target().HostCross != target.HostCross {
|
||||
continue
|
||||
}
|
||||
addDep(target, depName)
|
||||
}
|
||||
}
|
||||
for _, depName := range m.TargetRequiredModuleNames() {
|
||||
for _, target := range ctx.Config().Targets[Android] {
|
||||
addDep(target, depName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddProperties "registers" the provided props
|
||||
|
|
|
@ -1821,6 +1821,9 @@ func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.Paylo
|
|||
if dt, ok := depTag.(*dependencyTag); ok && !dt.payload {
|
||||
return false
|
||||
}
|
||||
if depTag == android.RequiredDepTag {
|
||||
return false
|
||||
}
|
||||
|
||||
ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider)
|
||||
externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants)
|
||||
|
@ -2314,6 +2317,8 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext,
|
|||
// nothing
|
||||
} else if depTag == android.DarwinUniversalVariantTag {
|
||||
// nothing
|
||||
} else if depTag == android.RequiredDepTag {
|
||||
// nothing
|
||||
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
|
||||
ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
|
||||
}
|
||||
|
|
|
@ -10047,7 +10047,6 @@ func TestAndroidMk_RequiredModules(t *testing.T) {
|
|||
key: "myapex.key",
|
||||
updatable: false,
|
||||
java_libs: ["foo"],
|
||||
required: ["otherapex"],
|
||||
}
|
||||
|
||||
apex_key {
|
||||
|
|
7
cc/cc.go
7
cc/cc.go
|
@ -2980,6 +2980,9 @@ func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
|
|||
if depTag == stubImplDepTag {
|
||||
return false
|
||||
}
|
||||
if depTag == android.RequiredDepTag {
|
||||
return false
|
||||
}
|
||||
|
||||
// Even if target lib has no vendor variant, keep checking dependency
|
||||
// graph in case it depends on vendor_available or product_available
|
||||
|
@ -3157,6 +3160,10 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||
return
|
||||
}
|
||||
|
||||
if depTag == android.RequiredDepTag {
|
||||
return
|
||||
}
|
||||
|
||||
if dep.Target().Os != ctx.Os() {
|
||||
ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
|
||||
return
|
||||
|
|
|
@ -76,6 +76,11 @@ func TestFileSystemDeps(t *testing.T) {
|
|||
|
||||
cc_library {
|
||||
name: "libbar",
|
||||
required: ["libbaz"],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libbaz",
|
||||
}
|
||||
`)
|
||||
|
||||
|
@ -87,6 +92,7 @@ func TestFileSystemDeps(t *testing.T) {
|
|||
"bin/foo",
|
||||
"lib/libbar.so",
|
||||
"lib64/libbar.so",
|
||||
"lib64/libbaz.so",
|
||||
"etc/bpf/bpf.o",
|
||||
}
|
||||
for _, e := range expected {
|
||||
|
|
Loading…
Reference in a new issue