Support multiple dists per Android.bp module, and dist output selection.
This CL adds "dists" to the base property struct to support multiple dist file configurations, and generic tag support to dist tagged outputs of modules. Fixes: b/152834186 Test: soong tests and `m sdk dist` Change-Id: I80c86bc9b7b09e671f640a4480c45d438bdd9a2a Signed-off-by: Jingwen Chen <jingwen@google.com>
This commit is contained in:
@@ -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,6 +137,96 @@ func (a *AndroidMkEntries) AddStrings(name string, value ...string) {
|
||||
a.EntryMap[name] = append(a.EntryMap[name], value...)
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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(*dist.Dest); err != nil {
|
||||
// This was checked in ModuleBase.GenerateBuildActions
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
if dist.Suffix != nil {
|
||||
ext := filepath.Ext(dest)
|
||||
suffix := *dist.Suffix
|
||||
dest = strings.TrimSuffix(dest, ext) + suffix + ext
|
||||
}
|
||||
|
||||
if dist.Dir != nil {
|
||||
var err error
|
||||
if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
|
||||
// This was checked in ModuleBase.GenerateBuildActions
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
@@ -149,42 +239,8 @@ func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod bluep
|
||||
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)
|
||||
}
|
||||
for _, distString := range a.GetDistForGoals(mod) {
|
||||
fmt.Fprintf(&a.header, distString)
|
||||
}
|
||||
|
||||
fmt.Fprintln(&a.header, "\ninclude $(CLEAR_VARS)")
|
||||
@@ -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,
|
||||
|
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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"`
|
||||
// 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 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"`
|
||||
} `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
|
||||
}
|
||||
|
@@ -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))
|
||||
|
@@ -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 {
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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{
|
||||
|
@@ -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"])
|
||||
}
|
||||
}
|
||||
|
||||
|
21
java/java.go
21
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)
|
||||
|
||||
|
@@ -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())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user