Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8bcf3c64 authored by Jiyong Park's avatar Jiyong Park
Browse files

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
parent 8fb0e973
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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)

+5 −0
Original line number Diff line number Diff line
@@ -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)
+90 −0
Original line number Diff line number Diff line
@@ -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
+5 −0
Original line number Diff line number Diff line
@@ -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)
	}
+0 −1
Original line number Diff line number Diff line
@@ -10047,7 +10047,6 @@ func TestAndroidMk_RequiredModules(t *testing.T) {
			key: "myapex.key",
			updatable: false,
			java_libs: ["foo"],
			required: ["otherapex"],
		}

		apex_key {
Loading