Loading android/api_domain.go +2 −2 Original line number Diff line number Diff line Loading @@ -73,9 +73,9 @@ func ApiDomainFactory() Module { func (a *apiDomain) DepsMutator(ctx BottomUpMutatorContext) { for _, cc := range a.properties.Cc_api_contributions { // Use FarVariationDependencies since the variants of api_domain is a subset of the variants of the dependency cc module // Creating a dependency on the first variant is ok since this is a no-op in Soong // Creating a dependency on the first variant that matches (os,arch) is ok since this is a no-op in Soong // The primary function of this dependency is to create a connected graph in the corresponding bp2build workspace ctx.AddFarVariationDependencies([]blueprint.Variation{}, nil, cc) ctx.AddFarVariationDependencies(ctx.Target().Variations(), nil, cc) } } Loading android/module.go +13 −1 Original line number Diff line number Diff line Loading @@ -915,9 +915,16 @@ type commonProperties struct { type CommonAttributes struct { // Soong nameProperties -> Bazel name Name string // Data mapped from: Required Data bazel.LabelListAttribute // SkipData is neither a Soong nor Bazel target attribute // If true, this will not fill the data attribute automatically // This is useful for Soong modules that have 1:many Bazel targets // Some of the generated Bazel targets might not have a data attribute SkipData *bool Tags bazel.StringListAttribute Applicable_licenses bazel.LabelListAttribute Loading Loading @@ -1305,7 +1312,12 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator platformEnabledAttribute.Add(&l) } if !proptools.Bool(attrs.SkipData) { attrs.Data.Append(required) } // SkipData is not an attribute of any Bazel target // Set this to nil so that it does not appear in the generated build file attrs.SkipData = nil moduleEnableConstraints := bazel.LabelListAttribute{} moduleEnableConstraints.Append(platformEnabledAttribute) Loading bazel/properties.go +16 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,17 @@ func MakeLabelList(labels []Label) LabelList { } } // MakeLabelListFromTargetNames creates a LabelList from unqualified target names // This is a utiltity function for bp2build converters of Soong modules that have 1:many generated targets func MakeLabelListFromTargetNames(targetNames []string) LabelList { labels := []Label{} for _, name := range targetNames { label := Label{Label: ":" + name} labels = append(labels, label) } return MakeLabelList(labels) } func (ll *LabelList) Equals(other LabelList) bool { if len(ll.Includes) != len(other.Includes) || len(ll.Excludes) != len(other.Excludes) { return false Loading Loading @@ -1178,6 +1189,11 @@ type StringListAttribute struct { ConfigurableValues configurableStringLists } // IsEmpty returns true if the attribute has no values under any configuration. func (sla StringListAttribute) IsEmpty() bool { return len(sla.Value) == 0 && !sla.HasConfigurableValues() } type configurableStringLists map[ConfigurationAxis]stringListSelectValues func (csl configurableStringLists) Append(other configurableStringLists) { Loading bp2build/cc_library_conversion_test.go +199 −0 Original line number Diff line number Diff line Loading @@ -2743,6 +2743,205 @@ cc_library { ) } func TestCcApiContributionsWithHdrs(t *testing.T) { bp := ` cc_library { name: "libfoo", stubs: { symbol_file: "libfoo.map.txt", versions: ["28", "29", "current"] }, llndk: { symbol_file: "libfoo.map.txt", override_export_include_dirs: ["dir2"]}, export_include_dirs: ["dir1"], } ` expectedBazelTargets := []string{ MakeBazelTarget( "cc_api_library_headers", "libfoo.systemapi.headers", AttrNameToString{ "export_includes": `["dir1"]`, }), MakeBazelTarget( "cc_api_library_headers", "libfoo.vendorapi.headers", AttrNameToString{ "export_includes": `["dir2"]`, }), MakeBazelTarget( "cc_api_contribution", "libfoo.contribution", AttrNameToString{ "api": `"libfoo.map.txt"`, "library_name": `"libfoo"`, "api_surfaces": `[ "systemapi", "vendorapi", ]`, "hdrs": `[ ":libfoo.systemapi.headers", ":libfoo.vendorapi.headers", ]`, }), } RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{ Blueprint: bp, Description: "cc API contributions to systemapi and vendorapi", ExpectedBazelTargets: expectedBazelTargets, }) } func TestCcApiSurfaceCombinations(t *testing.T) { testCases := []struct { bp string expectedApi string expectedApiSurfaces string description string }{ { bp: ` cc_library { name: "a", stubs: {symbol_file: "a.map.txt"}, }`, expectedApi: `"a.map.txt"`, expectedApiSurfaces: `["systemapi"]`, description: "Library that contributes to systemapi", }, { bp: ` cc_library { name: "a", llndk: {symbol_file: "a.map.txt"}, }`, expectedApi: `"a.map.txt"`, expectedApiSurfaces: `["vendorapi"]`, description: "Library that contributes to vendorapi", }, { bp: ` cc_library { name: "a", llndk: {symbol_file: "a.map.txt"}, stubs: {symbol_file: "a.map.txt"}, }`, expectedApi: `"a.map.txt"`, expectedApiSurfaces: `[ "systemapi", "vendorapi", ]`, description: "Library that contributes to systemapi and vendorapi", }, } for _, testCase := range testCases { expectedBazelTargets := []string{ MakeBazelTarget( "cc_api_contribution", "a.contribution", AttrNameToString{ "library_name": `"a"`, "hdrs": `[]`, "api": testCase.expectedApi, "api_surfaces": testCase.expectedApiSurfaces, }, ), } RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{ Blueprint: testCase.bp, Description: testCase.description, ExpectedBazelTargets: expectedBazelTargets, }) } } // llndk struct property in Soong provides users with several options to configure the exported include dirs // Test the generated bazel targets for the different configurations func TestCcVendorApiHeaders(t *testing.T) { testCases := []struct { bp string expectedIncludes string expectedSystemIncludes string description string }{ { bp: ` cc_library { name: "a", export_include_dirs: ["include"], export_system_include_dirs: ["base_system_include"], llndk: { symbol_file: "a.map.txt", export_headers_as_system: true, }, } `, expectedIncludes: "", expectedSystemIncludes: `[ "base_system_include", "include", ]`, description: "Headers are exported as system to API surface", }, { bp: ` cc_library { name: "a", export_include_dirs: ["include"], export_system_include_dirs: ["base_system_include"], llndk: { symbol_file: "a.map.txt", override_export_include_dirs: ["llndk_include"], }, } `, expectedIncludes: `["llndk_include"]`, expectedSystemIncludes: `["base_system_include"]`, description: "Non-system Headers are ovverriden before export to API surface", }, { bp: ` cc_library { name: "a", export_include_dirs: ["include"], export_system_include_dirs: ["base_system_include"], llndk: { symbol_file: "a.map.txt", override_export_include_dirs: ["llndk_include"], export_headers_as_system: true, }, } `, expectedIncludes: "", // includes are set to nil expectedSystemIncludes: `[ "base_system_include", "llndk_include", ]`, description: "System Headers are extended before export to API surface", }, } for _, testCase := range testCases { attrs := AttrNameToString{} if testCase.expectedIncludes != "" { attrs["export_includes"] = testCase.expectedIncludes } if testCase.expectedSystemIncludes != "" { attrs["export_system_includes"] = testCase.expectedSystemIncludes } expectedBazelTargets := []string{ MakeBazelTarget("cc_api_library_headers", "a.vendorapi.headers", attrs), // Create a target for cc_api_contribution target MakeBazelTarget("cc_api_contribution", "a.contribution", AttrNameToString{ "api": `"a.map.txt"`, "api_surfaces": `["vendorapi"]`, "hdrs": `[":a.vendorapi.headers"]`, "library_name": `"a"`, }), } RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{ Blueprint: testCase.bp, ExpectedBazelTargets: expectedBazelTargets, }) } } func TestCcLibraryStubsAcrossConfigsDuplicatesRemoved(t *testing.T) { runCcLibraryTestCase(t, Bp2buildTestCase{ Description: "stub target generation of the same lib across configs should not result in duplicates", Loading bp2build/cc_library_headers_conversion_test.go +63 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,69 @@ cc_library_headers { }) } func TestCcApiHeaders(t *testing.T) { fs := map[string]string{ "bar/Android.bp": `cc_library_headers { name: "bar_headers", }`, } bp := ` cc_library_headers { name: "foo_headers", export_include_dirs: ["dir1", "dir2"], export_header_lib_headers: ["bar_headers"], arch: { arm: { export_include_dirs: ["dir_arm"], }, x86: { export_include_dirs: ["dir_x86"], }, }, target: { android: { export_include_dirs: ["dir1", "dir_android"], }, windows: { export_include_dirs: ["dir_windows"], }, } } ` expectedBazelTargets := []string{ MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.arm", AttrNameToString{ "export_includes": `["dir_arm"]`, "arch": `"arm"`, }), MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.x86", AttrNameToString{ "export_includes": `["dir_x86"]`, "arch": `"x86"`, }), MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.androidos", AttrNameToString{ "export_includes": `["dir_android"]`, // common includes are deduped }), // Windows headers are not exported MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution", AttrNameToString{ "export_includes": `[ "dir1", "dir2", ]`, "deps": `[ "//bar:bar_headers.contribution", ":foo_headers.contribution.arm", ":foo_headers.contribution.x86", ":foo_headers.contribution.androidos", ]`, }), } RunApiBp2BuildTestCase(t, cc.RegisterLibraryHeadersBuildComponents, Bp2buildTestCase{ Blueprint: bp, Description: "Header library contributions to API surfaces", ExpectedBazelTargets: expectedBazelTargets, Filesystem: fs, }) } func TestCcLibraryHeadersOsSpecificHeader(t *testing.T) { runCcLibraryHeadersTestCase(t, Bp2buildTestCase{ Description: "cc_library_headers test with os-specific header_libs props", Loading Loading
android/api_domain.go +2 −2 Original line number Diff line number Diff line Loading @@ -73,9 +73,9 @@ func ApiDomainFactory() Module { func (a *apiDomain) DepsMutator(ctx BottomUpMutatorContext) { for _, cc := range a.properties.Cc_api_contributions { // Use FarVariationDependencies since the variants of api_domain is a subset of the variants of the dependency cc module // Creating a dependency on the first variant is ok since this is a no-op in Soong // Creating a dependency on the first variant that matches (os,arch) is ok since this is a no-op in Soong // The primary function of this dependency is to create a connected graph in the corresponding bp2build workspace ctx.AddFarVariationDependencies([]blueprint.Variation{}, nil, cc) ctx.AddFarVariationDependencies(ctx.Target().Variations(), nil, cc) } } Loading
android/module.go +13 −1 Original line number Diff line number Diff line Loading @@ -915,9 +915,16 @@ type commonProperties struct { type CommonAttributes struct { // Soong nameProperties -> Bazel name Name string // Data mapped from: Required Data bazel.LabelListAttribute // SkipData is neither a Soong nor Bazel target attribute // If true, this will not fill the data attribute automatically // This is useful for Soong modules that have 1:many Bazel targets // Some of the generated Bazel targets might not have a data attribute SkipData *bool Tags bazel.StringListAttribute Applicable_licenses bazel.LabelListAttribute Loading Loading @@ -1305,7 +1312,12 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator platformEnabledAttribute.Add(&l) } if !proptools.Bool(attrs.SkipData) { attrs.Data.Append(required) } // SkipData is not an attribute of any Bazel target // Set this to nil so that it does not appear in the generated build file attrs.SkipData = nil moduleEnableConstraints := bazel.LabelListAttribute{} moduleEnableConstraints.Append(platformEnabledAttribute) Loading
bazel/properties.go +16 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,17 @@ func MakeLabelList(labels []Label) LabelList { } } // MakeLabelListFromTargetNames creates a LabelList from unqualified target names // This is a utiltity function for bp2build converters of Soong modules that have 1:many generated targets func MakeLabelListFromTargetNames(targetNames []string) LabelList { labels := []Label{} for _, name := range targetNames { label := Label{Label: ":" + name} labels = append(labels, label) } return MakeLabelList(labels) } func (ll *LabelList) Equals(other LabelList) bool { if len(ll.Includes) != len(other.Includes) || len(ll.Excludes) != len(other.Excludes) { return false Loading Loading @@ -1178,6 +1189,11 @@ type StringListAttribute struct { ConfigurableValues configurableStringLists } // IsEmpty returns true if the attribute has no values under any configuration. func (sla StringListAttribute) IsEmpty() bool { return len(sla.Value) == 0 && !sla.HasConfigurableValues() } type configurableStringLists map[ConfigurationAxis]stringListSelectValues func (csl configurableStringLists) Append(other configurableStringLists) { Loading
bp2build/cc_library_conversion_test.go +199 −0 Original line number Diff line number Diff line Loading @@ -2743,6 +2743,205 @@ cc_library { ) } func TestCcApiContributionsWithHdrs(t *testing.T) { bp := ` cc_library { name: "libfoo", stubs: { symbol_file: "libfoo.map.txt", versions: ["28", "29", "current"] }, llndk: { symbol_file: "libfoo.map.txt", override_export_include_dirs: ["dir2"]}, export_include_dirs: ["dir1"], } ` expectedBazelTargets := []string{ MakeBazelTarget( "cc_api_library_headers", "libfoo.systemapi.headers", AttrNameToString{ "export_includes": `["dir1"]`, }), MakeBazelTarget( "cc_api_library_headers", "libfoo.vendorapi.headers", AttrNameToString{ "export_includes": `["dir2"]`, }), MakeBazelTarget( "cc_api_contribution", "libfoo.contribution", AttrNameToString{ "api": `"libfoo.map.txt"`, "library_name": `"libfoo"`, "api_surfaces": `[ "systemapi", "vendorapi", ]`, "hdrs": `[ ":libfoo.systemapi.headers", ":libfoo.vendorapi.headers", ]`, }), } RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{ Blueprint: bp, Description: "cc API contributions to systemapi and vendorapi", ExpectedBazelTargets: expectedBazelTargets, }) } func TestCcApiSurfaceCombinations(t *testing.T) { testCases := []struct { bp string expectedApi string expectedApiSurfaces string description string }{ { bp: ` cc_library { name: "a", stubs: {symbol_file: "a.map.txt"}, }`, expectedApi: `"a.map.txt"`, expectedApiSurfaces: `["systemapi"]`, description: "Library that contributes to systemapi", }, { bp: ` cc_library { name: "a", llndk: {symbol_file: "a.map.txt"}, }`, expectedApi: `"a.map.txt"`, expectedApiSurfaces: `["vendorapi"]`, description: "Library that contributes to vendorapi", }, { bp: ` cc_library { name: "a", llndk: {symbol_file: "a.map.txt"}, stubs: {symbol_file: "a.map.txt"}, }`, expectedApi: `"a.map.txt"`, expectedApiSurfaces: `[ "systemapi", "vendorapi", ]`, description: "Library that contributes to systemapi and vendorapi", }, } for _, testCase := range testCases { expectedBazelTargets := []string{ MakeBazelTarget( "cc_api_contribution", "a.contribution", AttrNameToString{ "library_name": `"a"`, "hdrs": `[]`, "api": testCase.expectedApi, "api_surfaces": testCase.expectedApiSurfaces, }, ), } RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{ Blueprint: testCase.bp, Description: testCase.description, ExpectedBazelTargets: expectedBazelTargets, }) } } // llndk struct property in Soong provides users with several options to configure the exported include dirs // Test the generated bazel targets for the different configurations func TestCcVendorApiHeaders(t *testing.T) { testCases := []struct { bp string expectedIncludes string expectedSystemIncludes string description string }{ { bp: ` cc_library { name: "a", export_include_dirs: ["include"], export_system_include_dirs: ["base_system_include"], llndk: { symbol_file: "a.map.txt", export_headers_as_system: true, }, } `, expectedIncludes: "", expectedSystemIncludes: `[ "base_system_include", "include", ]`, description: "Headers are exported as system to API surface", }, { bp: ` cc_library { name: "a", export_include_dirs: ["include"], export_system_include_dirs: ["base_system_include"], llndk: { symbol_file: "a.map.txt", override_export_include_dirs: ["llndk_include"], }, } `, expectedIncludes: `["llndk_include"]`, expectedSystemIncludes: `["base_system_include"]`, description: "Non-system Headers are ovverriden before export to API surface", }, { bp: ` cc_library { name: "a", export_include_dirs: ["include"], export_system_include_dirs: ["base_system_include"], llndk: { symbol_file: "a.map.txt", override_export_include_dirs: ["llndk_include"], export_headers_as_system: true, }, } `, expectedIncludes: "", // includes are set to nil expectedSystemIncludes: `[ "base_system_include", "llndk_include", ]`, description: "System Headers are extended before export to API surface", }, } for _, testCase := range testCases { attrs := AttrNameToString{} if testCase.expectedIncludes != "" { attrs["export_includes"] = testCase.expectedIncludes } if testCase.expectedSystemIncludes != "" { attrs["export_system_includes"] = testCase.expectedSystemIncludes } expectedBazelTargets := []string{ MakeBazelTarget("cc_api_library_headers", "a.vendorapi.headers", attrs), // Create a target for cc_api_contribution target MakeBazelTarget("cc_api_contribution", "a.contribution", AttrNameToString{ "api": `"a.map.txt"`, "api_surfaces": `["vendorapi"]`, "hdrs": `[":a.vendorapi.headers"]`, "library_name": `"a"`, }), } RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{ Blueprint: testCase.bp, ExpectedBazelTargets: expectedBazelTargets, }) } } func TestCcLibraryStubsAcrossConfigsDuplicatesRemoved(t *testing.T) { runCcLibraryTestCase(t, Bp2buildTestCase{ Description: "stub target generation of the same lib across configs should not result in duplicates", Loading
bp2build/cc_library_headers_conversion_test.go +63 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,69 @@ cc_library_headers { }) } func TestCcApiHeaders(t *testing.T) { fs := map[string]string{ "bar/Android.bp": `cc_library_headers { name: "bar_headers", }`, } bp := ` cc_library_headers { name: "foo_headers", export_include_dirs: ["dir1", "dir2"], export_header_lib_headers: ["bar_headers"], arch: { arm: { export_include_dirs: ["dir_arm"], }, x86: { export_include_dirs: ["dir_x86"], }, }, target: { android: { export_include_dirs: ["dir1", "dir_android"], }, windows: { export_include_dirs: ["dir_windows"], }, } } ` expectedBazelTargets := []string{ MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.arm", AttrNameToString{ "export_includes": `["dir_arm"]`, "arch": `"arm"`, }), MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.x86", AttrNameToString{ "export_includes": `["dir_x86"]`, "arch": `"x86"`, }), MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.androidos", AttrNameToString{ "export_includes": `["dir_android"]`, // common includes are deduped }), // Windows headers are not exported MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution", AttrNameToString{ "export_includes": `[ "dir1", "dir2", ]`, "deps": `[ "//bar:bar_headers.contribution", ":foo_headers.contribution.arm", ":foo_headers.contribution.x86", ":foo_headers.contribution.androidos", ]`, }), } RunApiBp2BuildTestCase(t, cc.RegisterLibraryHeadersBuildComponents, Bp2buildTestCase{ Blueprint: bp, Description: "Header library contributions to API surfaces", ExpectedBazelTargets: expectedBazelTargets, Filesystem: fs, }) } func TestCcLibraryHeadersOsSpecificHeader(t *testing.T) { runCcLibraryHeadersTestCase(t, Bp2buildTestCase{ Description: "cc_library_headers test with os-specific header_libs props", Loading