Create an extra variation in `test_per_src` mutator collecting all outputs.
Have `cc.testPerSrcMutator` create an additional variation named "",
having no sources (and generating no output file), but depending on
all other `test_per_src` variations and collecting their output files
in a new field named `cc.Module.testPerSrcOutputFiles`. This is useful
in the case where a module depends on all the `test_per_src`
variations of a test module.
Test: m
Bug: 129534335
Change-Id: I905decc0b9417f47cee9113466677d3bb61ad7b6
diff --git a/cc/cc.go b/cc/cc.go
index a0ab255..70da92d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -369,6 +369,7 @@
vndkExtDepTag = dependencyTag{name: "vndk extends", library: true}
runtimeDepTag = dependencyTag{name: "runtime lib"}
coverageDepTag = dependencyTag{name: "coverage"}
+ testPerSrcDepTag = dependencyTag{name: "test_per_src"}
)
// Module contains the properties and members used by all C/C++ module types, and implements
@@ -404,6 +405,9 @@
outputFile android.OptionalPath
+ // Test output files, in the case of a test module using `test_per_src`.
+ testPerSrcOutputFiles []android.Path
+
cachedToolchain config.Toolchain
subAndroidMkOnce map[subAndroidMkProvider]bool
@@ -426,6 +430,10 @@
return c.outputFile
}
+func (c *Module) TestPerSrcOutputFiles() []android.Path {
+ return c.testPerSrcOutputFiles
+}
+
func (c *Module) UnstrippedOutputFile() android.Path {
if c.linker != nil {
return c.linker.unstrippedOutputFilePath()
@@ -940,6 +948,29 @@
}
func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
+ // Handle the case of a test module split by `test_per_src` mutator.
+ if test, ok := c.linker.(testPerSrc); ok {
+ // The `test_per_src` mutator adds an extra variant named "", depending on all the
+ // other `test_per_src` variants of the test module. Collect the output files of
+ // these dependencies and record them in the `testPerSrcOutputFiles` for later use
+ // (see e.g. `apexBundle.GenerateAndroidBuildActions`).
+ if test.isAllTestsVariation() {
+ var testPerSrcOutputFiles []android.Path
+ for _, dep := range actx.GetDirectDepsWithTag(testPerSrcDepTag) {
+ if ccDep, ok := dep.(*Module); ok {
+ depOutputFile := ccDep.OutputFile().Path()
+ testPerSrcOutputFiles =
+ append(testPerSrcOutputFiles, depOutputFile)
+ }
+ }
+ c.testPerSrcOutputFiles = testPerSrcOutputFiles
+ // Set outputFile to an empty path, as this module does not produce an
+ // output file per se.
+ c.outputFile = android.OptionalPath{}
+ return
+ }
+ }
+
c.makeLinkType = c.getMakeLinkType(actx)
ctx := &moduleContext{
diff --git a/cc/test.go b/cc/test.go
index 0a00aa1..95d0bfa 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -121,7 +121,9 @@
type testPerSrc interface {
testPerSrc() bool
srcs() []string
+ isAllTestsVariation() bool
setSrc(string, string)
+ unsetSrc()
}
func (test *testBinary) testPerSrc() bool {
@@ -132,28 +134,55 @@
return test.baseCompiler.Properties.Srcs
}
+func (test *testBinary) isAllTestsVariation() bool {
+ stem := test.binaryDecorator.Properties.Stem
+ return stem != nil && *stem == ""
+}
+
func (test *testBinary) setSrc(name, src string) {
test.baseCompiler.Properties.Srcs = []string{src}
test.binaryDecorator.Properties.Stem = StringPtr(name)
}
+func (test *testBinary) unsetSrc() {
+ test.baseCompiler.Properties.Srcs = nil
+ test.binaryDecorator.Properties.Stem = StringPtr("")
+}
+
var _ testPerSrc = (*testBinary)(nil)
func testPerSrcMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*Module); ok {
if test, ok := m.linker.(testPerSrc); ok {
- if test.testPerSrc() && len(test.srcs()) > 0 {
+ numTests := len(test.srcs())
+ if test.testPerSrc() && numTests > 0 {
if duplicate, found := checkDuplicate(test.srcs()); found {
mctx.PropertyErrorf("srcs", "found a duplicate entry %q", duplicate)
return
}
- testNames := make([]string, len(test.srcs()))
+ testNames := make([]string, numTests)
for i, src := range test.srcs() {
testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
}
+ // In addition to creating one variation per test source file,
+ // create an additional "all tests" variation named "", and have it
+ // depends on all other test_per_src variations. This is useful to
+ // create subsequent dependencies of a given module on all
+ // test_per_src variations created above: by depending on
+ // variation "", that module will transitively depend on all the
+ // other test_per_src variations without the need to know their
+ // name or even their number.
+ testNames = append(testNames, "")
tests := mctx.CreateLocalVariations(testNames...)
+ all_tests := tests[numTests]
+ all_tests.(*Module).linker.(testPerSrc).unsetSrc()
+ // Prevent the "all tests" variation from being installable nor
+ // exporting to Make, as it won't create any output file.
+ all_tests.(*Module).Properties.PreventInstall = true
+ all_tests.(*Module).Properties.HideFromMake = true
for i, src := range test.srcs() {
tests[i].(*Module).linker.(testPerSrc).setSrc(testNames[i], src)
+ mctx.AddInterVariantDependency(testPerSrcDepTag, all_tests, tests[i])
}
}
}