summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/androidmk.go110
-rw-r--r--android/androidmk_test.go181
-rw-r--r--android/module.go87
-rw-r--r--android/paths.go9
-rw-r--r--cc/androidmk.go7
-rw-r--r--cc/binary.go8
-rw-r--r--cc/library.go8
-rw-r--r--java/androidmk.go8
-rw-r--r--java/androidmk_test.go157
-rw-r--r--java/java.go21
-rw-r--r--rust/androidmk.go14
-rw-r--r--sdk/sdk.go2
12 files changed, 523 insertions, 89 deletions
diff --git a/android/androidmk.go b/android/androidmk.go
index d579e30c3..3487b287d 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -46,7 +46,7 @@ type AndroidMkDataProvider interface {
type AndroidMkData struct {
Class string
SubName string
- DistFile OptionalPath
+ DistFiles TaggedDistFiles
OutputFile OptionalPath
Disabled bool
Include string
@@ -72,7 +72,7 @@ type AndroidMkEntriesProvider interface {
type AndroidMkEntries struct {
Class string
SubName string
- DistFile OptionalPath
+ DistFiles TaggedDistFiles
OutputFile OptionalPath
Disabled bool
Include string
@@ -137,56 +137,112 @@ func (a *AndroidMkEntries) AddStrings(name string, value ...string) {
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)
+// Compute the list of Make strings to declare phone goals and dist-for-goals
+// calls from the module's dist and dists properties.
+func (a *AndroidMkEntries) GetDistForGoals(mod blueprint.Module) []string {
amod := mod.(Module).base()
name := amod.BaseModuleName()
- if a.Include == "" {
- a.Include = "$(BUILD_PREBUILT)"
+ var ret []string
+
+ availableTaggedDists := TaggedDistFiles{}
+ if a.DistFiles != nil && len(a.DistFiles[""]) > 0 {
+ availableTaggedDists = a.DistFiles
+ } else if a.OutputFile.Valid() {
+ availableTaggedDists = MakeDefaultDistFiles(a.OutputFile.Path())
}
- 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
+ // Iterate over this module's dist structs, merged from the dist and dists properties.
+ for _, dist := range amod.Dists() {
+ // Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
+ goals := strings.Join(dist.Targets, " ")
+
+ // Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
+ var tag string
+ if dist.Tag == nil {
+ // If the dist struct does not specify a tag, use the default output files tag.
+ tag = ""
+ } else {
+ tag = *dist.Tag
}
- if distFile.Valid() {
- dest := filepath.Base(distFile.String())
- if amod.commonProperties.Dist.Dest != nil {
+ // Get the paths of the output files to be dist'd, represented by the tag.
+ // Can be an empty list.
+ tagPaths := availableTaggedDists[tag]
+ if len(tagPaths) == 0 {
+ // Nothing to dist for this tag, continue to the next dist.
+ continue
+ }
+
+ if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
+ errorMessage := "Cannot apply dest/suffix for more than one dist " +
+ "file for %s goals in module %s. The list of dist files, " +
+ "which should have a single element, is:\n%s"
+ panic(fmt.Errorf(errorMessage, goals, name, tagPaths))
+ }
+
+ ret = append(ret, fmt.Sprintf(".PHONY: %s\n", goals))
+
+ // Create dist-for-goals calls for each path in the dist'd files.
+ for _, path := range tagPaths {
+ // It's possible that the Path is nil from errant modules. Be defensive here.
+ if path == nil {
+ tagName := "default" // for error message readability
+ if dist.Tag != nil {
+ tagName = *dist.Tag
+ }
+ panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
+ }
+
+ dest := filepath.Base(path.String())
+
+ if dist.Dest != nil {
var err error
- if dest, err = validateSafePath(*amod.commonProperties.Dist.Dest); err != nil {
+ if dest, err = validateSafePath(*dist.Dest); err != nil {
// This was checked in ModuleBase.GenerateBuildActions
panic(err)
}
}
- if amod.commonProperties.Dist.Suffix != nil {
+ if dist.Suffix != nil {
ext := filepath.Ext(dest)
- suffix := *amod.commonProperties.Dist.Suffix
+ suffix := *dist.Suffix
dest = strings.TrimSuffix(dest, ext) + suffix + ext
}
- if amod.commonProperties.Dist.Dir != nil {
+ if dist.Dir != nil {
var err error
- if dest, err = validateSafePath(*amod.commonProperties.Dist.Dir, dest); err != nil {
+ if dest, err = validateSafePath(*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)
+ ret = append(
+ ret,
+ fmt.Sprintf("$(call dist-for-goals,%s,%s:%s)\n", goals, path.String(), dest))
}
}
+ return ret
+}
+
+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...)
+
+ for _, distString := range a.GetDistForGoals(mod) {
+ fmt.Fprintf(&a.header, distString)
+ }
+
fmt.Fprintln(&a.header, "\ninclude $(CLEAR_VARS)")
// Collect make variable assignment entries.
@@ -430,7 +486,7 @@ func (data *AndroidMkData) fillInData(config Config, bpPath string, mod blueprin
entries := AndroidMkEntries{
Class: data.Class,
SubName: data.SubName,
- DistFile: data.DistFile,
+ DistFiles: data.DistFiles,
OutputFile: data.OutputFile,
Disabled: data.Disabled,
Include: data.Include,
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 71f802043..250f086e5 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -15,6 +15,7 @@
package android
import (
+ "fmt"
"io"
"reflect"
"testing"
@@ -22,10 +23,12 @@ import (
type customModule struct {
ModuleBase
- data AndroidMkData
+ data AndroidMkData
+ distFiles TaggedDistFiles
}
func (m *customModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ m.distFiles = m.GenerateTaggedDistFiles(ctx)
}
func (m *customModule) AndroidMk() AndroidMkData {
@@ -36,6 +39,26 @@ func (m *customModule) AndroidMk() AndroidMkData {
}
}
+func (m *customModule) OutputFiles(tag string) (Paths, error) {
+ switch tag {
+ case "":
+ return PathsForTesting("one.out"), nil
+ case ".multiple":
+ return PathsForTesting("two.out", "three/four.out"), nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+}
+
+func (m *customModule) AndroidMkEntries() []AndroidMkEntries {
+ return []AndroidMkEntries{
+ {
+ Class: "CUSTOM_MODULE",
+ DistFiles: m.distFiles,
+ },
+ }
+}
+
func customModuleFactory() Module {
module := &customModule{}
InitAndroidModule(module)
@@ -76,3 +99,159 @@ func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testin
assertEqual([]string{"baz"}, m.data.Host_required)
assertEqual([]string{"qux"}, m.data.Target_required)
}
+
+func TestGetDistForGoals(t *testing.T) {
+ testCases := []struct {
+ bp string
+ expectedAndroidMkLines []string
+ }{
+ {
+ bp: `
+ custom {
+ name: "foo",
+ dist: {
+ targets: ["my_goal"]
+ }
+ }
+ `,
+ expectedAndroidMkLines: []string{
+ ".PHONY: my_goal\n",
+ "$(call dist-for-goals,my_goal,one.out:one.out)\n",
+ },
+ },
+ {
+ bp: `
+ custom {
+ name: "foo",
+ dists: [
+ {
+ targets: ["my_goal"],
+ },
+ {
+ targets: ["my_second_goal", "my_third_goal"],
+ },
+ ],
+ }
+ `,
+ expectedAndroidMkLines: []string{
+ ".PHONY: my_goal\n",
+ "$(call dist-for-goals,my_goal,one.out:one.out)\n",
+ ".PHONY: my_second_goal my_third_goal\n",
+ "$(call dist-for-goals,my_second_goal my_third_goal,one.out:one.out)\n",
+ },
+ },
+ {
+ bp: `
+ custom {
+ name: "foo",
+ dist: {
+ targets: ["my_goal"],
+ },
+ dists: [
+ {
+ targets: ["my_second_goal", "my_third_goal"],
+ },
+ ],
+ }
+ `,
+ expectedAndroidMkLines: []string{
+ ".PHONY: my_second_goal my_third_goal\n",
+ "$(call dist-for-goals,my_second_goal my_third_goal,one.out:one.out)\n",
+ ".PHONY: my_goal\n",
+ "$(call dist-for-goals,my_goal,one.out:one.out)\n",
+ },
+ },
+ {
+ bp: `
+ custom {
+ name: "foo",
+ dist: {
+ targets: ["my_goal", "my_other_goal"],
+ tag: ".multiple",
+ },
+ dists: [
+ {
+ targets: ["my_second_goal"],
+ tag: ".multiple",
+ },
+ {
+ targets: ["my_third_goal"],
+ dir: "test/dir",
+ },
+ {
+ targets: ["my_fourth_goal"],
+ suffix: ".suffix",
+ },
+ {
+ targets: ["my_fifth_goal"],
+ dest: "new-name",
+ },
+ {
+ targets: ["my_sixth_goal"],
+ dest: "new-name",
+ dir: "some/dir",
+ suffix: ".suffix",
+ },
+ ],
+ }
+ `,
+ expectedAndroidMkLines: []string{
+ ".PHONY: my_second_goal\n",
+ "$(call dist-for-goals,my_second_goal,two.out:two.out)\n",
+ "$(call dist-for-goals,my_second_goal,three/four.out:four.out)\n",
+ ".PHONY: my_third_goal\n",
+ "$(call dist-for-goals,my_third_goal,one.out:test/dir/one.out)\n",
+ ".PHONY: my_fourth_goal\n",
+ "$(call dist-for-goals,my_fourth_goal,one.out:one.suffix.out)\n",
+ ".PHONY: my_fifth_goal\n",
+ "$(call dist-for-goals,my_fifth_goal,one.out:new-name)\n",
+ ".PHONY: my_sixth_goal\n",
+ "$(call dist-for-goals,my_sixth_goal,one.out:some/dir/new-name.suffix)\n",
+ ".PHONY: my_goal my_other_goal\n",
+ "$(call dist-for-goals,my_goal my_other_goal,two.out:two.out)\n",
+ "$(call dist-for-goals,my_goal my_other_goal,three/four.out:four.out)\n",
+ },
+ },
+ }
+
+ for _, testCase := range testCases {
+ config := TestConfig(buildDir, nil, testCase.bp, nil)
+ config.inMake = true // Enable androidmk Singleton
+
+ ctx := NewTestContext()
+ ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
+ ctx.RegisterModuleType("custom", customModuleFactory)
+ ctx.Register(config)
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ FailIfErrored(t, errs)
+
+ module := ctx.ModuleForTests("foo", "").Module().(*customModule)
+ entries := AndroidMkEntriesForTest(t, config, "", module)
+ if len(entries) != 1 {
+ t.Errorf("Expected a single AndroidMk entry, got %d", len(entries))
+ }
+ androidMkLines := entries[0].GetDistForGoals(module)
+
+ if len(androidMkLines) != len(testCase.expectedAndroidMkLines) {
+ t.Errorf(
+ "Expected %d AndroidMk lines, got %d:\n%v",
+ len(testCase.expectedAndroidMkLines),
+ len(androidMkLines),
+ androidMkLines,
+ )
+ }
+ for idx, line := range androidMkLines {
+ expectedLine := testCase.expectedAndroidMkLines[idx]
+ if line != expectedLine {
+ t.Errorf(
+ "Expected AndroidMk line to be '%s', got '%s'",
+ line,
+ expectedLine,
+ )
+ }
+ }
+ }
+}
diff --git a/android/module.go b/android/module.go
index ac3394ddd..06079cae9 100644
--- a/android/module.go
+++ b/android/module.go
@@ -315,6 +315,28 @@ func newPackageId(pkg string) qualifiedModuleName {
return qualifiedModuleName{pkg: pkg, name: ""}
}
+type Dist struct {
+ // Copy the output of this module to the $DIST_DIR when `dist` is specified on the
+ // command line and any of these targets are also on the command line, or otherwise
+ // built
+ Targets []string `android:"arch_variant"`
+
+ // The name of the output artifact. This defaults to the basename of the output of
+ // the module.
+ Dest *string `android:"arch_variant"`
+
+ // The directory within the dist directory to store the artifact. Defaults to the
+ // top level directory ("").
+ Dir *string `android:"arch_variant"`
+
+ // A suffix to add to the artifact file name (before any extension).
+ Suffix *string `android:"arch_variant"`
+
+ // A string tag to select the OutputFiles associated with the tag. Defaults to the
+ // the empty "" string.
+ Tag *string `android:"arch_variant"`
+}
+
type nameProperties struct {
// The name of the module. Must be unique across all modules.
Name *string
@@ -454,23 +476,13 @@ type commonProperties struct {
// relative path to a file to include in the list of notices for the device
Notice *string `android:"path"`
- Dist struct {
- // copy the output of this module to the $DIST_DIR when `dist` is specified on the
- // command line and any of these targets are also on the command line, or otherwise
- // built
- Targets []string `android:"arch_variant"`
-
- // The name of the output artifact. This defaults to the basename of the output of
- // the module.
- Dest *string `android:"arch_variant"`
+ // configuration to distribute output files from this module to the distribution
+ // directory (default: $OUT/dist, configurable with $DIST_DIR)
+ Dist Dist `android:"arch_variant"`
- // The directory within the dist directory to store the artifact. Defaults to the
- // top level directory ("").
- Dir *string `android:"arch_variant"`
-
- // A suffix to add to the artifact file name (before any extension).
- Suffix *string `android:"arch_variant"`
- } `android:"arch_variant"`
+ // a list of configurations to distribute output files from this module to the
+ // distribution directory (default: $OUT/dist, configurable with $DIST_DIR)
+ Dists []Dist `android:"arch_variant"`
// The OsType of artifacts that this module variant is responsible for creating.
//
@@ -537,6 +549,14 @@ type commonProperties struct {
ImageVariation string `blueprint:"mutated"`
}
+// A map of OutputFile tag keys to Paths, for disting purposes.
+type TaggedDistFiles map[string]Paths
+
+func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles {
+ // The default OutputFile tag is the empty "" string.
+ return TaggedDistFiles{"": paths}
+}
+
type hostAndDeviceProperties struct {
// If set to true, build a variant of the module for the host. Defaults to false.
Host_supported *bool
@@ -815,6 +835,41 @@ func (m *ModuleBase) visibilityProperties() []visibilityProperty {
return m.visibilityPropertyInfo
}
+func (m *ModuleBase) Dists() []Dist {
+ if len(m.commonProperties.Dist.Targets) > 0 {
+ // Make a copy of the underlying Dists slice to protect against
+ // backing array modifications with repeated calls to this method.
+ distsCopy := append([]Dist(nil), m.commonProperties.Dists...)
+ return append(distsCopy, m.commonProperties.Dist)
+ } else {
+ return m.commonProperties.Dists
+ }
+}
+
+func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
+ distFiles := make(TaggedDistFiles)
+ for _, dist := range m.Dists() {
+ var tag string
+ var distFilesForTag Paths
+ if dist.Tag == nil {
+ tag = ""
+ } else {
+ tag = *dist.Tag
+ }
+ distFilesForTag, err := m.base().module.(OutputFileProducer).OutputFiles(tag)
+ if err != nil {
+ ctx.PropertyErrorf("dist.tag", "%s", err.Error())
+ }
+ for _, distFile := range distFilesForTag {
+ if distFile != nil && !distFiles[tag].containsPath(distFile) {
+ distFiles[tag] = append(distFiles[tag], distFile)
+ }
+ }
+ }
+
+ return distFiles
+}
+
func (m *ModuleBase) Target() Target {
return m.commonProperties.CompileTarget
}
diff --git a/android/paths.go b/android/paths.go
index bed6f3f58..d8d51a777 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -220,6 +220,15 @@ func (p OptionalPath) String() string {
// Paths is a slice of Path objects, with helpers to operate on the collection.
type Paths []Path
+func (paths Paths) containsPath(path Path) bool {
+ for _, p := range paths {
+ if p == path {
+ return true
+ }
+ }
+ return false
+}
+
// PathsForSource returns Paths rooted from SrcDir
func PathsForSource(ctx PathContext, paths []string) Paths {
ret := make(Paths, len(paths))
diff --git a/cc/androidmk.go b/cc/androidmk.go
index b3ad610d6..3f812c2c0 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -249,7 +249,10 @@ func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries
entries.Class = "HEADER_LIBRARIES"
}
- entries.DistFile = library.distFile
+ if library.distFile != nil {
+ entries.DistFiles = android.MakeDefaultDistFiles(library.distFile)
+ }
+
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
library.androidMkWriteExportedFlags(entries)
library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries)
@@ -318,7 +321,7 @@ func (binary *binaryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *a
ctx.subAndroidMk(entries, binary.baseInstaller)
entries.Class = "EXECUTABLES"
- entries.DistFile = binary.distFile
+ entries.DistFiles = binary.distFiles
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", binary.unstrippedOutputFile.String())
if len(binary.symlinks) > 0 {
diff --git a/cc/binary.go b/cc/binary.go
index 251b7f0c4..565cb8ae7 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -98,8 +98,8 @@ type binaryDecorator struct {
// Output archive of gcno coverage information
coverageOutputFile android.OptionalPath
- // Location of the file that should be copied to dist dir when requested
- distFile android.OptionalPath
+ // Location of the files that should be copied to dist dir when requested
+ distFiles android.TaggedDistFiles
post_install_cmds []string
}
@@ -367,11 +367,11 @@ func (binary *binaryDecorator) link(ctx ModuleContext,
binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
} else {
versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
- binary.distFile = android.OptionalPathForPath(versionedOutputFile)
+ binary.distFiles = android.MakeDefaultDistFiles(versionedOutputFile)
if binary.stripper.needsStrip(ctx) {
out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
- binary.distFile = android.OptionalPathForPath(out)
+ binary.distFiles = android.MakeDefaultDistFiles(out)
binary.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
}
diff --git a/cc/library.go b/cc/library.go
index 968702e59..98f4d48d6 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -369,7 +369,7 @@ type libraryDecorator struct {
unstrippedOutputFile android.Path
// Location of the file that should be copied to dist dir when requested
- distFile android.OptionalPath
+ distFile android.Path
versionScriptPath android.ModuleGenPath
@@ -894,7 +894,7 @@ func (library *libraryDecorator) linkStatic(ctx ModuleContext,
library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
} else {
versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
- library.distFile = android.OptionalPathForPath(versionedOutputFile)
+ library.distFile = versionedOutputFile
library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
}
}
@@ -988,11 +988,11 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
} else {
versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
- library.distFile = android.OptionalPathForPath(versionedOutputFile)
+ library.distFile = versionedOutputFile
if library.stripper.needsStrip(ctx) {
out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
- library.distFile = android.OptionalPathForPath(out)
+ library.distFile = out
library.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
}
diff --git a/java/androidmk.go b/java/androidmk.go
index 62cf169fa..e73b03058 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -91,7 +91,7 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
} else {
mainEntries = android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
- DistFile: android.OptionalPathForPath(library.distFile),
+ DistFiles: library.distFiles,
OutputFile: android.OptionalPathForPath(library.outputFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
@@ -550,14 +550,14 @@ func (dstubs *Droidstubs) AndroidMkEntries() []android.AndroidMkEntries {
// needed because an invalid output file would prevent the make entries from
// being written.
// TODO(b/146727827): Revert when we do not need to generate stubs and API separately.
- distFile := android.OptionalPathForPath(dstubs.apiFile)
+ distFile := dstubs.apiFile
outputFile := android.OptionalPathForPath(dstubs.stubsSrcJar)
if !outputFile.Valid() {
- outputFile = distFile
+ outputFile = android.OptionalPathForPath(distFile)
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
- DistFile: distFile,
+ DistFiles: android.MakeDefaultDistFiles(distFile),
OutputFile: outputFile,
Include: "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index d471fb7d5..075b7aa6f 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -156,17 +156,158 @@ func TestDistWithTag(t *testing.T) {
}
`)
- without_tag_entries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_without_tag", "android_common").Module())
- with_tag_entries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_with_tag", "android_common").Module())
+ withoutTagEntries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_without_tag", "android_common").Module())
+ withTagEntries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_with_tag", "android_common").Module())
- if len(without_tag_entries) != 2 || len(with_tag_entries) != 2 {
- t.Errorf("two mk entries per module expected, got %d and %d", len(without_tag_entries), len(with_tag_entries))
+ if len(withoutTagEntries) != 2 || len(withTagEntries) != 2 {
+ t.Errorf("two mk entries per module expected, got %d and %d", len(withoutTagEntries), len(withTagEntries))
}
- if !with_tag_entries[0].DistFile.Valid() || !strings.Contains(with_tag_entries[0].DistFile.String(), "/javac/foo_with_tag.jar") {
- t.Errorf("expected classes.jar DistFile, got %v", with_tag_entries[0].DistFile)
+ if len(withTagEntries[0].DistFiles[".jar"]) != 1 ||
+ !strings.Contains(withTagEntries[0].DistFiles[".jar"][0].String(), "/javac/foo_with_tag.jar") {
+ t.Errorf("expected DistFiles to contain classes.jar, got %v", withTagEntries[0].DistFiles)
}
- if without_tag_entries[0].DistFile.Valid() {
- t.Errorf("did not expect explicit DistFile, got %v", without_tag_entries[0].DistFile)
+ if len(withoutTagEntries[0].DistFiles[".jar"]) > 0 {
+ t.Errorf("did not expect explicit DistFile for .jar tag, got %v", withoutTagEntries[0].DistFiles[".jar"])
+ }
+}
+
+func TestDistWithDest(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dist: {
+ targets: ["my_goal"],
+ dest: "my/custom/dest/dir",
+ },
+ }
+ `)
+
+ module := ctx.ModuleForTests("foo", "android_common").Module()
+ entries := android.AndroidMkEntriesForTest(t, config, "", module)
+ if len(entries) != 2 {
+ t.Errorf("Expected 2 AndroidMk entries, got %d", len(entries))
+ }
+
+ distStrings := entries[0].GetDistForGoals(module)
+
+ if len(distStrings) != 2 {
+ t.Errorf("Expected 2 entries for dist: PHONY and dist-for-goals, but got %q", distStrings)
+ }
+
+ if distStrings[0] != ".PHONY: my_goal\n" {
+ t.Errorf("Expected .PHONY entry to declare my_goal, but got: %s", distStrings[0])
+ }
+
+ if !strings.Contains(distStrings[1], "$(call dist-for-goals,my_goal") ||
+ !strings.Contains(distStrings[1], ".intermediates/foo/android_common/dex/foo.jar:my/custom/dest/dir") {
+ t.Errorf(
+ "Expected dist-for-goals entry to contain my_goal and new dest dir, but got: %s", distStrings[1])
+ }
+}
+
+func TestDistsWithAllProperties(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dist: {
+ targets: ["baz"],
+ },
+ dists: [
+ {
+ targets: ["bar"],
+ tag: ".jar",
+ dest: "bar.jar",
+ dir: "bar/dir",
+ suffix: ".qux",
+ },
+ ]
+ }
+ `)
+
+ module := ctx.ModuleForTests("foo", "android_common").Module()
+ entries := android.AndroidMkEntriesForTest(t, config, "", module)
+ if len(entries) != 2 {
+ t.Errorf("Expected 2 AndroidMk entries, got %d", len(entries))
+ }
+
+ distStrings := entries[0].GetDistForGoals(module)
+
+ if len(distStrings) != 4 {
+ t.Errorf("Expected 4 entries for dist: PHONY and dist-for-goals, but got %d", len(distStrings))
+ }
+
+ if distStrings[0] != ".PHONY: bar\n" {
+ t.Errorf("Expected .PHONY entry to declare bar, but got: %s", distStrings[0])
+ }
+
+ if !strings.Contains(distStrings[1], "$(call dist-for-goals,bar") ||
+ !strings.Contains(
+ distStrings[1],
+ ".intermediates/foo/android_common/javac/foo.jar:bar/dir/bar.qux.jar") {
+ t.Errorf(
+ "Expected dist-for-goals entry to contain bar and new dest dir, but got: %s", distStrings[1])
+ }
+
+ if distStrings[2] != ".PHONY: baz\n" {
+ t.Errorf("Expected .PHONY entry to declare baz, but got: %s", distStrings[2])
+ }
+
+ if !strings.Contains(distStrings[3], "$(call dist-for-goals,baz") ||
+ !strings.Contains(distStrings[3], ".intermediates/foo/android_common/dex/foo.jar:foo.jar") {
+ t.Errorf(
+ "Expected dist-for-goals entry to contain my_other_goal and new dest dir, but got: %s",
+ distStrings[3])
+ }
+}
+
+func TestDistsWithTag(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_library {
+ name: "foo_without_tag",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dists: [
+ {
+ targets: ["hi"],
+ },
+ ],
+ }
+ java_library {
+ name: "foo_with_tag",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dists: [
+ {
+ targets: ["hi"],
+ tag: ".jar",
+ },
+ ],
+ }
+ `)
+
+ moduleWithoutTag := ctx.ModuleForTests("foo_without_tag", "android_common").Module()
+ moduleWithTag := ctx.ModuleForTests("foo_with_tag", "android_common").Module()
+
+ withoutTagEntries := android.AndroidMkEntriesForTest(t, config, "", moduleWithoutTag)
+ withTagEntries := android.AndroidMkEntriesForTest(t, config, "", moduleWithTag)
+
+ if len(withoutTagEntries) != 2 || len(withTagEntries) != 2 {
+ t.Errorf("two mk entries per module expected, got %d and %d", len(withoutTagEntries), len(withTagEntries))
+ }
+
+ distFilesWithoutTag := withoutTagEntries[0].DistFiles
+ distFilesWithTag := withTagEntries[0].DistFiles
+
+ if len(distFilesWithTag[".jar"]) != 1 ||
+ !strings.Contains(distFilesWithTag[".jar"][0].String(), "/javac/foo_with_tag.jar") {
+ t.Errorf("expected foo_with_tag's .jar-tagged DistFiles to contain classes.jar, got %v", distFilesWithTag[".jar"])
+ }
+ if len(distFilesWithoutTag[".jar"]) > 0 {
+ t.Errorf("did not expect foo_without_tag's .jar-tagged DistFiles to contain files, but got %v", distFilesWithoutTag[".jar"])
}
}
diff --git a/java/java.go b/java/java.go
index 5b3163087..0a8eb992c 100644
--- a/java/java.go
+++ b/java/java.go
@@ -479,7 +479,7 @@ type Module struct {
// list of the xref extraction files
kytheFiles android.Paths
- distFile android.Path
+ distFiles android.TaggedDistFiles
// Collect the module directory for IDE info in java/jdeps.go.
modulePaths []string
@@ -1921,18 +1921,9 @@ func (j *Module) IsInstallable() bool {
// Java libraries (.jar file)
//
-type LibraryProperties struct {
- Dist struct {
- // The tag of the output of this module that should be output.
- Tag *string `android:"arch_variant"`
- } `android:"arch_variant"`
-}
-
type Library struct {
Module
- libraryProperties LibraryProperties
-
InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
}
@@ -1994,14 +1985,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.Stem()+".jar", j.outputFile, extraInstallDeps...)
}
- // Verify Dist.Tag is set to a supported output
- if j.libraryProperties.Dist.Tag != nil {
- distFiles, err := j.OutputFiles(*j.libraryProperties.Dist.Tag)
- if err != nil {
- ctx.PropertyErrorf("dist.tag", "%s", err.Error())
- }
- j.distFile = distFiles[0]
- }
+ j.distFiles = j.GenerateTaggedDistFiles(ctx)
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -2119,7 +2103,6 @@ func LibraryFactory() android.Module {
module := &Library{}
module.addHostAndDeviceProperties()
- module.AddProperties(&module.libraryProperties)
module.initModuleAndImport(&module.ModuleBase)
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 69d0df562..aea899baa 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -86,8 +86,11 @@ func (mod *Module) AndroidMk() android.AndroidMkData {
func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
ctx.subAndroidMk(ret, binary.baseCompiler)
+ if binary.distFile.Valid() {
+ ret.DistFiles = android.MakeDefaultDistFiles(binary.distFile.Path())
+ }
+
ret.Class = "EXECUTABLES"
- ret.DistFile = binary.distFile
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", binary.unstrippedOutputFile.String())
if binary.coverageOutputZipFile.Valid() {
@@ -127,7 +130,10 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
ret.Class = "SHARED_LIBRARIES"
}
- ret.DistFile = library.distFile
+ if library.distFile.Valid() {
+ ret.DistFiles = android.MakeDefaultDistFiles(library.distFile.Path())
+ }
+
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
if !library.rlib() {
fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", library.unstrippedOutputFile.String())
@@ -143,7 +149,9 @@ func (procMacro *procMacroDecorator) AndroidMk(ctx AndroidMkContext, ret *androi
ctx.subAndroidMk(ret, procMacro.baseCompiler)
ret.Class = "PROC_MACRO_LIBRARIES"
- ret.DistFile = procMacro.distFile
+ if procMacro.distFile.Valid() {
+ ret.DistFiles = android.MakeDefaultDistFiles(procMacro.distFile.Path())
+ }
}
diff --git a/sdk/sdk.go b/sdk/sdk.go
index cb5a6053d..b9b8199d3 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -291,7 +291,7 @@ func (s *sdk) AndroidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "FAKE",
OutputFile: s.snapshotFile,
- DistFile: s.snapshotFile,
+ DistFiles: android.MakeDefaultDistFiles(s.snapshotFile.Path()),
Include: "$(BUILD_PHONY_PACKAGE)",
ExtraFooters: []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {