New AndroidMk authoring system based on entry map.
The new system collects all Android.mk variable assignments using a map and writes them to io.Writer. Compared to the previous system, which directly writes all entries to buffers, this new system is more robust and test-friendly. Test: Built without prebuilt_etc.go change and diffed the mk output. Test: prebuilt_etc_test.go Change-Id: Idd28443d129ff70053295015e69328a8fa3eca47
This commit is contained in:
parent
8bf9bd9f91
commit
9aa3ab1f3f
|
@ -32,6 +32,8 @@ func init() {
|
|||
RegisterSingletonType("androidmk", AndroidMkSingleton)
|
||||
}
|
||||
|
||||
// Deprecated: consider using AndroidMkEntriesProvider instead, especially if you're not going to
|
||||
// use the Custom function.
|
||||
type AndroidMkDataProvider interface {
|
||||
AndroidMk() AndroidMkData
|
||||
BaseModuleName() string
|
||||
|
@ -57,6 +59,200 @@ type AndroidMkData struct {
|
|||
|
||||
type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
|
||||
|
||||
// Allows modules to customize their Android*.mk output.
|
||||
type AndroidMkEntriesProvider interface {
|
||||
AndroidMkEntries() AndroidMkEntries
|
||||
BaseModuleName() string
|
||||
}
|
||||
|
||||
type AndroidMkEntries struct {
|
||||
Class string
|
||||
SubName string
|
||||
DistFile OptionalPath
|
||||
OutputFile OptionalPath
|
||||
Disabled bool
|
||||
Include string
|
||||
Required []string
|
||||
Host_required []string
|
||||
Target_required []string
|
||||
|
||||
header bytes.Buffer
|
||||
footer bytes.Buffer
|
||||
|
||||
AddCustomEntries func(name, prefix, moduleDir string, entries *AndroidMkEntries)
|
||||
|
||||
EntryMap map[string][]string
|
||||
entryOrder []string
|
||||
}
|
||||
|
||||
func (a *AndroidMkEntries) SetString(name, value string) {
|
||||
if _, ok := a.EntryMap[name]; !ok {
|
||||
a.entryOrder = append(a.entryOrder, name)
|
||||
}
|
||||
a.EntryMap[name] = []string{value}
|
||||
}
|
||||
|
||||
func (a *AndroidMkEntries) SetBoolIfTrue(name string, flag bool) {
|
||||
if flag {
|
||||
if _, ok := a.EntryMap[name]; !ok {
|
||||
a.entryOrder = append(a.entryOrder, name)
|
||||
}
|
||||
a.EntryMap[name] = []string{"true"}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AndroidMkEntries) AddStrings(name string, value ...string) {
|
||||
if len(value) == 0 {
|
||||
return
|
||||
}
|
||||
if _, ok := a.EntryMap[name]; !ok {
|
||||
a.entryOrder = append(a.entryOrder, name)
|
||||
}
|
||||
a.EntryMap[name] = append(a.EntryMap[name], value...)
|
||||
}
|
||||
|
||||
func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod blueprint.Module) {
|
||||
a.EntryMap = make(map[string][]string)
|
||||
amod := mod.(Module).base()
|
||||
name := amod.BaseModuleName()
|
||||
|
||||
if a.Include == "" {
|
||||
a.Include = "$(BUILD_PREBUILT)"
|
||||
}
|
||||
a.Required = append(a.Required, amod.commonProperties.Required...)
|
||||
a.Host_required = append(a.Host_required, amod.commonProperties.Host_required...)
|
||||
a.Target_required = append(a.Target_required, amod.commonProperties.Target_required...)
|
||||
|
||||
// Fill in the header part.
|
||||
if len(amod.commonProperties.Dist.Targets) > 0 {
|
||||
distFile := a.DistFile
|
||||
if !distFile.Valid() {
|
||||
distFile = a.OutputFile
|
||||
}
|
||||
if distFile.Valid() {
|
||||
dest := filepath.Base(distFile.String())
|
||||
|
||||
if amod.commonProperties.Dist.Dest != nil {
|
||||
var err error
|
||||
if dest, err = validateSafePath(*amod.commonProperties.Dist.Dest); err != nil {
|
||||
// This was checked in ModuleBase.GenerateBuildActions
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if amod.commonProperties.Dist.Suffix != nil {
|
||||
ext := filepath.Ext(dest)
|
||||
suffix := *amod.commonProperties.Dist.Suffix
|
||||
dest = strings.TrimSuffix(dest, ext) + suffix + ext
|
||||
}
|
||||
|
||||
if amod.commonProperties.Dist.Dir != nil {
|
||||
var err error
|
||||
if dest, err = validateSafePath(*amod.commonProperties.Dist.Dir, dest); err != nil {
|
||||
// This was checked in ModuleBase.GenerateBuildActions
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
goals := strings.Join(amod.commonProperties.Dist.Targets, " ")
|
||||
fmt.Fprintln(&a.header, ".PHONY:", goals)
|
||||
fmt.Fprintf(&a.header, "$(call dist-for-goals,%s,%s:%s)\n",
|
||||
goals, distFile.String(), dest)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintln(&a.header, "\ninclude $(CLEAR_VARS)")
|
||||
|
||||
// Collect make variable assignment entries.
|
||||
a.SetString("LOCAL_PATH", filepath.Dir(bpPath))
|
||||
a.SetString("LOCAL_MODULE", name+a.SubName)
|
||||
a.SetString("LOCAL_MODULE_CLASS", a.Class)
|
||||
a.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
|
||||
a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
|
||||
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
|
||||
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
|
||||
|
||||
archStr := amod.Arch().ArchType.String()
|
||||
host := false
|
||||
switch amod.Os().Class {
|
||||
case Host:
|
||||
// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
|
||||
if archStr != "common" {
|
||||
a.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
|
||||
}
|
||||
host = true
|
||||
case HostCross:
|
||||
// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
|
||||
if archStr != "common" {
|
||||
a.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
|
||||
}
|
||||
host = true
|
||||
case Device:
|
||||
// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
|
||||
if archStr != "common" {
|
||||
a.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
|
||||
}
|
||||
|
||||
a.AddStrings("LOCAL_INIT_RC", amod.commonProperties.Init_rc...)
|
||||
a.AddStrings("LOCAL_VINTF_FRAGMENTS", amod.commonProperties.Vintf_fragments...)
|
||||
a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(amod.commonProperties.Proprietary))
|
||||
if Bool(amod.commonProperties.Vendor) || Bool(amod.commonProperties.Soc_specific) {
|
||||
a.SetString("LOCAL_VENDOR_MODULE", "true")
|
||||
}
|
||||
a.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(amod.commonProperties.Device_specific))
|
||||
a.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(amod.commonProperties.Product_specific))
|
||||
a.SetBoolIfTrue("LOCAL_PRODUCT_SERVICES_MODULE", Bool(amod.commonProperties.Product_services_specific))
|
||||
if amod.commonProperties.Owner != nil {
|
||||
a.SetString("LOCAL_MODULE_OWNER", *amod.commonProperties.Owner)
|
||||
}
|
||||
}
|
||||
|
||||
if amod.noticeFile.Valid() {
|
||||
a.SetString("LOCAL_NOTICE_FILE", amod.noticeFile.String())
|
||||
}
|
||||
|
||||
if host {
|
||||
makeOs := amod.Os().String()
|
||||
if amod.Os() == Linux || amod.Os() == LinuxBionic {
|
||||
makeOs = "linux"
|
||||
}
|
||||
a.SetString("LOCAL_MODULE_HOST_OS", makeOs)
|
||||
a.SetString("LOCAL_IS_HOST_MODULE", "true")
|
||||
}
|
||||
|
||||
prefix := ""
|
||||
if amod.ArchSpecific() {
|
||||
switch amod.Os().Class {
|
||||
case Host:
|
||||
prefix = "HOST_"
|
||||
case HostCross:
|
||||
prefix = "HOST_CROSS_"
|
||||
case Device:
|
||||
prefix = "TARGET_"
|
||||
|
||||
}
|
||||
|
||||
if amod.Arch().ArchType != config.Targets[amod.Os()][0].Arch.ArchType {
|
||||
prefix = "2ND_" + prefix
|
||||
}
|
||||
}
|
||||
blueprintDir := filepath.Dir(bpPath)
|
||||
if a.AddCustomEntries != nil {
|
||||
a.AddCustomEntries(name, prefix, blueprintDir, a)
|
||||
}
|
||||
|
||||
// Write to footer.
|
||||
fmt.Fprintln(&a.footer, "include "+a.Include)
|
||||
}
|
||||
|
||||
func (a *AndroidMkEntries) write(w io.Writer) {
|
||||
w.Write(a.header.Bytes())
|
||||
for _, name := range a.entryOrder {
|
||||
fmt.Fprintln(w, name+" := "+strings.Join(a.EntryMap[name], " "))
|
||||
}
|
||||
w.Write(a.footer.Bytes())
|
||||
}
|
||||
|
||||
func AndroidMkSingleton() Singleton {
|
||||
return &androidMkSingleton{}
|
||||
}
|
||||
|
@ -159,6 +355,8 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.M
|
|||
return translateAndroidModule(ctx, w, mod, x)
|
||||
case bootstrap.GoBinaryTool:
|
||||
return translateGoBinaryModule(ctx, w, mod, x)
|
||||
case AndroidMkEntriesProvider:
|
||||
return translateAndroidMkEntriesModule(ctx, w, mod, x)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
@ -178,37 +376,32 @@ func translateGoBinaryModule(ctx SingletonContext, w io.Writer, mod blueprint.Mo
|
|||
func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
|
||||
provider AndroidMkDataProvider) error {
|
||||
|
||||
name := provider.BaseModuleName()
|
||||
amod := mod.(Module).base()
|
||||
|
||||
if !amod.Enabled() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if amod.commonProperties.SkipInstall {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !amod.commonProperties.NamespaceExportedToMake {
|
||||
// TODO(jeffrygaston) do we want to validate that there are no modules being
|
||||
// exported to Kati that depend on this module?
|
||||
if shouldSkipAndroidMkProcessing(amod) {
|
||||
return nil
|
||||
}
|
||||
|
||||
data := provider.AndroidMk()
|
||||
|
||||
if data.Include == "" {
|
||||
data.Include = "$(BUILD_PREBUILT)"
|
||||
}
|
||||
|
||||
data.Required = append(data.Required, amod.commonProperties.Required...)
|
||||
data.Host_required = append(data.Host_required, amod.commonProperties.Host_required...)
|
||||
data.Target_required = append(data.Target_required, amod.commonProperties.Target_required...)
|
||||
|
||||
// Make does not understand LinuxBionic
|
||||
if amod.Os() == LinuxBionic {
|
||||
return nil
|
||||
// Get the preamble content through AndroidMkEntries logic.
|
||||
entries := AndroidMkEntries{
|
||||
Class: data.Class,
|
||||
SubName: data.SubName,
|
||||
DistFile: data.DistFile,
|
||||
OutputFile: data.OutputFile,
|
||||
Disabled: data.Disabled,
|
||||
Include: data.Include,
|
||||
Required: data.Required,
|
||||
Host_required: data.Host_required,
|
||||
Target_required: data.Target_required,
|
||||
}
|
||||
entries.fillInEntries(ctx.Config(), ctx.BlueprintFile(mod), mod)
|
||||
// preamble doesn't need the footer content.
|
||||
entries.footer = bytes.Buffer{}
|
||||
entries.write(&data.preamble)
|
||||
|
||||
prefix := ""
|
||||
if amod.ArchSpecific() {
|
||||
|
@ -227,112 +420,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Mod
|
|||
}
|
||||
}
|
||||
|
||||
if len(amod.commonProperties.Dist.Targets) > 0 {
|
||||
distFile := data.DistFile
|
||||
if !distFile.Valid() {
|
||||
distFile = data.OutputFile
|
||||
}
|
||||
if distFile.Valid() {
|
||||
dest := filepath.Base(distFile.String())
|
||||
|
||||
if amod.commonProperties.Dist.Dest != nil {
|
||||
var err error
|
||||
dest, err = validateSafePath(*amod.commonProperties.Dist.Dest)
|
||||
if err != nil {
|
||||
// This was checked in ModuleBase.GenerateBuildActions
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if amod.commonProperties.Dist.Suffix != nil {
|
||||
ext := filepath.Ext(dest)
|
||||
suffix := *amod.commonProperties.Dist.Suffix
|
||||
dest = strings.TrimSuffix(dest, ext) + suffix + ext
|
||||
}
|
||||
|
||||
if amod.commonProperties.Dist.Dir != nil {
|
||||
var err error
|
||||
dest, err = validateSafePath(*amod.commonProperties.Dist.Dir, dest)
|
||||
if err != nil {
|
||||
// This was checked in ModuleBase.GenerateBuildActions
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
goals := strings.Join(amod.commonProperties.Dist.Targets, " ")
|
||||
fmt.Fprintln(&data.preamble, ".PHONY:", goals)
|
||||
fmt.Fprintf(&data.preamble, "$(call dist-for-goals,%s,%s:%s)\n",
|
||||
goals, distFile.String(), dest)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintln(&data.preamble, "\ninclude $(CLEAR_VARS)")
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_PATH :=", filepath.Dir(ctx.BlueprintFile(mod)))
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_MODULE :=", name+data.SubName)
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_MODULE_CLASS :=", data.Class)
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_PREBUILT_MODULE_FILE :=", data.OutputFile.String())
|
||||
WriteRequiredModulesSettings(&data.preamble, data)
|
||||
|
||||
archStr := amod.Arch().ArchType.String()
|
||||
host := false
|
||||
switch amod.Os().Class {
|
||||
case Host:
|
||||
// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
|
||||
if archStr != "common" {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_MODULE_HOST_ARCH :=", archStr)
|
||||
}
|
||||
host = true
|
||||
case HostCross:
|
||||
// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
|
||||
if archStr != "common" {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_MODULE_HOST_CROSS_ARCH :=", archStr)
|
||||
}
|
||||
host = true
|
||||
case Device:
|
||||
// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
|
||||
if archStr != "common" {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_MODULE_TARGET_ARCH :=", archStr)
|
||||
}
|
||||
|
||||
if len(amod.commonProperties.Init_rc) > 0 {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_INIT_RC := ", strings.Join(amod.commonProperties.Init_rc, " "))
|
||||
}
|
||||
if len(amod.commonProperties.Vintf_fragments) > 0 {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_VINTF_FRAGMENTS := ", strings.Join(amod.commonProperties.Vintf_fragments, " "))
|
||||
}
|
||||
if Bool(amod.commonProperties.Proprietary) {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_PROPRIETARY_MODULE := true")
|
||||
}
|
||||
if Bool(amod.commonProperties.Vendor) || Bool(amod.commonProperties.Soc_specific) {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_VENDOR_MODULE := true")
|
||||
}
|
||||
if Bool(amod.commonProperties.Device_specific) {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_ODM_MODULE := true")
|
||||
}
|
||||
if Bool(amod.commonProperties.Product_specific) {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_PRODUCT_MODULE := true")
|
||||
}
|
||||
if Bool(amod.commonProperties.Product_services_specific) {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_PRODUCT_SERVICES_MODULE := true")
|
||||
}
|
||||
if amod.commonProperties.Owner != nil {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_MODULE_OWNER :=", *amod.commonProperties.Owner)
|
||||
}
|
||||
}
|
||||
|
||||
if amod.noticeFile.Valid() {
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_NOTICE_FILE :=", amod.noticeFile.String())
|
||||
}
|
||||
|
||||
if host {
|
||||
makeOs := amod.Os().String()
|
||||
if amod.Os() == Linux || amod.Os() == LinuxBionic {
|
||||
makeOs = "linux"
|
||||
}
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_MODULE_HOST_OS :=", makeOs)
|
||||
fmt.Fprintln(&data.preamble, "LOCAL_IS_HOST_MODULE := true")
|
||||
}
|
||||
|
||||
name := provider.BaseModuleName()
|
||||
blueprintDir := filepath.Dir(ctx.BlueprintFile(mod))
|
||||
|
||||
if data.Custom != nil {
|
||||
|
@ -362,14 +450,29 @@ func WriteAndroidMkData(w io.Writer, data AndroidMkData) {
|
|||
fmt.Fprintln(w, "include "+data.Include)
|
||||
}
|
||||
|
||||
func WriteRequiredModulesSettings(w io.Writer, data AndroidMkData) {
|
||||
if len(data.Required) > 0 {
|
||||
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(data.Required, " "))
|
||||
}
|
||||
if len(data.Host_required) > 0 {
|
||||
fmt.Fprintln(w, "LOCAL_HOST_REQUIRED_MODULES :=", strings.Join(data.Host_required, " "))
|
||||
}
|
||||
if len(data.Target_required) > 0 {
|
||||
fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES :=", strings.Join(data.Target_required, " "))
|
||||
func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
|
||||
provider AndroidMkEntriesProvider) error {
|
||||
if shouldSkipAndroidMkProcessing(mod.(Module).base()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
entries := provider.AndroidMkEntries()
|
||||
entries.fillInEntries(ctx.Config(), ctx.BlueprintFile(mod), mod)
|
||||
|
||||
entries.write(w)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func shouldSkipAndroidMkProcessing(module *ModuleBase) bool {
|
||||
if !module.commonProperties.NamespaceExportedToMake {
|
||||
// TODO(jeffrygaston) do we want to validate that there are no modules being
|
||||
// exported to Kati that depend on this module?
|
||||
return true
|
||||
}
|
||||
|
||||
return !module.Enabled() ||
|
||||
module.commonProperties.SkipInstall ||
|
||||
// Make does not understand LinuxBionic
|
||||
module.Os() == LinuxBionic
|
||||
}
|
||||
|
|
|
@ -14,10 +14,7 @@
|
|||
|
||||
package android
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
import "strconv"
|
||||
|
||||
// TODO(jungw): Now that it handles more than the ones in etc/, consider renaming this file.
|
||||
|
||||
|
@ -134,37 +131,25 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|||
})
|
||||
}
|
||||
|
||||
func (p *PrebuiltEtc) AndroidMk() AndroidMkData {
|
||||
return AndroidMkData{
|
||||
Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
|
||||
nameSuffix := ""
|
||||
if p.inRecovery() && !p.onlyInRecovery() {
|
||||
nameSuffix = ".recovery"
|
||||
}
|
||||
fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
|
||||
fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
|
||||
fmt.Fprintln(w, "LOCAL_MODULE :=", name+nameSuffix)
|
||||
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
|
||||
if p.commonProperties.Owner != nil {
|
||||
fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", *p.commonProperties.Owner)
|
||||
}
|
||||
fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
|
||||
if p.Host() {
|
||||
fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
|
||||
}
|
||||
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", p.outputFilePath.String())
|
||||
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
|
||||
fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", p.outputFilePath.Base())
|
||||
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !p.Installable())
|
||||
WriteRequiredModulesSettings(w, data)
|
||||
func (p *PrebuiltEtc) AndroidMkEntries() AndroidMkEntries {
|
||||
nameSuffix := ""
|
||||
if p.inRecovery() && !p.onlyInRecovery() {
|
||||
nameSuffix = ".recovery"
|
||||
}
|
||||
return AndroidMkEntries{
|
||||
Class: "ETC",
|
||||
SubName: nameSuffix,
|
||||
OutputFile: OptionalPathForPath(p.outputFilePath),
|
||||
AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) {
|
||||
entries.SetString("LOCAL_MODULE_TAGS", "optional")
|
||||
entries.SetString("LOCAL_MODULE_PATH", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
|
||||
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
|
||||
entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable()))
|
||||
if p.additionalDependencies != nil {
|
||||
fmt.Fprint(w, "LOCAL_ADDITIONAL_DEPENDENCIES :=")
|
||||
for _, path := range *p.additionalDependencies {
|
||||
fmt.Fprint(w, " "+path.String())
|
||||
entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", path.String())
|
||||
}
|
||||
fmt.Fprintln(w, "")
|
||||
}
|
||||
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,10 @@
|
|||
package android
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -139,49 +137,37 @@ func TestPrebuiltEtcGlob(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPrebuiltEtcAndroidMk(t *testing.T) {
|
||||
ctx, _ := testPrebuiltEtc(t, `
|
||||
ctx, config := testPrebuiltEtc(t, `
|
||||
prebuilt_etc {
|
||||
name: "foo",
|
||||
src: "foo.conf",
|
||||
owner: "abc",
|
||||
filename_from_src: true,
|
||||
required: ["modA", "moduleB"],
|
||||
host_required: ["hostModA", "hostModB"],
|
||||
target_required: ["targetModA"],
|
||||
}
|
||||
`)
|
||||
|
||||
data := AndroidMkData{}
|
||||
data.Required = append(data.Required, "modA", "moduleB")
|
||||
data.Host_required = append(data.Host_required, "hostModA", "hostModB")
|
||||
data.Target_required = append(data.Target_required, "targetModA")
|
||||
|
||||
expected := map[string]string{
|
||||
"LOCAL_MODULE": "foo",
|
||||
"LOCAL_MODULE_CLASS": "ETC",
|
||||
"LOCAL_MODULE_OWNER": "abc",
|
||||
"LOCAL_INSTALLED_MODULE_STEM": "foo.conf",
|
||||
"LOCAL_REQUIRED_MODULES": "modA moduleB",
|
||||
"LOCAL_HOST_REQUIRED_MODULES": "hostModA hostModB",
|
||||
"LOCAL_TARGET_REQUIRED_MODULES": "targetModA",
|
||||
expected := map[string][]string{
|
||||
"LOCAL_MODULE": {"foo"},
|
||||
"LOCAL_MODULE_CLASS": {"ETC"},
|
||||
"LOCAL_MODULE_OWNER": {"abc"},
|
||||
"LOCAL_INSTALLED_MODULE_STEM": {"foo.conf"},
|
||||
"LOCAL_REQUIRED_MODULES": {"modA", "moduleB"},
|
||||
"LOCAL_HOST_REQUIRED_MODULES": {"hostModA", "hostModB"},
|
||||
"LOCAL_TARGET_REQUIRED_MODULES": {"targetModA"},
|
||||
}
|
||||
|
||||
mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a_core").Module().(*PrebuiltEtc)
|
||||
buf := &bytes.Buffer{}
|
||||
mod.AndroidMk().Custom(buf, "foo", "", "", data)
|
||||
for k, expected := range expected {
|
||||
found := false
|
||||
scanner := bufio.NewScanner(bytes.NewReader(buf.Bytes()))
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
tok := strings.Split(line, " := ")
|
||||
if tok[0] == k {
|
||||
found = true
|
||||
if tok[1] != expected {
|
||||
t.Errorf("Incorrect %s '%s', expected '%s'", k, tok[1], expected)
|
||||
}
|
||||
entries := AndroidMkEntriesForTest(t, config, "", mod)
|
||||
for k, expectedValue := range expected {
|
||||
if value, ok := entries.EntryMap[k]; ok {
|
||||
if !reflect.DeepEqual(value, expectedValue) {
|
||||
t.Errorf("Incorrect %s '%s', expected '%s'", k, value, expectedValue)
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Errorf("No %s defined, saw %s", k, buf.String())
|
||||
} else {
|
||||
t.Errorf("No %s defined, saw %q", k, entries.EntryMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -371,3 +371,14 @@ func FailIfNoMatchingErrors(t *testing.T, pattern string, errs []error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AndroidMkEntriesForTest(t *testing.T, config Config, bpPath string, mod blueprint.Module) AndroidMkEntries {
|
||||
var p AndroidMkEntriesProvider
|
||||
var ok bool
|
||||
if p, ok = mod.(AndroidMkEntriesProvider); !ok {
|
||||
t.Errorf("module does not implmement AndroidMkEntriesProvider: " + mod.Name())
|
||||
}
|
||||
entries := p.AndroidMkEntries()
|
||||
entries.fillInEntries(config, bpPath, mod)
|
||||
return entries
|
||||
}
|
||||
|
|
|
@ -38,7 +38,15 @@ func (library *Library) AndroidMkHostDex(w io.Writer, name string, data android.
|
|||
}
|
||||
fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", library.headerJarFile.String())
|
||||
fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", library.implementationAndResourcesJar.String())
|
||||
android.WriteRequiredModulesSettings(w, data)
|
||||
if len(data.Required) > 0 {
|
||||
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(data.Required, " "))
|
||||
}
|
||||
if len(data.Host_required) > 0 {
|
||||
fmt.Fprintln(w, "LOCAL_HOST_REQUIRED_MODULES :=", strings.Join(data.Host_required, " "))
|
||||
}
|
||||
if len(data.Target_required) > 0 {
|
||||
fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES :=", strings.Join(data.Target_required, " "))
|
||||
}
|
||||
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue