diff --git a/apex/apex.go b/apex/apex.go index 284af5cf1..4e6c0b1ff 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -449,6 +449,7 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, ctx.AddFarVariationDependencies([]blueprint.Variation{ {Mutator: "arch", Variation: arch}, {Mutator: "image", Variation: imageVariation}, + {Mutator: "test_per_src", Variation: ""}, // "" is the all-tests variant }, testTag, tests...) } @@ -492,6 +493,7 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddFarVariationDependencies([]blueprint.Variation{ {Mutator: "arch", Variation: target.String()}, {Mutator: "image", Variation: a.getImageVariation(config)}, + {Mutator: "test_per_src", Variation: ""}, // "" is the all-tests variant }, testTag, a.properties.Tests...) // Add native modules targetting both ABIs @@ -692,6 +694,12 @@ func getCopyManifestForExecutable(cc *cc.Module) (fileToCopy android.Path, dirIn return } +func getCopyManifestForTestPerSrcExecutables(cc *cc.Module) (filesToCopy []android.Path, dirInApex string) { + dirInApex = filepath.Join("bin", cc.RelativeInstallPath()) + filesToCopy = cc.TestPerSrcOutputFiles() + return +} + func getCopyManifestForPyBinary(py *python.Module) (fileToCopy android.Path, dirInApex string) { dirInApex = "bin" fileToCopy = py.HostToolPath().Path() @@ -827,8 +835,22 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } case testTag: if cc, ok := child.(*cc.Module); ok { - fileToCopy, dirInApex := getCopyManifestForExecutable(cc) - filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeTest, cc, nil}) + if cc.TestPerSrcOutputFiles() != nil { + // Multiple-output test module (using `test_per_src`). + filesToCopy, dirInApex := getCopyManifestForTestPerSrcExecutables(cc) + for _, fileToCopy := range filesToCopy { + // Handle modules created as `test_per_src` variations of a single test module: + // replace the name of the original test module (`depName`, shared by all + // `test_per_src` variants of that module) with the name of the generated test + // binary. + moduleName := filepath.Base(fileToCopy.String()) + filesInfo = append(filesInfo, apexFile{fileToCopy, moduleName, dirInApex, nativeTest, cc, nil}) + } + } else { + // Single-output test module (not using `test_per_src`). + fileToCopy, dirInApex := getCopyManifestForExecutable(cc) + filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeTest, cc, nil}) + } return true } else { ctx.PropertyErrorf("tests", "%q is not a cc module", depName) diff --git a/apex/apex_test.go b/apex/apex_test.go index 5fc07384d..bb0c4c5be 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -98,6 +98,7 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con ctx.BottomUp("image", cc.ImageMutator).Parallel() ctx.BottomUp("link", cc.LinkageMutator).Parallel() ctx.BottomUp("vndk", cc.VndkMutator).Parallel() + ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel() ctx.BottomUp("version", cc.VersionMutator).Parallel() ctx.BottomUp("begin", cc.BeginMutator).Parallel() }) @@ -197,8 +198,11 @@ func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Con "system/sepolicy/apex/otherapex-file_contexts": nil, "system/sepolicy/apex/commonapex-file_contexts": nil, "mylib.cpp": nil, - "mytest.cpp": nil, "mylib_common.cpp": nil, + "mytest.cpp": nil, + "mytest1.cpp": nil, + "mytest2.cpp": nil, + "mytest3.cpp": nil, "myprebuilt": nil, "my_include": nil, "vendor/foo/devkeys/test.x509.pem": nil, @@ -1367,6 +1371,7 @@ func TestApexWithTests(t *testing.T) { key: "myapex.key", tests: [ "mytest", + "mytests", ], } @@ -1385,6 +1390,21 @@ func TestApexWithTests(t *testing.T) { static_executable: true, stl: "none", } + + cc_test { + name: "mytests", + gtest: false, + srcs: [ + "mytest1.cpp", + "mytest2.cpp", + "mytest3.cpp", + ], + test_per_src: true, + relative_install_path: "test", + system_shared_libs: [], + static_executable: true, + stl: "none", + } `) apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule") @@ -1392,6 +1412,11 @@ func TestApexWithTests(t *testing.T) { // Ensure that test dep is copied into apex. ensureContains(t, copyCmds, "image.apex/bin/test/mytest") + + // Ensure that test deps built with `test_per_src` are copied into apex. + ensureContains(t, copyCmds, "image.apex/bin/test/mytest1") + ensureContains(t, copyCmds, "image.apex/bin/test/mytest2") + ensureContains(t, copyCmds, "image.apex/bin/test/mytest3") } func TestApexUsesOtherApex(t *testing.T) { diff --git a/cc/cc.go b/cc/cc.go index eb54bc293..2cee80717 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -40,7 +40,7 @@ func init() { ctx.BottomUp("link", LinkageMutator).Parallel() ctx.BottomUp("vndk", VndkMutator).Parallel() ctx.BottomUp("ndk_api", ndkApiMutator).Parallel() - ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel() + ctx.BottomUp("test_per_src", TestPerSrcMutator).Parallel() ctx.BottomUp("version", VersionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() ctx.BottomUp("sysprop", SyspropMutator).Parallel() diff --git a/cc/test.go b/cc/test.go index 95d0bfa53..aff8ba57f 100644 --- a/cc/test.go +++ b/cc/test.go @@ -151,7 +151,7 @@ func (test *testBinary) unsetSrc() { var _ testPerSrc = (*testBinary)(nil) -func testPerSrcMutator(mctx android.BottomUpMutatorContext) { +func TestPerSrcMutator(mctx android.BottomUpMutatorContext) { if m, ok := mctx.Module().(*Module); ok { if test, ok := m.linker.(testPerSrc); ok { numTests := len(test.srcs())