Handle `test_per_src` modules as indirect dependencies in APEXes.
In `apex.apexBundle.GenerateAndroidBuildActions`, we used to pass the
"all tests" ("") module as `module` for all `apexFile` objects created
from a test module using `test_per_src: true`. An immediate issue of
this situation was that the "" module is hidden from Make, which made
all the generated `apexFile` objects hidden from Make too. This would
break the construction of flattened APEXes, as they rely on Make logic
to install their files.
Instead of collecting `test_per_src` test variations' output files in
`cc.Module.GenerateAndroidBuildActions` and using them in
`apex.apexBundle.GenerateAndroidBuildActions` as part of handling the
"" variation as a direct dependency of an `apexBundle`, process them
as indirect dependencies (and do nothing for the "" variation direct
dependency).
Adjust the indirect dependency logic in
`apex.apexBundle.GenerateAndroidBuildActions` to allow not only
shared/runtime native libraries as indirect dependencies of an
`apexBundle`, but also `test_per_src` tests.
Test: m (`apex/apex_test.go` amended)
Bug: 129534335
Change-Id: I845e0f0dd3a98d61d0b7118c5eaf61f3e5335724
diff --git a/cc/cc.go b/cc/cc.go
index 2cee807..e31eb2d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -340,6 +340,7 @@
blueprint.BaseDependencyTag
name string
library bool
+ shared bool
reexportFlags bool
@@ -347,10 +348,10 @@
}
var (
- sharedDepTag = dependencyTag{name: "shared", library: true}
- sharedExportDepTag = dependencyTag{name: "shared", library: true, reexportFlags: true}
- earlySharedDepTag = dependencyTag{name: "early_shared", library: true}
- lateSharedDepTag = dependencyTag{name: "late shared", library: true}
+ sharedDepTag = dependencyTag{name: "shared", library: true, shared: true}
+ sharedExportDepTag = dependencyTag{name: "shared", library: true, shared: true, reexportFlags: true}
+ earlySharedDepTag = dependencyTag{name: "early_shared", library: true, shared: true}
+ lateSharedDepTag = dependencyTag{name: "late shared", library: true, shared: true}
staticDepTag = dependencyTag{name: "static", library: true}
staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true}
lateStaticDepTag = dependencyTag{name: "late static", library: true}
@@ -375,6 +376,21 @@
testPerSrcDepTag = dependencyTag{name: "test_per_src"}
)
+func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
+ ccDepTag, ok := depTag.(dependencyTag)
+ return ok && ccDepTag.shared
+}
+
+func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
+ ccDepTag, ok := depTag.(dependencyTag)
+ return ok && ccDepTag == runtimeDepTag
+}
+
+func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool {
+ ccDepTag, ok := depTag.(dependencyTag)
+ return ok && ccDepTag == testPerSrcDepTag
+}
+
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer interface
@@ -408,9 +424,6 @@
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
@@ -433,10 +446,6 @@
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()
@@ -950,28 +959,20 @@
return results
}
+func (c *Module) IsTestPerSrcAllTestsVariation() bool {
+ test, ok := c.linker.(testPerSrc)
+ return ok && test.isAllTestsVariation()
+}
+
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
- }
+ //
+ // The `test_per_src` mutator adds an extra variation named "", depending on all the other
+ // `test_per_src` variations of the test module. Set `outputFile` to an empty path for this
+ // module and return early, as this module does not produce an output file per se.
+ if c.IsTestPerSrcAllTestsVariation() {
+ c.outputFile = android.OptionalPath{}
+ return
}
c.makeLinkType = c.getMakeLinkType(actx)
@@ -2050,12 +2051,14 @@
}
// Overrides ApexModule.IsInstallabeToApex()
-// Only shared libraries are installable to APEX.
+// Only shared/runtime libraries and "test_per_src" tests are installable to APEX.
func (c *Module) IsInstallableToApex() bool {
if shared, ok := c.linker.(interface {
shared() bool
}); ok {
return shared.shared()
+ } else if _, ok := c.linker.(testPerSrc); ok {
+ return true
}
return false
}