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

Commit a35f8db1 authored by Paul Duffin's avatar Paul Duffin
Browse files

Make apex variants of prebuilt apex exported modules available in make

Previously, the apex variants of modules exported from prebuilt_apex
and apex_set modules were not exported to make. Neither by the modules
themselves or by the prebuilt apex module. The master-art build relied
on the platform variants of the conscrypt and core-icu4j libraries
being exported to make so that they could be used by vogar.

Unfortunately, a change to export the prebuilt_bootclasspath_fragment
modules that contain the conscrypt and core-icu4j prebuilt libraries
from the corresponding prebuilt_apex prevented the platform variants
of those libraries from being exported at all which broke the
master-art builds as it only has prebuilts of those modules. It did not
break the aosp/master build as that has source modules.

The difference between the two builds is that the apex module type
makes its contents available in make but the prebuilt_apex/apex_set
module types do not.

This change causes the prebuilt_apex/apex_set module types to behave
more like the apex module type by making its exported libraries
available in make.

Test: m droid
      - in aosp/master
      art/tools/buildbot-build.sh --target --installclean
      - in master-art and aosp/master
Change-Id: I57537d17d4920d37d896ed491c6aaa15302cb25d
parent 6717d88f
Loading
Loading
Loading
Loading
+82 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ package apex

import (
	"fmt"
	"io"
	"path/filepath"
	"strconv"
	"strings"
@@ -57,6 +58,10 @@ type prebuiltCommon struct {
	installFilename string
	outputApex      android.WritablePath

	// A list of apexFile objects created in prebuiltCommon.initApexFilesForAndroidMk which are used
	// to create make modules in prebuiltCommon.AndroidMkEntries.
	apexFilesForAndroidMk []apexFile

	// list of commands to create symlinks for backward compatibility.
	// these commands will be attached as LOCAL_POST_INSTALL_CMD
	compatSymlinks []string
@@ -155,8 +160,37 @@ func (p *prebuiltCommon) installable() bool {
	return proptools.BoolDefault(p.prebuiltCommonProperties.Installable, true)
}

// initApexFilesForAndroidMk initializes the prebuiltCommon.apexFilesForAndroidMk field from the
// modules that this depends upon.
func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
	// Walk the dependencies of this module looking for the java modules that it exports.
	ctx.WalkDeps(func(child, parent android.Module) bool {
		tag := ctx.OtherModuleDependencyTag(child)

		name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
		if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
			// If the exported java module provides a dex jar path then add it to the list of apexFiles.
			path := child.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath()
			if path != nil {
				p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, apexFile{
					module:              child,
					moduleDir:           ctx.OtherModuleDir(child),
					androidMkModuleName: name,
					builtFile:           path,
					class:               javaSharedLib,
				})
			}
		} else if tag == exportedBootclasspathFragmentTag {
			// Visit the children of the bootclasspath_fragment.
			return true
		}

		return false
	})
}

func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
	return []android.AndroidMkEntries{
	entriesList := []android.AndroidMkEntries{
		{
			Class:         "ETC",
			OutputFile:    android.OptionalPathForPath(p.outputApex),
@@ -177,6 +211,47 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
			},
		},
	}

	// Iterate over the apexFilesForAndroidMk list and create an AndroidMkEntries struct for each
	// file. This provides similar behavior to that provided in apexBundle.AndroidMk() as it makes the
	// apex specific variants of the exported java modules available for use from within make.
	apexName := p.BaseModuleName()
	for _, fi := range p.apexFilesForAndroidMk {
		moduleName := fi.androidMkModuleName + "." + apexName
		entries := android.AndroidMkEntries{
			Class:        fi.class.nameInMake(),
			OverrideName: moduleName,
			OutputFile:   android.OptionalPathForPath(fi.builtFile),
			Include:      "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
			ExtraEntries: []android.AndroidMkExtraEntriesFunc{
				func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
					entries.SetString("LOCAL_MODULE_PATH", p.installDir.ToMakePath().String())

					// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar  Therefore
					// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
					// we will have foo.jar.jar
					entries.SetString("LOCAL_MODULE_STEM", strings.TrimSuffix(fi.stem(), ".jar"))
					entries.SetString("LOCAL_SOONG_CLASSES_JAR", fi.builtFile.String())
					entries.SetString("LOCAL_SOONG_HEADER_JAR", fi.builtFile.String())
					entries.SetString("LOCAL_SOONG_DEX_JAR", fi.builtFile.String())
					entries.SetString("LOCAL_DEX_PREOPT", "false")
				},
			},
			ExtraFooters: []android.AndroidMkExtraFootersFunc{
				func(w io.Writer, name, prefix, moduleDir string) {
					// m <module_name> will build <module_name>.<apex_name> as well.
					if fi.androidMkModuleName != moduleName {
						fmt.Fprintf(w, ".PHONY: %s\n", fi.androidMkModuleName)
						fmt.Fprintf(w, "%s: %s\n", fi.androidMkModuleName, moduleName)
					}
				},
			},
		}

		entriesList = append(entriesList, entries)
	}

	return entriesList
}

// prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and
@@ -635,6 +710,9 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		return
	}

	// Save the files that need to be made available to Make.
	p.initApexFilesForAndroidMk(ctx)

	if p.installable() {
		ctx.InstallFile(p.installDir, p.installFilename, p.inputApex)
	}
@@ -834,6 +912,9 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		return
	}

	// Save the files that need to be made available to Make.
	a.initApexFilesForAndroidMk(ctx)

	a.installDir = android.PathForModuleInstall(ctx, "apex")
	if a.installable() {
		ctx.InstallFile(a.installDir, a.installFilename, a.outputApex)