diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go index b88960e0e..8c33be3c9 100644 --- a/bp2build/cc_prebuilt_library_conversion_test.go +++ b/bp2build/cc_prebuilt_library_conversion_test.go @@ -17,6 +17,7 @@ import ( "fmt" "testing" + "android/soong/android" "android/soong/cc" ) @@ -360,3 +361,52 @@ cc_prebuilt_library { }, }) } + +func TestPrebuiltNdkStlConversion(t *testing.T) { + registerNdkStlModuleTypes := func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("ndk_prebuilt_static_stl", cc.NdkPrebuiltStaticStlFactory) + ctx.RegisterModuleType("ndk_prebuilt_shared_stl", cc.NdkPrebuiltSharedStlFactory) + } + RunBp2BuildTestCase(t, registerNdkStlModuleTypes, Bp2buildTestCase{ + Description: "TODO", + Blueprint: ` +ndk_prebuilt_static_stl { + name: "ndk_libfoo_static", + export_include_dirs: ["dir1", "dir2"], +} +ndk_prebuilt_shared_stl { + name: "ndk_libfoo_shared", + export_include_dirs: ["dir1", "dir2"], +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_static", "ndk_libfoo_static", AttrNameToString{ + "static_library": `select({ + "//build/bazel/platforms/os_arch:android_arm": "current/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libfoo_static.a", + "//build/bazel/platforms/os_arch:android_arm64": "current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libfoo_static.a", + "//build/bazel/platforms/os_arch:android_riscv64": "current/sources/cxx-stl/llvm-libc++/libs/riscv64/libfoo_static.a", + "//build/bazel/platforms/os_arch:android_x86": "current/sources/cxx-stl/llvm-libc++/libs/x86/libfoo_static.a", + "//build/bazel/platforms/os_arch:android_x86_64": "current/sources/cxx-stl/llvm-libc++/libs/x86_64/libfoo_static.a", + "//conditions:default": None, + })`, + "export_system_includes": `[ + "dir1", + "dir2", + ]`, + }), + MakeBazelTarget("cc_prebuilt_library_shared", "ndk_libfoo_shared", AttrNameToString{ + "shared_library": `select({ + "//build/bazel/platforms/os_arch:android_arm": "current/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libfoo_shared.so", + "//build/bazel/platforms/os_arch:android_arm64": "current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libfoo_shared.so", + "//build/bazel/platforms/os_arch:android_riscv64": "current/sources/cxx-stl/llvm-libc++/libs/riscv64/libfoo_shared.so", + "//build/bazel/platforms/os_arch:android_x86": "current/sources/cxx-stl/llvm-libc++/libs/x86/libfoo_shared.so", + "//build/bazel/platforms/os_arch:android_x86_64": "current/sources/cxx-stl/llvm-libc++/libs/x86_64/libfoo_shared.so", + "//conditions:default": None, + })`, + "export_system_includes": `[ + "dir1", + "dir2", + ]`, + }), + }, + }) +} diff --git a/cc/cc.go b/cc/cc.go index 3b92696bc..8d79df24b 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -879,16 +879,16 @@ type Module struct { installer installer bazelHandler BazelHandler - features []feature - stl *stl - sanitize *sanitize - coverage *coverage - fuzzer *fuzzer - sabi *sabi - vndkdep *vndkdep - lto *lto - afdo *afdo - pgo *pgo + features []feature + stl *stl + sanitize *sanitize + coverage *coverage + fuzzer *fuzzer + sabi *sabi + vndkdep *vndkdep + lto *lto + afdo *afdo + pgo *pgo orderfile *orderfile library libraryInterface @@ -1104,6 +1104,16 @@ func (c *Module) CcLibraryInterface() bool { return false } +func (c *Module) IsNdkPrebuiltStl() bool { + if c.linker == nil { + return false + } + if _, ok := c.linker.(*ndkPrebuiltStlLinker); ok { + return true + } + return false +} + func (c *Module) RlibStd() bool { panic(fmt.Errorf("RlibStd called on non-Rust module: %q", c.BaseModuleName())) } @@ -4158,6 +4168,7 @@ const ( headerLibrary testBin // testBinary already declared ndkLibrary + ndkPrebuiltStl ) func (c *Module) typ() moduleType { @@ -4196,6 +4207,8 @@ func (c *Module) typ() moduleType { return sharedLibrary } else if c.isNDKStubLibrary() { return ndkLibrary + } else if c.IsNdkPrebuiltStl() { + return ndkPrebuiltStl } return unknownType } @@ -4240,6 +4253,8 @@ func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } else { sharedOrStaticLibraryBp2Build(ctx, c, false) } + case ndkPrebuiltStl: + ndkPrebuiltStlBp2build(ctx, c) default: ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "") } diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go index d3a0a002e..c2382b33e 100644 --- a/cc/ndk_prebuilt.go +++ b/cc/ndk_prebuilt.go @@ -15,9 +15,11 @@ package cc import ( + "path/filepath" "strings" "android/soong/android" + "android/soong/bazel" ) func init() { @@ -64,6 +66,7 @@ func NdkPrebuiltSharedStlFactory() android.Module { module.Properties.Sdk_version = StringPtr("minimum") module.Properties.AlwaysSdk = true module.stl.Properties.Stl = StringPtr("none") + module.bazelable = true return module.Init() } @@ -84,12 +87,16 @@ func NdkPrebuiltStaticStlFactory() android.Module { module.Properties.AlwaysSdk = true module.Properties.Sdk_version = StringPtr("current") module.stl.Properties.Stl = StringPtr("none") + module.bazelable = true return module.Init() } +const ( + libDir = "current/sources/cxx-stl/llvm-libc++/libs" +) + func getNdkStlLibDir(ctx android.ModuleContext) android.SourcePath { - libDir := "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs" - return android.PathForSource(ctx, libDir).Join(ctx, ctx.Arch().Abi[0]) + return android.PathForSource(ctx, ctx.ModuleDir(), libDir).Join(ctx, ctx.Arch().Abi[0]) } func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags, @@ -128,3 +135,81 @@ func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags, return lib } + +var ( + archToAbiDirMap = map[string]string{ + "android_arm": "armeabi-v7a", + "android_arm64": "arm64-v8a", + "android_riscv64": "riscv64", + "android_x86": "x86", + "android_x86_64": "x86_64", + } +) + +// stlSrcBp2build returns a bazel label for the checked-in .so/.a file +// It contains a select statement for each ABI +func stlSrcBp2build(ctx android.TopDownMutatorContext, c *Module) bazel.LabelAttribute { + libName := strings.TrimPrefix(c.Name(), "ndk_") + libExt := ".so" // TODO - b/201079053: Support windows + if ctx.ModuleType() == "ndk_prebuilt_static_stl" { + libExt = ".a" + } + src := bazel.LabelAttribute{} + for arch, abiDir := range archToAbiDirMap { + srcPath := filepath.Join(libDir, abiDir, libName+libExt) + src.SetSelectValue( + bazel.OsArchConfigurationAxis, + arch, + android.BazelLabelForModuleSrcSingle(ctx, srcPath), + ) + } + return src +} + +// stlIncludesBp2build returns the includes exported by the STL +func stlIncludesBp2build(c *Module) bazel.StringListAttribute { + linker, _ := c.linker.(*ndkPrebuiltStlLinker) + includeDirs := append( + []string{}, + linker.libraryDecorator.flagExporter.Properties.Export_include_dirs..., + ) + includeDirs = append( + includeDirs, + linker.libraryDecorator.flagExporter.Properties.Export_system_include_dirs..., + ) + return bazel.MakeStringListAttribute(android.FirstUniqueStrings(includeDirs)) +} + +func ndkPrebuiltStlBp2build(ctx android.TopDownMutatorContext, c *Module) { + if ctx.ModuleType() == "ndk_prebuilt_static_stl" { + ndkPrebuiltStaticStlBp2build(ctx, c) + } else { + ndkPrebuiltSharedStlBp2build(ctx, c) + } +} + +func ndkPrebuiltStaticStlBp2build(ctx android.TopDownMutatorContext, c *Module) { + props := bazel.BazelTargetModuleProperties{ + Rule_class: "cc_prebuilt_library_static", + Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_static.bzl", + } + attrs := &bazelPrebuiltLibraryStaticAttributes{ + Static_library: stlSrcBp2build(ctx, c), + Export_system_includes: stlIncludesBp2build(c), // The exports are always as system + } + // TODO: min_sdk_version + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: c.Name()}, attrs) +} + +func ndkPrebuiltSharedStlBp2build(ctx android.TopDownMutatorContext, c *Module) { + props := bazel.BazelTargetModuleProperties{ + Rule_class: "cc_prebuilt_library_shared", + Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_shared.bzl", + } + attrs := &bazelPrebuiltLibrarySharedAttributes{ + Shared_library: stlSrcBp2build(ctx, c), + Export_system_includes: stlIncludesBp2build(c), // The exports are always as system + } + // TODO: min_sdk_version + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: c.Name()}, attrs) +} diff --git a/cc/testing.go b/cc/testing.go index d1632aaa6..24d6b0f5f 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -558,7 +558,7 @@ var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers( // This includes files that are needed by all, or at least most, instances of a cc module type. android.MockFS{ // Needed for ndk_prebuilt_(shared|static)_stl. - "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs": nil, + "defaults/cc/common/current/sources/cxx-stl/llvm-libc++/libs": nil, }.AddToFixture(), )