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
diff --git a/android/module.go b/android/module.go
index 000476c..cce4fa6 100644
--- a/android/module.go
+++ b/android/module.go
@@ -542,6 +542,15 @@
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 @@
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