diff --git a/apex/androidmk.go b/apex/androidmk.go index 6b168fee4..08d190c66 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -78,6 +78,8 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo } } + seenDataOutPaths := make(map[string]bool) + for _, fi := range a.filesInfo { if cc, ok := fi.module.(*cc.Module); ok && cc.Properties.HideFromMake { continue @@ -112,16 +114,24 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir) if apexType == flattenedApex { // /system/apex//{lib|framework|...} - fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join(a.installDir.ToMakePath().String(), - apexBundleName, fi.installDir)) + modulePath := filepath.Join(a.installDir.ToMakePath().String(), apexBundleName, fi.installDir) + fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath) if a.primaryApexType && !symbolFilesNotNeeded { fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated) } if len(fi.symlinks) > 0 { fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " ")) } - if len(fi.dataPaths) > 0 { - fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(cc.AndroidMkDataPaths(fi.dataPaths), " ")) + newDataPaths := []android.Path{} + for _, path := range fi.dataPaths { + dataOutPath := modulePath + ":" + path.Rel() + if ok := seenDataOutPaths[dataOutPath]; !ok { + newDataPaths = append(newDataPaths, path) + seenDataOutPaths[dataOutPath] = true + } + } + if len(newDataPaths) > 0 { + fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(cc.AndroidMkDataPaths(newDataPaths), " ")) } if fi.module != nil && len(fi.module.NoticeFiles()) > 0 { diff --git a/apex/apex_test.go b/apex/apex_test.go index 9633f2713..ced113f2f 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -184,6 +184,7 @@ func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*andr "dummy.txt": nil, "baz": nil, "bar/baz": nil, + "testdata/baz": nil, } cc.GatherRequiredFilesForTest(fs) @@ -274,6 +275,15 @@ func ensureContains(t *testing.T, result string, expected string) { } } +// ensure that 'result' contains 'expected' exactly one time +func ensureContainsOnce(t *testing.T, result string, expected string) { + t.Helper() + count := strings.Count(result, expected) + if count != 1 { + t.Errorf("%q is found %d times (expected 1 time) in %q", expected, count, result) + } +} + // ensures that 'result' does not contain 'notExpected' func ensureNotContains(t *testing.T, result string, notExpected string) { t.Helper() @@ -3423,6 +3433,13 @@ func TestApexWithTests(t *testing.T) { stl: "none", } + filegroup { + name: "fg2", + srcs: [ + "testdata/baz" + ], + } + cc_test { name: "mytests", gtest: false, @@ -3436,6 +3453,10 @@ func TestApexWithTests(t *testing.T) { system_shared_libs: [], static_executable: true, stl: "none", + data: [ + ":fg", + ":fg2", + ], } `) @@ -3475,7 +3496,8 @@ func TestApexWithTests(t *testing.T) { data = android.AndroidMkDataForTest(t, config, "", flatBundle) data.Custom(&builder, name, prefix, "", data) flatAndroidMk := builder.String() - ensureContains(t, flatAndroidMk, "LOCAL_TEST_DATA := :baz :bar/baz\n") + ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :baz :bar/baz\n") + ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :testdata/baz\n") } func TestInstallExtraFlattenedApexes(t *testing.T) {