Merge "Clients of PackagingBase can customize dependency tag to use"
diff --git a/Android.bp b/Android.bp
index e7a5de2..866ed25 100644
--- a/Android.bp
+++ b/Android.bp
@@ -75,6 +75,10 @@
product_available: true,
recovery_available: true,
native_bridge_supported: true,
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
arch: {
arm: {
diff --git a/android/androidmk.go b/android/androidmk.go
index 7afc9de..063830b 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -222,13 +222,32 @@
amod := mod.(Module).base()
name := amod.BaseModuleName()
+ // Collate the set of associated tag/paths available for copying to the dist.
+ // Start with an empty (nil) set.
var availableTaggedDists TaggedDistFiles
+ // Then merge in any that are provided explicitly by the module.
if a.DistFiles != nil {
- availableTaggedDists = a.DistFiles
- } else if a.OutputFile.Valid() {
- availableTaggedDists = MakeDefaultDistFiles(a.OutputFile.Path())
- } else {
+ // Merge the DistFiles into the set.
+ availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
+ }
+
+ // If no paths have been provided for the DefaultDistTag and the output file is
+ // valid then add that as the default dist path.
+ if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
+ availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
+ }
+
+ // If the distFiles created by GenerateTaggedDistFiles contains paths for the
+ // DefaultDistTag then that takes priority so delete any existing paths.
+ if _, ok := amod.distFiles[DefaultDistTag]; ok {
+ delete(availableTaggedDists, DefaultDistTag)
+ }
+
+ // Finally, merge the distFiles created by GenerateTaggedDistFiles.
+ availableTaggedDists = availableTaggedDists.merge(amod.distFiles)
+
+ if len(availableTaggedDists) == 0 {
// Nothing dist-able for this module.
return nil
}
@@ -245,7 +264,7 @@
var tag string
if dist.Tag == nil {
// If the dist struct does not specify a tag, use the default output files tag.
- tag = ""
+ tag = DefaultDistTag
} else {
tag = *dist.Tag
}
@@ -259,10 +278,10 @@
}
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, " +
+ errorMessage := "%s: Cannot apply dest/suffix for more than one dist " +
+ "file for %q goals tag %q in module %s. The list of dist files, " +
"which should have a single element, is:\n%s"
- panic(fmt.Errorf(errorMessage, goals, name, tagPaths))
+ panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths))
}
copiesForGoals := distContributions.getCopiesForGoals(goals)
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 5d05d91..347b92e 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -35,6 +35,10 @@
data AndroidMkData
distFiles TaggedDistFiles
outputFile OptionalPath
+
+ // The paths that will be used as the default dist paths if no tag is
+ // specified.
+ defaultDistPaths Paths
}
const (
@@ -48,7 +52,14 @@
// If the dist_output_file: true then create an output file that is stored in
// the OutputFile property of the AndroidMkEntry.
if proptools.BoolDefault(m.properties.Dist_output_file, true) {
- m.outputFile = OptionalPathForPath(PathForTesting("dist-output-file.out"))
+ path := PathForTesting("dist-output-file.out")
+ m.outputFile = OptionalPathForPath(path)
+
+ // Previous code would prioritize the DistFiles property over the OutputFile
+ // property in AndroidMkEntry when determining the default dist paths.
+ // Setting this first allows it to be overridden based on the
+ // default_dist_files setting replicating that previous behavior.
+ m.defaultDistPaths = Paths{path}
}
// Based on the setting of the default_dist_files property possibly create a
@@ -60,9 +71,22 @@
// Do nothing
case defaultDistFiles_Default:
- m.distFiles = MakeDefaultDistFiles(PathForTesting("default-dist.out"))
+ path := PathForTesting("default-dist.out")
+ m.defaultDistPaths = Paths{path}
+ m.distFiles = MakeDefaultDistFiles(path)
case defaultDistFiles_Tagged:
+ // Module types that set AndroidMkEntry.DistFiles to the result of calling
+ // GenerateTaggedDistFiles(ctx) relied on no tag being treated as "" which
+ // meant that the default dist paths would be whatever was returned by
+ // OutputFiles(""). In order to preserve that behavior when treating no tag
+ // as being equal to DefaultDistTag this ensures that
+ // OutputFiles(DefaultDistTag) will return the same as OutputFiles("").
+ m.defaultDistPaths = PathsForTesting("one.out")
+
+ // This must be called after setting defaultDistPaths/outputFile as
+ // GenerateTaggedDistFiles calls into OutputFiles(tag) which may use those
+ // fields.
m.distFiles = m.GenerateTaggedDistFiles(ctx)
}
}
@@ -77,6 +101,12 @@
func (m *customModule) OutputFiles(tag string) (Paths, error) {
switch tag {
+ case DefaultDistTag:
+ if m.defaultDistPaths != nil {
+ return m.defaultDistPaths, nil
+ } else {
+ return nil, fmt.Errorf("default dist tag is not available")
+ }
case "":
return PathsForTesting("one.out"), nil
case ".multiple":
@@ -571,8 +601,6 @@
{
targets: ["my_goal"],
},
- // The following is silently ignored because the dist files do not
- // contain the tagged files.
{
targets: ["my_goal"],
tag: ".multiple",
@@ -587,6 +615,13 @@
distCopyForTest("default-dist.out", "default-dist.out"),
},
},
+ {
+ goals: "my_goal",
+ copies: []distCopy{
+ distCopyForTest("two.out", "two.out"),
+ distCopyForTest("three/four.out", "four.out"),
+ },
+ },
},
})
@@ -601,15 +636,23 @@
{
targets: ["my_goal"],
},
- // The following is silently ignored because the dist files do not
- // contain the tagged files.
{
targets: ["my_goal"],
tag: ".multiple",
},
],
}
-`, nil)
+`, &distContributions{
+ copiesForGoals: []*copiesForGoals{
+ {
+ goals: "my_goal",
+ copies: []distCopy{
+ distCopyForTest("two.out", "two.out"),
+ distCopyForTest("three/four.out", "four.out"),
+ },
+ },
+ },
+ })
testHelper(t, "tagged-dist-files-default-output", `
custom {
@@ -653,8 +696,6 @@
{
targets: ["my_goal"],
},
- // The following is silently ignored because the dist files do not
- // contain the tagged files.
{
targets: ["my_goal"],
tag: ".multiple",
@@ -669,6 +710,13 @@
distCopyForTest("default-dist.out", "default-dist.out"),
},
},
+ {
+ goals: "my_goal",
+ copies: []distCopy{
+ distCopyForTest("two.out", "two.out"),
+ distCopyForTest("three/four.out", "four.out"),
+ },
+ },
},
})
@@ -681,8 +729,6 @@
{
targets: ["my_goal"],
},
- // The following is silently ignored because the dist files do not
- // contain the tagged files.
{
targets: ["my_goal"],
tag: ".multiple",
@@ -697,6 +743,13 @@
distCopyForTest("dist-output-file.out", "dist-output-file.out"),
},
},
+ {
+ goals: "my_goal",
+ copies: []distCopy{
+ distCopyForTest("two.out", "two.out"),
+ distCopyForTest("three/four.out", "four.out"),
+ },
+ },
},
})
}
diff --git a/android/module.go b/android/module.go
index 0716b5d..d680baa 100644
--- a/android/module.go
+++ b/android/module.go
@@ -503,8 +503,12 @@
// 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.
+ // A string tag to select the OutputFiles associated with the tag.
+ //
+ // If no tag is specified then it will select the default dist paths provided
+ // by the module type. If a tag of "" is specified then it will return the
+ // default output files provided by the modules, i.e. the result of calling
+ // OutputFiles("").
Tag *string `android:"arch_variant"`
}
@@ -733,9 +737,45 @@
Dists []Dist `android:"arch_variant"`
}
+// The key to use in TaggedDistFiles when a Dist structure does not specify a
+// tag property. This intentionally does not use "" as the default because that
+// would mean that an empty tag would have a different meaning when used in a dist
+// structure that when used to reference a specific set of output paths using the
+// :module{tag} syntax, which passes tag to the OutputFiles(tag) method.
+const DefaultDistTag = "<default-dist-tag>"
+
// A map of OutputFile tag keys to Paths, for disting purposes.
type TaggedDistFiles map[string]Paths
+// addPathsForTag adds a mapping from the tag to the paths. If the map is nil
+// then it will create a map, update it and then return it. If a mapping already
+// exists for the tag then the paths are appended to the end of the current list
+// of paths, ignoring any duplicates.
+func (t TaggedDistFiles) addPathsForTag(tag string, paths ...Path) TaggedDistFiles {
+ if t == nil {
+ t = make(TaggedDistFiles)
+ }
+
+ for _, distFile := range paths {
+ if distFile != nil && !t[tag].containsPath(distFile) {
+ t[tag] = append(t[tag], distFile)
+ }
+ }
+
+ return t
+}
+
+// merge merges the entries from the other TaggedDistFiles object into this one.
+// If the TaggedDistFiles is nil then it will create a new instance, merge the
+// other into it, and then return it.
+func (t TaggedDistFiles) merge(other TaggedDistFiles) TaggedDistFiles {
+ for tag, paths := range other {
+ t = t.addPathsForTag(tag, paths...)
+ }
+
+ return t
+}
+
func MakeDefaultDistFiles(paths ...Path) TaggedDistFiles {
for _, path := range paths {
if path == nil {
@@ -744,7 +784,7 @@
}
// The default OutputFile tag is the empty "" string.
- return TaggedDistFiles{"": paths}
+ return TaggedDistFiles{DefaultDistTag: paths}
}
type hostAndDeviceProperties struct {
@@ -970,6 +1010,9 @@
noticeFiles Paths
phonies map[string]Paths
+ // The files to copy to the dist as explicitly specified in the .bp file.
+ distFiles TaggedDistFiles
+
// Used by buildTargetSingleton to create checkbuild and per-directory build targets
// Only set on the final variant of each module
installTarget WritablePath
@@ -1071,23 +1114,30 @@
}
func (m *ModuleBase) GenerateTaggedDistFiles(ctx BaseModuleContext) TaggedDistFiles {
- distFiles := make(TaggedDistFiles)
+ var distFiles 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)
+ // If no tag is specified then it means to use the default dist paths so use
+ // the special tag name which represents that.
+ tag := proptools.StringDefault(dist.Tag, DefaultDistTag)
+
+ if outputFileProducer, ok := m.module.(OutputFileProducer); ok {
+ // Call the OutputFiles(tag) method to get the paths associated with the tag.
+ distFilesForTag, err := outputFileProducer.OutputFiles(tag)
+
+ // If the tag was not supported and is not DefaultDistTag then it is an error.
+ // Failing to find paths for DefaultDistTag is not an error. It just means
+ // that the module type requires the legacy behavior.
+ if err != nil && tag != DefaultDistTag {
+ ctx.PropertyErrorf("dist.tag", "%s", err.Error())
}
+
+ distFiles = distFiles.addPathsForTag(tag, distFilesForTag...)
+ } else if tag != DefaultDistTag {
+ // If the tag was specified then it is an error if the module does not
+ // implement OutputFileProducer because there is no other way of accessing
+ // the paths for the specified tag.
+ ctx.PropertyErrorf("dist.tag",
+ "tag %s not supported because the module does not implement OutputFileProducer", tag)
}
}
@@ -1618,6 +1668,15 @@
return
}
+ // Create the set of tagged dist files after calling GenerateAndroidBuildActions
+ // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
+ // output paths being set which must be done before or during
+ // GenerateAndroidBuildActions.
+ m.distFiles = m.GenerateTaggedDistFiles(ctx)
+ if ctx.Failed() {
+ return
+ }
+
m.installFiles = append(m.installFiles, ctx.installFiles...)
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
diff --git a/android/paths.go b/android/paths.go
index a62c9e3..b7117a3 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -665,7 +665,7 @@
return Paths(ret)
}
-// WritablePaths is a slice of WritablePaths, used for multiple outputs.
+// WritablePaths is a slice of WritablePath, used for multiple outputs.
type WritablePaths []WritablePath
// Strings returns the string forms of the writable paths.
diff --git a/apex/Android.bp b/apex/Android.bp
index 1a5f683..9e8c30d 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -9,6 +9,7 @@
"soong-cc",
"soong-java",
"soong-python",
+ "soong-rust",
"soong-sh",
],
srcs: [
diff --git a/apex/androidmk.go b/apex/androidmk.go
index fe89b73..da38c2a 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -334,7 +334,6 @@
func (a *apexBundle) androidMkForType() android.AndroidMkData {
return android.AndroidMkData{
- DistFiles: a.distFiles,
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
moduleNames := []string{}
apexType := a.properties.ApexType
diff --git a/apex/apex.go b/apex/apex.go
index d0e0156..f127757 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -32,6 +32,7 @@
prebuilt_etc "android/soong/etc"
"android/soong/java"
"android/soong/python"
+ "android/soong/rust"
"android/soong/sh"
)
@@ -179,6 +180,9 @@
// List of JNI libraries that are embedded inside this APEX.
Jni_libs []string
+ // List of rust dyn libraries
+ Rust_dyn_libs []string
+
// List of native executables that are embedded inside this APEX.
Binaries []string
@@ -349,8 +353,6 @@
lintReports android.Paths
prebuiltFileToDelete string
-
- distFiles android.TaggedDistFiles
}
// apexFileClass represents a type of file that can be included in APEX.
@@ -513,13 +515,15 @@
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
binVariations := target.Variations()
libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
+ rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
if ctx.Device() {
binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
libVariations = append(libVariations,
blueprint.Variation{Mutator: "image", Variation: imageVariation},
- blueprint.Variation{Mutator: "version", Variation: ""}, // "" is the non-stub variant
- )
+ blueprint.Variation{Mutator: "version", Variation: ""}) // "" is the non-stub variant
+ rustLibVariations = append(rustLibVariations,
+ blueprint.Variation{Mutator: "image", Variation: imageVariation})
}
// Use *FarVariation* to be able to depend on modules having conflicting variations with
@@ -529,6 +533,7 @@
ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
+ ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
}
func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
@@ -1096,7 +1101,8 @@
// Implements android.OutputFileProducer
func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
switch tag {
- case "":
+ case "", android.DefaultDistTag:
+ // This is the default dist path.
return android.Paths{a.outputFile}, nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
@@ -1264,6 +1270,35 @@
return af
}
+func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
+ dirInApex := "bin"
+ if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
+ dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
+ }
+ fileToCopy := rustm.OutputFile().Path()
+ androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
+ af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
+ return af
+}
+
+func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
+ // Decide the APEX-local directory by the multilib of the library
+ // In the future, we may query this to the module.
+ var dirInApex string
+ switch rustm.Arch().ArchType.Multilib {
+ case "lib32":
+ dirInApex = "lib"
+ case "lib64":
+ dirInApex = "lib64"
+ }
+ if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
+ dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
+ }
+ fileToCopy := rustm.OutputFile().Path()
+ androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
+ return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
+}
+
func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
dirInApex := "bin"
fileToCopy := py.HostToolPath().Path()
@@ -1501,8 +1536,11 @@
filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py))
} else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb))
+ } else if rust, ok := child.(*rust.Module); ok {
+ filesInfo = append(filesInfo, apexFileForRustExecutable(ctx, rust))
+ return true // track transitive dependencies
} else {
- ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
+ ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
}
case javaLibTag:
switch child.(type) {
@@ -1663,6 +1701,13 @@
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
}
+ } else if rust.IsDylibDepTag(depTag) {
+ if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
+ af := apexFileForRustLibrary(ctx, rustm)
+ af.transitiveDep = true
+ filesInfo = append(filesInfo, af)
+ return true // track transitive dependencies
+ }
} else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
// nothing
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
@@ -1798,7 +1843,6 @@
}
a.buildApexDependencyInfo(ctx)
a.buildLintReports(ctx)
- a.distFiles = a.GenerateTaggedDistFiles(ctx)
// Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
if a.installable() {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 33e5077..a94e3b4 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -32,6 +32,7 @@
"android/soong/dexpreopt"
prebuilt_etc "android/soong/etc"
"android/soong/java"
+ "android/soong/rust"
"android/soong/sh"
)
@@ -136,6 +137,8 @@
bp = bp + cc.GatherRequiredDepsForTest(android.Android)
+ bp = bp + rust.GatherRequiredDepsForTest()
+
bp = bp + java.GatherRequiredDepsForTest()
fs := map[string][]byte{
@@ -185,6 +188,7 @@
"bar/baz": nil,
"testdata/baz": nil,
"AppSet.apks": nil,
+ "foo.rs": nil,
}
cc.GatherRequiredFilesForTest(fs)
@@ -241,6 +245,7 @@
ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
cc.RegisterRequiredBuildComponentsForTest(ctx)
+ rust.RegisterRequiredBuildComponentsForTest(ctx)
ctx.RegisterModuleType("cc_test", cc.TestFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
@@ -349,10 +354,12 @@
manifest: ":myapex.manifest",
androidManifest: ":myapex.androidmanifest",
key: "myapex.key",
+ binaries: ["foo.rust"],
native_shared_libs: ["mylib"],
+ rust_dyn_libs: ["libfoo.dylib.rust"],
multilib: {
both: {
- binaries: ["foo",],
+ binaries: ["foo"],
}
},
java_libs: [
@@ -415,6 +422,28 @@
apex_available: [ "myapex", "com.android.gki.*" ],
}
+ rust_binary {
+ name: "foo.rust",
+ srcs: ["foo.rs"],
+ rlibs: ["libfoo.rlib.rust"],
+ dylibs: ["libfoo.dylib.rust"],
+ apex_available: ["myapex"],
+ }
+
+ rust_library_rlib {
+ name: "libfoo.rlib.rust",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ apex_available: ["myapex"],
+ }
+
+ rust_library_dylib {
+ name: "libfoo.dylib.rust",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ apex_available: ["myapex"],
+ }
+
apex {
name: "com.android.gki.fake",
binaries: ["foo"],
@@ -529,16 +558,20 @@
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_apex10000")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("foo.rust"), "android_arm64_armv8-a_apex10000")
// Ensure that apex variant is created for the indirect dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.rlib.rust"), "android_arm64_armv8-a_rlib_dylib-std_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000")
// Ensure that both direct and indirect deps are copied into apex
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar")
ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar")
+ ensureContains(t, copyCmds, "image.apex/lib64/libfoo.dylib.rust.dylib.so")
// .. but not for java libs
ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar")
diff --git a/cc/testing.go b/cc/testing.go
index 198764b..95a93a0 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -166,6 +166,10 @@
product_available: true,
recovery_available: true,
src: "",
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
}
toolchain_library {
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index 633c6b2..a4f57ea 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -16,6 +16,8 @@
import (
"bytes"
+ "crypto/sha1"
+ "encoding/hex"
"errors"
"flag"
"fmt"
@@ -121,7 +123,22 @@
return fmt.Errorf("failed to create %q: %w", sandboxesRoot, err)
}
- tempDir, err := ioutil.TempDir(sandboxesRoot, "sbox")
+ // This tool assumes that there are no two concurrent runs with the same
+ // manifestFile. It should therefore be safe to use the hash of the
+ // manifestFile as the temporary directory name. We do this because it
+ // makes the temporary directory name deterministic. There are some
+ // tools that embed the name of the temporary output in the output, and
+ // they otherwise cause non-determinism, which then poisons actions
+ // depending on this one.
+ hash := sha1.New()
+ hash.Write([]byte(manifestFile))
+ tempDir := filepath.Join(sandboxesRoot, "sbox", hex.EncodeToString(hash.Sum(nil)))
+
+ err = os.RemoveAll(tempDir)
+ if err != nil {
+ return err
+ }
+ err = os.MkdirAll(tempDir, 0777)
if err != nil {
return fmt.Errorf("failed to create temporary dir in %q: %w", sandboxesRoot, err)
}
diff --git a/cmd/soong_build/queryview_test.go b/cmd/soong_build/queryview_test.go
index 525802a..9471a91 100644
--- a/cmd/soong_build/queryview_test.go
+++ b/cmd/soong_build/queryview_test.go
@@ -53,6 +53,12 @@
android.ModuleBase
}
+// OutputFiles is needed because some instances of this module use dist with a
+// tag property which requires the module implements OutputFileProducer.
+func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
+ return android.PathsForTesting("path" + tag), nil
+}
+
func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// nothing for now.
}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index d667e94..e5ee3fc 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// A genrule module takes a list of source files ("srcs" property), an optional
+// list of tools ("tools" property), and a command line ("cmd" property), to
+// generate output files ("out" property).
+
package genrule
import (
@@ -47,6 +51,8 @@
var (
pctx = android.NewPackageContext("android/soong/genrule")
+ // Used by gensrcs when there is more than 1 shard to merge the outputs
+ // of each shard into a zip file.
gensrcsMerge = pctx.AndroidStaticRule("gensrcsMerge", blueprint.RuleParams{
Command: "${soongZip} -o ${tmpZip} @${tmpZip}.rsp && ${zipSync} -d ${genDir} ${tmpZip}",
CommandDeps: []string{"${soongZip}", "${zipSync}"},
@@ -115,6 +121,7 @@
// Properties for Bazel migration purposes.
bazel.Properties
}
+
type Module struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -127,6 +134,9 @@
properties generatorProperties
+ // For the different tasks that genrule and gensrc generate. genrule will
+ // generate 1 task, and gensrc will generate 1 or more tasks based on the
+ // number of shards the input files are sharded into.
taskGenerator taskFunc
deps android.Paths
@@ -151,11 +161,12 @@
in android.Paths
out android.WritablePaths
depFile android.WritablePath
- copyTo android.WritablePaths
+ copyTo android.WritablePaths // For gensrcs to set on gensrcsMerge rule.
genDir android.WritablePath
extraTools android.Paths // dependencies on tools used by the generator
- cmd string
+ cmd string
+ // For gensrsc sharding.
shard int
shards int
}
@@ -324,6 +335,7 @@
var outputFiles android.WritablePaths
var zipArgs strings.Builder
+ // Generate tasks, either from genrule or gensrcs.
for _, task := range g.taskGenerator(ctx, String(g.properties.Cmd), srcFiles) {
if len(task.out) == 0 {
ctx.ModuleErrorf("must have at least one output file")
diff --git a/java/androidmk.go b/java/androidmk.go
index 386a97f..9ad3f9b 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -85,7 +85,6 @@
} else {
entriesList = append(entriesList, android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
- DistFiles: library.distFiles,
OutputFile: android.OptionalPathForPath(library.outputFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
@@ -524,17 +523,12 @@
// Note that dstubs.apiFile can be also be nil if WITHOUT_CHECKS_API is true.
// TODO(b/146727827): Revert when we do not need to generate stubs and API separately.
- var distFiles android.TaggedDistFiles
- if dstubs.apiFile != nil {
- distFiles = android.MakeDefaultDistFiles(dstubs.apiFile)
- }
outputFile := android.OptionalPathForPath(dstubs.stubsSrcJar)
if !outputFile.Valid() {
outputFile = android.OptionalPathForPath(dstubs.apiFile)
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
- DistFiles: distFiles,
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 075b7aa..233e9d5 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -16,7 +16,6 @@
import (
"reflect"
- "strings"
"testing"
"android/soong/android"
@@ -135,182 +134,6 @@
}
}
-func TestDistWithTag(t *testing.T) {
- ctx, config := testJava(t, `
- java_library {
- name: "foo_without_tag",
- srcs: ["a.java"],
- compile_dex: true,
- dist: {
- targets: ["hi"],
- },
- }
- java_library {
- name: "foo_with_tag",
- srcs: ["a.java"],
- compile_dex: true,
- dist: {
- targets: ["hi"],
- tag: ".jar",
- },
- }
- `)
-
- 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(withoutTagEntries) != 2 || len(withTagEntries) != 2 {
- t.Errorf("two mk entries per module expected, got %d and %d", len(withoutTagEntries), len(withTagEntries))
- }
- 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 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"])
- }
-}
-
func TestJavaSdkLibrary_RequireXmlPermissionFile(t *testing.T) {
ctx, config := testJava(t, `
java_sdk_library {
diff --git a/java/droiddoc.go b/java/droiddoc.go
index cf7f4fb..da8489a 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1050,7 +1050,8 @@
return android.Paths{d.stubsSrcJar}, nil
case ".docs.zip":
return android.Paths{d.docZip}, nil
- case ".api.txt":
+ case ".api.txt", android.DefaultDistTag:
+ // This is the default dist path for dist properties that have no tag property.
return android.Paths{d.apiFilePath}, nil
case ".removed-api.txt":
return android.Paths{d.removedApiFilePath}, nil
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index e57f323..8f0e09c 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -259,7 +259,7 @@
FlagWithInput("--blocked ",
android.PathForSource(ctx, "frameworks/base/config/hiddenapi-force-blocked.txt")).
FlagWithInput("--blocked ",
- android.PathForSource(ctx, "frameworks/base/config/hiddenapi-temp-blocklist.txt")).
+ android.PathForSource(ctx, "frameworks/base/config/hiddenapi-temp-blocklist.txt")).FlagWithArg("--tag ", "lo-prio").
FlagWithInput("--unsupported ", android.PathForSource(
ctx, "frameworks/base/config/hiddenapi-unsupported-packages.txt")).Flag("--packages ").
FlagWithOutput("--output ", tempPath)
diff --git a/java/java.go b/java/java.go
index bf139a8..8738e00 100644
--- a/java/java.go
+++ b/java/java.go
@@ -456,8 +456,6 @@
// list of the xref extraction files
kytheFiles android.Paths
- distFiles android.TaggedDistFiles
-
// Collect the module directory for IDE info in java/jdeps.go.
modulePaths []string
@@ -486,6 +484,8 @@
switch tag {
case "":
return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil
+ case android.DefaultDistTag:
+ return android.Paths{j.outputFile}, nil
case ".jar":
return android.Paths{j.implementationAndResourcesJar}, nil
case ".proguard_map":
@@ -2112,8 +2112,6 @@
if lib := proptools.String(j.usesLibraryProperties.Provides_uses_lib); lib != "" {
j.classLoaderContexts.AddContext(ctx, lib, j.DexJarBuildPath(), j.DexJarInstallPath())
}
-
- j.distFiles = j.GenerateTaggedDistFiles(ctx)
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index b832678..32bc077 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1281,11 +1281,7 @@
Include_dirs []string
Local_include_dirs []string
}
- Dist struct {
- Targets []string
- Dest *string
- Dir *string
- }
+ Dists []android.Dist
}{}
// The stubs source processing uses the same compile time classpath when extracting the
@@ -1385,11 +1381,23 @@
}
}
- // Dist the api txt artifact for sdk builds.
if !Bool(module.sdkLibraryProperties.No_dist) {
- props.Dist.Targets = []string{"sdk", "win_sdk"}
- props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.txt", module.distStem()))
- props.Dist.Dir = proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
+ // Dist the api txt and removed api txt artifacts for sdk builds.
+ distDir := proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
+ for _, p := range []struct {
+ tag string
+ pattern string
+ }{
+ {tag: ".api.txt", pattern: "%s.txt"},
+ {tag: ".removed-api.txt", pattern: "%s-removed.txt"},
+ } {
+ props.Dists = append(props.Dists, android.Dist{
+ Targets: []string{"sdk", "win_sdk"},
+ Dir: distDir,
+ Dest: proptools.StringPtr(fmt.Sprintf(p.pattern, module.distStem())),
+ Tag: proptools.StringPtr(p.tag),
+ })
+ }
}
mctx.CreateModule(DroidstubsFactory, &props)
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 74cd9bf..4e8b14d 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -43,7 +43,7 @@
}
func (mod *Module) AndroidMkEntries() []android.AndroidMkEntries {
- if mod.Properties.HideFromMake {
+ if mod.Properties.HideFromMake || mod.hideApexVariantFromMake {
return []android.AndroidMkEntries{android.AndroidMkEntries{Disabled: true}}
}
diff --git a/rust/clippy_test.go b/rust/clippy_test.go
index 132b7b8..e24f666 100644
--- a/rust/clippy_test.go
+++ b/rust/clippy_test.go
@@ -18,6 +18,7 @@
"testing"
"android/soong/android"
+ "android/soong/cc"
)
func TestClippy(t *testing.T) {
@@ -45,6 +46,7 @@
}`
bp = bp + GatherRequiredDepsForTest()
+ bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)
fs := map[string][]byte{
// Reuse the same blueprint file for subdirectories.
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index a6dba9e..2b40727 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -19,6 +19,7 @@
"testing"
"android/soong/android"
+ "android/soong/cc"
)
// Test that feature flags are being correctly generated.
@@ -132,6 +133,7 @@
}`
bp = bp + GatherRequiredDepsForTest()
+ bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)
fs := map[string][]byte{
// Reuse the same blueprint file for subdirectories.
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 3ad32fa..e6643f5 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -6,6 +6,7 @@
// for an example.
// TODO(b/160223496): enable rustfmt globally.
RustAllowedPaths = []string{
+ "device/google/cuttlefish",
"external/adhd",
"external/crosvm",
"external/minijail",
diff --git a/rust/rust.go b/rust/rust.go
index bd81c17..38caad3 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -74,6 +74,7 @@
type Module struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.ApexModuleBase
Properties BaseProperties
@@ -88,6 +89,8 @@
subAndroidMkOnce map[SubAndroidMkProvider]bool
outputFile android.OptionalPath
+
+ hideApexVariantFromMake bool
}
func (mod *Module) OutputFiles(tag string) (android.Paths, error) {
@@ -508,6 +511,7 @@
}
android.InitAndroidArchModule(mod, mod.hod, mod.multilib)
+ android.InitApexModule(mod)
android.InitDefaultableModule(mod)
return mod
@@ -605,6 +609,11 @@
ModuleContext: actx,
}
+ apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+ if !apexInfo.IsForPlatform() {
+ mod.hideApexVariantFromMake = true
+ }
+
toolchain := mod.toolchain(ctx)
if !toolchain.Supported() {
@@ -702,6 +711,11 @@
sourceDepTag = dependencyTag{name: "source"}
)
+func IsDylibDepTag(depTag blueprint.DependencyTag) bool {
+ tag, ok := depTag.(dependencyTag)
+ return ok && tag == dylibDepTag
+}
+
type autoDep struct {
variation string
depTag dependencyTag
@@ -1060,6 +1074,58 @@
return android.OptionalPath{}
}
+var _ android.ApexModule = (*Module)(nil)
+
+func (mod *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
+ return nil
+}
+
+func (mod *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+ depTag := ctx.OtherModuleDependencyTag(dep)
+
+ if ccm, ok := dep.(*cc.Module); ok {
+ if ccm.HasStubsVariants() {
+ if cc.IsSharedDepTag(depTag) {
+ // dynamic dep to a stubs lib crosses APEX boundary
+ return false
+ }
+ if cc.IsRuntimeDepTag(depTag) {
+ // runtime dep to a stubs lib also crosses APEX boundary
+ return false
+ }
+
+ if cc.IsHeaderDepTag(depTag) {
+ return false
+ }
+ }
+ if mod.Static() && cc.IsSharedDepTag(depTag) {
+ // shared_lib dependency from a static lib is considered as crossing
+ // the APEX boundary because the dependency doesn't actually is
+ // linked; the dependency is used only during the compilation phase.
+ return false
+ }
+ }
+
+ if depTag == procMacroDepTag {
+ return false
+ }
+
+ return true
+}
+
+// Overrides ApexModule.IsInstallabeToApex()
+func (mod *Module) IsInstallableToApex() bool {
+ if mod.compiler != nil {
+ if lib, ok := mod.compiler.(*libraryDecorator); ok && (lib.shared() || lib.dylib()) {
+ return true
+ }
+ if _, ok := mod.compiler.(*binaryDecorator); ok {
+ return true
+ }
+ }
+ return false
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 187f0b6..646b252 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -120,6 +120,7 @@
// attributes of the testRustCtx.
func (tctx *testRustCtx) generateConfig() {
tctx.bp = tctx.bp + GatherRequiredDepsForTest()
+ tctx.bp = tctx.bp + cc.GatherRequiredDepsForTest(android.NoOsType)
cc.GatherRequiredFilesForTest(tctx.fs)
config := android.TestArchConfig(buildDir, tctx.env, tctx.bp, tctx.fs)
tctx.config = &config
diff --git a/rust/testing.go b/rust/testing.go
index 001f322..a8496d9 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -77,6 +77,7 @@
no_libcrt: true,
nocrt: true,
system_shared_libs: [],
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
}
cc_library {
name: "libprotobuf-cpp-full",
@@ -93,6 +94,7 @@
host_supported: true,
native_coverage: false,
sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
}
rust_library {
name: "libtest",
@@ -102,6 +104,7 @@
host_supported: true,
native_coverage: false,
sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
}
rust_library {
name: "libprotobuf",
@@ -122,15 +125,11 @@
host_supported: true,
}
-` + cc.GatherRequiredDepsForTest(android.NoOsType)
+`
return bp
}
-func CreateTestContext(config android.Config) *android.TestContext {
- ctx := android.NewTestArchContext(config)
- android.RegisterPrebuiltMutators(ctx)
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- cc.RegisterRequiredBuildComponentsForTest(ctx)
+func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
ctx.RegisterModuleType("rust_bindgen", RustBindgenFactory)
@@ -164,6 +163,14 @@
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
ctx.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
+}
+
+func CreateTestContext(config android.Config) *android.TestContext {
+ ctx := android.NewTestArchContext(config)
+ android.RegisterPrebuiltMutators(ctx)
+ ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ cc.RegisterRequiredBuildComponentsForTest(ctx)
+ RegisterRequiredBuildComponentsForTest(ctx)
return ctx
}
diff --git a/ui/build/upload.go b/ui/build/upload.go
index a9346e0..4f30136 100644
--- a/ui/build/upload.go
+++ b/ui/build/upload.go
@@ -30,32 +30,34 @@
)
const (
+ // Used to generate a raw protobuf file that contains information
+ // of the list of metrics files from host to destination storage.
uploadPbFilename = ".uploader.pb"
)
var (
- // For testing purpose
- getTmpDir = ioutil.TempDir
+ // For testing purpose.
+ tmpDir = ioutil.TempDir
)
// UploadMetrics uploads a set of metrics files to a server for analysis. An
-// uploader full path is required to be specified in order to upload the set
-// of metrics files. This is accomplished by defining the ANDROID_ENABLE_METRICS_UPLOAD
-// environment variable. The metrics files are copied to a temporary directory
-// and the uploader is then executed in the background to allow the user to continue
-// working.
+// uploader full path is specified in ANDROID_ENABLE_METRICS_UPLOAD environment
+// variable in order to upload the set of metrics files. The metrics files are
+// first copied to a temporary directory and the uploader is then executed in
+// the background to allow the user/system to continue working. Soong communicates
+// to the uploader through the upload_proto raw protobuf file.
func UploadMetrics(ctx Context, config Config, simpleOutput bool, buildStarted time.Time, files ...string) {
ctx.BeginTrace(metrics.RunSetupTool, "upload_metrics")
defer ctx.EndTrace()
uploader := config.MetricsUploaderApp()
- // No metrics to upload if the path to the uploader was not specified.
if uploader == "" {
+ // If the uploader path was not specified, no metrics shall be uploaded.
return
}
- // Some files may not exist. For example, build errors protobuf file
- // may not exist since the build was successful.
+ // Some files passed in to this function may not exist. For example,
+ // build errors protobuf file may not exist since the build was successful.
var metricsFiles []string
for _, f := range files {
if _, err := os.Stat(f); err == nil {
@@ -70,7 +72,7 @@
// The temporary directory cannot be deleted as the metrics uploader is started
// in the background and requires to exist until the operation is done. The
// uploader can delete the directory as it is specified in the upload proto.
- tmpDir, err := getTmpDir("", "upload_metrics")
+ tmpDir, err := tmpDir("", "upload_metrics")
if err != nil {
ctx.Fatalf("failed to create a temporary directory to store the list of metrics files: %v\n", err)
}
@@ -103,7 +105,7 @@
}
// Start the uploader in the background as it takes several milliseconds to start the uploader
- // and prepare the metrics for upload. This affects small commands like "lunch".
+ // and prepare the metrics for upload. This affects small shell commands like "lunch".
cmd := Command(ctx, config, "upload metrics", uploader, "--upload-metrics", pbFile)
if simpleOutput {
cmd.RunOrFatal()
diff --git a/ui/build/upload_test.go b/ui/build/upload_test.go
index dccf156..768b031 100644
--- a/ui/build/upload_test.go
+++ b/ui/build/upload_test.go
@@ -62,16 +62,16 @@
}
defer os.RemoveAll(outDir)
- // Supply our own getTmpDir to delete the temp dir once the test is done.
- orgGetTmpDir := getTmpDir
- getTmpDir = func(string, string) (string, error) {
+ // Supply our own tmpDir to delete the temp dir once the test is done.
+ orgTmpDir := tmpDir
+ tmpDir = func(string, string) (string, error) {
retDir := filepath.Join(outDir, "tmp_upload_dir")
if err := os.Mkdir(retDir, 0755); err != nil {
t.Fatalf("failed to create temporary directory %q: %v", retDir, err)
}
return retDir, nil
}
- defer func() { getTmpDir = orgGetTmpDir }()
+ defer func() { tmpDir = orgTmpDir }()
metricsUploadDir := filepath.Join(outDir, ".metrics_uploader")
if err := os.Mkdir(metricsUploadDir, 0755); err != nil {
@@ -134,11 +134,11 @@
}
defer os.RemoveAll(outDir)
- orgGetTmpDir := getTmpDir
- getTmpDir = func(string, string) (string, error) {
+ orgTmpDir := tmpDir
+ tmpDir = func(string, string) (string, error) {
return tt.tmpDir, tt.tmpDirErr
}
- defer func() { getTmpDir = orgGetTmpDir }()
+ defer func() { tmpDir = orgTmpDir }()
metricsFile := filepath.Join(outDir, "metrics_file_1")
if err := ioutil.WriteFile(metricsFile, []byte("test file"), 0644); err != nil {