Merge "Support multiple dists per Android.bp module, and dist output selection." am: d06f11ee71
am: 3779799731
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1335521 Change-Id: I2ca43562972b4d50f1e9fd4a801026aa9abb6816
This commit is contained in:
commit
ce00ee318f
12 changed files with 535 additions and 101 deletions
|
@ -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
|
@ -483,7 +483,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
|
||||
|
@ -1925,18 +1925,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)
|
||||
}
|
||||
|
||||
|
@ -1998,14 +1989,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) {
|
||||
|
@ -2123,7 +2107,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) {
|
||||
|
|
Loading…
Reference in a new issue