Loading bp2build/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ bootstrap_go_package { "java_plugin_conversion_test.go", "java_proto_conversion_test.go", "linker_config_conversion_test.go", "ndk_headers_conversion_test.go", "performance_test.go", "prebuilt_etc_conversion_test.go", "python_binary_conversion_test.go", Loading bp2build/ndk_headers_conversion_test.go 0 → 100644 +164 −0 Original line number Diff line number Diff line // Copyright 2022 Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bp2build import ( "fmt" "testing" "android/soong/cc" ) func TestNdkHeaderFilepaths(t *testing.T) { bpTemplate := ` ndk_headers { name: "foo", srcs: %v, exclude_srcs: %v, } ` testCases := []struct { desc string srcs string excludeSrcs string expectedHdrs string }{ { desc: "Single header file", srcs: `["foo.h"]`, excludeSrcs: `[]`, expectedHdrs: `["foo.h"]`, }, { desc: "Multiple header files", srcs: `["foo.h", "foo_other.h"]`, excludeSrcs: `[]`, expectedHdrs: `[ "foo.h", "foo_other.h", ]`, }, { desc: "Multiple header files with excludes", srcs: `["foo.h", "foo_other.h"]`, excludeSrcs: `["foo_other.h"]`, expectedHdrs: `["foo.h"]`, }, { desc: "Multiple header files via Soong-supported globs", srcs: `["*.h"]`, excludeSrcs: `[]`, expectedHdrs: `[ "foo.h", "foo_other.h", ]`, }, } for _, testCase := range testCases { fs := map[string]string{ "foo.h": "", "foo_other.h": "", } expectedApiContributionTargetName := "foo.contribution" expectedBazelTarget := MakeBazelTargetNoRestrictions( "cc_api_headers", expectedApiContributionTargetName, AttrNameToString{ "hdrs": testCase.expectedHdrs, }, ) RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ Description: testCase.desc, Blueprint: fmt.Sprintf(bpTemplate, testCase.srcs, testCase.excludeSrcs), ExpectedBazelTargets: []string{expectedBazelTarget}, Filesystem: fs, }) } } func TestNdkHeaderIncludeDir(t *testing.T) { bpTemplate := ` ndk_headers { name: "foo", from: %v, to: "this/value/is/ignored", } ` testCases := []struct { desc string from string expectedIncludeDir string }{ { desc: "Empty `from` value", from: `""`, expectedIncludeDir: `""`, }, { desc: "Non-Empty `from` value", from: `"include"`, expectedIncludeDir: `"include"`, }, } for _, testCase := range testCases { expectedApiContributionTargetName := "foo.contribution" expectedBazelTarget := MakeBazelTargetNoRestrictions( "cc_api_headers", expectedApiContributionTargetName, AttrNameToString{ "include_dir": testCase.expectedIncludeDir, }, ) RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ Description: testCase.desc, Blueprint: fmt.Sprintf(bpTemplate, testCase.from), ExpectedBazelTargets: []string{expectedBazelTarget}, }) } } func TestVersionedNdkHeaderFilepaths(t *testing.T) { bp := ` versioned_ndk_headers { name: "common_libc", from: "include" } ` fs := map[string]string{ "include/math.h": "", "include/stdio.h": "", "include/arm/arm.h": "", "include/x86/x86.h": "", } expectedApiContributionTargetName := "common_libc.contribution" expectedBazelTarget := MakeBazelTargetNoRestrictions( "cc_api_headers", expectedApiContributionTargetName, AttrNameToString{ "include_dir": `"include"`, "hdrs": `[ "include/math.h", "include/stdio.h", "include/arm/arm.h", "include/x86/x86.h", ]`, }, ) RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ Blueprint: bp, Filesystem: fs, ExpectedBazelTargets: []string{expectedBazelTarget}, }) } cc/ndk_headers.go +68 −7 Original line number Diff line number Diff line Loading @@ -19,8 +19,10 @@ import ( "path/filepath" "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" "android/soong/bazel" ) var ( Loading Loading @@ -79,6 +81,7 @@ type headerProperties struct { type headerModule struct { android.ModuleBase android.BazelModuleBase properties headerProperties Loading Loading @@ -144,6 +147,47 @@ func (m *headerModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } const ( apiContributionSuffix = ".contribution" ) // apiContributionTargetName returns the name of the cc_api(headers|contribution) bp2build target of ndk modules // A suffix is necessary to prevent a name collision with the base ndk_(library|header) target in the same bp2build bazel package func apiContributionTargetName(moduleName string) string { return moduleName + apiContributionSuffix } // TODO(b/243196151): Populate `system` and `arch` metadata type bazelCcApiHeadersAttributes struct { Hdrs bazel.LabelListAttribute Include_dir *string } func createCcApiHeadersTarget(ctx android.TopDownMutatorContext, includes []string, excludes []string, include_dir *string) { props := bazel.BazelTargetModuleProperties{ Rule_class: "cc_api_headers", Bzl_load_location: "//build/bazel/rules/apis:cc_api_contribution.bzl", } attrs := &bazelCcApiHeadersAttributes{ Hdrs: bazel.MakeLabelListAttribute( android.BazelLabelForModuleSrcExcludes( ctx, includes, excludes, ), ), Include_dir: include_dir, } ctx.CreateBazelTargetModule(props, android.CommonAttributes{ Name: apiContributionTargetName(ctx.ModuleName()), }, attrs) } func (h *headerModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { // Generate `cc_api_headers` target for Multi-tree API export createCcApiHeadersTarget(ctx, h.properties.Srcs, h.properties.Exclude_srcs, h.properties.From) } // ndk_headers installs the sets of ndk headers defined in the srcs property // to the sysroot base + "usr/include" + to directory + directory component. // ndk_headers requires the license file to be specified. Example: Loading @@ -158,6 +202,7 @@ func ndkHeadersFactory() android.Module { module := &headerModule{} module.AddProperties(&module.properties) android.InitAndroidModule(module) android.InitBazelModule(module) return module } Loading Loading @@ -190,6 +235,7 @@ type versionedHeaderProperties struct { // Note that this is really only built to handle bionic/libc/include. type versionedHeaderModule struct { android.ModuleBase android.BazelModuleBase properties versionedHeaderProperties Loading @@ -197,6 +243,11 @@ type versionedHeaderModule struct { licensePath android.Path } // Return the glob pattern to find all .h files beneath `dir` func headerGlobPattern(dir string) string { return filepath.Join(dir, "**", "*.h") } func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { if String(m.properties.License) == "" { ctx.PropertyErrorf("license", "field is required") Loading @@ -206,7 +257,7 @@ func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleCo fromSrcPath := android.PathForModuleSrc(ctx, String(m.properties.From)) toOutputPath := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To)) srcFiles := ctx.GlobFiles(filepath.Join(fromSrcPath.String(), "**/*.h"), nil) srcFiles := ctx.GlobFiles(headerGlobPattern(fromSrcPath.String()), nil) var installPaths []android.WritablePath for _, header := range srcFiles { installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To)) Loading @@ -222,6 +273,13 @@ func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleCo processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths) } func (h *versionedHeaderModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { // Glob all .h files under `From` includePattern := headerGlobPattern(proptools.String(h.properties.From)) // Generate `cc_api_headers` target for Multi-tree API export createCcApiHeadersTarget(ctx, []string{includePattern}, []string{}, h.properties.From) } func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path, srcFiles android.Paths, installPaths []android.WritablePath) android.Path { // The versioner depends on a dependencies directory to simplify determining include paths Loading Loading @@ -271,15 +329,18 @@ func versionedNdkHeadersFactory() android.Module { module.AddProperties(&module.properties) android.InitAndroidModule(module) android.InitBazelModule(module) return module } // preprocessed_ndk_header { // // name: "foo", // preprocessor: "foo.sh", // srcs: [...], // to: "android", // // } // // Will invoke the preprocessor as: Loading cc/ndk_sysroot.go +9 −6 Original line number Diff line number Diff line Loading @@ -57,15 +57,18 @@ import ( ) func init() { android.RegisterModuleType("ndk_headers", ndkHeadersFactory) android.RegisterModuleType("ndk_library", NdkLibraryFactory) android.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory) android.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory) android.RegisterSingletonType("ndk", NdkSingleton) RegisterNdkModuleTypes(android.InitRegistrationContext) pctx.Import("android/soong/android") } func RegisterNdkModuleTypes(ctx android.RegistrationContext) { ctx.RegisterModuleType("ndk_headers", ndkHeadersFactory) ctx.RegisterModuleType("ndk_library", NdkLibraryFactory) ctx.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory) ctx.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory) ctx.RegisterSingletonType("ndk", NdkSingleton) } func getNdkInstallBase(ctx android.PathContext) android.InstallPath { return android.PathForNdkInstall(ctx) } Loading Loading
bp2build/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ bootstrap_go_package { "java_plugin_conversion_test.go", "java_proto_conversion_test.go", "linker_config_conversion_test.go", "ndk_headers_conversion_test.go", "performance_test.go", "prebuilt_etc_conversion_test.go", "python_binary_conversion_test.go", Loading
bp2build/ndk_headers_conversion_test.go 0 → 100644 +164 −0 Original line number Diff line number Diff line // Copyright 2022 Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bp2build import ( "fmt" "testing" "android/soong/cc" ) func TestNdkHeaderFilepaths(t *testing.T) { bpTemplate := ` ndk_headers { name: "foo", srcs: %v, exclude_srcs: %v, } ` testCases := []struct { desc string srcs string excludeSrcs string expectedHdrs string }{ { desc: "Single header file", srcs: `["foo.h"]`, excludeSrcs: `[]`, expectedHdrs: `["foo.h"]`, }, { desc: "Multiple header files", srcs: `["foo.h", "foo_other.h"]`, excludeSrcs: `[]`, expectedHdrs: `[ "foo.h", "foo_other.h", ]`, }, { desc: "Multiple header files with excludes", srcs: `["foo.h", "foo_other.h"]`, excludeSrcs: `["foo_other.h"]`, expectedHdrs: `["foo.h"]`, }, { desc: "Multiple header files via Soong-supported globs", srcs: `["*.h"]`, excludeSrcs: `[]`, expectedHdrs: `[ "foo.h", "foo_other.h", ]`, }, } for _, testCase := range testCases { fs := map[string]string{ "foo.h": "", "foo_other.h": "", } expectedApiContributionTargetName := "foo.contribution" expectedBazelTarget := MakeBazelTargetNoRestrictions( "cc_api_headers", expectedApiContributionTargetName, AttrNameToString{ "hdrs": testCase.expectedHdrs, }, ) RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ Description: testCase.desc, Blueprint: fmt.Sprintf(bpTemplate, testCase.srcs, testCase.excludeSrcs), ExpectedBazelTargets: []string{expectedBazelTarget}, Filesystem: fs, }) } } func TestNdkHeaderIncludeDir(t *testing.T) { bpTemplate := ` ndk_headers { name: "foo", from: %v, to: "this/value/is/ignored", } ` testCases := []struct { desc string from string expectedIncludeDir string }{ { desc: "Empty `from` value", from: `""`, expectedIncludeDir: `""`, }, { desc: "Non-Empty `from` value", from: `"include"`, expectedIncludeDir: `"include"`, }, } for _, testCase := range testCases { expectedApiContributionTargetName := "foo.contribution" expectedBazelTarget := MakeBazelTargetNoRestrictions( "cc_api_headers", expectedApiContributionTargetName, AttrNameToString{ "include_dir": testCase.expectedIncludeDir, }, ) RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ Description: testCase.desc, Blueprint: fmt.Sprintf(bpTemplate, testCase.from), ExpectedBazelTargets: []string{expectedBazelTarget}, }) } } func TestVersionedNdkHeaderFilepaths(t *testing.T) { bp := ` versioned_ndk_headers { name: "common_libc", from: "include" } ` fs := map[string]string{ "include/math.h": "", "include/stdio.h": "", "include/arm/arm.h": "", "include/x86/x86.h": "", } expectedApiContributionTargetName := "common_libc.contribution" expectedBazelTarget := MakeBazelTargetNoRestrictions( "cc_api_headers", expectedApiContributionTargetName, AttrNameToString{ "include_dir": `"include"`, "hdrs": `[ "include/math.h", "include/stdio.h", "include/arm/arm.h", "include/x86/x86.h", ]`, }, ) RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ Blueprint: bp, Filesystem: fs, ExpectedBazelTargets: []string{expectedBazelTarget}, }) }
cc/ndk_headers.go +68 −7 Original line number Diff line number Diff line Loading @@ -19,8 +19,10 @@ import ( "path/filepath" "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/android" "android/soong/bazel" ) var ( Loading Loading @@ -79,6 +81,7 @@ type headerProperties struct { type headerModule struct { android.ModuleBase android.BazelModuleBase properties headerProperties Loading Loading @@ -144,6 +147,47 @@ func (m *headerModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } const ( apiContributionSuffix = ".contribution" ) // apiContributionTargetName returns the name of the cc_api(headers|contribution) bp2build target of ndk modules // A suffix is necessary to prevent a name collision with the base ndk_(library|header) target in the same bp2build bazel package func apiContributionTargetName(moduleName string) string { return moduleName + apiContributionSuffix } // TODO(b/243196151): Populate `system` and `arch` metadata type bazelCcApiHeadersAttributes struct { Hdrs bazel.LabelListAttribute Include_dir *string } func createCcApiHeadersTarget(ctx android.TopDownMutatorContext, includes []string, excludes []string, include_dir *string) { props := bazel.BazelTargetModuleProperties{ Rule_class: "cc_api_headers", Bzl_load_location: "//build/bazel/rules/apis:cc_api_contribution.bzl", } attrs := &bazelCcApiHeadersAttributes{ Hdrs: bazel.MakeLabelListAttribute( android.BazelLabelForModuleSrcExcludes( ctx, includes, excludes, ), ), Include_dir: include_dir, } ctx.CreateBazelTargetModule(props, android.CommonAttributes{ Name: apiContributionTargetName(ctx.ModuleName()), }, attrs) } func (h *headerModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { // Generate `cc_api_headers` target for Multi-tree API export createCcApiHeadersTarget(ctx, h.properties.Srcs, h.properties.Exclude_srcs, h.properties.From) } // ndk_headers installs the sets of ndk headers defined in the srcs property // to the sysroot base + "usr/include" + to directory + directory component. // ndk_headers requires the license file to be specified. Example: Loading @@ -158,6 +202,7 @@ func ndkHeadersFactory() android.Module { module := &headerModule{} module.AddProperties(&module.properties) android.InitAndroidModule(module) android.InitBazelModule(module) return module } Loading Loading @@ -190,6 +235,7 @@ type versionedHeaderProperties struct { // Note that this is really only built to handle bionic/libc/include. type versionedHeaderModule struct { android.ModuleBase android.BazelModuleBase properties versionedHeaderProperties Loading @@ -197,6 +243,11 @@ type versionedHeaderModule struct { licensePath android.Path } // Return the glob pattern to find all .h files beneath `dir` func headerGlobPattern(dir string) string { return filepath.Join(dir, "**", "*.h") } func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { if String(m.properties.License) == "" { ctx.PropertyErrorf("license", "field is required") Loading @@ -206,7 +257,7 @@ func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleCo fromSrcPath := android.PathForModuleSrc(ctx, String(m.properties.From)) toOutputPath := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To)) srcFiles := ctx.GlobFiles(filepath.Join(fromSrcPath.String(), "**/*.h"), nil) srcFiles := ctx.GlobFiles(headerGlobPattern(fromSrcPath.String()), nil) var installPaths []android.WritablePath for _, header := range srcFiles { installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To)) Loading @@ -222,6 +273,13 @@ func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleCo processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths) } func (h *versionedHeaderModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { // Glob all .h files under `From` includePattern := headerGlobPattern(proptools.String(h.properties.From)) // Generate `cc_api_headers` target for Multi-tree API export createCcApiHeadersTarget(ctx, []string{includePattern}, []string{}, h.properties.From) } func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path, srcFiles android.Paths, installPaths []android.WritablePath) android.Path { // The versioner depends on a dependencies directory to simplify determining include paths Loading Loading @@ -271,15 +329,18 @@ func versionedNdkHeadersFactory() android.Module { module.AddProperties(&module.properties) android.InitAndroidModule(module) android.InitBazelModule(module) return module } // preprocessed_ndk_header { // // name: "foo", // preprocessor: "foo.sh", // srcs: [...], // to: "android", // // } // // Will invoke the preprocessor as: Loading
cc/ndk_sysroot.go +9 −6 Original line number Diff line number Diff line Loading @@ -57,15 +57,18 @@ import ( ) func init() { android.RegisterModuleType("ndk_headers", ndkHeadersFactory) android.RegisterModuleType("ndk_library", NdkLibraryFactory) android.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory) android.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory) android.RegisterSingletonType("ndk", NdkSingleton) RegisterNdkModuleTypes(android.InitRegistrationContext) pctx.Import("android/soong/android") } func RegisterNdkModuleTypes(ctx android.RegistrationContext) { ctx.RegisterModuleType("ndk_headers", ndkHeadersFactory) ctx.RegisterModuleType("ndk_library", NdkLibraryFactory) ctx.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory) ctx.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory) ctx.RegisterSingletonType("ndk", NdkSingleton) } func getNdkInstallBase(ctx android.PathContext) android.InstallPath { return android.PathForNdkInstall(ctx) } Loading