aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com>2024-03-25 04:10:50 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-03-25 04:10:50 +0000
commite58af3da5a4bc0452364632f3c7161233f5479ab (patch)
treee70b52d761eac415e61fa07772e99ad87aca6d72
parent74ff1f80bc380134f00b6ce5a38509a223c6f101 (diff)
parent8bcf3c64f17fafd86758523b8f660e79be3a44f8 (diff)
downloadsoong-e58af3da5a4bc0452364632f3c7161233f5479ab.tar.gz
Merge "Add required, host_required, and target_required as dependencies" into main
-rw-r--r--android/base_module_context.go6
-rw-r--r--android/license_metadata.go5
-rw-r--r--android/module.go90
-rw-r--r--apex/apex.go5
-rw-r--r--apex/apex_test.go1
-rw-r--r--cc/cc.go7
-rw-r--r--filesystem/filesystem_test.go6
7 files changed, 119 insertions, 1 deletions
diff --git a/android/base_module_context.go b/android/base_module_context.go
index dd38a4ec8..9be3fad9a 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -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)
diff --git a/android/license_metadata.go b/android/license_metadata.go
index 463fd07b3..eabb1b170 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -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)
diff --git a/android/module.go b/android/module.go
index 000476cba..cce4fa6cb 100644
--- a/android/module.go
+++ b/android/module.go
@@ -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
diff --git a/apex/apex.go b/apex/apex.go
index ed2ca984e..bc91407a7 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1820,6 +1820,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)
@@ -2319,6 +2322,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)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index add6083c9..b7362b202 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -10047,7 +10047,6 @@ func TestAndroidMk_RequiredModules(t *testing.T) {
key: "myapex.key",
updatable: false,
java_libs: ["foo"],
- required: ["otherapex"],
}
apex_key {
diff --git a/cc/cc.go b/cc/cc.go
index 0fa34571a..90185ea96 100644
--- a/cc/cc.go
+++ b/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
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 6d62746ec..74c79e3bb 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -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 {