Merge "Build contexts files with Soong"
diff --git a/android/androidmk.go b/android/androidmk.go
index 42e1439..2a3748e 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -32,6 +32,8 @@
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 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 @@
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 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 @@
}
}
- 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 @@
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, " "))
+func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
+ provider AndroidMkEntriesProvider) error {
+ if shouldSkipAndroidMkProcessing(mod.(Module).base()) {
+ return nil
}
- if len(data.Host_required) > 0 {
- fmt.Fprintln(w, "LOCAL_HOST_REQUIRED_MODULES :=", strings.Join(data.Host_required, " "))
+
+ 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
}
- if len(data.Target_required) > 0 {
- fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES :=", strings.Join(data.Target_required, " "))
- }
+
+ return !module.Enabled() ||
+ module.commonProperties.SkipInstall ||
+ // Make does not understand LinuxBionic
+ module.Os() == LinuxBionic
}
diff --git a/android/config.go b/android/config.go
index 18ce6c3..3495ad2 100644
--- a/android/config.go
+++ b/android/config.go
@@ -198,6 +198,14 @@
// TestConfig returns a Config object suitable for using for tests
func TestConfig(buildDir string, env map[string]string) Config {
+ envCopy := make(map[string]string)
+ for k, v := range env {
+ envCopy[k] = v
+ }
+
+ // Copy the real PATH value to the test environment, it's needed by HostSystemTool() used in x86_darwin_host.go
+ envCopy["PATH"] = originalEnv["PATH"]
+
config := &config{
productVariables: productVariables{
DeviceName: stringPtr("test_device"),
@@ -212,7 +220,7 @@
buildDir: buildDir,
captureBuild: true,
- env: env,
+ env: envCopy,
}
config.deviceConfig = &deviceConfig{
config: config,
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index 3cadaeb..bec24c7 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -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) 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)")
},
}
}
diff --git a/android/prebuilt_etc_test.go b/android/prebuilt_etc_test.go
index fbdbc97..08700ae 100644
--- a/android/prebuilt_etc_test.go
+++ b/android/prebuilt_etc_test.go
@@ -15,12 +15,10 @@
package android
import (
- "bufio"
- "bytes"
"io/ioutil"
"os"
"path/filepath"
- "strings"
+ "reflect"
"testing"
)
@@ -139,49 +137,37 @@
}
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)
}
}
}
diff --git a/android/testing.go b/android/testing.go
index aee6855..c0db75e 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -371,3 +371,14 @@
}
}
}
+
+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
+}
diff --git a/cc/proto_test.go b/cc/proto_test.go
index a7fcef9..4f0de78 100644
--- a/cc/proto_test.go
+++ b/cc/proto_test.go
@@ -15,7 +15,6 @@
package cc
import (
- "runtime"
"strings"
"testing"
@@ -38,9 +37,6 @@
})
t.Run("plugin", func(t *testing.T) {
- if runtime.GOOS != "linux" {
- t.Skip("TODO(b/129763458): cc_binary_host tests fail on mac when trying to exec xcrun")
- }
ctx := testCc(t, `
cc_binary_host {
name: "protoc-gen-foobar",
diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go
index 2dfa546..c858c40 100644
--- a/cmd/pom2bp/pom2bp.go
+++ b/cmd/pom2bp/pom2bp.go
@@ -126,6 +126,7 @@
var sdkVersion string
var useVersion string
+var staticDeps bool
var jetifier bool
func InList(s string, list []string) bool {
@@ -333,6 +334,38 @@
var bpTemplate = template.Must(template.New("bp").Parse(`
{{.ImportModuleType}} {
+ name: "{{.BpName}}",
+ {{.ImportProperty}}: ["{{.ArtifactFile}}"],
+ sdk_version: "{{.SdkVersion}}",
+ {{- if .Jetifier}}
+ jetifier: true,
+ {{- end}}
+ {{- if .IsAar}}
+ min_sdk_version: "{{.MinSdkVersion}}",
+ static_libs: [
+ {{- range .BpJarDeps}}
+ "{{.}}",
+ {{- end}}
+ {{- range .BpAarDeps}}
+ "{{.}}",
+ {{- end}}
+ {{- range .BpExtraStaticLibs}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- if .BpExtraLibs}}
+ libs: [
+ {{- range .BpExtraLibs}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
+ {{- end}}
+}
+`))
+
+var bpDepsTemplate = template.Must(template.New("bp").Parse(`
+{{.ImportModuleType}} {
name: "{{.BpName}}-nodeps",
{{.ImportProperty}}: ["{{.ArtifactFile}}"],
sdk_version: "{{.SdkVersion}}",
@@ -533,8 +566,8 @@
flag.Var(&hostModuleNames, "host", "Specifies that the corresponding module (specified in the form 'module.group:module.artifact') is a host module")
flag.StringVar(&sdkVersion, "sdk-version", "", "What to write to sdk_version")
flag.StringVar(&useVersion, "use-version", "", "Only read artifacts of a specific version")
+ flag.BoolVar(&staticDeps, "static-deps", false, "Statically include direct dependencies")
flag.BoolVar(&jetifier, "jetifier", false, "Sets jetifier: true on all modules")
- flag.Bool("static-deps", false, "Ignored")
flag.StringVar(®en, "regen", "", "Rewrite specified file")
flag.Parse()
@@ -648,7 +681,11 @@
for _, pom := range poms {
var err error
- err = bpTemplate.Execute(buf, pom)
+ if staticDeps {
+ err = bpDepsTemplate.Execute(buf, pom)
+ } else {
+ err = bpTemplate.Execute(buf, pom)
+ }
if err != nil {
fmt.Fprintln(os.Stderr, "Error writing", pom.PomFile, pom.BpName(), err)
os.Exit(1)
diff --git a/java/androidmk.go b/java/androidmk.go
index d2e0f2e..068f7b1 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -38,7 +38,18 @@
}
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, " "))
+ }
+ if r := library.deviceProperties.Target.Hostdex.Required; len(r) > 0 {
+ fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(r, " "))
+ }
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
}
}
@@ -83,6 +94,10 @@
fmt.Fprintln(w, "LOCAL_ADDITIONAL_CHECKED_MODULE +=", strings.Join(library.additionalCheckedModules.Strings(), " "))
}
+ if library.proguardDictionary != nil {
+ fmt.Fprintln(w, "LOCAL_SOONG_PROGUARD_DICT :=", library.proguardDictionary.String())
+ }
+
// Temporary hack: export sources used to compile framework.jar to Make
// to be used for droiddoc
// TODO(ccross): remove this once droiddoc is in soong
@@ -365,9 +380,6 @@
if a.aarFile != nil {
fmt.Fprintln(w, "LOCAL_SOONG_AAR :=", a.aarFile.String())
}
- if a.proguardDictionary != nil {
- fmt.Fprintln(w, "LOCAL_SOONG_PROGUARD_DICT :=", a.proguardDictionary.String())
- }
if a.Name() == "framework-res" {
fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)")
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 9f40a6c..9c883e5 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -15,9 +15,12 @@
package java
import (
- "android/soong/android"
+ "fmt"
+ "io"
"github.com/google/blueprint"
+
+ "android/soong/android"
)
type DeviceHostConverter struct {
@@ -30,6 +33,9 @@
implementationJars android.Paths
implementationAndResourceJars android.Paths
resourceJars android.Paths
+
+ combinedHeaderJar android.Path
+ combinedImplementationJar android.Path
}
type DeviceHostConverterProperties struct {
@@ -98,6 +104,27 @@
ctx.PropertyErrorf("libs", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
}
})
+
+ jarName := ctx.ModuleName() + ".jar"
+
+ if len(d.implementationAndResourceJars) > 1 {
+ outputFile := android.PathForModuleOut(ctx, "combined", jarName)
+ TransformJarsToJar(ctx, outputFile, "combine", d.implementationAndResourceJars,
+ android.OptionalPath{}, false, nil, nil)
+ d.combinedImplementationJar = outputFile
+ } else {
+ d.combinedImplementationJar = d.implementationAndResourceJars[0]
+ }
+
+ if len(d.headerJars) > 1 {
+ outputFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
+ TransformJarsToJar(ctx, outputFile, "turbine combine", d.headerJars,
+ android.OptionalPath{}, false, nil, nil)
+ d.combinedHeaderJar = outputFile
+ } else {
+ d.combinedHeaderJar = d.headerJars[0]
+ }
+
}
var _ Dependency = (*DeviceHostConverter)(nil)
@@ -129,3 +156,18 @@
func (d *DeviceHostConverter) ExportedSdkLibs() []string {
return nil
}
+
+func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData {
+ return android.AndroidMkData{
+ Class: "JAVA_LIBRARIES",
+ OutputFile: android.OptionalPathForPath(d.combinedImplementationJar),
+ Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+ Extra: []android.AndroidMkExtraFunc{
+ func(w io.Writer, outputFile android.Path) {
+ fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", d.combinedHeaderJar.String())
+ fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", d.combinedImplementationJar.String())
+ },
+ },
+ }
+}
diff --git a/java/java.go b/java/java.go
index d6c759b..6168b38 100644
--- a/java/java.go
+++ b/java/java.go
@@ -221,6 +221,13 @@
// If true, export a copy of the module as a -hostdex module for host testing.
Hostdex *bool
+ Target struct {
+ Hostdex struct {
+ // Additional required dependencies to add to -hostdex modules.
+ Required []string
+ }
+ }
+
// If set to true, compile dex regardless of installable. Defaults to false.
Compile_dex *bool
@@ -1632,6 +1639,9 @@
&module.Module.protoProperties,
&module.testHelperLibraryProperties)
+ module.Module.properties.Installable = proptools.BoolPtr(true)
+ module.Module.dexpreopter.isTest = true
+
InitJavaModule(module, android.HostAndDeviceSupported)
return module
}