diff --git a/android/util.go b/android/util.go index 234bda365..947af699c 100644 --- a/android/util.go +++ b/android/util.go @@ -144,22 +144,28 @@ func setFromList[T comparable](l []T) map[T]bool { return m } -// ListDifference checks if the two lists contain the same elements -func ListDifference[T comparable](l1, l2 []T) []T { - diff := []T{} +// ListSetDifference checks if the two lists contain the same elements. It returns +// a boolean which is true if there is a difference, and then returns lists of elements +// that are in l1 but not l2, and l2 but not l1. +func ListSetDifference[T comparable](l1, l2 []T) (bool, []T, []T) { + listsDiffer := false + diff1 := []T{} + diff2 := []T{} m1 := setFromList(l1) m2 := setFromList(l2) - for _, t := range l1 { + for t := range m1 { if _, ok := m2[t]; !ok { - diff = append(diff, t) + diff1 = append(diff1, t) + listsDiffer = true } } - for _, t := range l2 { + for t := range m2 { if _, ok := m1[t]; !ok { - diff = append(diff, t) + diff2 = append(diff2, t) + listsDiffer = true } } - return diff + return listsDiffer, diff1, diff2 } // Returns true if the given string s is prefixed with any string in the given prefix list. diff --git a/cc/binary.go b/cc/binary.go index 54c1abccd..2f8ee7ff1 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -591,6 +591,8 @@ func (handler *ccBinaryBazelHandler) ProcessBazelQueryResponse(ctx android.Modul outputFilePath := android.PathForBazelOut(ctx, info.OutputFile) handler.module.outputFile = android.OptionalPathForPath(outputFilePath) handler.module.linker.(*binaryDecorator).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput) + + handler.module.setAndroidMkVariablesFromCquery(info.CcAndroidMkInfo) } func binaryBp2buildAttrs(ctx android.TopDownMutatorContext, m *Module) binaryAttributes { diff --git a/cc/cc.go b/cc/cc.go index f6f2a488b..a7f22ef28 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -28,6 +28,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/bazel/cquery" "android/soong/cc/config" "android/soong/fuzz" "android/soong/genrule" @@ -1889,14 +1890,6 @@ func (c *Module) ProcessBazelQueryResponse(ctx android.ModuleContext) { bazelCtx := ctx.Config().BazelContext if ccInfo, err := bazelCtx.GetCcInfo(bazelModuleLabel, android.GetConfigKey(ctx)); err == nil { c.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles) - c.Properties.AndroidMkSharedLibs = ccInfo.LocalSharedLibs - c.Properties.AndroidMkStaticLibs = ccInfo.LocalStaticLibs - c.Properties.AndroidMkWholeStaticLibs = ccInfo.LocalWholeStaticLibs - } - if unstrippedInfo, err := bazelCtx.GetCcUnstrippedInfo(bazelModuleLabel, android.GetConfigKey(ctx)); err == nil { - c.Properties.AndroidMkSharedLibs = unstrippedInfo.LocalSharedLibs - c.Properties.AndroidMkStaticLibs = unstrippedInfo.LocalStaticLibs - c.Properties.AndroidMkWholeStaticLibs = unstrippedInfo.LocalWholeStaticLibs } c.bazelHandler.ProcessBazelQueryResponse(ctx, bazelModuleLabel) @@ -2094,6 +2087,12 @@ func (c *Module) maybeInstall(ctx ModuleContext, apexInfo android.ApexInfo) { } } +func (c *Module) setAndroidMkVariablesFromCquery(info cquery.CcAndroidMkInfo) { + c.Properties.AndroidMkSharedLibs = info.LocalSharedLibs + c.Properties.AndroidMkStaticLibs = info.LocalStaticLibs + c.Properties.AndroidMkWholeStaticLibs = info.LocalWholeStaticLibs +} + func (c *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain { if c.cachedToolchain == nil { c.cachedToolchain = config.FindToolchainWithContext(ctx) diff --git a/cc/cc_test.go b/cc/cc_test.go index 39cc0730c..62adfd3ae 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -3029,32 +3029,6 @@ func checkStaticLibs(t *testing.T, expected []string, module *Module) { } } -func checkWholeStaticLibs(t *testing.T, expected []string, module *Module) { - t.Helper() - actual := module.Properties.AndroidMkWholeStaticLibs - if !reflect.DeepEqual(actual, expected) { - t.Errorf("incorrect whole_static_libs"+ - "\nactual: %v"+ - "\nexpected: %v", - actual, - expected, - ) - } -} - -func checkSharedLibs(t *testing.T, expected []string, module *Module) { - t.Helper() - actual := module.Properties.AndroidMkSharedLibs - if !reflect.DeepEqual(actual, expected) { - t.Errorf("incorrect shared_libs"+ - "\nactual: %v"+ - "\nexpected: %v", - actual, - expected, - ) - } -} - const staticLibAndroidBp = ` cc_library { name: "lib1", @@ -3114,6 +3088,20 @@ func TestLibDepAndroidMkExportInMixedBuilds(t *testing.T) { whole_static_libs: ["whole_static_dep"], shared_libs: ["shared_dep"], } + cc_library_headers { + name: "lib_headers", + bazel_module: { label: "//:lib_headers" }, + static_libs: ["static_dep"], + whole_static_libs: ["whole_static_dep"], + shared_libs: ["shared_dep"], + } + cc_prebuilt_library { + name: "lib_prebuilt", + bazel_module: { label: "//:lib_prebuilt" }, + static_libs: ["static_dep"], + whole_static_libs: ["whole_static_dep"], + shared_libs: ["shared_dep"], + } ` testCases := []struct { @@ -3172,6 +3160,36 @@ func TestLibDepAndroidMkExportInMixedBuilds(t *testing.T) { LocalSharedLibs: []string{"shared_dep"}, }, }, + { + name: "cc_library_headers", + moduleName: "lib_headers", + variant: "android_arm64_armv8-a", + androidMkInfo: cquery.CcAndroidMkInfo{ + LocalStaticLibs: []string{"static_dep"}, + LocalWholeStaticLibs: []string{"whole_static_dep"}, + LocalSharedLibs: []string{"shared_dep"}, + }, + }, + { + name: "prebuilt lib static", + moduleName: "lib_prebuilt", + variant: "android_arm64_armv8-a_static", + androidMkInfo: cquery.CcAndroidMkInfo{ + LocalStaticLibs: []string{"static_dep"}, + LocalWholeStaticLibs: []string{"whole_static_dep"}, + LocalSharedLibs: []string{"shared_dep"}, + }, + }, + { + name: "prebuilt lib shared", + moduleName: "lib_prebuilt", + variant: "android_arm64_armv8-a_shared", + androidMkInfo: cquery.CcAndroidMkInfo{ + LocalStaticLibs: []string{"static_dep"}, + LocalWholeStaticLibs: []string{"whole_static_dep"}, + LocalSharedLibs: []string{"shared_dep"}, + }, + }, } outputBaseDir := "out/bazel" @@ -3191,6 +3209,16 @@ func TestLibDepAndroidMkExportInMixedBuilds(t *testing.T) { CcAndroidMkInfo: tc.androidMkInfo, RootStaticArchives: []string{""}, }, + "//:lib_headers": cquery.CcInfo{ + CcAndroidMkInfo: tc.androidMkInfo, + OutputFiles: []string{""}, + }, + "//:lib_prebuilt": cquery.CcInfo{ + CcAndroidMkInfo: tc.androidMkInfo, + }, + "//:lib_prebuilt_bp2build_cc_library_static": cquery.CcInfo{ + CcAndroidMkInfo: tc.androidMkInfo, + }, }, LabelToCcBinary: map[string]cquery.CcUnstrippedInfo{ "//:test": cquery.CcUnstrippedInfo{ @@ -3207,25 +3235,68 @@ func TestLibDepAndroidMkExportInMixedBuilds(t *testing.T) { module := ctx.ModuleForTests(tc.moduleName, tc.variant).Module().(*Module) entries := android.AndroidMkEntriesForTest(t, ctx, module)[0] - checkStaticLibs(t, tc.androidMkInfo.LocalStaticLibs, module) - missingStaticDeps := android.ListDifference(entries.EntryMap["LOCAL_STATIC_LIBRARIES"], tc.androidMkInfo.LocalStaticLibs) - if len(missingStaticDeps) > 0 { - t.Errorf("expected LOCAL_STATIC_LIBRARIES to be %q"+ - " but was %q; difference: %q", tc.androidMkInfo.LocalStaticLibs, entries.EntryMap["LOCAL_STATIC_LIBRARIES"], missingStaticDeps) + if !reflect.DeepEqual(module.Properties.AndroidMkStaticLibs, tc.androidMkInfo.LocalStaticLibs) { + t.Errorf("incorrect static_libs"+ + "\nactual: %v"+ + "\nexpected: %v", + module.Properties.AndroidMkStaticLibs, + tc.androidMkInfo.LocalStaticLibs, + ) + } + staticDepsDiffer, missingStaticDeps, additionalStaticDeps := android.ListSetDifference( + entries.EntryMap["LOCAL_STATIC_LIBRARIES"], + tc.androidMkInfo.LocalStaticLibs, + ) + if staticDepsDiffer { + t.Errorf( + "expected LOCAL_STATIC_LIBRARIES to be %q but was %q; missing: %q; extra %q", + tc.androidMkInfo.LocalStaticLibs, + entries.EntryMap["LOCAL_STATIC_LIBRARIES"], + missingStaticDeps, + additionalStaticDeps, + ) } - checkWholeStaticLibs(t, tc.androidMkInfo.LocalWholeStaticLibs, module) - missingWholeStaticDeps := android.ListDifference(entries.EntryMap["LOCAL_WHOLE_STATIC_LIBRARIES"], tc.androidMkInfo.LocalWholeStaticLibs) - if len(missingWholeStaticDeps) > 0 { - t.Errorf("expected LOCAL_WHOLE_STATIC_LIBRARIES to be %q"+ - " but was %q; difference: %q", tc.androidMkInfo.LocalWholeStaticLibs, entries.EntryMap["LOCAL_WHOLE_STATIC_LIBRARIES"], missingWholeStaticDeps) + if !reflect.DeepEqual(module.Properties.AndroidMkWholeStaticLibs, tc.androidMkInfo.LocalWholeStaticLibs) { + t.Errorf("expected module.Properties.AndroidMkWholeStaticLibs to be %q, but was %q", + tc.androidMkInfo.LocalWholeStaticLibs, + module.Properties.AndroidMkWholeStaticLibs, + ) + } + wholeStaticDepsDiffer, missingWholeStaticDeps, additionalWholeStaticDeps := android.ListSetDifference( + entries.EntryMap["LOCAL_WHOLE_STATIC_LIBRARIES"], + tc.androidMkInfo.LocalWholeStaticLibs, + ) + if wholeStaticDepsDiffer { + t.Errorf( + "expected LOCAL_WHOLE_STATIC_LIBRARIES to be %q but was %q; missing: %q; extra %q", + tc.androidMkInfo.LocalWholeStaticLibs, + entries.EntryMap["LOCAL_WHOLE_STATIC_LIBRARIES"], + missingWholeStaticDeps, + additionalWholeStaticDeps, + ) } - checkSharedLibs(t, tc.androidMkInfo.LocalSharedLibs, module) - missingSharedDeps := android.ListDifference(entries.EntryMap["LOCAL_SHARED_LIBRARIES"], tc.androidMkInfo.LocalSharedLibs) - if len(missingSharedDeps) > 0 { - t.Errorf("expected LOCAL_SHARED_LIBRARIES to be %q"+ - " but was %q; difference: %q", tc.androidMkInfo.LocalSharedLibs, entries.EntryMap["LOCAL_SHARED_LIBRARIES"], missingSharedDeps) + if !reflect.DeepEqual(module.Properties.AndroidMkSharedLibs, tc.androidMkInfo.LocalSharedLibs) { + t.Errorf("incorrect shared_libs"+ + "\nactual: %v"+ + "\nexpected: %v", + module.Properties.AndroidMkSharedLibs, + tc.androidMkInfo.LocalSharedLibs, + ) + } + sharedDepsDiffer, missingSharedDeps, additionalSharedDeps := android.ListSetDifference( + entries.EntryMap["LOCAL_SHARED_LIBRARIES"], + tc.androidMkInfo.LocalSharedLibs, + ) + if sharedDepsDiffer { + t.Errorf( + "expected LOCAL_SHARED_LIBRARIES to be %q but was %q; missing %q; extra %q", + tc.androidMkInfo.LocalSharedLibs, + entries.EntryMap["LOCAL_SHARED_LIBRARIES"], + missingSharedDeps, + additionalSharedDeps, + ) } }) } diff --git a/cc/library.go b/cc/library.go index 1291f5cd3..ed219b6cf 100644 --- a/cc/library.go +++ b/cc/library.go @@ -936,6 +936,8 @@ func (handler *ccLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.Modu // implementation. i.(*libraryDecorator).collectedSnapshotHeaders = android.Paths{} } + + handler.module.setAndroidMkVariablesFromCquery(ccInfo.CcAndroidMkInfo) } func (library *libraryDecorator) setFlagExporterInfoFromCcInfo(ctx android.ModuleContext, ccInfo cquery.CcInfo) { diff --git a/cc/library_headers.go b/cc/library_headers.go index 4d38068fd..aea3fe676 100644 --- a/cc/library_headers.go +++ b/cc/library_headers.go @@ -88,6 +88,8 @@ func (h *libraryHeaderBazelHandler) ProcessBazelQueryResponse(ctx android.Module // validation will fail. For now, set this to an empty list. // TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation. h.library.collectedSnapshotHeaders = android.Paths{} + + h.module.setAndroidMkVariablesFromCquery(ccInfo.CcAndroidMkInfo) } // cc_library_headers contains a set of c/c++ headers which are imported by diff --git a/cc/prebuilt.go b/cc/prebuilt.go index af83278ac..9e62bf8ba 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -462,6 +462,8 @@ func (h *prebuiltLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.Modu } h.module.maybeUnhideFromMake() + + h.module.setAndroidMkVariablesFromCquery(ccInfo.CcAndroidMkInfo) } func (h *prebuiltLibraryBazelHandler) processStaticBazelQueryResponse(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool { diff --git a/cc/test.go b/cc/test.go index 4b968dcf6..5c4d54833 100644 --- a/cc/test.go +++ b/cc/test.go @@ -652,6 +652,8 @@ func (handler *ccTestBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleC outputFilePath := android.PathForBazelOut(ctx, info.OutputFile) handler.module.outputFile = android.OptionalPathForPath(outputFilePath) handler.module.linker.(*testBinary).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput) + + handler.module.setAndroidMkVariablesFromCquery(info.CcAndroidMkInfo) } // binaryAttributes contains Bazel attributes corresponding to a cc test