diff options
74 files changed, 1775 insertions, 1408 deletions
diff --git a/android/arch.go b/android/arch.go index 3cc5e8228..e08fd5c0a 100644 --- a/android/arch.go +++ b/android/arch.go @@ -168,7 +168,7 @@ func newArch(name, multilib string) ArchType { return archType } -// ArchTypeList returns the a slice copy of the 4 supported ArchTypes for arm, +// ArchTypeList returns a slice copy of the 4 supported ArchTypes for arm, // arm64, x86 and x86_64. func ArchTypeList() []ArchType { return append([]ArchType(nil), archTypeList...) @@ -408,7 +408,7 @@ func bp2buildArchPathDepsMutator(ctx BottomUpMutatorContext) { // addPathDepsForProps does not descend into sub structs, so we need to descend into the // arch-specific properties ourselves - properties := []interface{}{} + var properties []interface{} for _, archProperties := range m.archProperties { for _, archProps := range archProperties { archPropValues := reflect.ValueOf(archProps).Elem() @@ -995,8 +995,11 @@ func initArchModule(m Module) { // Store the original list of top level property structs base.generalProperties = m.GetProperties() + if len(base.archProperties) != 0 { + panic(fmt.Errorf("module %s already has archProperties", m.Name())) + } - for _, properties := range base.generalProperties { + getStructType := func(properties interface{}) reflect.Type { propertiesValue := reflect.ValueOf(properties) t := propertiesValue.Type() if propertiesValue.Kind() != reflect.Ptr { @@ -1006,10 +1009,14 @@ func initArchModule(m Module) { propertiesValue = propertiesValue.Elem() if propertiesValue.Kind() != reflect.Struct { - panic(fmt.Errorf("properties must be a pointer to a struct, got %T", + panic(fmt.Errorf("properties must be a pointer to a struct, got a pointer to %T", propertiesValue.Interface())) } + return t + } + for _, properties := range base.generalProperties { + t := getStructType(properties) // Get or create the arch-specific property struct types for this property struct type. archPropTypes := archPropTypeMap.Once(NewCustomOnceKey(t), func() interface{} { return createArchPropTypeDesc(t) diff --git a/android/bazel.go b/android/bazel.go index 169f6ba29..4114f37a3 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -15,6 +15,8 @@ package android import ( + "bufio" + "errors" "fmt" "io/ioutil" "path/filepath" @@ -39,6 +41,10 @@ type bazelModuleProperties struct { // To opt-out a module, set bazel_module: { bp2build_available: false } // To defer the default setting for the directory, do not set the value. Bp2build_available *bool + + // CanConvertToBazel is set via InitBazelModule to indicate that a module type can be converted to + // Bazel with Bp2build. + CanConvertToBazel bool `blueprint:"mutated"` } // Properties contains common module properties for Bazel migration purposes. @@ -80,9 +86,10 @@ type Bazelable interface { HasHandcraftedLabel() bool HandcraftedLabel() string GetBazelLabel(ctx BazelConversionPathContext, module blueprint.Module) string - ConvertWithBp2build(ctx BazelConversionContext) bool - convertWithBp2build(ctx BazelConversionContext, module blueprint.Module) bool + ShouldConvertWithBp2build(ctx BazelConversionContext) bool + shouldConvertWithBp2build(ctx BazelConversionContext, module blueprint.Module) bool GetBazelBuildFileContents(c Config, path, name string) (string, error) + ConvertWithBp2build(ctx TopDownMutatorContext) // namespacedVariableProps is a map from a soong config variable namespace // (e.g. acme, android) to a map of interfaces{}, which are really @@ -109,6 +116,7 @@ type BazelModule interface { // properties. func InitBazelModule(module BazelModule) { module.AddProperties(module.bazelProps()) + module.bazelProps().Bazel_module.CanConvertToBazel = true } // bazelProps returns the Bazel properties for the given BazelModuleBase. @@ -147,7 +155,7 @@ func (b *BazelModuleBase) GetBazelLabel(ctx BazelConversionPathContext, module b if b.HasHandcraftedLabel() { return b.HandcraftedLabel() } - if b.ConvertWithBp2build(ctx) { + if b.ShouldConvertWithBp2build(ctx) { return bp2buildModuleLabel(ctx, module) } return "" // no label for unconverted module @@ -200,7 +208,8 @@ var ( "build/bazel/platforms":/* recursive = */ true, "build/bazel/product_variables":/* recursive = */ true, "build/bazel_common_rules":/* recursive = */ true, - "build/make/tools":/* recursive = */ true, + // build/make/tools/signapk BUILD file is generated, so build/make/tools is not recursive. + "build/make/tools":/* recursive = */ false, "build/pesto":/* recursive = */ true, // external/bazelbuild-rules_android/... is needed by mixed builds, otherwise mixed builds analysis fails @@ -231,6 +240,7 @@ var ( "bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue, "build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively, "build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively, + "build/make/tools/signapk": Bp2BuildDefaultTrue, "build/soong": Bp2BuildDefaultTrue, "build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir "build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue, @@ -273,7 +283,9 @@ var ( "development/sdk": Bp2BuildDefaultTrueRecursively, "external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively, "external/boringssl": Bp2BuildDefaultTrueRecursively, + "external/bouncycastle": Bp2BuildDefaultTrue, "external/brotli": Bp2BuildDefaultTrue, + "external/conscrypt": Bp2BuildDefaultTrue, "external/fmtlib": Bp2BuildDefaultTrueRecursively, "external/google-benchmark": Bp2BuildDefaultTrueRecursively, "external/googletest": Bp2BuildDefaultTrueRecursively, @@ -321,7 +333,7 @@ var ( "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultTrue, "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, "system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures - "system/core/debuggerd": Bp2BuildDefaultTrue, + "system/core/debuggerd": Bp2BuildDefaultTrueRecursively, "system/core/diagnose_usb": Bp2BuildDefaultTrueRecursively, "system/core/libasyncio": Bp2BuildDefaultTrue, "system/core/libcrypto_utils": Bp2BuildDefaultTrueRecursively, @@ -343,6 +355,8 @@ var ( "system/timezone/output_data": Bp2BuildDefaultTrueRecursively, "system/unwinding/libbacktrace": Bp2BuildDefaultTrueRecursively, "system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively, + "tools/apksig": Bp2BuildDefaultTrue, + "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, } // Per-module denylist to always opt modules out of both bp2build and mixed builds. @@ -380,9 +394,13 @@ var ( "libbacktrace", // depends on unconverted module libunwindstack "libdebuggerd_handler", // depends on unconverted module libdebuggerd_handler_core "libdebuggerd_handler_core", "libdebuggerd_handler_fallback", // depends on unconverted module libdebuggerd - "unwind_for_offline", // depends on unconverted module libunwindstack_utils - "libdebuggerd", // depends on unconverted modules libdexfile_support, libunwindstack, gwp_asan_crash_handler, libtombstone_proto, libprotobuf-cpp-lite - "libdexfile_static", // depends on libartpalette, libartbase, libdexfile, which are of unsupported type: art_cc_library. + "unwind_for_offline", // depends on unconverted module libunwindstack_utils + "libdebuggerd", // depends on unconverted modules libdexfile_support, libunwindstack, gwp_asan_crash_handler, libtombstone_proto, libprotobuf-cpp-lite + "libdexfile_static", // depends on libartpalette, libartbase, libdexfile, which are of unsupported type: art_cc_library. + + "crasher", // depends on unconverted modules: libseccomp_policy + "static_crasher", // depends on unconverted modules: libdebuggerd_handler, libseccomp_policy + "host_bionic_linker_asm", // depends on extract_linker, a go binary. "host_bionic_linker_script", // depends on extract_linker, a go binary. @@ -395,11 +413,12 @@ var ( "libbase_ndk", // http://b/186826477, fails to link libctscamera2_jni for device (required for CtsCameraTestCases) - "lib_linker_config_proto_lite", // contains .proto sources - "libprotobuf-python", // contains .proto sources - "libprotobuf-internal-protos", // we don't handle path property for fileegroups - "libprotobuf-internal-python-srcs", // we don't handle path property for fileegroups + "libprotobuf-internal-protos", // b/210751803, we don't handle path property for filegroups + "libprotobuf-internal-python-srcs", // b/210751803, we don't handle path property for filegroups + "libprotobuf-java-full", // b/210751803, we don't handle path property for filegroups + "libprotobuf-java-util-full", // b/210751803, we don't handle path property for filegroups + "conscrypt", // b/210751803, we don't handle path property for filegroups "libseccomp_policy", // b/201094425: depends on func_to_syscall_nrs, which depends on py_binary, which is unsupported in mixed builds. "libfdtrack", // depends on unconverted module libunwindstack @@ -422,17 +441,11 @@ var ( // APEX support "com.android.runtime", // http://b/194746715, apex, depends on 'libc_malloc_debug' - "libadbd_core", // http://b/208481704: requijres use_version_lib - "libadbd_services", // http://b/208481704: requires use_version_lib - - "libadbd", // depends on unconverted modules: libadbd_core, libadbd_services - "libgtest_ndk_c++", // b/201816222: Requires sdk_version support. "libgtest_main_ndk_c++", // b/201816222: Requires sdk_version support. - "abb", // depends on unconverted modules: libadbd_core, libadbd_services, - "adb", // depends on unconverted modules: bin2c_fastdeployagent, libadb_crypto, libadb_host, libadb_pairing_connection, libadb_protos, libandroidfw, libapp_processes_protos_full, libfastdeploy_host, libopenscreen-discovery, libopenscreen-platform-impl, libusb, libzstd, AdbWinApi - "adbd", // depends on unconverted modules: libadb_crypto, libadb_pairing_connection, libadb_protos, libadbd, libadbd_core, libapp_processes_protos_lite, libzstd, libadbd_services, libcap, libminijail + "abb", // depends on unconverted modules: libcmd, libbinder + "adb", // depends on unconverted modules: AdbWinApi, libadb_host, libandroidfw, libapp_processes_protos_full, libfastdeploy_host, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi "linker", // depends on unconverted modules: libdebuggerd_handler_fallback "linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_* "versioner", // depends on unconverted modules: libclang_cxx_host, libLLVM_host, of unsupported type llvm_host_prebuilt_library_shared @@ -442,6 +455,9 @@ var ( "acvp_modulewrapper", // disabled for android x86/x86_64 "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib + + "libdexfile", // depends on unconverted modules: dexfile_operator_srcs, libartbase, libartpalette, + "libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette } // Per-module denylist of cc_library modules to only generate the static @@ -536,32 +552,21 @@ func convertedToBazel(ctx BazelConversionContext, module blueprint.Module) bool if !ok { return false } - return b.convertWithBp2build(ctx, module) || b.HasHandcraftedLabel() + return b.shouldConvertWithBp2build(ctx, module) || b.HasHandcraftedLabel() } -// ConvertWithBp2build returns whether the given BazelModuleBase should be converted with bp2build. -func (b *BazelModuleBase) ConvertWithBp2build(ctx BazelConversionContext) bool { - return b.convertWithBp2build(ctx, ctx.Module()) +// ShouldConvertWithBp2build returns whether the given BazelModuleBase should be converted with bp2build. +func (b *BazelModuleBase) ShouldConvertWithBp2build(ctx BazelConversionContext) bool { + return b.shouldConvertWithBp2build(ctx, ctx.Module()) } -func (b *BazelModuleBase) convertWithBp2build(ctx BazelConversionContext, module blueprint.Module) bool { +func (b *BazelModuleBase) shouldConvertWithBp2build(ctx BazelConversionContext, module blueprint.Module) bool { if bp2buildModuleDoNotConvert[module.Name()] { return false } - // Ensure that the module type of this module has a bp2build converter. This - // prevents mixed builds from using auto-converted modules just by matching - // the package dir; it also has to have a bp2build mutator as well. - if ctx.Config().bp2buildModuleTypeConfig[ctx.OtherModuleType(module)] == false { - if b, ok := module.(Bazelable); ok && b.BaseModuleType() != "" { - // For modules with custom types from soong_config_module_types, - // check that their _base module type_ has a bp2build mutator. - if ctx.Config().bp2buildModuleTypeConfig[b.BaseModuleType()] == false { - return false - } - } else { - return false - } + if !b.bazelProps().Bazel_module.CanConvertToBazel { + return false } packagePath := ctx.OtherModuleDir(module) @@ -635,3 +640,35 @@ func (b *BazelModuleBase) GetBazelBuildFileContents(c Config, path, name string) } return string(data[:]), nil } + +func registerBp2buildConversionMutator(ctx RegisterMutatorsContext) { + ctx.TopDown("bp2build_conversion", convertWithBp2build).Parallel() +} + +func convertWithBp2build(ctx TopDownMutatorContext) { + bModule, ok := ctx.Module().(Bazelable) + if !ok || !bModule.shouldConvertWithBp2build(ctx, ctx.Module()) { + return + } + + bModule.ConvertWithBp2build(ctx) +} + +// GetMainClassInManifest scans the manifest file specified in filepath and returns +// the value of attribute Main-Class in the manifest file if it exists, or returns error. +// WARNING: this is for bp2build converters of java_* modules only. +func GetMainClassInManifest(c Config, filepath string) (string, error) { + file, err := c.fs.Open(filepath) + if err != nil { + return "", err + } + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "Main-Class:") { + return strings.TrimSpace(line[len("Main-Class:"):]), nil + } + } + + return "", errors.New("Main-Class is not found.") +} diff --git a/android/config.go b/android/config.go index 3ce59b2b0..5d90fd21d 100644 --- a/android/config.go +++ b/android/config.go @@ -157,7 +157,6 @@ type config struct { runningAsBp2Build bool bp2buildPackageConfig Bp2BuildConfig - bp2buildModuleTypeConfig map[string]bool Bp2buildSoongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions // If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error @@ -353,8 +352,6 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string config.mockFileSystem(bp, fs) - config.bp2buildModuleTypeConfig = map[string]bool{} - determineBuildOS(config) return Config{config} @@ -522,7 +519,6 @@ func NewConfig(moduleListFile string, runGoTests bool, outDir, soongOutDir strin config.BazelContext, err = NewBazelContext(config) config.bp2buildPackageConfig = bp2buildDefaultConfig - config.bp2buildModuleTypeConfig = make(map[string]bool) return Config{config}, err } diff --git a/android/deapexer.go b/android/deapexer.go index bed657464..265f5312b 100644 --- a/android/deapexer.go +++ b/android/deapexer.go @@ -143,12 +143,16 @@ type RequiresFilesFromPrebuiltApexTag interface { } // FindDeapexerProviderForModule searches through the direct dependencies of the current context -// module for a DeapexerTag dependency and returns its DeapexerInfo. If there is an error then it is -// reported with ctx.ModuleErrorf and nil is returned. +// module for a DeapexerTag dependency and returns its DeapexerInfo. If a single nonambiguous +// deapexer module isn't found then errors are reported with ctx.ModuleErrorf and nil is returned. func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo { var di *DeapexerInfo ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) { p := ctx.OtherModuleProvider(m, DeapexerProvider).(DeapexerInfo) + if di != nil { + ctx.ModuleErrorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s", + di.ApexModuleName(), p.ApexModuleName()) + } di = &p }) if di != nil { diff --git a/android/defaults.go b/android/defaults.go index d2b351d04..0953f9505 100644 --- a/android/defaults.go +++ b/android/defaults.go @@ -173,6 +173,10 @@ func (d *DefaultsModuleBase) productVariableProperties() interface{} { func (d *DefaultsModuleBase) GenerateAndroidBuildActions(ctx ModuleContext) { } +// ConvertWithBp2build to fulfill Bazelable interface; however, at this time defaults module are +// *NOT* converted with bp2build +func (defaultable *DefaultsModuleBase) ConvertWithBp2build(ctx TopDownMutatorContext) {} + func InitDefaultsModule(module DefaultsModule) { commonProperties := &commonProperties{} @@ -208,7 +212,6 @@ func InitDefaultsModule(module DefaultsModule) { // The applicable licenses property for defaults is 'licenses'. setPrimaryLicensesProperty(module, "licenses", &commonProperties.Licenses) - base.module = module } var _ Defaults = (*DefaultsModuleBase)(nil) diff --git a/android/filegroup.go b/android/filegroup.go index a79374d1f..c932ffad2 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -22,7 +22,6 @@ import ( func init() { RegisterModuleType("filegroup", FileGroupFactory) - RegisterBp2BuildMutator("filegroup", FilegroupBp2Build) } var PrepareForTestWithFilegroup = FixtureRegisterWithContext(func(ctx RegistrationContext) { @@ -34,12 +33,8 @@ type bazelFilegroupAttributes struct { Srcs bazel.LabelListAttribute } -func FilegroupBp2Build(ctx TopDownMutatorContext) { - fg, ok := ctx.Module().(*fileGroup) - if !ok || !fg.ConvertWithBp2build(ctx) { - return - } - +// ConvertWithBp2build performs bp2build conversion of filegroup +func (fg *fileGroup) ConvertWithBp2build(ctx TopDownMutatorContext) { srcs := bazel.MakeLabelListAttribute( BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs)) diff --git a/android/module.go b/android/module.go index 6c7fc6505..c479b596b 100644 --- a/android/module.go +++ b/android/module.go @@ -1290,7 +1290,7 @@ func (b *baseModuleContext) AddUnconvertedBp2buildDep(dep string) { // GetUnconvertedBp2buildDeps returns the list of module names of this module's direct dependencies that // were not converted to Bazel. func (m *ModuleBase) GetUnconvertedBp2buildDeps() []string { - return m.commonProperties.UnconvertedBp2buildDeps + return FirstUniqueStrings(m.commonProperties.UnconvertedBp2buildDeps) } func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { @@ -2096,18 +2096,18 @@ func (e *earlyModuleContext) GlobFiles(globPattern string, excludes []string) Pa return GlobFiles(e, globPattern, excludes) } -func (b *earlyModuleContext) IsSymlink(path Path) bool { - fileInfo, err := b.config.fs.Lstat(path.String()) +func (e *earlyModuleContext) IsSymlink(path Path) bool { + fileInfo, err := e.config.fs.Lstat(path.String()) if err != nil { - b.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err) + e.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err) } return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink } -func (b *earlyModuleContext) Readlink(path Path) string { - dest, err := b.config.fs.Readlink(path.String()) +func (e *earlyModuleContext) Readlink(path Path) string { + dest, err := e.config.fs.Readlink(path.String()) if err != nil { - b.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err) + e.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err) } return dest } diff --git a/android/mutator.go b/android/mutator.go index bf1cf806e..dbd8c04db 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -16,7 +16,6 @@ package android import ( "reflect" - "sync" "android/soong/bazel" @@ -34,12 +33,12 @@ import ( // continue on to GenerateAndroidBuildActions // RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing. -func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators, bp2buildMutators []RegisterMutatorFunc) { +func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators []RegisterMutatorFunc) { mctx := ®isterMutatorsContext{ bazelConversionMode: true, } - bp2buildPreArchMutators = append([]RegisterMutatorFunc{ + bp2buildMutators := append([]RegisterMutatorFunc{ RegisterNamespaceMutator, RegisterDefaultsPreArchMutators, // TODO(b/165114590): this is required to resolve deps that are only prebuilts, but we should @@ -47,10 +46,7 @@ func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators, bp2buildM RegisterPrebuiltsPreArchMutators, }, preArchMutators...) - - for _, f := range bp2buildPreArchMutators { - f(mctx) - } + bp2buildMutators = append(bp2buildMutators, registerBp2buildConversionMutator) // Register bp2build mutators for _, f := range bp2buildMutators { @@ -216,10 +212,6 @@ func FinalDepsMutators(f RegisterMutatorFunc) { } var bp2buildPreArchMutators = []RegisterMutatorFunc{} -var bp2buildMutators = map[string]RegisterMutatorFunc{} - -// See http://b/192523357 -var bp2buildLock sync.Mutex // A minimal context for Bp2build conversion type Bp2buildMutatorContext interface { @@ -228,21 +220,6 @@ type Bp2buildMutatorContext interface { CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}) } -// RegisterBp2BuildMutator registers specially crafted mutators for -// converting Blueprint/Android modules into special modules that can -// be code-generated into Bazel BUILD targets. -// -// TODO(b/178068862): bring this into TestContext. -func RegisterBp2BuildMutator(moduleType string, m func(TopDownMutatorContext)) { - f := func(ctx RegisterMutatorsContext) { - ctx.TopDown(moduleType, m) - } - // Use a lock to avoid a concurrent map write if RegisterBp2BuildMutator is called in parallel - bp2buildLock.Lock() - defer bp2buildLock.Unlock() - bp2buildMutators[moduleType] = f -} - // PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules // into Bazel BUILD targets that should run prior to deps and conversion. func PreArchBp2BuildMutators(f RegisterMutatorFunc) { diff --git a/android/package_test.go b/android/package_test.go index 7ea10a4da..65c424013 100644 --- a/android/package_test.go +++ b/android/package_test.go @@ -11,7 +11,7 @@ var packageTests = []struct { }{ // Package default_visibility handling is tested in visibility_test.go { - name: "package must not accept visibility and name properties", + name: "package must not accept visibility, name or licenses properties", fs: map[string][]byte{ "top/Android.bp": []byte(` package { @@ -48,8 +48,7 @@ var packageTests = []struct { default_visibility: ["//visibility:private"], default_applicable_licenses: ["license"], } - - package { + package { }`), }, expectedErrors: []string{ diff --git a/android/register.go b/android/register.go index 424439806..1ac44402d 100644 --- a/android/register.go +++ b/android/register.go @@ -178,13 +178,7 @@ func (ctx *Context) RegisterForBazelConversion() { t.register(ctx) } - bp2buildMutatorList := []RegisterMutatorFunc{} - for t, f := range bp2buildMutators { - ctx.config.bp2buildModuleTypeConfig[t] = true - bp2buildMutatorList = append(bp2buildMutatorList, f) - } - - RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators, bp2buildMutatorList) + RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators) } // Register the pipeline of singletons, module types, and mutators for @@ -196,15 +190,6 @@ func (ctx *Context) Register() { t.register(ctx) } - if ctx.config.BazelContext.BazelEnabled() { - // Hydrate the configuration of bp2build-enabled module types. This is - // required as a signal to identify which modules should be deferred to - // Bazel in mixed builds, if it is enabled. - for t, _ := range bp2buildMutators { - ctx.config.bp2buildModuleTypeConfig[t] = true - } - } - mutators := collateGloballyRegisteredMutators() mutators.registerAll(ctx) diff --git a/android/testing.go b/android/testing.go index 6290d4317..8daf6b783 100644 --- a/android/testing.go +++ b/android/testing.go @@ -208,16 +208,6 @@ func (ctx *TestContext) RegisterBp2BuildConfig(config Bp2BuildConfig) { ctx.config.bp2buildPackageConfig = config } -// RegisterBp2BuildMutator registers a BazelTargetModule mutator for converting a module -// type to the equivalent Bazel target. -func (ctx *TestContext) RegisterBp2BuildMutator(moduleType string, m func(TopDownMutatorContext)) { - f := func(ctx RegisterMutatorsContext) { - ctx.TopDown(moduleType, m) - } - ctx.config.bp2buildModuleTypeConfig[moduleType] = true - ctx.bp2buildMutators = append(ctx.bp2buildMutators, f) -} - // PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules // into Bazel BUILD targets that should run prior to deps and conversion. func (ctx *TestContext) PreArchBp2BuildMutators(f RegisterMutatorFunc) { @@ -459,7 +449,7 @@ func (ctx *TestContext) Register() { // RegisterForBazelConversion prepares a test context for bp2build conversion. func (ctx *TestContext) RegisterForBazelConversion() { ctx.SetRunningAsBp2build() - RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch, ctx.bp2buildMutators) + RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch) } func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) { diff --git a/apex/apex.go b/apex/apex.go index 0a785f3d0..b7faa5b98 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -54,8 +54,6 @@ func registerApexBuildComponents(ctx android.RegistrationContext) { ctx.PreArchMutators(registerPreArchMutators) ctx.PreDepsMutators(RegisterPreDepsMutators) ctx.PostDepsMutators(RegisterPostDepsMutators) - - android.RegisterBp2BuildMutator("apex", ApexBundleBp2Build) } func registerPreArchMutators(ctx android.RegisterMutatorsContext) { @@ -98,6 +96,14 @@ type apexBundleProperties struct { // /system/sepolicy/apex/<module_name>_file_contexts. File_contexts *string `android:"path"` + // Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The + // format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a + // path or glob pattern for a file or set of files, uid/gid are numerial values of user ID + // and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the + // capability. If this property is not set, or a file is missing in the file, default config + // is used. + Canned_fs_config *string `android:"path"` + ApexNativeDependencies Multilib apexMultilibProperties @@ -3270,76 +3276,66 @@ type bazelApexBundleAttributes struct { Updatable bazel.BoolAttribute Installable bazel.BoolAttribute Native_shared_libs bazel.LabelListAttribute - Binaries bazel.StringListAttribute + Binaries bazel.LabelListAttribute Prebuilts bazel.LabelListAttribute } -func ApexBundleBp2Build(ctx android.TopDownMutatorContext) { - module, ok := ctx.Module().(*apexBundle) - if !ok { - // Not an APEX bundle - return - } - if !module.ConvertWithBp2build(ctx) { - return - } +// ConvertWithBp2build performs bp2build conversion of an apex +func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + // We do not convert apex_test modules at this time if ctx.ModuleType() != "apex" { return } - apexBundleBp2BuildInternal(ctx, module) -} - -func apexBundleBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexBundle) { var manifestLabelAttribute bazel.LabelAttribute - if module.properties.Manifest != nil { - manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.Manifest)) + if a.properties.Manifest != nil { + manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.Manifest)) } var androidManifestLabelAttribute bazel.LabelAttribute - if module.properties.AndroidManifest != nil { - androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.AndroidManifest)) + if a.properties.AndroidManifest != nil { + androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.AndroidManifest)) } var fileContextsLabelAttribute bazel.LabelAttribute - if module.properties.File_contexts != nil { - fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.properties.File_contexts)) + if a.properties.File_contexts != nil { + fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts)) } var minSdkVersion *string - if module.properties.Min_sdk_version != nil { - minSdkVersion = module.properties.Min_sdk_version + if a.properties.Min_sdk_version != nil { + minSdkVersion = a.properties.Min_sdk_version } var keyLabelAttribute bazel.LabelAttribute - if module.overridableProperties.Key != nil { - keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.overridableProperties.Key)) + if a.overridableProperties.Key != nil { + keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key)) } var certificateLabelAttribute bazel.LabelAttribute - if module.overridableProperties.Certificate != nil { - certificateLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.overridableProperties.Certificate)) + if a.overridableProperties.Certificate != nil { + certificateLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Certificate)) } - nativeSharedLibs := module.properties.ApexNativeDependencies.Native_shared_libs + nativeSharedLibs := a.properties.ApexNativeDependencies.Native_shared_libs nativeSharedLibsLabelList := android.BazelLabelForModuleDeps(ctx, nativeSharedLibs) nativeSharedLibsLabelListAttribute := bazel.MakeLabelListAttribute(nativeSharedLibsLabelList) - prebuilts := module.overridableProperties.Prebuilts + prebuilts := a.overridableProperties.Prebuilts prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts) prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList) - binaries := module.properties.ApexNativeDependencies.Binaries - binariesStringListAttribute := bazel.MakeStringListAttribute(binaries) + binaries := android.BazelLabelForModuleDeps(ctx, a.properties.ApexNativeDependencies.Binaries) + binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries) var updatableAttribute bazel.BoolAttribute - if module.properties.Updatable != nil { - updatableAttribute.Value = module.properties.Updatable + if a.properties.Updatable != nil { + updatableAttribute.Value = a.properties.Updatable } var installableAttribute bazel.BoolAttribute - if module.properties.Installable != nil { - installableAttribute.Value = module.properties.Installable + if a.properties.Installable != nil { + installableAttribute.Value = a.properties.Installable } attrs := &bazelApexBundleAttributes{ @@ -3352,7 +3348,7 @@ func apexBundleBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexB Updatable: updatableAttribute, Installable: installableAttribute, Native_shared_libs: nativeSharedLibsLabelListAttribute, - Binaries: binariesStringListAttribute, + Binaries: binariesLabelListAttribute, Prebuilts: prebuiltsLabelListAttribute, } @@ -3361,5 +3357,5 @@ func apexBundleBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexB Bzl_load_location: "//build/bazel/rules:apex.bzl", } - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs) + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs) } diff --git a/apex/apex_test.go b/apex/apex_test.go index 3cc312dbd..a749ea161 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -2581,22 +2581,21 @@ func TestFilesInSubDir(t *testing.T) { `) generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("generateFsConfig") - dirs := strings.Split(generateFsRule.Args["exec_paths"], " ") + cmd := generateFsRule.RuleParams.Command // Ensure that the subdirectories are all listed - ensureListContains(t, dirs, "etc") - ensureListContains(t, dirs, "etc/foo") - ensureListContains(t, dirs, "etc/foo/bar") - ensureListContains(t, dirs, "lib64") - ensureListContains(t, dirs, "lib64/foo") - ensureListContains(t, dirs, "lib64/foo/bar") - ensureListContains(t, dirs, "lib") - ensureListContains(t, dirs, "lib/foo") - ensureListContains(t, dirs, "lib/foo/bar") - - ensureListContains(t, dirs, "bin") - ensureListContains(t, dirs, "bin/foo") - ensureListContains(t, dirs, "bin/foo/bar") + ensureContains(t, cmd, "/etc ") + ensureContains(t, cmd, "/etc/foo ") + ensureContains(t, cmd, "/etc/foo/bar ") + ensureContains(t, cmd, "/lib64 ") + ensureContains(t, cmd, "/lib64/foo ") + ensureContains(t, cmd, "/lib64/foo/bar ") + ensureContains(t, cmd, "/lib ") + ensureContains(t, cmd, "/lib/foo ") + ensureContains(t, cmd, "/lib/foo/bar ") + ensureContains(t, cmd, "/bin ") + ensureContains(t, cmd, "/bin/foo ") + ensureContains(t, cmd, "/bin/foo/bar ") } func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) { @@ -7045,6 +7044,75 @@ func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.F return result.TestContext } +func TestDuplicateDeapexeresFromPrebuiltApexes(t *testing.T) { + preparers := android.GroupFixturePreparers( + java.PrepareForTestWithJavaDefaultModules, + PrepareForTestWithApexBuildComponents, + ). + ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( + "Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.myapex and com.mycompany.android.myapex")) + + bpBase := ` + apex_set { + name: "com.android.myapex", + installable: true, + exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], + set: "myapex.apks", + } + + apex_set { + name: "com.mycompany.android.myapex", + apex_name: "com.android.myapex", + installable: true, + exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], + set: "company-myapex.apks", + } + + prebuilt_bootclasspath_fragment { + name: "my-bootclasspath-fragment", + apex_available: ["com.android.myapex"], + %s + } + ` + + t.Run("java_import", func(t *testing.T) { + _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+` + java_import { + name: "libfoo", + jars: ["libfoo.jar"], + apex_available: ["com.android.myapex"], + } + `) + }) + + t.Run("java_sdk_library_import", func(t *testing.T) { + _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+` + java_sdk_library_import { + name: "libfoo", + public: { + jars: ["libbar.jar"], + }, + apex_available: ["com.android.myapex"], + } + `) + }) + + t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) { + _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, ` + image_name: "art", + contents: ["libfoo"], + `)+` + java_sdk_library_import { + name: "libfoo", + public: { + jars: ["libbar.jar"], + }, + apex_available: ["com.android.myapex"], + } + `) + }) +} + func TestUpdatable_should_set_min_sdk_version(t *testing.T) { testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, ` apex { diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index 9e030f10c..7ecf9b20f 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -548,7 +548,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) { } func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { - result := android.GroupFixturePreparers( + preparers := android.GroupFixturePreparers( prepareForTestWithBootclasspathFragment, prepareForTestWithArtApex, @@ -559,7 +559,9 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { // Configure some libraries in the art bootclasspath_fragment. java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"), - ).RunTestWithBp(t, ` + ) + + bp := ` prebuilt_apex { name: "com.android.art", arch: { @@ -605,22 +607,45 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { all_flags: "mybootclasspathfragment/all-flags.csv", }, } - `) - java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{ - `com.android.art.apex.selector`, - `prebuilt_mybootclasspathfragment`, - }) + // A prebuilt apex with the same apex_name that shouldn't interfere when it isn't enabled. + prebuilt_apex { + name: "com.mycompany.android.art", + apex_name: "com.android.art", + %s + src: "com.mycompany.android.art.apex", + exported_bootclasspath_fragments: ["mybootclasspathfragment"], + } + ` - java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_com.android.art", []string{ - `com.android.art.deapexer`, - `dex2oatd`, - `prebuilt_bar`, - `prebuilt_foo`, + t.Run("disabled alternative APEX", func(t *testing.T) { + result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,")) + + java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{ + `com.android.art.apex.selector`, + `prebuilt_mybootclasspathfragment`, + }) + + java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_com.android.art", []string{ + `com.android.art.deapexer`, + `dex2oatd`, + `prebuilt_bar`, + `prebuilt_foo`, + }) + + module := result.ModuleForTests("mybootclasspathfragment", "android_common_com.android.art") + checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo") + + // Check that the right deapexer module was chosen for a boot image. + param := module.Output("out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art") + android.AssertStringDoesContain(t, "didn't find the expected deapexer in the input path", param.Input.String(), "/com.android.art.deapexer") }) - module := result.ModuleForTests("mybootclasspathfragment", "android_common_com.android.art") - checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo") + t.Run("enabled alternative APEX", func(t *testing.T) { + preparers.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( + "Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.art and com.mycompany.android.art")). + RunTestWithBp(t, fmt.Sprintf(bp, "")) + }) } // checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the diff --git a/apex/builder.go b/apex/builder.go index 5910784b2..ea25537ca 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -72,19 +72,6 @@ func init() { } var ( - // Create a canned fs config file where all files and directories are - // by default set to (uid/gid/mode) = (1000/1000/0644) - // TODO(b/113082813) make this configurable using config.fs syntax - generateFsConfig = pctx.StaticRule("generateFsConfig", blueprint.RuleParams{ - Command: `( set -e; echo '/ 1000 1000 0755' ` + - `&& for i in ${ro_paths}; do echo "/$$i 1000 1000 0644"; done ` + - `&& for i in ${exec_paths}; do echo "/$$i 0 2000 0755"; done ` + - `&& ( tr ' ' '\n' <${out}.apklist | for i in ${apk_paths}; do read apk; echo "/$$i 0 2000 0755"; zipinfo -1 $$apk | sed "s:\(.*\):/$$i/\1 1000 1000 0644:"; done ) ) > ${out}`, - Description: "fs_config ${out}", - Rspfile: "$out.apklist", - RspfileContent: "$in", - }, "ro_paths", "exec_paths", "apk_paths") - apexManifestRule = pctx.StaticRule("apexManifestRule", blueprint.RuleParams{ Command: `rm -f $out && ${jsonmodify} $in ` + `-a provideNativeLibs ${provideNativeLibs} ` + @@ -583,55 +570,11 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { // Figure out if need to compress apex. compressionEnabled := ctx.Config().CompressedApex() && proptools.BoolDefault(a.properties.Compressible, false) && !a.testApex && !ctx.Config().UnbundledBuildApps() if apexType == imageApex { + //////////////////////////////////////////////////////////////////////////////////// // Step 2: create canned_fs_config which encodes filemode,uid,gid of each files // in this APEX. The file will be used by apexer in later steps. - // TODO(jiyong): make this as a function - // TODO(jiyong): use the RuleBuilder - var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"} - var executablePaths []string // this also includes dirs - var extractedAppSetPaths android.Paths - var extractedAppSetDirs []string - for _, f := range a.filesInfo { - pathInApex := f.path() - if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") { - executablePaths = append(executablePaths, pathInApex) - for _, d := range f.dataPaths { - readOnlyPaths = append(readOnlyPaths, filepath.Join(f.installDir, d.RelativeInstallPath, d.SrcPath.Rel())) - } - for _, s := range f.symlinks { - executablePaths = append(executablePaths, filepath.Join(f.installDir, s)) - } - } else if f.class == appSet { - extractedAppSetPaths = append(extractedAppSetPaths, f.builtFile) - extractedAppSetDirs = append(extractedAppSetDirs, f.installDir) - } else { - readOnlyPaths = append(readOnlyPaths, pathInApex) - } - dir := f.installDir - for !android.InList(dir, executablePaths) && dir != "" { - executablePaths = append(executablePaths, dir) - dir, _ = filepath.Split(dir) // move up to the parent - if len(dir) > 0 { - // remove trailing slash - dir = dir[:len(dir)-1] - } - } - } - sort.Strings(readOnlyPaths) - sort.Strings(executablePaths) - cannedFsConfig := android.PathForModuleOut(ctx, "canned_fs_config") - ctx.Build(pctx, android.BuildParams{ - Rule: generateFsConfig, - Output: cannedFsConfig, - Description: "generate fs config", - Inputs: extractedAppSetPaths, - Args: map[string]string{ - "ro_paths": strings.Join(readOnlyPaths, " "), - "exec_paths": strings.Join(executablePaths, " "), - "apk_paths": strings.Join(extractedAppSetDirs, " "), - }, - }) + cannedFsConfig := a.buildCannedFsConfig(ctx) implicitInputs = append(implicitInputs, cannedFsConfig) //////////////////////////////////////////////////////////////////////////////////// @@ -1072,3 +1015,65 @@ func (a *apexBundle) buildLintReports(ctx android.ModuleContext) { a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build()) } + +func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath { + var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"} + var executablePaths []string // this also includes dirs + var appSetDirs []string + appSetFiles := make(map[string]android.Path) + for _, f := range a.filesInfo { + pathInApex := f.path() + if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") { + executablePaths = append(executablePaths, pathInApex) + for _, d := range f.dataPaths { + readOnlyPaths = append(readOnlyPaths, filepath.Join(f.installDir, d.RelativeInstallPath, d.SrcPath.Rel())) + } + for _, s := range f.symlinks { + executablePaths = append(executablePaths, filepath.Join(f.installDir, s)) + } + } else if f.class == appSet { + appSetDirs = append(appSetDirs, f.installDir) + appSetFiles[f.installDir] = f.builtFile + } else { + readOnlyPaths = append(readOnlyPaths, pathInApex) + } + dir := f.installDir + for !android.InList(dir, executablePaths) && dir != "" { + executablePaths = append(executablePaths, dir) + dir, _ = filepath.Split(dir) // move up to the parent + if len(dir) > 0 { + // remove trailing slash + dir = dir[:len(dir)-1] + } + } + } + sort.Strings(readOnlyPaths) + sort.Strings(executablePaths) + sort.Strings(appSetDirs) + + cannedFsConfig := android.PathForModuleOut(ctx, "canned_fs_config") + builder := android.NewRuleBuilder(pctx, ctx) + cmd := builder.Command() + cmd.Text("(") + cmd.Text("echo '/ 1000 1000 0755';") + for _, p := range readOnlyPaths { + cmd.Textf("echo '/%s 1000 1000 0644';", p) + } + for _, p := range executablePaths { + cmd.Textf("echo '/%s 0 2000 0755';", p) + } + for _, dir := range appSetDirs { + cmd.Textf("echo '/%s 0 2000 0755';", dir) + file := appSetFiles[dir] + cmd.Text("zipinfo -1").Input(file).Textf(`| sed "s:\(.*\):/%s/\1 1000 1000 0644:";`, dir) + } + // Custom fs_config is "appended" to the last so that entries from the file are preferred + // over default ones set above. + if a.properties.Canned_fs_config != nil { + cmd.Text("cat").Input(android.PathForModuleSrc(ctx, *a.properties.Canned_fs_config)) + } + cmd.Text(")").FlagWithOutput("> ", cannedFsConfig) + builder.Build("generateFsConfig", fmt.Sprintf("Generating canned fs config for %s", a.BaseModuleName())) + + return cannedFsConfig.OutputPath +} diff --git a/apex/key.go b/apex/key.go index 259060f3b..829410ed2 100644 --- a/apex/key.go +++ b/apex/key.go @@ -34,8 +34,6 @@ func init() { func registerApexKeyBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("apex_key", ApexKeyFactory) ctx.RegisterSingletonType("apex_keys_text", apexKeysTextFactory) - - android.RegisterBp2BuildMutator("apex_key", ApexKeyBp2Build) } type apexKey struct { @@ -209,20 +207,9 @@ type bazelApexKeyAttributes struct { Private_key bazel.LabelAttribute } -func ApexKeyBp2Build(ctx android.TopDownMutatorContext) { - module, ok := ctx.Module().(*apexKey) - if !ok { - // Not an APEX key - return - } - if !module.ConvertWithBp2build(ctx) { - return - } - if ctx.ModuleType() != "apex_key" { - return - } - - apexKeyBp2BuildInternal(ctx, module) +// ConvertWithBp2build performs conversion apexKey for bp2build +func (m *apexKey) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + apexKeyBp2BuildInternal(ctx, m) } func apexKeyBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexKey) { diff --git a/apex/vndk.go b/apex/vndk.go index cf525a874..ef3e5e1c5 100644 --- a/apex/vndk.go +++ b/apex/vndk.go @@ -140,21 +140,5 @@ func makeCompatSymlinks(name string, ctx android.ModuleContext, primaryApex bool addSymlink("/apex/com.android.i18n/etc/icu", dir, "icu") } - // TODO(b/124106384): Clean up compat symlinks for ART binaries. - if name == "com.android.art" { - dir := android.PathForModuleInPartitionInstall(ctx, "system", "bin") - addSymlink("/apex/com.android.art/bin/dalvikvm", dir, "dalvikvm") - dex2oat := "dex2oat32" - if ctx.Config().Android64() { - dex2oat = "dex2oat64" - } - addSymlink("/apex/com.android.art/bin/"+dex2oat, dir, "dex2oat") - } else if name == "com.android.art" || strings.HasPrefix(name, "com.android.art.") { - dir := android.PathForModuleInPartitionInstall(ctx, "system", "bin") - symlinks = append(symlinks, - dir.Join(ctx, "dalvikvm"), - dir.Join(ctx, "dex2oat")) - } - return symlinks } diff --git a/bp2build/Android.bp b/bp2build/Android.bp index 9b66354b1..ae0fb11a5 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -19,6 +19,7 @@ bootstrap_go_package { deps: [ "soong-android", "soong-android-soongconfig", + "soong-shared", "soong-apex", "soong-bazel", "soong-cc", @@ -27,18 +28,21 @@ bootstrap_go_package { "soong-genrule", "soong-python", "soong-sh", + "soong-ui-metrics", ], testSrcs: [ "android_app_certificate_conversion_test.go", + "android_app_conversion_test.go", "apex_conversion_test.go", "apex_key_conversion_test.go", "build_conversion_test.go", "bzl_conversion_test.go", + "cc_binary_conversion_test.go", "cc_genrule_conversion_test.go", "cc_library_conversion_test.go", "cc_library_headers_conversion_test.go", - "cc_library_static_conversion_test.go", "cc_library_shared_conversion_test.go", + "cc_library_static_conversion_test.go", "cc_object_conversion_test.go", "conversion_test.go", "filegroup_conversion_test.go", @@ -48,6 +52,7 @@ bootstrap_go_package { "python_binary_conversion_test.go", "python_library_conversion_test.go", "sh_conversion_test.go", + "soong_config_module_type_conversion_test.go", "testing.go", ], pluginFor: [ diff --git a/bp2build/android_app_certificate_conversion_test.go b/bp2build/android_app_certificate_conversion_test.go index 6a53b00da..035a3529e 100644 --- a/bp2build/android_app_certificate_conversion_test.go +++ b/bp2build/android_app_certificate_conversion_test.go @@ -31,11 +31,10 @@ func registerAndroidAppCertificateModuleTypes(ctx android.RegistrationContext) { func TestAndroidAppCertificateSimple(t *testing.T) { runAndroidAppCertificateTestCase(t, bp2buildTestCase{ - description: "Android app certificate - simple example", - moduleTypeUnderTest: "android_app_certificate", - moduleTypeUnderTestFactory: java.AndroidAppCertificateFactory, - moduleTypeUnderTestBp2BuildMutator: java.AndroidAppCertificateBp2Build, - filesystem: map[string]string{}, + description: "Android app certificate - simple example", + moduleTypeUnderTest: "android_app_certificate", + moduleTypeUnderTestFactory: java.AndroidAppCertificateFactory, + filesystem: map[string]string{}, blueprint: ` android_app_certificate { name: "com.android.apogee.cert", diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go index b12b567f3..153817b08 100644 --- a/bp2build/android_app_conversion_test.go +++ b/bp2build/android_app_conversion_test.go @@ -31,10 +31,9 @@ func registerAndroidAppModuleTypes(ctx android.RegistrationContext) { func TestMinimalAndroidApp(t *testing.T) { runAndroidAppTestCase(t, bp2buildTestCase{ - description: "Android app - simple example", - moduleTypeUnderTest: "android_app", - moduleTypeUnderTestFactory: java.AndroidAppFactory, - moduleTypeUnderTestBp2BuildMutator: java.AppBp2Build, + description: "Android app - simple example", + moduleTypeUnderTest: "android_app", + moduleTypeUnderTestFactory: java.AndroidAppFactory, filesystem: map[string]string{ "app.java": "", "res/res.png": "", @@ -58,10 +57,9 @@ android_app { func TestAndroidAppAllSupportedFields(t *testing.T) { runAndroidAppTestCase(t, bp2buildTestCase{ - description: "Android app - all supported fields", - moduleTypeUnderTest: "android_app", - moduleTypeUnderTestFactory: java.AndroidAppFactory, - moduleTypeUnderTestBp2BuildMutator: java.AppBp2Build, + description: "Android app - all supported fields", + moduleTypeUnderTest: "android_app", + moduleTypeUnderTestFactory: java.AndroidAppFactory, filesystem: map[string]string{ "app.java": "", "resa/res.png": "", diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go index 1a23db700..a3825e663 100644 --- a/bp2build/apex_conversion_test.go +++ b/bp2build/apex_conversion_test.go @@ -19,6 +19,7 @@ import ( "android/soong/apex" "android/soong/cc" "android/soong/java" + "android/soong/sh" "testing" ) @@ -32,6 +33,8 @@ func registerApexModuleTypes(ctx android.RegistrationContext) { // CC module types needed as they can be APEX dependencies cc.RegisterCCBuildComponents(ctx) + ctx.RegisterModuleType("sh_binary", sh.ShBinaryFactory) + ctx.RegisterModuleType("cc_binary", cc.BinaryFactory) ctx.RegisterModuleType("cc_library", cc.LibraryFactory) ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory) ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory) @@ -40,60 +43,62 @@ func registerApexModuleTypes(ctx android.RegistrationContext) { func TestApexBundleSimple(t *testing.T) { runApexTestCase(t, bp2buildTestCase{ - description: "apex - simple example", - moduleTypeUnderTest: "apex", - moduleTypeUnderTestFactory: apex.BundleFactory, - moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build, - filesystem: map[string]string{}, + description: "apex - example with all props", + moduleTypeUnderTest: "apex", + moduleTypeUnderTestFactory: apex.BundleFactory, + filesystem: map[string]string{}, blueprint: ` apex_key { - name: "com.android.apogee.key", - public_key: "com.android.apogee.avbpubkey", - private_key: "com.android.apogee.pem", + name: "com.android.apogee.key", + public_key: "com.android.apogee.avbpubkey", + private_key: "com.android.apogee.pem", bazel_module: { bp2build_available: false }, } android_app_certificate { - name: "com.android.apogee.certificate", - certificate: "com.android.apogee", - bazel_module: { bp2build_available: false }, + name: "com.android.apogee.certificate", + certificate: "com.android.apogee", + bazel_module: { bp2build_available: false }, } cc_library { - name: "native_shared_lib_1", + name: "native_shared_lib_1", bazel_module: { bp2build_available: false }, } cc_library { - name: "native_shared_lib_2", + name: "native_shared_lib_2", bazel_module: { bp2build_available: false }, } // TODO(b/194878861): Add bp2build support for prebuilt_etc cc_library { - name: "pretend_prebuilt_1", - bazel_module: { bp2build_available: false }, + name: "pretend_prebuilt_1", + bazel_module: { bp2build_available: false }, } // TODO(b/194878861): Add bp2build support for prebuilt_etc cc_library { - name: "pretend_prebuilt_2", - bazel_module: { bp2build_available: false }, + name: "pretend_prebuilt_2", + bazel_module: { bp2build_available: false }, } filegroup { name: "com.android.apogee-file_contexts", - srcs: [ - "com.android.apogee-file_contexts", - ], - bazel_module: { bp2build_available: false }, + srcs: [ + "com.android.apogee-file_contexts", + ], + bazel_module: { bp2build_available: false }, } +cc_binary { name: "cc_binary_1", bazel_module: { bp2build_available: false } } +sh_binary { name: "sh_binary_2", bazel_module: { bp2build_available: false } } + apex { name: "com.android.apogee", manifest: "apogee_manifest.json", androidManifest: "ApogeeAndroidManifest.xml", - file_contexts: "com.android.apogee-file_contexts", + file_contexts: "com.android.apogee-file_contexts", min_sdk_version: "29", key: "com.android.apogee.key", certificate: "com.android.apogee.certificate", @@ -104,8 +109,8 @@ apex { "native_shared_lib_2", ], binaries: [ - "binary_1", - "binary_2", + "cc_binary_1", + "sh_binary_2", ], prebuilts: [ "pretend_prebuilt_1", @@ -117,8 +122,8 @@ apex { makeBazelTarget("apex", "com.android.apogee", attrNameToString{ "android_manifest": `"ApogeeAndroidManifest.xml"`, "binaries": `[ - "binary_1", - "binary_2", + ":cc_binary_1", + ":sh_binary_2", ]`, "certificate": `":com.android.apogee.certificate"`, "file_contexts": `":com.android.apogee-file_contexts"`, @@ -141,11 +146,10 @@ apex { func TestApexBundleDefaultPropertyValues(t *testing.T) { runApexTestCase(t, bp2buildTestCase{ - description: "apex - default property values", - moduleTypeUnderTest: "apex", - moduleTypeUnderTestFactory: apex.BundleFactory, - moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build, - filesystem: map[string]string{}, + description: "apex - default property values", + moduleTypeUnderTest: "apex", + moduleTypeUnderTestFactory: apex.BundleFactory, + filesystem: map[string]string{}, blueprint: ` apex { name: "com.android.apogee", @@ -160,11 +164,10 @@ apex { func TestApexBundleHasBazelModuleProps(t *testing.T) { runApexTestCase(t, bp2buildTestCase{ - description: "apex - has bazel module props", - moduleTypeUnderTest: "apex", - moduleTypeUnderTestFactory: apex.BundleFactory, - moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build, - filesystem: map[string]string{}, + description: "apex - has bazel module props", + moduleTypeUnderTest: "apex", + moduleTypeUnderTestFactory: apex.BundleFactory, + filesystem: map[string]string{}, blueprint: ` apex { name: "apogee", diff --git a/bp2build/apex_key_conversion_test.go b/bp2build/apex_key_conversion_test.go index 17f79a6b0..1d949901c 100644 --- a/bp2build/apex_key_conversion_test.go +++ b/bp2build/apex_key_conversion_test.go @@ -31,11 +31,10 @@ func registerApexKeyModuleTypes(ctx android.RegistrationContext) { func TestApexKeySimple(t *testing.T) { runApexKeyTestCase(t, bp2buildTestCase{ - description: "apex key - simple example", - moduleTypeUnderTest: "apex_key", - moduleTypeUnderTestFactory: apex.ApexKeyFactory, - moduleTypeUnderTestBp2BuildMutator: apex.ApexKeyBp2Build, - filesystem: map[string]string{}, + description: "apex key - simple example", + moduleTypeUnderTest: "apex_key", + moduleTypeUnderTestFactory: apex.ApexKeyFactory, + filesystem: map[string]string{}, blueprint: ` apex_key { name: "com.android.apogee.key", diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go index eb60cd16c..54b59af3a 100644 --- a/bp2build/build_conversion.go +++ b/bp2build/build_conversion.go @@ -259,7 +259,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers // Simple metrics tracking for bp2build metrics := CodegenMetrics{ - ruleClassCount: make(map[string]int), + ruleClassCount: make(map[string]uint64), } dirs := make(map[string]bool) diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index 95a26a963..1440b6fce 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -245,7 +245,7 @@ func TestGenerateBazelTargetModules(t *testing.T) { { description: "string props", blueprint: `custom { - name: "foo", + name: "foo", string_list_prop: ["a", "b"], string_ptr_prop: "a", bazel_module: { bp2build_available: true }, @@ -470,7 +470,7 @@ custom { android.FailIfErrored(t, err) if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount { - t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount) + t.Errorf("Expected %d bazel target (%s),\ngot %d (%s)", expectedCount, testCase.expectedBazelTargets, actualCount, bazelTargets) } else { for i, expectedBazelTarget := range testCase.expectedBazelTargets { actualBazelTarget := bazelTargets[i] @@ -596,6 +596,7 @@ func TestGenerateBazelTargetModules_OneToMany_LoadedFromStarlark(t *testing.T) { { bp: `custom { name: "bar", + one_to_many_prop: true, bazel_module: { bp2build_available: true }, }`, expectedBazelTarget: `my_library( @@ -620,7 +621,6 @@ load("//build/bazel/rules:rules.bzl", "my_library")`, config := android.TestConfig(buildDir, nil, testCase.bp, nil) ctx := android.NewTestContext(config) ctx.RegisterModuleType("custom", customModuleFactory) - ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutatorFromStarlark) ctx.RegisterForBazelConversion() _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) @@ -658,10 +658,9 @@ load("//build/bazel/rules:rules.bzl", "my_library")`, func TestModuleTypeBp2Build(t *testing.T) { testCases := []bp2buildTestCase{ { - description: "filegroup with does not specify srcs", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "filegroup with does not specify srcs", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { name: "fg_foo", bazel_module: { bp2build_available: true }, @@ -671,10 +670,9 @@ func TestModuleTypeBp2Build(t *testing.T) { }, }, { - description: "filegroup with no srcs", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "filegroup with no srcs", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { name: "fg_foo", srcs: [], @@ -685,10 +683,9 @@ func TestModuleTypeBp2Build(t *testing.T) { }, }, { - description: "filegroup with srcs", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "filegroup with srcs", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { name: "fg_foo", srcs: ["a", "b"], @@ -704,10 +701,9 @@ func TestModuleTypeBp2Build(t *testing.T) { }, }, { - description: "filegroup with excludes srcs", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "filegroup with excludes srcs", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { name: "fg_foo", srcs: ["a", "b"], @@ -721,10 +717,9 @@ func TestModuleTypeBp2Build(t *testing.T) { }, }, { - description: "filegroup with glob", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "filegroup with glob", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { name: "fg_foo", srcs: ["**/*.txt"], @@ -747,12 +742,10 @@ func TestModuleTypeBp2Build(t *testing.T) { }, }, { - description: "filegroup with glob in subdir", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - blueprint: ``, - dir: "other", + description: "filegroup with glob in subdir", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + dir: "other", filesystem: map[string]string{ "other/Android.bp": `filegroup { name: "fg_foo", @@ -775,10 +768,9 @@ func TestModuleTypeBp2Build(t *testing.T) { }, }, { - description: "depends_on_other_dir_module", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "depends_on_other_dir_module", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { name: "fg_foo", srcs: [ @@ -804,26 +796,25 @@ func TestModuleTypeBp2Build(t *testing.T) { }, }, { - description: "depends_on_other_unconverted_module_error", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - unconvertedDepsMode: errorModulesUnconvertedDeps, - filesystem: map[string]string{ - "other/Android.bp": `filegroup { - name: "foo", - srcs: ["a", "b"], -}`, - }, + description: "depends_on_other_unconverted_module_error", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + unconvertedDepsMode: errorModulesUnconvertedDeps, blueprint: `filegroup { - name: "fg_foo", + name: "foobar", srcs: [ ":foo", "c", ], bazel_module: { bp2build_available: true }, }`, - expectedErr: fmt.Errorf(`"fg_foo" depends on unconverted modules: foo`), + expectedErr: fmt.Errorf(`"foobar" depends on unconverted modules: foo`), + filesystem: map[string]string{ + "other/Android.bp": `filegroup { + name: "foo", + srcs: ["a", "b"], +}`, + }, }, } @@ -838,18 +829,16 @@ type bp2buildMutator = func(android.TopDownMutatorContext) func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) { testCases := []struct { - moduleTypeUnderTest string - moduleTypeUnderTestFactory android.ModuleFactory - moduleTypeUnderTestBp2BuildMutator bp2buildMutator - bp string - expectedCount int - description string + moduleTypeUnderTest string + moduleTypeUnderTestFactory android.ModuleFactory + bp string + expectedCount int + description string }{ { - description: "explicitly unavailable", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "explicitly unavailable", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, bp: `filegroup { name: "foo", srcs: ["a", "b"], @@ -858,10 +847,9 @@ func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) { expectedCount: 0, }, { - description: "implicitly unavailable", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "implicitly unavailable", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, bp: `filegroup { name: "foo", srcs: ["a", "b"], @@ -869,10 +857,9 @@ func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) { expectedCount: 0, }, { - description: "explicitly available", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "explicitly available", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, bp: `filegroup { name: "foo", srcs: ["a", "b"], @@ -881,12 +868,12 @@ func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) { expectedCount: 1, }, { - description: "generates more than 1 target if needed", - moduleTypeUnderTest: "custom", - moduleTypeUnderTestFactory: customModuleFactory, - moduleTypeUnderTestBp2BuildMutator: customBp2BuildMutatorFromStarlark, + description: "generates more than 1 target if needed", + moduleTypeUnderTest: "custom", + moduleTypeUnderTestFactory: customModuleFactory, bp: `custom { name: "foo", + one_to_many_prop: true, bazel_module: { bp2build_available: true }, }`, expectedCount: 3, @@ -899,7 +886,6 @@ func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) { config := android.TestConfig(buildDir, nil, testCase.bp, nil) ctx := android.NewTestContext(config) ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) - ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterForBazelConversion() _, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) @@ -919,20 +905,18 @@ func TestAllowlistingBp2buildTargetsExplicitly(t *testing.T) { func TestAllowlistingBp2buildTargetsWithConfig(t *testing.T) { testCases := []struct { - moduleTypeUnderTest string - moduleTypeUnderTestFactory android.ModuleFactory - moduleTypeUnderTestBp2BuildMutator bp2buildMutator - expectedCount map[string]int - description string - bp2buildConfig android.Bp2BuildConfig - checkDir string - fs map[string]string + moduleTypeUnderTest string + moduleTypeUnderTestFactory android.ModuleFactory + expectedCount map[string]int + description string + bp2buildConfig android.Bp2BuildConfig + checkDir string + fs map[string]string }{ { - description: "test bp2build config package and subpackages config", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "test bp2build config package and subpackages config", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, expectedCount: map[string]int{ "migrated": 1, "migrated/but_not_really": 0, @@ -954,10 +938,9 @@ func TestAllowlistingBp2buildTargetsWithConfig(t *testing.T) { }, }, { - description: "test bp2build config opt-in and opt-out", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "test bp2build config opt-in and opt-out", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, expectedCount: map[string]int{ "package-opt-in": 2, "package-opt-in/subpackage": 0, @@ -1008,7 +991,6 @@ filegroup { name: "opt-out-h", bazel_module: { bp2build_available: false } } config := android.TestConfig(buildDir, nil, "", fs) ctx := android.NewTestContext(config) ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) - ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterBp2BuildConfig(testCase.bp2buildConfig) ctx.RegisterForBazelConversion() @@ -1039,10 +1021,9 @@ filegroup { name: "opt-out-h", bazel_module: { bp2build_available: false } } func TestCombineBuildFilesBp2buildTargets(t *testing.T) { testCases := []bp2buildTestCase{ { - description: "filegroup bazel_module.label", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "filegroup bazel_module.label", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { name: "fg_foo", bazel_module: { label: "//other:fg_foo" }, @@ -1055,19 +1036,18 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { }, }, { - description: "multiple bazel_module.label same BUILD", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "multiple bazel_module.label same BUILD", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { - name: "fg_foo", - bazel_module: { label: "//other:fg_foo" }, - } + name: "fg_foo", + bazel_module: { label: "//other:fg_foo" }, + } - filegroup { - name: "foo", - bazel_module: { label: "//other:foo" }, - }`, + filegroup { + name: "foo", + bazel_module: { label: "//other:foo" }, + }`, expectedBazelTargets: []string{ `// BUILD file`, }, @@ -1076,25 +1056,24 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { }, }, { - description: "filegroup bazel_module.label and bp2build in subdir", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - dir: "other", - blueprint: ``, + description: "filegroup bazel_module.label and bp2build in subdir", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + dir: "other", + blueprint: ``, filesystem: map[string]string{ "other/Android.bp": `filegroup { - name: "fg_foo", - bazel_module: { - bp2build_available: true, - }, - } - filegroup { - name: "fg_bar", - bazel_module: { - label: "//other:fg_bar" - }, - }`, + name: "fg_foo", + bazel_module: { + bp2build_available: true, + }, + } + filegroup { + name: "fg_bar", + bazel_module: { + label: "//other:fg_bar" + }, + }`, "other/BUILD.bazel": `// definition for fg_bar`, }, expectedBazelTargets: []string{ @@ -1103,26 +1082,26 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { }, }, { - description: "filegroup bazel_module.label and filegroup bp2build", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "filegroup bazel_module.label and filegroup bp2build", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + filesystem: map[string]string{ "other/BUILD.bazel": `// BUILD file`, }, blueprint: `filegroup { - name: "fg_foo", - bazel_module: { - label: "//other:fg_foo", - }, - } + name: "fg_foo", + bazel_module: { + label: "//other:fg_foo", + }, + } - filegroup { - name: "fg_bar", - bazel_module: { - bp2build_available: true, - }, - }`, + filegroup { + name: "fg_bar", + bazel_module: { + bp2build_available: true, + }, + }`, expectedBazelTargets: []string{ makeBazelTarget("filegroup", "fg_bar", map[string]string{}), `// BUILD file`, @@ -1146,7 +1125,6 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { config := android.TestConfig(buildDir, nil, testCase.blueprint, fs) ctx := android.NewTestContext(config) ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) - ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterForBazelConversion() _, errs := ctx.ParseFileList(dir, toParse) @@ -1192,10 +1170,9 @@ func TestCombineBuildFilesBp2buildTargets(t *testing.T) { func TestGlobExcludeSrcs(t *testing.T) { testCases := []bp2buildTestCase{ { - description: "filegroup top level exclude_srcs", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "filegroup top level exclude_srcs", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: `filegroup { name: "fg_foo", srcs: ["**/*.txt"], @@ -1222,12 +1199,11 @@ func TestGlobExcludeSrcs(t *testing.T) { }, }, { - description: "filegroup in subdir exclude_srcs", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, - blueprint: "", - dir: "dir", + description: "filegroup in subdir exclude_srcs", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + blueprint: "", + dir: "dir", filesystem: map[string]string{ "dir/Android.bp": `filegroup { name: "fg_foo", @@ -1264,10 +1240,9 @@ func TestGlobExcludeSrcs(t *testing.T) { func TestCommonBp2BuildModuleAttrs(t *testing.T) { testCases := []bp2buildTestCase{ { - description: "Required into data test", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "Required into data test", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + ` filegroup { name: "fg_foo", @@ -1281,21 +1256,20 @@ filegroup { }, }, { - description: "Required via arch into data test", - moduleTypeUnderTest: "python_library", - moduleTypeUnderTestFactory: python.PythonLibraryFactory, - moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build, + description: "Required via arch into data test", + moduleTypeUnderTest: "python_library", + moduleTypeUnderTestFactory: python.PythonLibraryFactory, blueprint: simpleModuleDoNotConvertBp2build("python_library", "reqdx86") + simpleModuleDoNotConvertBp2build("python_library", "reqdarm") + ` python_library { name: "fg_foo", arch: { - arm: { - required: ["reqdarm"], - }, - x86: { - required: ["reqdx86"], - }, + arm: { + required: ["reqdarm"], + }, + x86: { + required: ["reqdx86"], + }, }, bazel_module: { bp2build_available: true }, }`, @@ -1311,10 +1285,9 @@ python_library { }, }, { - description: "Required appended to data test", - moduleTypeUnderTest: "python_library", - moduleTypeUnderTestFactory: python.PythonLibraryFactory, - moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build, + description: "Required appended to data test", + moduleTypeUnderTest: "python_library", + moduleTypeUnderTestFactory: python.PythonLibraryFactory, filesystem: map[string]string{ "data.bin": "", "src.py": "", @@ -1337,10 +1310,9 @@ python_library { }, }, { - description: "All props-to-attrs at once together test", - moduleTypeUnderTest: "filegroup", - moduleTypeUnderTestFactory: android.FileGroupFactory, - moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build, + description: "All props-to-attrs at once together test", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + ` filegroup { name: "fg_foo", diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go index 1e78c0ecd..f3345a6ae 100644 --- a/bp2build/bzl_conversion_test.go +++ b/bp2build/bzl_conversion_test.go @@ -100,6 +100,7 @@ custom = rule( # nested_props_ptr start # "nested_prop": attr.string(), # nested_props_ptr end + "one_to_many_prop": attr.bool(), "other_embedded_prop": attr.string(), "string_list_prop": attr.string_list(), "string_prop": attr.string(), @@ -128,6 +129,7 @@ custom_defaults = rule( # nested_props_ptr start # "nested_prop": attr.string(), # nested_props_ptr end + "one_to_many_prop": attr.bool(), "other_embedded_prop": attr.string(), "string_list_prop": attr.string_list(), "string_prop": attr.string(), @@ -156,6 +158,7 @@ custom_test_ = rule( # nested_props_ptr start # "nested_prop": attr.string(), # nested_props_ptr end + "one_to_many_prop": attr.bool(), "other_embedded_prop": attr.string(), "string_list_prop": attr.string_list(), "string_prop": attr.string(), diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 24468506f..a156480d2 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -68,14 +68,14 @@ func runCcBinaryTestCase(t *testing.T, tc ccBinaryBp2buildTestCase) { t.Helper() moduleTypeUnderTest := "cc_binary" testCase := bp2buildTestCase{ - expectedBazelTargets: generateBazelTargetsForTest(tc.targets), - moduleTypeUnderTest: moduleTypeUnderTest, - moduleTypeUnderTestFactory: cc.BinaryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.BinaryBp2build, - description: fmt.Sprintf("%s %s", moduleTypeUnderTest, tc.description), - blueprint: binaryReplacer.Replace(tc.blueprint), + expectedBazelTargets: generateBazelTargetsForTest(tc.targets), + moduleTypeUnderTest: moduleTypeUnderTest, + moduleTypeUnderTestFactory: cc.BinaryFactory, + description: fmt.Sprintf("%s %s", moduleTypeUnderTest, tc.description), + blueprint: binaryReplacer.Replace(tc.blueprint), } t.Run(testCase.description, func(t *testing.T) { + t.Helper() runBp2BuildTestCase(t, registerCcBinaryModuleTypes, testCase) }) } @@ -96,12 +96,11 @@ func runCcHostBinaryTestCase(t *testing.T, tc ccBinaryBp2buildTestCase) { moduleTypeUnderTest := "cc_binary_host" t.Run(testCase.description, func(t *testing.T) { runBp2BuildTestCase(t, registerCcBinaryModuleTypes, bp2buildTestCase{ - expectedBazelTargets: generateBazelTargetsForTest(testCase.targets), - moduleTypeUnderTest: moduleTypeUnderTest, - moduleTypeUnderTestFactory: cc.BinaryHostFactory, - moduleTypeUnderTestBp2BuildMutator: cc.BinaryHostBp2build, - description: fmt.Sprintf("%s %s", moduleTypeUnderTest, tc.description), - blueprint: hostBinaryReplacer.Replace(testCase.blueprint), + expectedBazelTargets: generateBazelTargetsForTest(testCase.targets), + moduleTypeUnderTest: moduleTypeUnderTest, + moduleTypeUnderTestFactory: cc.BinaryHostFactory, + description: fmt.Sprintf("%s %s", moduleTypeUnderTest, tc.description), + blueprint: hostBinaryReplacer.Replace(testCase.blueprint), }) }) } @@ -258,11 +257,13 @@ func TestCcBinaryDoNotDistinguishBetweenDepsAndImplementationDeps(t *testing.T) genrule { name: "generated_hdr", cmd: "nothing to see here", + bazel_module: { bp2build_available: false }, } genrule { name: "export_generated_hdr", cmd: "nothing to see here", + bazel_module: { bp2build_available: false }, } {rule_name} { @@ -303,6 +304,7 @@ genrule { ":not_explicitly_exported_whole_static_dep", ":whole_static_dep", ]`, + "local_includes": `["."]`, }, }, }, diff --git a/bp2build/cc_genrule_conversion_test.go b/bp2build/cc_genrule_conversion_test.go index b3624ddb0..440b462b9 100644 --- a/bp2build/cc_genrule_conversion_test.go +++ b/bp2build/cc_genrule_conversion_test.go @@ -19,7 +19,6 @@ import ( "android/soong/android" "android/soong/cc" - "android/soong/genrule" ) var otherCcGenruleBp = map[string]string{ @@ -41,7 +40,6 @@ func runCcGenruleTestCase(t *testing.T, tc bp2buildTestCase) { t.Helper() (&tc).moduleTypeUnderTest = "cc_genrule" (&tc).moduleTypeUnderTestFactory = cc.GenRuleFactory - (&tc).moduleTypeUnderTestBp2BuildMutator = genrule.CcGenruleBp2Build runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc) } diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index dcbe326e9..eaceea969 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -70,10 +70,9 @@ func registerCcLibraryModuleTypes(ctx android.RegistrationContext) { func TestCcLibrarySimple(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library - simple example", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library - simple example", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "android.cpp": "", "bionic.cpp": "", @@ -159,10 +158,9 @@ cc_library { func TestCcLibraryTrimmedLdAndroid(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library - trimmed example of //bionic/linker:ld-android", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library - trimmed example of //bionic/linker:ld-android", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "ld-android.cpp": "", "linked_list.h": "", @@ -170,8 +168,8 @@ func TestCcLibraryTrimmedLdAndroid(t *testing.T) { "linker_block_allocator.h": "", "linker_cfi.h": "", }, - blueprint: soongCcLibraryPreamble + ` -cc_library_headers { name: "libc_headers" } + blueprint: soongCcLibraryPreamble + + simpleModuleDoNotConvertBp2build("cc_library_headers", "libc_headers") + ` cc_library { name: "fake-ld-android", srcs: ["ld_android.cpp"], @@ -228,11 +226,10 @@ cc_library { func TestCcLibraryExcludeSrcs(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library exclude_srcs - trimmed example of //external/arm-optimized-routines:libarm-optimized-routines-math", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, - dir: "external", + description: "cc_library exclude_srcs - trimmed example of //external/arm-optimized-routines:libarm-optimized-routines-math", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + dir: "external", filesystem: map[string]string{ "external/math/cosf.c": "", "external/math/erf.c": "", @@ -280,10 +277,9 @@ cc_library { func TestCcLibrarySharedStaticProps(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library shared/static props", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library shared/static props", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "both.cpp": "", "sharedonly.cpp": "", @@ -409,10 +405,9 @@ cc_library { func TestCcLibraryDeps(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library shared/static props", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library shared/static props", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "both.cpp": "", "sharedonly.cpp": "", @@ -537,10 +532,9 @@ cc_library { func TestCcLibraryWholeStaticLibsAlwaysLink(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, - dir: "foo/bar", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + dir: "foo/bar", filesystem: map[string]string{ "foo/bar/Android.bp": ` cc_library { @@ -584,11 +578,10 @@ cc_prebuilt_library_static { name: "whole_static_lib_for_both" } func TestCcLibrarySharedStaticPropsInArch(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library shared/static props in arch", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, - dir: "foo/bar", + description: "cc_library shared/static props in arch", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + dir: "foo/bar", filesystem: map[string]string{ "foo/bar/arm.cpp": "", "foo/bar/x86.cpp": "", @@ -735,11 +728,10 @@ cc_library_static { name: "android_dep_for_shared" } func TestCcLibrarySharedStaticPropsWithMixedSources(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library shared/static props with c/cpp/s mixed sources", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, - dir: "foo/bar", + description: "cc_library shared/static props with c/cpp/s mixed sources", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + dir: "foo/bar", filesystem: map[string]string{ "foo/bar/both_source.cpp": "", "foo/bar/both_source.cc": "", @@ -868,11 +860,10 @@ filegroup { func TestCcLibraryNonConfiguredVersionScript(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library non-configured version script", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, - dir: "foo/bar", + description: "cc_library non-configured version script", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + dir: "foo/bar", filesystem: map[string]string{ "foo/bar/Android.bp": ` cc_library { @@ -896,11 +887,10 @@ cc_library { func TestCcLibraryConfiguredVersionScript(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library configured version script", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, - dir: "foo/bar", + description: "cc_library configured version script", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + dir: "foo/bar", filesystem: map[string]string{ "foo/bar/Android.bp": ` cc_library { @@ -940,10 +930,9 @@ cc_library { func TestCcLibrarySharedLibs(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library shared_libs", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library shared_libs", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "mylib", @@ -994,10 +983,9 @@ func TestCcLibraryFeatures(t *testing.T) { })...) runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library pack_relocations test", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library pack_relocations test", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "a", @@ -1036,10 +1024,9 @@ cc_library { func TestCcLibrarySpacesInCopts(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library spaces in copts", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library spaces in copts", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "a", @@ -1059,10 +1046,9 @@ cc_library { func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library cppflags usage", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library cppflags usage", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + `cc_library { name: "a", srcs: ["a.cpp"], @@ -1104,10 +1090,9 @@ func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) { func TestCcLibraryExcludeLibs(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, - filesystem: map[string]string{}, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + filesystem: map[string]string{}, blueprint: soongCcLibraryStaticPreamble + ` cc_library { name: "foo_static", @@ -1212,10 +1197,9 @@ cc_library { func TestCCLibraryNoCrtTrue(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library - nocrt: true emits attribute", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library - nocrt: true emits attribute", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "impl.cpp": "", }, @@ -1237,10 +1221,9 @@ cc_library { func TestCCLibraryNoCrtFalse(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library - nocrt: false - does not emit attribute", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library - nocrt: false - does not emit attribute", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "impl.cpp": "", }, @@ -1260,10 +1243,9 @@ cc_library { func TestCCLibraryNoCrtArchVariant(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library - nocrt in select", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library - nocrt in select", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "impl.cpp": "", }, @@ -1288,15 +1270,12 @@ cc_library { func TestCCLibraryNoLibCrtTrue(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library - simple example", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "impl.cpp": "", }, blueprint: soongCcLibraryPreamble + ` -cc_library_headers { name: "some-headers" } cc_library { name: "foo-lib", srcs: ["impl.cpp"], @@ -1337,14 +1316,12 @@ func makeCcLibraryTargets(name string, attrs attrNameToString) []string { func TestCCLibraryNoLibCrtFalse(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "impl.cpp": "", }, blueprint: soongCcLibraryPreamble + ` -cc_library_headers { name: "some-headers" } cc_library { name: "foo-lib", srcs: ["impl.cpp"], @@ -1361,9 +1338,8 @@ cc_library { func TestCCLibraryNoLibCrtArchVariant(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, filesystem: map[string]string{ "impl.cpp": "", }, @@ -1423,10 +1399,9 @@ func TestCcLibraryStrip(t *testing.T) { expectedTargets = append(expectedTargets, makeCcLibraryTargets("nothing", attrNameToString{})...) runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library strip args", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library strip args", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "nothing", @@ -1474,10 +1449,9 @@ cc_library { func TestCcLibraryStripWithArch(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library strip args", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library strip args", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "multi-arch", @@ -1528,10 +1502,9 @@ cc_library { func TestCcLibrary_SystemSharedLibsRootEmpty(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library system_shared_libs empty at root", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library system_shared_libs empty at root", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "root_empty", @@ -1548,10 +1521,9 @@ cc_library { func TestCcLibrary_SystemSharedLibsStaticEmpty(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library system_shared_libs empty for static variant", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library system_shared_libs empty for static variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "static_empty", @@ -1572,10 +1544,9 @@ cc_library { func TestCcLibrary_SystemSharedLibsSharedEmpty(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library system_shared_libs empty for shared variant", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library system_shared_libs empty for shared variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "shared_empty", @@ -1596,10 +1567,9 @@ cc_library { func TestCcLibrary_SystemSharedLibsSharedBionicEmpty(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library system_shared_libs empty for shared, bionic variant", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library system_shared_libs empty for shared, bionic variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "shared_empty", @@ -1628,10 +1598,9 @@ func TestCcLibrary_SystemSharedLibsLinuxBionicEmpty(t *testing.T) { // only for linux_bionic, but `android` had `["libc", "libdl", "libm"]. // b/195791252 tracks the fix. runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library system_shared_libs empty for linux_bionic variant", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library system_shared_libs empty for linux_bionic variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "target_linux_bionic_empty", @@ -1652,10 +1621,9 @@ cc_library { func TestCcLibrary_SystemSharedLibsBionicEmpty(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library system_shared_libs empty for bionic variant", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library system_shared_libs empty for bionic variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "target_bionic_empty", @@ -1676,10 +1644,9 @@ cc_library { func TestCcLibrary_SystemSharedLibsSharedAndRoot(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library system_shared_libs set for shared and root", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + description: "cc_library system_shared_libs set for shared and root", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + ` cc_library { name: "libc", @@ -1715,13 +1682,11 @@ cc_library { func TestCcLibraryOsSelects(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - description: "cc_library - selects for all os targets", - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, - filesystem: map[string]string{}, + description: "cc_library - selects for all os targets", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + filesystem: map[string]string{}, blueprint: soongCcLibraryPreamble + ` -cc_library_headers { name: "some-headers" } cc_library { name: "foo-lib", srcs: ["base.cpp"], @@ -1861,10 +1826,9 @@ func TestCcLibraryCppStdWithGnuExtensions_ConvertsToFeatureAttr(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ description: fmt.Sprintf( - "cc_library with c_std: %s, cpp_std: %s and gnu_extensions: %s", tc.c_std, tc.cpp_std, tc.gnu_extensions), - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + "cc_library with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions), + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcLibraryPreamble + fmt.Sprintf(` cc_library { name: "%s_full", @@ -1879,10 +1843,9 @@ cc_library { runCcLibraryStaticTestCase(t, bp2buildTestCase{ description: fmt.Sprintf( - "cc_library_static with c_std: %s, cpp_std: %s and gnu_extensions: %s", tc.c_std, tc.cpp_std, tc.gnu_extensions), - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + "cc_library_static with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions), + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, blueprint: soongCcLibraryPreamble + fmt.Sprintf(` cc_library_static { name: "%s_static", @@ -1899,10 +1862,9 @@ cc_library_static { runCcLibrarySharedTestCase(t, bp2buildTestCase{ description: fmt.Sprintf( - "cc_library_shared with c_std: %s, cpp_std: %s and gnu_extensions: %s", tc.c_std, tc.cpp_std, tc.gnu_extensions), - moduleTypeUnderTest: "cc_library_shared", - moduleTypeUnderTestFactory: cc.LibrarySharedFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build, + "cc_library_shared with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions), + moduleTypeUnderTest: "cc_library_shared", + moduleTypeUnderTestFactory: cc.LibrarySharedFactory, blueprint: soongCcLibraryPreamble + fmt.Sprintf(` cc_library_shared { name: "%s_shared", @@ -1921,9 +1883,8 @@ cc_library_shared { func TestCcLibraryProtoSimple(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcProtoPreamble + `cc_library { name: "foo", srcs: ["foo.proto"], @@ -1947,9 +1908,8 @@ func TestCcLibraryProtoSimple(t *testing.T) { func TestCcLibraryProtoNoCanonicalPathFromRoot(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcProtoPreamble + `cc_library { name: "foo", srcs: ["foo.proto"], @@ -1973,9 +1933,8 @@ func TestCcLibraryProtoNoCanonicalPathFromRoot(t *testing.T) { func TestCcLibraryProtoExplicitCanonicalPathFromRoot(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcProtoPreamble + `cc_library { name: "foo", srcs: ["foo.proto"], @@ -2000,9 +1959,8 @@ func TestCcLibraryProtoExplicitCanonicalPathFromRoot(t *testing.T) { func TestCcLibraryProtoFull(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcProtoPreamble + `cc_library { name: "foo", srcs: ["foo.proto"], @@ -2029,9 +1987,8 @@ func TestCcLibraryProtoFull(t *testing.T) { func TestCcLibraryProtoLite(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcProtoPreamble + `cc_library { name: "foo", srcs: ["foo.proto"], @@ -2058,9 +2015,8 @@ func TestCcLibraryProtoLite(t *testing.T) { func TestCcLibraryProtoExportHeaders(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ - moduleTypeUnderTest: "cc_library", - moduleTypeUnderTestFactory: cc.LibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, blueprint: soongCcProtoPreamble + `cc_library { name: "foo", srcs: ["foo.proto"], @@ -2085,3 +2041,121 @@ func TestCcLibraryProtoExportHeaders(t *testing.T) { }, }) } + +func TestCcLibraryProtoFilegroups(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + blueprint: soongCcProtoPreamble + + simpleModuleDoNotConvertBp2build("filegroup", "a_fg_proto") + + simpleModuleDoNotConvertBp2build("filegroup", "b_protos") + + simpleModuleDoNotConvertBp2build("filegroup", "c-proto-srcs") + + simpleModuleDoNotConvertBp2build("filegroup", "proto-srcs-d") + ` +cc_library { + name: "a", + srcs: [":a_fg_proto"], + proto: { + canonical_path_from_root: false, + export_proto_headers: true, + }, + include_build_directory: false, +} + +cc_library { + name: "b", + srcs: [":b_protos"], + proto: { + canonical_path_from_root: false, + export_proto_headers: true, + }, + include_build_directory: false, +} + +cc_library { + name: "c", + srcs: [":c-proto-srcs"], + proto: { + canonical_path_from_root: false, + export_proto_headers: true, + }, + include_build_directory: false, +} + +cc_library { + name: "d", + srcs: [":proto-srcs-d"], + proto: { + canonical_path_from_root: false, + export_proto_headers: true, + }, + include_build_directory: false, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("proto_library", "a_proto", attrNameToString{ + "srcs": `[":a_fg_proto"]`, + }), makeBazelTarget("cc_lite_proto_library", "a_cc_proto_lite", attrNameToString{ + "deps": `[":a_proto"]`, + }), makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{ + "deps": `[":libprotobuf-cpp-lite"]`, + "whole_archive_deps": `[":a_cc_proto_lite"]`, + "srcs": `[":a_fg_proto_cpp_srcs"]`, + "srcs_as": `[":a_fg_proto_as_srcs"]`, + "srcs_c": `[":a_fg_proto_c_srcs"]`, + }), makeBazelTarget("cc_library_shared", "a", attrNameToString{ + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "whole_archive_deps": `[":a_cc_proto_lite"]`, + "srcs": `[":a_fg_proto_cpp_srcs"]`, + "srcs_as": `[":a_fg_proto_as_srcs"]`, + "srcs_c": `[":a_fg_proto_c_srcs"]`, + }), makeBazelTarget("proto_library", "b_proto", attrNameToString{ + "srcs": `[":b_protos"]`, + }), makeBazelTarget("cc_lite_proto_library", "b_cc_proto_lite", attrNameToString{ + "deps": `[":b_proto"]`, + }), makeBazelTarget("cc_library_static", "b_bp2build_cc_library_static", attrNameToString{ + "deps": `[":libprotobuf-cpp-lite"]`, + "whole_archive_deps": `[":b_cc_proto_lite"]`, + "srcs": `[":b_protos_cpp_srcs"]`, + "srcs_as": `[":b_protos_as_srcs"]`, + "srcs_c": `[":b_protos_c_srcs"]`, + }), makeBazelTarget("cc_library_shared", "b", attrNameToString{ + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "whole_archive_deps": `[":b_cc_proto_lite"]`, + "srcs": `[":b_protos_cpp_srcs"]`, + "srcs_as": `[":b_protos_as_srcs"]`, + "srcs_c": `[":b_protos_c_srcs"]`, + }), makeBazelTarget("proto_library", "c_proto", attrNameToString{ + "srcs": `[":c-proto-srcs"]`, + }), makeBazelTarget("cc_lite_proto_library", "c_cc_proto_lite", attrNameToString{ + "deps": `[":c_proto"]`, + }), makeBazelTarget("cc_library_static", "c_bp2build_cc_library_static", attrNameToString{ + "deps": `[":libprotobuf-cpp-lite"]`, + "whole_archive_deps": `[":c_cc_proto_lite"]`, + "srcs": `[":c-proto-srcs_cpp_srcs"]`, + "srcs_as": `[":c-proto-srcs_as_srcs"]`, + "srcs_c": `[":c-proto-srcs_c_srcs"]`, + }), makeBazelTarget("cc_library_shared", "c", attrNameToString{ + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "whole_archive_deps": `[":c_cc_proto_lite"]`, + "srcs": `[":c-proto-srcs_cpp_srcs"]`, + "srcs_as": `[":c-proto-srcs_as_srcs"]`, + "srcs_c": `[":c-proto-srcs_c_srcs"]`, + }), makeBazelTarget("proto_library", "d_proto", attrNameToString{ + "srcs": `[":proto-srcs-d"]`, + }), makeBazelTarget("cc_lite_proto_library", "d_cc_proto_lite", attrNameToString{ + "deps": `[":d_proto"]`, + }), makeBazelTarget("cc_library_static", "d_bp2build_cc_library_static", attrNameToString{ + "deps": `[":libprotobuf-cpp-lite"]`, + "whole_archive_deps": `[":d_cc_proto_lite"]`, + "srcs": `[":proto-srcs-d_cpp_srcs"]`, + "srcs_as": `[":proto-srcs-d_as_srcs"]`, + "srcs_c": `[":proto-srcs-d_c_srcs"]`, + }), makeBazelTarget("cc_library_shared", "d", attrNameToString{ + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "whole_archive_deps": `[":d_cc_proto_lite"]`, + "srcs": `[":proto-srcs-d_cpp_srcs"]`, + "srcs_as": `[":proto-srcs-d_as_srcs"]`, + "srcs_c": `[":proto-srcs-d_c_srcs"]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go index 76fdab2f4..594c05009 100644 --- a/bp2build/cc_library_headers_conversion_test.go +++ b/bp2build/cc_library_headers_conversion_test.go @@ -78,10 +78,9 @@ func runCcLibraryHeadersTestCase(t *testing.T, tc bp2buildTestCase) { func TestCcLibraryHeadersSimple(t *testing.T) { runCcLibraryHeadersTestCase(t, bp2buildTestCase{ - description: "cc_library_headers test", - moduleTypeUnderTest: "cc_library_headers", - moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build, + description: "cc_library_headers test", + moduleTypeUnderTest: "cc_library_headers", + moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, filesystem: map[string]string{ "lib-1/lib1a.h": "", "lib-1/lib1b.h": "", @@ -150,11 +149,10 @@ cc_library_headers { func TestCcLibraryHeadersOsSpecificHeader(t *testing.T) { runCcLibraryHeadersTestCase(t, bp2buildTestCase{ - description: "cc_library_headers test with os-specific header_libs props", - moduleTypeUnderTest: "cc_library_headers", - moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build, - filesystem: map[string]string{}, + description: "cc_library_headers test with os-specific header_libs props", + moduleTypeUnderTest: "cc_library_headers", + moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, + filesystem: map[string]string{}, blueprint: soongCcLibraryPreamble + ` cc_library_headers { name: "android-lib", @@ -209,11 +207,10 @@ cc_library_headers { func TestCcLibraryHeadersOsSpecficHeaderLibsExportHeaderLibHeaders(t *testing.T) { runCcLibraryHeadersTestCase(t, bp2buildTestCase{ - description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props", - moduleTypeUnderTest: "cc_library_headers", - moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build, - filesystem: map[string]string{}, + description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props", + moduleTypeUnderTest: "cc_library_headers", + moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, + filesystem: map[string]string{}, blueprint: soongCcLibraryPreamble + ` cc_library_headers { name: "android-lib", @@ -250,11 +247,10 @@ cc_library_headers { func TestCcLibraryHeadersArchAndTargetExportSystemIncludes(t *testing.T) { runCcLibraryHeadersTestCase(t, bp2buildTestCase{ - description: "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props", - moduleTypeUnderTest: "cc_library_headers", - moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build, - filesystem: map[string]string{}, + description: "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props", + moduleTypeUnderTest: "cc_library_headers", + moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, + filesystem: map[string]string{}, blueprint: soongCcLibraryPreamble + `cc_library_headers { name: "foo_headers", export_system_include_dirs: [ @@ -310,10 +306,9 @@ func TestCcLibraryHeadersArchAndTargetExportSystemIncludes(t *testing.T) { func TestCcLibraryHeadersNoCrtIgnored(t *testing.T) { runCcLibraryHeadersTestCase(t, bp2buildTestCase{ - description: "cc_library_headers test", - moduleTypeUnderTest: "cc_library_headers", - moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build, + description: "cc_library_headers test", + moduleTypeUnderTest: "cc_library_headers", + moduleTypeUnderTestFactory: cc.LibraryHeaderFactory, filesystem: map[string]string{ "lib-1/lib1a.h": "", "lib-1/lib1b.h": "", diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index e0331bee5..97a600a99 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -40,7 +40,6 @@ func runCcLibrarySharedTestCase(t *testing.T, tc bp2buildTestCase) { t.Helper() (&tc).moduleTypeUnderTest = "cc_library_shared" (&tc).moduleTypeUnderTestFactory = cc.LibrarySharedFactory - (&tc).moduleTypeUnderTestBp2BuildMutator = cc.CcLibrarySharedBp2Build runBp2BuildTestCase(t, registerCcLibrarySharedModuleTypes, tc) } @@ -450,3 +449,18 @@ func TestCcLibrarySharedProto(t *testing.T) { }, }) } + +func TestCcLibrarySharedUseVersionLib(t *testing.T) { + runCcLibrarySharedTestCase(t, bp2buildTestCase{ + blueprint: soongCcProtoPreamble + `cc_library_shared { + name: "foo", + use_version_lib: true, + include_build_directory: false, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("cc_library_shared", "foo", attrNameToString{ + "use_version_lib": "True", + }), + }, + }) +} diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index 02229e51e..e2e55ddee 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -82,7 +82,6 @@ func runCcLibraryStaticTestCase(t *testing.T, tc bp2buildTestCase) { (&tc).moduleTypeUnderTest = "cc_library_static" (&tc).moduleTypeUnderTestFactory = cc.LibraryStaticFactory - (&tc).moduleTypeUnderTestBp2BuildMutator = cc.CcLibraryStaticBp2Build runBp2BuildTestCase(t, registerCcLibraryStaticModuleTypes, tc) } @@ -954,11 +953,13 @@ func TestCcLibraryStaticGeneratedHeadersAllPartitions(t *testing.T) { genrule { name: "generated_hdr", cmd: "nothing to see here", + bazel_module: { bp2build_available: false }, } genrule { name: "export_generated_hdr", cmd: "nothing to see here", + bazel_module: { bp2build_available: false }, } cc_library_static { @@ -970,7 +971,9 @@ cc_library_static { }`, expectedBazelTargets: []string{ makeBazelTarget("cc_library_static", "foo_static", attrNameToString{ - "hdrs": `[":export_generated_hdr"]`, + "export_includes": `["."]`, + "local_includes": `["."]`, + "hdrs": `[":export_generated_hdr"]`, "srcs": `[ "cpp_src.cpp", ":generated_hdr", @@ -996,66 +999,38 @@ func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) { "for-x86.cpp": "", "not-for-x86.cpp": "", "not-for-everything.cpp": "", - "dep/Android.bp": ` -genrule { - name: "generated_src_other_pkg", - cmd: "nothing to see here", -} - -genrule { - name: "generated_hdr_other_pkg", - cmd: "nothing to see here", -} - -genrule { - name: "generated_hdr_other_pkg_x86", - cmd: "nothing to see here", -} - -genrule { - name: "generated_hdr_other_pkg_android", - cmd: "nothing to see here", -}`, + "dep/Android.bp": simpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg") + + simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg") + + simpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg_x86") + + simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_x86") + + simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_android"), }, - blueprint: soongCcLibraryStaticPreamble + ` -genrule { - name: "generated_src", - cmd: "nothing to see here", -} - -genrule { - name: "generated_src_not_x86", - cmd: "nothing to see here", -} - -genrule { - name: "generated_src_android", - cmd: "nothing to see here", -} - -genrule { - name: "generated_hdr", - cmd: "nothing to see here", -} - + blueprint: soongCcLibraryStaticPreamble + + simpleModuleDoNotConvertBp2build("genrule", "generated_src") + + simpleModuleDoNotConvertBp2build("genrule", "generated_src_not_x86") + + simpleModuleDoNotConvertBp2build("genrule", "generated_src_android") + + simpleModuleDoNotConvertBp2build("genrule", "generated_hdr") + ` cc_library_static { name: "foo_static", srcs: ["common.cpp", "not-for-*.cpp"], exclude_srcs: ["not-for-everything.cpp"], generated_sources: ["generated_src", "generated_src_other_pkg", "generated_src_not_x86"], generated_headers: ["generated_hdr", "generated_hdr_other_pkg"], + export_generated_headers: ["generated_hdr_other_pkg"], arch: { x86: { srcs: ["for-x86.cpp"], exclude_srcs: ["not-for-x86.cpp"], generated_headers: ["generated_hdr_other_pkg_x86"], exclude_generated_sources: ["generated_src_not_x86"], + export_generated_headers: ["generated_hdr_other_pkg_x86"], }, }, target: { android: { generated_sources: ["generated_src_android"], generated_headers: ["generated_hdr_other_pkg_android"], + export_generated_headers: ["generated_hdr_other_pkg_android"], }, }, @@ -1069,23 +1044,25 @@ cc_library_static { ":generated_src", "//dep:generated_src_other_pkg", ":generated_hdr", - "//dep:generated_hdr_other_pkg", ] + select({ - "//build/bazel/platforms/arch:x86": [ - "for-x86.cpp", - "//dep:generated_hdr_other_pkg_x86", - ], + "//build/bazel/platforms/arch:x86": ["for-x86.cpp"], "//conditions:default": [ "not-for-x86.cpp", ":generated_src_not_x86", ], }) + select({ - "//build/bazel/platforms/os:android": [ - ":generated_src_android", - "//dep:generated_hdr_other_pkg_android", - ], + "//build/bazel/platforms/os:android": [":generated_src_android"], "//conditions:default": [], })`, + "hdrs": `["//dep:generated_hdr_other_pkg"] + select({ + "//build/bazel/platforms/arch:x86": ["//dep:generated_hdr_other_pkg_x86"], + "//conditions:default": [], + }) + select({ + "//build/bazel/platforms/os:android": ["//dep:generated_hdr_other_pkg_android"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + "export_absolute_includes": `["dep"]`, }), }, }) @@ -1366,9 +1343,8 @@ cc_library_static { func TestStaticLibrary_SystemSharedLibsBionic(t *testing.T) { runCcLibraryStaticTestCase(t, bp2buildTestCase{ description: "cc_library_static system_shared_libs set for bionic variant", - blueprint: soongCcLibraryStaticPreamble + ` -cc_library{name: "libc"} - + blueprint: soongCcLibraryStaticPreamble + + simpleModuleDoNotConvertBp2build("cc_library", "libc") + ` cc_library_static { name: "target_bionic", target: { @@ -1394,10 +1370,9 @@ cc_library_static { func TestStaticLibrary_SystemSharedLibsLinuxRootAndLinuxBionic(t *testing.T) { runCcLibraryStaticTestCase(t, bp2buildTestCase{ description: "cc_library_static system_shared_libs set for root and linux_bionic variant", - blueprint: soongCcLibraryStaticPreamble + ` -cc_library{name: "libc"} -cc_library{name: "libm"} - + blueprint: soongCcLibraryStaticPreamble + + simpleModuleDoNotConvertBp2build("cc_library", "libc") + + simpleModuleDoNotConvertBp2build("cc_library", "libm") + ` cc_library_static { name: "target_linux_bionic", system_shared_libs: ["libc"], @@ -1443,3 +1418,18 @@ func TestCcLibraryStaticProto(t *testing.T) { }, }) } + +func TestCcLibraryStaticUseVersionLib(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + blueprint: soongCcProtoPreamble + `cc_library_static { + name: "foo", + use_version_lib: true, + include_build_directory: false, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("cc_library_static", "foo", attrNameToString{ + "use_version_lib": "True", + }), + }, + }) +} diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go index 5ab9129e7..0a6c3175d 100644 --- a/bp2build/cc_object_conversion_test.go +++ b/bp2build/cc_object_conversion_test.go @@ -30,7 +30,6 @@ func runCcObjectTestCase(t *testing.T, tc bp2buildTestCase) { t.Helper() (&tc).moduleTypeUnderTest = "cc_object" (&tc).moduleTypeUnderTestFactory = cc.ObjectFactory - (&tc).moduleTypeUnderTestBp2BuildMutator = cc.ObjectBp2Build runBp2BuildTestCase(t, registerCcObjectModuleTypes, tc) } diff --git a/bp2build/cc_prebuilt_library_shared_test.go b/bp2build/cc_prebuilt_library_shared_test.go index bac3908da..ef2fddc5b 100644 --- a/bp2build/cc_prebuilt_library_shared_test.go +++ b/bp2build/cc_prebuilt_library_shared_test.go @@ -9,10 +9,9 @@ import ( func TestSharedPrebuiltLibrary(t *testing.T) { runBp2BuildTestCaseSimple(t, bp2buildTestCase{ - description: "prebuilt library shared simple", - moduleTypeUnderTest: "cc_prebuilt_library_shared", - moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.PrebuiltLibrarySharedBp2Build, + description: "prebuilt library shared simple", + moduleTypeUnderTest: "cc_prebuilt_library_shared", + moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory, filesystem: map[string]string{ "libf.so": "", }, @@ -33,10 +32,9 @@ cc_prebuilt_library_shared { func TestSharedPrebuiltLibraryWithArchVariance(t *testing.T) { runBp2BuildTestCaseSimple(t, bp2buildTestCase{ - description: "prebuilt library shared with arch variance", - moduleTypeUnderTest: "cc_prebuilt_library_shared", - moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.PrebuiltLibrarySharedBp2Build, + description: "prebuilt library shared with arch variance", + moduleTypeUnderTest: "cc_prebuilt_library_shared", + moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory, filesystem: map[string]string{ "libf.so": "", "libg.so": "", diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go index 9f4add2ff..b43cf5374 100644 --- a/bp2build/filegroup_conversion_test.go +++ b/bp2build/filegroup_conversion_test.go @@ -25,7 +25,6 @@ func runFilegroupTestCase(t *testing.T, tc bp2buildTestCase) { t.Helper() (&tc).moduleTypeUnderTest = "filegroup" (&tc).moduleTypeUnderTestFactory = android.FileGroupFactory - (&tc).moduleTypeUnderTestBp2BuildMutator = android.FilegroupBp2Build runBp2BuildTestCase(t, registerFilegroupModuleTypes, tc) } diff --git a/bp2build/genrule_conversion_test.go b/bp2build/genrule_conversion_test.go index 597666694..fd631a53b 100644 --- a/bp2build/genrule_conversion_test.go +++ b/bp2build/genrule_conversion_test.go @@ -28,7 +28,6 @@ func runGenruleTestCase(t *testing.T, tc bp2buildTestCase) { t.Helper() (&tc).moduleTypeUnderTest = "genrule" (&tc).moduleTypeUnderTestFactory = genrule.GenRuleFactory - (&tc).moduleTypeUnderTestBp2BuildMutator = genrule.GenruleBp2Build runBp2BuildTestCase(t, registerGenruleModuleTypes, tc) } diff --git a/bp2build/java_binary_host_conversion_test.go b/bp2build/java_binary_host_conversion_test.go new file mode 100644 index 000000000..96b895876 --- /dev/null +++ b/bp2build/java_binary_host_conversion_test.go @@ -0,0 +1,63 @@ +// Copyright 2021 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 ( + "testing" + + "android/soong/android" + "android/soong/cc" + "android/soong/java" +) + +func runJavaBinaryHostTestCase(t *testing.T, tc bp2buildTestCase) { + t.Helper() + (&tc).moduleTypeUnderTest = "java_binary_host" + (&tc).moduleTypeUnderTestFactory = java.BinaryHostFactory + runBp2BuildTestCase(t, func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("cc_library_host_shared", cc.LibraryHostSharedFactory) + }, tc) +} + +var fs = map[string]string{ + "test.mf": "Main-Class: com.android.test.MainClass", + "other/Android.bp": `cc_library_host_shared { + name: "jni-lib-1", + stl: "none", +}`, +} + +func TestJavaBinaryHost(t *testing.T) { + runJavaBinaryHostTestCase(t, bp2buildTestCase{ + description: "java_binary_host with srcs, exclude_srcs, jni_libs and manifest.", + filesystem: fs, + blueprint: `java_binary_host { + name: "java-binary-host-1", + srcs: ["a.java", "b.java"], + exclude_srcs: ["b.java"], + manifest: "test.mf", + jni_libs: ["jni-lib-1"], + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("java_binary", "java-binary-host-1", attrNameToString{ + "srcs": `["a.java"]`, + "main_class": `"com.android.test.MainClass"`, + "deps": `["//other:jni-lib-1"]`, + "jvm_flags": `["-Djava.library.path=$${RUNPATH}other"]`, + }), + }, + }) +} diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go new file mode 100644 index 000000000..5c65ec230 --- /dev/null +++ b/bp2build/java_library_conversion_test.go @@ -0,0 +1,57 @@ +// Copyright 2021 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 ( + "testing" + + "android/soong/android" + "android/soong/java" +) + +func runJavaLibraryTestCase(t *testing.T, tc bp2buildTestCase) { + t.Helper() + (&tc).moduleTypeUnderTest = "java_library" + (&tc).moduleTypeUnderTestFactory = java.LibraryFactory + runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc) +} + +func TestJavaLibrary(t *testing.T) { + runJavaLibraryTestCase(t, bp2buildTestCase{ + description: "java_library with srcs, exclude_srcs and libs", + blueprint: `java_library { + name: "java-lib-1", + srcs: ["a.java", "b.java"], + exclude_srcs: ["b.java"], + libs: ["java-lib-2"], + bazel_module: { bp2build_available: true }, +} + +java_library { + name: "java-lib-2", + srcs: ["b.java"], + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("java_library", "java-lib-1", attrNameToString{ + "srcs": `["a.java"]`, + "deps": `[":java-lib-2"]`, + }), + makeBazelTarget("java_library", "java-lib-2", attrNameToString{ + "srcs": `["b.java"]`, + }), + }, + }) +} diff --git a/bp2build/java_library_host_conversion_test.go b/bp2build/java_library_host_conversion_test.go new file mode 100644 index 000000000..6ac82dbd2 --- /dev/null +++ b/bp2build/java_library_host_conversion_test.go @@ -0,0 +1,57 @@ +// Copyright 2021 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 ( + "testing" + + "android/soong/android" + "android/soong/java" +) + +func runJavaLibraryHostTestCase(t *testing.T, tc bp2buildTestCase) { + t.Helper() + (&tc).moduleTypeUnderTest = "java_library_host" + (&tc).moduleTypeUnderTestFactory = java.LibraryHostFactory + runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc) +} + +func TestJavaLibraryHost(t *testing.T) { + runJavaLibraryHostTestCase(t, bp2buildTestCase{ + description: "java_library_host with srcs, exclude_srcs and libs", + blueprint: `java_library_host { + name: "java-lib-host-1", + srcs: ["a.java", "b.java"], + exclude_srcs: ["b.java"], + libs: ["java-lib-host-2"], + bazel_module: { bp2build_available: true }, +} + +java_library_host { + name: "java-lib-host-2", + srcs: ["c.java"], + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("java_library", "java-lib-host-1", attrNameToString{ + "srcs": `["a.java"]`, + "deps": `[":java-lib-host-2"]`, + }), + makeBazelTarget("java_library", "java-lib-host-2", attrNameToString{ + "srcs": `["c.java"]`, + }), + }, + }) +} diff --git a/bp2build/metrics.go b/bp2build/metrics.go index b3d5afb74..68ac54435 100644 --- a/bp2build/metrics.go +++ b/bp2build/metrics.go @@ -2,34 +2,52 @@ package bp2build import ( "fmt" + "os" + "path/filepath" "strings" "android/soong/android" + "android/soong/shared" + "android/soong/ui/metrics/bp2build_metrics_proto" ) // Simple metrics struct to collect information about a Blueprint to BUILD // conversion process. type CodegenMetrics struct { // Total number of Soong modules converted to generated targets - generatedModuleCount int + generatedModuleCount uint64 // Total number of Soong modules converted to handcrafted targets - handCraftedModuleCount int + handCraftedModuleCount uint64 // Total number of unconverted Soong modules - unconvertedModuleCount int + unconvertedModuleCount uint64 // Counts of generated Bazel targets per Bazel rule class - ruleClassCount map[string]int + ruleClassCount map[string]uint64 + // List of modules with unconverted deps + // NOTE: NOT in the .proto moduleWithUnconvertedDepsMsgs []string + // List of converted modules convertedModules []string } +// Serialize returns the protoized version of CodegenMetrics: bp2build_metrics_proto.Bp2BuildMetrics +func (metrics *CodegenMetrics) Serialize() bp2build_metrics_proto.Bp2BuildMetrics { + return bp2build_metrics_proto.Bp2BuildMetrics{ + GeneratedModuleCount: metrics.generatedModuleCount, + HandCraftedModuleCount: metrics.handCraftedModuleCount, + UnconvertedModuleCount: metrics.unconvertedModuleCount, + RuleClassCount: metrics.ruleClassCount, + ConvertedModules: metrics.convertedModules, + } +} + // Print the codegen metrics to stdout. func (metrics *CodegenMetrics) Print() { - generatedTargetCount := 0 + generatedTargetCount := uint64(0) for _, ruleClass := range android.SortedStringKeys(metrics.ruleClassCount) { count := metrics.ruleClassCount[ruleClass] fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count) @@ -45,6 +63,40 @@ func (metrics *CodegenMetrics) Print() { strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t")) } +const bp2buildMetricsFilename = "bp2build_metrics.pb" + +// fail prints $PWD to stderr, followed by the given printf string and args (vals), +// then the given alert, and then exits with 1 for failure +func fail(err error, alertFmt string, vals ...interface{}) { + cwd, wderr := os.Getwd() + if wderr != nil { + cwd = "FAILED TO GET $PWD: " + wderr.Error() + } + fmt.Fprintf(os.Stderr, "\nIn "+cwd+":\n"+alertFmt+"\n"+err.Error()+"\n", vals...) + os.Exit(1) +} + +// Write the bp2build-protoized codegen metrics into the given directory +func (metrics *CodegenMetrics) Write(dir string) { + if _, err := os.Stat(dir); os.IsNotExist(err) { + // The metrics dir doesn't already exist, so create it (and parents) + if err := os.MkdirAll(dir, 0755); err != nil { // rx for all; w for user + fail(err, "Failed to `mkdir -p` %s", dir) + } + } else if err != nil { + fail(err, "Failed to `stat` %s", dir) + } + metricsFile := filepath.Join(dir, bp2buildMetricsFilename) + if err := metrics.dump(metricsFile); err != nil { + fail(err, "Error outputting %s", metricsFile) + } + if _, err := os.Stat(metricsFile); err != nil { + fail(err, "MISSING BP2BUILD METRICS OUTPUT: Failed to `stat` %s", metricsFile) + } else { + fmt.Printf("\nWrote bp2build metrics to: %s\n", metricsFile) + } +} + func (metrics *CodegenMetrics) IncrementRuleClassCount(ruleClass string) { metrics.ruleClassCount[ruleClass] += 1 } @@ -53,12 +105,18 @@ func (metrics *CodegenMetrics) IncrementUnconvertedCount() { metrics.unconvertedModuleCount += 1 } -func (metrics *CodegenMetrics) TotalModuleCount() int { +func (metrics *CodegenMetrics) TotalModuleCount() uint64 { return metrics.handCraftedModuleCount + metrics.generatedModuleCount + metrics.unconvertedModuleCount } +// Dump serializes the metrics to the given filename +func (metrics *CodegenMetrics) dump(filename string) (err error) { + ser := metrics.Serialize() + return shared.Save(&ser, filename) +} + type ConversionType int const ( diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go index 118930994..506589389 100644 --- a/bp2build/prebuilt_etc_conversion_test.go +++ b/bp2build/prebuilt_etc_conversion_test.go @@ -25,7 +25,6 @@ func runPrebuiltEtcTestCase(t *testing.T, tc bp2buildTestCase) { t.Helper() (&tc).moduleTypeUnderTest = "prebuilt_etc" (&tc).moduleTypeUnderTestFactory = etc.PrebuiltEtcFactory - (&tc).moduleTypeUnderTestBp2BuildMutator = etc.PrebuiltEtcBp2Build runBp2BuildTestCase(t, registerPrebuiltEtcModuleTypes, tc) } diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go index 01b6aa268..40c8ba1e9 100644 --- a/bp2build/python_binary_conversion_test.go +++ b/bp2build/python_binary_conversion_test.go @@ -17,10 +17,9 @@ func runBp2BuildTestCaseWithPythonLibraries(t *testing.T, tc bp2buildTestCase) { func TestPythonBinaryHostSimple(t *testing.T) { runBp2BuildTestCaseWithPythonLibraries(t, bp2buildTestCase{ - description: "simple python_binary_host converts to a native py_binary", - moduleTypeUnderTest: "python_binary_host", - moduleTypeUnderTestFactory: python.PythonBinaryHostFactory, - moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build, + description: "simple python_binary_host converts to a native py_binary", + moduleTypeUnderTest: "python_binary_host", + moduleTypeUnderTestFactory: python.PythonBinaryHostFactory, filesystem: map[string]string{ "a.py": "", "b/c.py": "", @@ -40,7 +39,7 @@ func TestPythonBinaryHostSimple(t *testing.T) { python_library_host { name: "bar", srcs: ["b/e.py"], - bazel_module: { bp2build_available: true }, + bazel_module: { bp2build_available: false }, }`, expectedBazelTargets: []string{ makeBazelTarget("py_binary", "foo", attrNameToString{ @@ -59,10 +58,9 @@ func TestPythonBinaryHostSimple(t *testing.T) { func TestPythonBinaryHostPy2(t *testing.T) { runBp2BuildTestCaseSimple(t, bp2buildTestCase{ - description: "py2 python_binary_host", - moduleTypeUnderTest: "python_binary_host", - moduleTypeUnderTestFactory: python.PythonBinaryHostFactory, - moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build, + description: "py2 python_binary_host", + moduleTypeUnderTest: "python_binary_host", + moduleTypeUnderTestFactory: python.PythonBinaryHostFactory, blueprint: `python_binary_host { name: "foo", srcs: ["a.py"], @@ -89,10 +87,9 @@ func TestPythonBinaryHostPy2(t *testing.T) { func TestPythonBinaryHostPy3(t *testing.T) { runBp2BuildTestCaseSimple(t, bp2buildTestCase{ - description: "py3 python_binary_host", - moduleTypeUnderTest: "python_binary_host", - moduleTypeUnderTestFactory: python.PythonBinaryHostFactory, - moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build, + description: "py3 python_binary_host", + moduleTypeUnderTest: "python_binary_host", + moduleTypeUnderTestFactory: python.PythonBinaryHostFactory, blueprint: `python_binary_host { name: "foo", srcs: ["a.py"], @@ -119,10 +116,9 @@ func TestPythonBinaryHostPy3(t *testing.T) { func TestPythonBinaryHostArchVariance(t *testing.T) { runBp2BuildTestCaseSimple(t, bp2buildTestCase{ - description: "test arch variants", - moduleTypeUnderTest: "python_binary_host", - moduleTypeUnderTestFactory: python.PythonBinaryHostFactory, - moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build, + description: "test arch variants", + moduleTypeUnderTest: "python_binary_host", + moduleTypeUnderTestFactory: python.PythonBinaryHostFactory, filesystem: map[string]string{ "dir/arm.py": "", "dir/x86.py": "", diff --git a/bp2build/python_library_conversion_test.go b/bp2build/python_library_conversion_test.go index e3345921e..6b261052c 100644 --- a/bp2build/python_library_conversion_test.go +++ b/bp2build/python_library_conversion_test.go @@ -18,7 +18,6 @@ func runPythonLibraryTestCase(t *testing.T, tc bp2buildTestCase) { testCase.blueprint = fmt.Sprintf(testCase.blueprint, "python_library") testCase.moduleTypeUnderTest = "python_library" testCase.moduleTypeUnderTestFactory = python.PythonLibraryFactory - testCase.moduleTypeUnderTestBp2BuildMutator = python.PythonLibraryBp2Build runBp2BuildTestCaseSimple(t, testCase) } @@ -29,7 +28,6 @@ func runPythonLibraryHostTestCase(t *testing.T, tc bp2buildTestCase) { testCase.blueprint = fmt.Sprintf(testCase.blueprint, "python_library_host") testCase.moduleTypeUnderTest = "python_library_host" testCase.moduleTypeUnderTestFactory = python.PythonLibraryHostFactory - testCase.moduleTypeUnderTestBp2BuildMutator = python.PythonLibraryHostBp2Build runBp2BuildTestCase(t, func(ctx android.RegistrationContext) { ctx.RegisterModuleType("python_library", python.PythonLibraryFactory) }, diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go index 0d87c8d28..f6d2a2066 100644 --- a/bp2build/sh_conversion_test.go +++ b/bp2build/sh_conversion_test.go @@ -55,10 +55,9 @@ func runShBinaryTestCase(t *testing.T, tc bp2buildTestCase) { func TestShBinarySimple(t *testing.T) { runShBinaryTestCase(t, bp2buildTestCase{ - description: "sh_binary test", - moduleTypeUnderTest: "sh_binary", - moduleTypeUnderTestFactory: sh.ShBinaryFactory, - moduleTypeUnderTestBp2BuildMutator: sh.ShBinaryBp2Build, + description: "sh_binary test", + moduleTypeUnderTest: "sh_binary", + moduleTypeUnderTestFactory: sh.ShBinaryFactory, blueprint: `sh_binary { name: "foo", src: "foo.sh", diff --git a/bp2build/soong_config_module_type_conversion_test.go b/bp2build/soong_config_module_type_conversion_test.go index d21db0459..f1489aab9 100644 --- a/bp2build/soong_config_module_type_conversion_test.go +++ b/bp2build/soong_config_module_type_conversion_test.go @@ -61,11 +61,10 @@ custom_cc_library_static { ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - soong_config_module_type is supported in bp2build", - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, - blueprint: bp, + description: "soong config variables - soong_config_module_type is supported in bp2build", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + blueprint: bp, expectedBazelTargets: []string{`cc_library_static( name = "foo", copts = select({ @@ -107,10 +106,9 @@ custom_cc_library_static { ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - soong_config_module_type_import is supported in bp2build", - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + description: "soong config variables - soong_config_module_type_import is supported in bp2build", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, filesystem: map[string]string{ "foo/bar/SoongConfig.bp": configBp, }, @@ -161,11 +159,10 @@ custom_cc_library_static { ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - generates selects for string vars", - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, - blueprint: bp, + description: "soong config variables - generates selects for string vars", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + blueprint: bp, expectedBazelTargets: []string{`cc_library_static( name = "foo", copts = select({ @@ -232,11 +229,10 @@ custom_cc_library_static { }` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - generates selects for multiple variable types", - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, - blueprint: bp, + description: "soong config variables - generates selects for multiple variable types", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + blueprint: bp, expectedBazelTargets: []string{`cc_library_static( name = "foo", copts = select({ @@ -298,11 +294,10 @@ cc_library_static { name: "soc_default_static_dep", bazel_module: { bp2build_ava ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - generates selects for label list attributes", - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, - blueprint: bp, + description: "soong config variables - generates selects for label list attributes", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + blueprint: bp, filesystem: map[string]string{ "foo/bar/Android.bp": otherDeps, }, @@ -365,11 +360,10 @@ cc_library_static { ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - defaults with a single namespace", - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, - blueprint: bp, + description: "soong config variables - defaults with a single namespace", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + blueprint: bp, expectedBazelTargets: []string{`cc_library_static( name = "lib", copts = select({ @@ -445,11 +439,10 @@ cc_library_static { ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - multiple defaults with a single namespace", - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, - blueprint: bp, + description: "soong config variables - multiple defaults with a single namespace", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + blueprint: bp, expectedBazelTargets: []string{`cc_library_static( name = "lib", asflags = select({ @@ -561,11 +554,10 @@ cc_library_static { ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - defaults with multiple namespaces", - moduleTypeUnderTest: "cc_library_static", - moduleTypeUnderTestFactory: cc.LibraryStaticFactory, - moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, - blueprint: bp, + description: "soong config variables - defaults with multiple namespaces", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + blueprint: bp, expectedBazelTargets: []string{`cc_library_static( name = "lib", copts = select({ @@ -652,11 +644,10 @@ cc_library { name: "lib_default", bazel_module: { bp2build_available: false } } ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - generates selects for library_linking_strategy", - moduleTypeUnderTest: "cc_binary", - moduleTypeUnderTestFactory: cc.BinaryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.BinaryBp2build, - blueprint: bp, + description: "soong config variables - generates selects for library_linking_strategy", + moduleTypeUnderTest: "cc_binary", + moduleTypeUnderTestFactory: cc.BinaryFactory, + blueprint: bp, filesystem: map[string]string{ "foo/bar/Android.bp": otherDeps, }, @@ -733,11 +724,10 @@ cc_library { name: "lib_b", bazel_module: { bp2build_available: false } } ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - generates selects for library_linking_strategy", - moduleTypeUnderTest: "cc_binary", - moduleTypeUnderTestFactory: cc.BinaryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.BinaryBp2build, - blueprint: bp, + description: "soong config variables - generates selects for library_linking_strategy", + moduleTypeUnderTest: "cc_binary", + moduleTypeUnderTestFactory: cc.BinaryFactory, + blueprint: bp, filesystem: map[string]string{ "foo/bar/Android.bp": otherDeps, }, @@ -821,11 +811,10 @@ cc_library { name: "lib_default", bazel_module: { bp2build_available: false } } ` runSoongConfigModuleTypeTest(t, bp2buildTestCase{ - description: "soong config variables - generates selects for library_linking_strategy", - moduleTypeUnderTest: "cc_binary", - moduleTypeUnderTestFactory: cc.BinaryFactory, - moduleTypeUnderTestBp2BuildMutator: cc.BinaryBp2build, - blueprint: bp, + description: "soong config variables - generates selects for library_linking_strategy", + moduleTypeUnderTest: "cc_binary", + moduleTypeUnderTestFactory: cc.BinaryFactory, + blueprint: bp, filesystem: map[string]string{ "foo/bar/Android.bp": otherDeps, }, diff --git a/bp2build/testing.go b/bp2build/testing.go index cd84519f2..8ae1a38ba 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -74,16 +74,15 @@ func runBp2BuildTestCaseSimple(t *testing.T, tc bp2buildTestCase) { } type bp2buildTestCase struct { - description string - moduleTypeUnderTest string - moduleTypeUnderTestFactory android.ModuleFactory - moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext) - blueprint string - expectedBazelTargets []string - filesystem map[string]string - dir string - expectedErr error - unconvertedDepsMode unconvertedDepsMode + description string + moduleTypeUnderTest string + moduleTypeUnderTestFactory android.ModuleFactory + blueprint string + expectedBazelTargets []string + filesystem map[string]string + dir string + expectedErr error + unconvertedDepsMode unconvertedDepsMode } func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) { @@ -105,7 +104,6 @@ func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.Regi registerModuleTypes(ctx) ctx.RegisterModuleType(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestFactory) ctx.RegisterBp2BuildConfig(bp2buildConfig) - ctx.RegisterBp2BuildMutator(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestBp2BuildMutator) ctx.RegisterForBazelConversion() _, parseErrs := ctx.ParseFileList(dir, toParse) @@ -135,8 +133,8 @@ func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.Regi android.FailIfErrored(t, errs) } if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount { - t.Errorf("%s: Expected %d bazel target, got `%d``", - tc.description, expectedCount, actualCount) + t.Errorf("%s: Expected %d bazel target (%s), got `%d`` (%s)", + tc.description, expectedCount, tc.expectedBazelTargets, actualCount, bazelTargets) } else { for i, target := range bazelTargets { if w, g := tc.expectedBazelTargets[i], target.content; w != g { @@ -178,6 +176,9 @@ type customProps struct { Arch_paths []string `android:"path,arch_variant"` Arch_paths_exclude []string `android:"path,arch_variant"` + + // Prop used to indicate this conversion should be 1 module -> multiple targets + One_to_many_prop *bool } type customModule struct { @@ -277,71 +278,65 @@ type customBazelModuleAttributes struct { Arch_paths bazel.LabelListAttribute } -func customBp2BuildMutator(ctx android.TopDownMutatorContext) { - if m, ok := ctx.Module().(*customModule); ok { - if !m.ConvertWithBp2build(ctx) { - return - } +func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + paths := bazel.LabelListAttribute{} - paths := bazel.LabelListAttribute{} + if p := m.props.One_to_many_prop; p != nil && *p { + customBp2buildOneToMany(ctx, m) + return + } - for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) { - for config, props := range configToProps { - if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil { - paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, archProps.Arch_paths, archProps.Arch_paths_exclude)) - } + for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) { + for config, props := range configToProps { + if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil { + paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, archProps.Arch_paths, archProps.Arch_paths_exclude)) } } + } - paths.ResolveExcludes() - - attrs := &customBazelModuleAttributes{ - String_ptr_prop: m.props.String_ptr_prop, - String_list_prop: m.props.String_list_prop, - Arch_paths: paths, - } - attrs.Embedded_attr = m.props.Embedded_prop - if m.props.OtherEmbeddedProps != nil { - attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop} - } + paths.ResolveExcludes() - props := bazel.BazelTargetModuleProperties{ - Rule_class: "custom", - } + attrs := &customBazelModuleAttributes{ + String_ptr_prop: m.props.String_ptr_prop, + String_list_prop: m.props.String_list_prop, + Arch_paths: paths, + } + attrs.Embedded_attr = m.props.Embedded_prop + if m.props.OtherEmbeddedProps != nil { + attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop} + } - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) + props := bazel.BazelTargetModuleProperties{ + Rule_class: "custom", } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) } // A bp2build mutator that uses load statements and creates a 1:M mapping from // module to target. -func customBp2BuildMutatorFromStarlark(ctx android.TopDownMutatorContext) { - if m, ok := ctx.Module().(*customModule); ok { - if !m.ConvertWithBp2build(ctx) { - return - } +func customBp2buildOneToMany(ctx android.TopDownMutatorContext, m *customModule) { - baseName := m.Name() - attrs := &customBazelModuleAttributes{} + baseName := m.Name() + attrs := &customBazelModuleAttributes{} - myLibraryProps := bazel.BazelTargetModuleProperties{ - Rule_class: "my_library", - Bzl_load_location: "//build/bazel/rules:rules.bzl", - } - ctx.CreateBazelTargetModule(myLibraryProps, android.CommonAttributes{Name: baseName}, attrs) + myLibraryProps := bazel.BazelTargetModuleProperties{ + Rule_class: "my_library", + Bzl_load_location: "//build/bazel/rules:rules.bzl", + } + ctx.CreateBazelTargetModule(myLibraryProps, android.CommonAttributes{Name: baseName}, attrs) - protoLibraryProps := bazel.BazelTargetModuleProperties{ - Rule_class: "proto_library", - Bzl_load_location: "//build/bazel/rules:proto.bzl", - } - ctx.CreateBazelTargetModule(protoLibraryProps, android.CommonAttributes{Name: baseName + "_proto_library_deps"}, attrs) + protoLibraryProps := bazel.BazelTargetModuleProperties{ + Rule_class: "proto_library", + Bzl_load_location: "//build/bazel/rules:proto.bzl", + } + ctx.CreateBazelTargetModule(protoLibraryProps, android.CommonAttributes{Name: baseName + "_proto_library_deps"}, attrs) - myProtoLibraryProps := bazel.BazelTargetModuleProperties{ - Rule_class: "my_proto_library", - Bzl_load_location: "//build/bazel/rules:proto.bzl", - } - ctx.CreateBazelTargetModule(myProtoLibraryProps, android.CommonAttributes{Name: baseName + "_my_proto_library_deps"}, attrs) + myProtoLibraryProps := bazel.BazelTargetModuleProperties{ + Rule_class: "my_proto_library", + Bzl_load_location: "//build/bazel/rules:proto.bzl", } + ctx.CreateBazelTargetModule(myProtoLibraryProps, android.CommonAttributes{Name: baseName + "_my_proto_library_deps"}, attrs) } // Helper method for tests to easily access the targets in a dir. @@ -353,7 +348,6 @@ func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTa func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) { ctx.RegisterModuleType("custom", customModuleFactory) - ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator) ctx.RegisterForBazelConversion() } diff --git a/cc/binary.go b/cc/binary.go index e839122f4..50175d92f 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -69,13 +69,14 @@ func RegisterBinaryBuildComponents(ctx android.RegistrationContext) { // cc_binary produces a binary that is runnable on a device. func BinaryFactory() android.Module { - module, _ := NewBinary(android.HostAndDeviceSupported) + module, _ := newBinary(android.HostAndDeviceSupported, true) return module.Init() } // cc_binary_host produces a binary that is runnable on a host. func BinaryHostFactory() android.Module { - module, _ := NewBinary(android.HostSupported) + module, _ := newBinary(android.HostSupported, true) + module.bazelable = true return module.Init() } @@ -193,6 +194,10 @@ func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { // Individual module implementations which comprise a C++ binary should call this function, // set some fields on the result, and then call the Init function. func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { + return newBinary(hod, true) +} + +func newBinary(hod android.HostOrDeviceSupported, bazelable bool) (*Module, *binaryDecorator) { module := newModule(hod, android.MultilibFirst) binary := &binaryDecorator{ baseLinker: NewBaseLinker(module.sanitize), @@ -201,6 +206,7 @@ func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { module.compiler = NewBaseCompiler() module.linker = binary module.installer = binary + module.bazelable = bazelable // Allow module to be added as member of an sdk/module_exports. module.sdkMemberTypes = []android.SdkMemberType{ @@ -551,33 +557,7 @@ func (binary *binaryDecorator) verifyHostBionicLinker(ctx ModuleContext, in, lin }) } -func init() { - android.RegisterBp2BuildMutator("cc_binary", BinaryBp2build) - android.RegisterBp2BuildMutator("cc_binary_host", BinaryHostBp2build) -} - -func BinaryBp2build(ctx android.TopDownMutatorContext) { - binaryBp2build(ctx, "cc_binary") -} - -func BinaryHostBp2build(ctx android.TopDownMutatorContext) { - binaryBp2build(ctx, "cc_binary_host") -} - -func binaryBp2build(ctx android.TopDownMutatorContext, typ string) { - m, ok := ctx.Module().(*Module) - if !ok { - // Not a cc module - return - } - if !m.ConvertWithBp2build(ctx) { - return - } - - if ctx.ModuleType() != typ { - return - } - +func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) { var compatibleWith bazel.StringListAttribute if typ == "cc_binary_host" { //incompatible with android OS diff --git a/cc/bp2build.go b/cc/bp2build.go index f9bbe8752..fad40beea 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -16,6 +16,7 @@ package cc import ( "fmt" "path/filepath" + "regexp" "strings" "android/soong/android" @@ -33,6 +34,12 @@ const ( protoSrcPartition = "proto" ) +var ( + // ignoring case, checks for proto or protos as an independent word in the name, whether at the + // beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match + filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)") +) + // staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties -- // properties which apply to either the shared or static version of a cc_library module. type staticOrSharedAttributes struct { @@ -77,18 +84,18 @@ func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.Lab if !exists || !isFilegroup(m) { return labelStr, false } - likelyProtos := strings.HasSuffix(labelStr, "proto") || strings.HasSuffix(labelStr, "protos") + likelyProtos := filegroupLikelyProtoPattern.MatchString(label.OriginalModuleName) return labelStr, likelyProtos } // TODO(b/190006308): Handle language detection of sources in a Bazel rule. partitioned := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{ - cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")}, - asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")}, + protoSrcPartition: bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup}, + cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")}, + asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")}, // C++ is the "catch-all" group, and comprises generated sources because we don't // know the language of these sources until the genrule is executed. - cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true}, - protoSrcPartition: bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup}, + cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true}, }) return partitioned @@ -267,6 +274,8 @@ type compilerAttributes struct { localIncludes bazel.StringListAttribute absoluteIncludes bazel.StringListAttribute + includes BazelIncludes + protoSrcs bazel.LabelListAttribute } @@ -412,6 +421,33 @@ func bp2buildResolveCppStdValue(c_std *string, cpp_std *string, gnu_extensions * return c_std_prop, cpp_std_prop } +// packageFromLabel extracts package from a fully-qualified or relative Label and whether the label +// is fully-qualified. +// e.g. fully-qualified "//a/b:foo" -> "a/b", true, relative: ":bar" -> ".", false +func packageFromLabel(label string) (string, bool) { + split := strings.Split(label, ":") + if len(split) != 2 { + return "", false + } + if split[0] == "" { + return ".", false + } + // remove leading "//" + return split[0][2:], true +} + +// includesFromLabelList extracts relative/absolute includes from a bazel.LabelList> +func includesFromLabelList(labelList bazel.LabelList) (relative, absolute []string) { + for _, hdr := range labelList.Includes { + if pkg, hasPkg := packageFromLabel(hdr.Label); hasPkg { + absolute = append(absolute, pkg) + } else if pkg != "" { + relative = append(relative, pkg) + } + } + return relative, absolute +} + // bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes. func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) baseAttributes { archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) @@ -455,6 +491,18 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) headers := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrs, exportHdrs, android.BazelLabelForModuleDeps) implementationHdrs.SetSelectValue(axis, config, headers.implementation) compilerAttrs.hdrs.SetSelectValue(axis, config, headers.export) + + exportIncludes, exportAbsoluteIncludes := includesFromLabelList(headers.export) + compilerAttrs.includes.Includes.SetSelectValue(axis, config, exportIncludes) + compilerAttrs.includes.AbsoluteIncludes.SetSelectValue(axis, config, exportAbsoluteIncludes) + + includes, absoluteIncludes := includesFromLabelList(headers.implementation) + currAbsoluteIncludes := compilerAttrs.absoluteIncludes.SelectValue(axis, config) + currAbsoluteIncludes = android.FirstUniqueStrings(append(currAbsoluteIncludes, absoluteIncludes...)) + compilerAttrs.absoluteIncludes.SetSelectValue(axis, config, currAbsoluteIncludes) + currIncludes := compilerAttrs.localIncludes.SelectValue(axis, config) + currIncludes = android.FirstUniqueStrings(append(currIncludes, includes...)) + compilerAttrs.localIncludes.SetSelectValue(axis, config, currIncludes) } } @@ -496,6 +544,7 @@ type linkerAttributes struct { linkCrt bazel.BoolAttribute useLibcrt bazel.BoolAttribute + useVersionLib bazel.BoolAttribute linkopts bazel.StringListAttribute additionalLinkerInputs bazel.LabelListAttribute stripKeepSymbols bazel.BoolAttribute @@ -565,6 +614,10 @@ func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversion la.linkopts.SetSelectValue(axis, config, linkerFlags) la.useLibcrt.SetSelectValue(axis, config, props.libCrt()) + if axis == bazel.NoConfigAxis { + la.useVersionLib.SetSelectValue(axis, config, props.Use_version_lib) + } + // it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it. if props.crt() != nil { if axis == bazel.NoConfigAxis { @@ -687,13 +740,14 @@ func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, p // BazelIncludes contains information about -I and -isystem paths from a module converted to Bazel // attributes. type BazelIncludes struct { - Includes bazel.StringListAttribute - SystemIncludes bazel.StringListAttribute + AbsoluteIncludes bazel.StringListAttribute + Includes bazel.StringListAttribute + SystemIncludes bazel.StringListAttribute } -func bp2BuildParseExportedIncludes(ctx android.BazelConversionPathContext, module *Module) BazelIncludes { +func bp2BuildParseExportedIncludes(ctx android.BazelConversionPathContext, module *Module, existingIncludes BazelIncludes) BazelIncludes { libraryDecorator := module.linker.(*libraryDecorator) - return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator) + return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator, &existingIncludes) } // Bp2buildParseExportedIncludesForPrebuiltLibrary returns a BazelIncludes with Bazel-ified values @@ -701,25 +755,31 @@ func bp2BuildParseExportedIncludes(ctx android.BazelConversionPathContext, modul func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.BazelConversionPathContext, module *Module) BazelIncludes { prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker) libraryDecorator := prebuiltLibraryLinker.libraryDecorator - return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator) + return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator, nil) } // bp2BuildParseExportedIncludes creates a string list attribute contains the // exported included directories of a module. -func bp2BuildParseExportedIncludesHelper(ctx android.BazelConversionPathContext, module *Module, libraryDecorator *libraryDecorator) BazelIncludes { - exported := BazelIncludes{} +func bp2BuildParseExportedIncludesHelper(ctx android.BazelConversionPathContext, module *Module, libraryDecorator *libraryDecorator, includes *BazelIncludes) BazelIncludes { + var exported BazelIncludes + if includes != nil { + exported = *includes + } else { + exported = BazelIncludes{} + } for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) { for config, props := range configToProps { if flagExporterProperties, ok := props.(*FlagExporterProperties); ok { if len(flagExporterProperties.Export_include_dirs) > 0 { - exported.Includes.SetSelectValue(axis, config, flagExporterProperties.Export_include_dirs) + exported.Includes.SetSelectValue(axis, config, android.FirstUniqueStrings(append(exported.Includes.SelectValue(axis, config), flagExporterProperties.Export_include_dirs...))) } if len(flagExporterProperties.Export_system_include_dirs) > 0 { - exported.SystemIncludes.SetSelectValue(axis, config, flagExporterProperties.Export_system_include_dirs) + exported.SystemIncludes.SetSelectValue(axis, config, android.FirstUniqueStrings(append(exported.SystemIncludes.SelectValue(axis, config), flagExporterProperties.Export_system_include_dirs...))) } } } } + exported.AbsoluteIncludes.DeduplicateAxesFromBase() exported.Includes.DeduplicateAxesFromBase() exported.SystemIncludes.DeduplicateAxesFromBase() @@ -786,8 +786,9 @@ type Module struct { Properties BaseProperties // initialize before calling Init - hod android.HostOrDeviceSupported - multilib android.Multilib + hod android.HostOrDeviceSupported + multilib android.Multilib + bazelable bool // Allowable SdkMemberTypes of this module type. sdkMemberTypes []android.SdkMemberType @@ -1150,7 +1151,9 @@ func (c *Module) Init() android.Module { } android.InitAndroidArchModule(c, c.hod, c.multilib) - android.InitBazelModule(c) + if c.bazelable { + android.InitBazelModule(c) + } android.InitApexModule(c) android.InitSdkAwareModule(c) android.InitDefaultableModule(c) @@ -3185,6 +3188,24 @@ func (c *Module) testBinary() bool { return false } +func (c *Module) benchmarkBinary() bool { + if b, ok := c.linker.(interface { + benchmarkBinary() bool + }); ok { + return b.benchmarkBinary() + } + return false +} + +func (c *Module) fuzzBinary() bool { + if f, ok := c.linker.(interface { + fuzzBinary() bool + }); ok { + return f.fuzzBinary() + } + return false +} + // Header returns true if the module is a header-only variant. (See cc/library.go header()). func (c *Module) Header() bool { if h, ok := c.linker.(interface { @@ -3430,6 +3451,45 @@ func (c *Module) AlwaysRequiresPlatformApexVariant() bool { var _ snapshot.RelativeInstallPath = (*Module)(nil) +// ConvertWithBp2build converts Module to Bazel for bp2build. +func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + prebuilt := c.IsPrebuilt() + if c.Binary() { + if !prebuilt { + binaryBp2build(ctx, c, ctx.ModuleType()) + } + } else if c.Object() { + if !prebuilt { + objectBp2Build(ctx, c) + } + } else if c.CcLibrary() { + static := c.BuildStaticVariant() + shared := c.BuildSharedVariant() + + if static && shared { + if !prebuilt { + libraryBp2Build(ctx, c) + } + } else if !static && !shared { + if !prebuilt { + libraryHeadersBp2Build(ctx, c) + } + } else if static { + if prebuilt { + prebuiltLibraryStaticBp2Build(ctx, c) + } else { + sharedOrStaticLibraryBp2Build(ctx, c, true) + } + } else if shared { + if prebuilt { + prebuiltLibrarySharedBp2Build(ctx, c) + } else { + sharedOrStaticLibraryBp2Build(ctx, c, false) + } + } + } +} + // // Defaults // diff --git a/cc/fuzz.go b/cc/fuzz.go index e987fe43b..23d81d600 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -52,6 +52,10 @@ type fuzzBinary struct { installedSharedDeps []string } +func (fuzz *fuzzBinary) fuzzBinary() bool { + return true +} + func (fuzz *fuzzBinary) linkerProps() []interface{} { props := fuzz.binaryDecorator.linkerProps() props = append(props, &fuzz.fuzzPackagedModule.FuzzProperties) @@ -234,7 +238,7 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { } func NewFuzz(hod android.HostOrDeviceSupported) *Module { - module, binary := NewBinary(hod) + module, binary := newBinary(hod, false) binary.baseInstaller = NewFuzzInstaller() module.sanitize.SetSanitizer(Fuzzer, true) diff --git a/cc/library.go b/cc/library.go index a081c7db0..216c12409 100644 --- a/cc/library.go +++ b/cc/library.go @@ -207,10 +207,6 @@ type FlagExporterProperties struct { func init() { RegisterLibraryBuildComponents(android.InitRegistrationContext) - - android.RegisterBp2BuildMutator("cc_library_static", CcLibraryStaticBp2Build) - android.RegisterBp2BuildMutator("cc_library_shared", CcLibrarySharedBp2Build) - android.RegisterBp2BuildMutator("cc_library", CcLibraryBp2Build) } func RegisterLibraryBuildComponents(ctx android.RegistrationContext) { @@ -277,21 +273,12 @@ type stripAttributes struct { None bazel.BoolAttribute } -func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { - m, ok := ctx.Module().(*Module) - if !ok || !m.ConvertWithBp2build(ctx) { - return - } - - if ctx.ModuleType() != "cc_library" { - return - } - +func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { // For some cc_library modules, their static variants are ready to be // converted, but not their shared variants. For these modules, delegate to // the cc_library_static bp2build converter temporarily instead. if android.GenerateCcLibraryStaticOnly(ctx.Module().Name()) { - ccSharedOrStaticBp2BuildMutatorInternal(ctx, m, "cc_library_static") + sharedOrStaticLibraryBp2Build(ctx, m, true) return } @@ -300,7 +287,7 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { baseAttributes := bp2BuildParseBaseProps(ctx, m) compilerAttrs := baseAttributes.compilerAttributes linkerAttrs := baseAttributes.linkerAttributes - exportedIncludes := bp2BuildParseExportedIncludes(ctx, m) + exportedIncludes := bp2BuildParseExportedIncludes(ctx, m, compilerAttrs.includes) srcs := compilerAttrs.srcs @@ -351,15 +338,16 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { Conlyflags: compilerAttrs.conlyFlags, Asflags: asFlags, - Export_includes: exportedIncludes.Includes, - Export_system_includes: exportedIncludes.SystemIncludes, - Local_includes: compilerAttrs.localIncludes, - Absolute_includes: compilerAttrs.absoluteIncludes, - Use_libcrt: linkerAttrs.useLibcrt, - Rtti: compilerAttrs.rtti, - Stl: compilerAttrs.stl, - Cpp_std: compilerAttrs.cppStd, - C_std: compilerAttrs.cStd, + Export_includes: exportedIncludes.Includes, + Export_absolute_includes: exportedIncludes.AbsoluteIncludes, + Export_system_includes: exportedIncludes.SystemIncludes, + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, + Use_libcrt: linkerAttrs.useLibcrt, + Rtti: compilerAttrs.rtti, + Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, + C_std: compilerAttrs.cStd, Features: linkerAttrs.features, } @@ -370,17 +358,18 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { Conlyflags: compilerAttrs.conlyFlags, Asflags: asFlags, - Export_includes: exportedIncludes.Includes, - Export_system_includes: exportedIncludes.SystemIncludes, - Local_includes: compilerAttrs.localIncludes, - Absolute_includes: compilerAttrs.absoluteIncludes, - Linkopts: linkerAttrs.linkopts, - Link_crt: linkerAttrs.linkCrt, - Use_libcrt: linkerAttrs.useLibcrt, - Rtti: compilerAttrs.rtti, - Stl: compilerAttrs.stl, - Cpp_std: compilerAttrs.cppStd, - C_std: compilerAttrs.cStd, + Export_includes: exportedIncludes.Includes, + Export_absolute_includes: exportedIncludes.AbsoluteIncludes, + Export_system_includes: exportedIncludes.SystemIncludes, + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, + Linkopts: linkerAttrs.linkopts, + Link_crt: linkerAttrs.linkCrt, + Use_libcrt: linkerAttrs.useLibcrt, + Rtti: compilerAttrs.rtti, + Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, + C_std: compilerAttrs.cStd, Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, @@ -419,6 +408,7 @@ func LibraryFactory() android.Module { staticLibrarySdkMemberType, staticAndSharedLibrarySdkMemberType, } + module.bazelable = true module.bazelHandler = &ccLibraryBazelHandler{module: module} return module.Init() } @@ -428,6 +418,7 @@ func LibraryStaticFactory() android.Module { module, library := NewLibrary(android.HostAndDeviceSupported) library.BuildOnlyStatic() module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType} + module.bazelable = true module.bazelHandler = &ccLibraryBazelHandler{module: module} return module.Init() } @@ -437,6 +428,7 @@ func LibrarySharedFactory() android.Module { module, library := NewLibrary(android.HostAndDeviceSupported) library.BuildOnlyShared() module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType} + module.bazelable = true module.bazelHandler = &ccLibraryBazelHandler{module: module} return module.Init() } @@ -455,6 +447,8 @@ func LibraryHostSharedFactory() android.Module { module, library := NewLibrary(android.HostSupported) library.BuildOnlyShared() module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType} + module.bazelable = true + module.bazelHandler = &ccLibraryBazelHandler{module: module} return module.Init() } @@ -2411,30 +2405,12 @@ func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.Modu return outputFile } -func ccSharedOrStaticBp2BuildMutator(ctx android.TopDownMutatorContext, modType string) { - module, ok := ctx.Module().(*Module) - if !ok { - // Not a cc module - return - } - if !module.ConvertWithBp2build(ctx) { - return - } - - ccSharedOrStaticBp2BuildMutatorInternal(ctx, module, modType) -} - -func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, module *Module, modType string) { - if modType != "cc_library_static" && modType != "cc_library_shared" { - panic("ccSharedOrStaticBp2BuildMutatorInternal only supports cc_library_{static,shared}") - } - isStatic := modType == "cc_library_static" - +func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module, isStatic bool) { baseAttributes := bp2BuildParseBaseProps(ctx, module) compilerAttrs := baseAttributes.compilerAttributes linkerAttrs := baseAttributes.linkerAttributes - exportedIncludes := bp2BuildParseExportedIncludes(ctx, module) + exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, compilerAttrs.includes) // Append shared/static{} stanza properties. These won't be specified on // cc_library_* itself, but may be specified in cc_defaults that this module @@ -2480,15 +2456,19 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, attrs = &bazelCcLibraryStaticAttributes{ staticOrSharedAttributes: commonAttrs, - Use_libcrt: linkerAttrs.useLibcrt, - Rtti: compilerAttrs.rtti, - Stl: compilerAttrs.stl, - Cpp_std: compilerAttrs.cppStd, - C_std: compilerAttrs.cStd, - Export_includes: exportedIncludes.Includes, - Export_system_includes: exportedIncludes.SystemIncludes, - Local_includes: compilerAttrs.localIncludes, - Absolute_includes: compilerAttrs.absoluteIncludes, + Use_libcrt: linkerAttrs.useLibcrt, + Use_version_lib: linkerAttrs.useVersionLib, + + Rtti: compilerAttrs.rtti, + Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, + C_std: compilerAttrs.cStd, + + Export_includes: exportedIncludes.Includes, + Export_absolute_includes: exportedIncludes.AbsoluteIncludes, + Export_system_includes: exportedIncludes.SystemIncludes, + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, Cppflags: compilerAttrs.cppFlags, Conlyflags: compilerAttrs.conlyFlags, @@ -2505,16 +2485,19 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, Cppflags: compilerAttrs.cppFlags, Conlyflags: compilerAttrs.conlyFlags, Asflags: asFlags, - Linkopts: linkerAttrs.linkopts, - Link_crt: linkerAttrs.linkCrt, - Use_libcrt: linkerAttrs.useLibcrt, - Rtti: compilerAttrs.rtti, - Stl: compilerAttrs.stl, - Cpp_std: compilerAttrs.cppStd, - C_std: compilerAttrs.cStd, + Linkopts: linkerAttrs.linkopts, + Link_crt: linkerAttrs.linkCrt, + Use_libcrt: linkerAttrs.useLibcrt, + Use_version_lib: linkerAttrs.useVersionLib, + + Rtti: compilerAttrs.rtti, + Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, + C_std: compilerAttrs.cStd, Export_includes: exportedIncludes.Includes, + Export_absolute_includes: exportedIncludes.AbsoluteIncludes, Export_system_includes: exportedIncludes.SystemIncludes, Local_includes: compilerAttrs.localIncludes, Absolute_includes: compilerAttrs.absoluteIncludes, @@ -2532,6 +2515,12 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, } } + var modType string + if isStatic { + modType = "cc_library_static" + } else { + modType = "cc_library_shared" + } props := bazel.BazelTargetModuleProperties{ Rule_class: modType, Bzl_load_location: fmt.Sprintf("//build/bazel/rules:%s.bzl", modType), @@ -2544,17 +2533,20 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, type bazelCcLibraryStaticAttributes struct { staticOrSharedAttributes - Use_libcrt bazel.BoolAttribute - Rtti bazel.BoolAttribute - Stl *string - Cpp_std *string - C_std *string + Use_libcrt bazel.BoolAttribute + Use_version_lib bazel.BoolAttribute - Export_includes bazel.StringListAttribute - Export_system_includes bazel.StringListAttribute - Local_includes bazel.StringListAttribute - Absolute_includes bazel.StringListAttribute - Hdrs bazel.LabelListAttribute + Rtti bazel.BoolAttribute + Stl *string + Cpp_std *string + C_std *string + + Export_includes bazel.StringListAttribute + Export_absolute_includes bazel.StringListAttribute + Export_system_includes bazel.StringListAttribute + Local_includes bazel.StringListAttribute + Absolute_includes bazel.StringListAttribute + Hdrs bazel.LabelListAttribute Cppflags bazel.StringListAttribute Conlyflags bazel.StringListAttribute @@ -2563,35 +2555,27 @@ type bazelCcLibraryStaticAttributes struct { Features bazel.StringListAttribute } -func CcLibraryStaticBp2Build(ctx android.TopDownMutatorContext) { - isLibraryStatic := ctx.ModuleType() == "cc_library_static" - if b, ok := ctx.Module().(android.Bazelable); ok { - // This is created by a custom soong config module type, so its ctx.ModuleType() is not - // cc_library_static. Check its BaseModuleType. - isLibraryStatic = isLibraryStatic || b.BaseModuleType() == "cc_library_static" - } - if isLibraryStatic { - ccSharedOrStaticBp2BuildMutator(ctx, "cc_library_static") - } -} - // TODO(b/199902614): Can this be factored to share with the other Attributes? type bazelCcLibrarySharedAttributes struct { staticOrSharedAttributes - Linkopts bazel.StringListAttribute - Link_crt bazel.BoolAttribute // Only for linking shared library (and cc_binary) - Use_libcrt bazel.BoolAttribute - Rtti bazel.BoolAttribute - Stl *string - Cpp_std *string - C_std *string + Linkopts bazel.StringListAttribute + Link_crt bazel.BoolAttribute // Only for linking shared library (and cc_binary) - Export_includes bazel.StringListAttribute - Export_system_includes bazel.StringListAttribute - Local_includes bazel.StringListAttribute - Absolute_includes bazel.StringListAttribute - Hdrs bazel.LabelListAttribute + Use_libcrt bazel.BoolAttribute + Use_version_lib bazel.BoolAttribute + + Rtti bazel.BoolAttribute + Stl *string + Cpp_std *string + C_std *string + + Export_includes bazel.StringListAttribute + Export_absolute_includes bazel.StringListAttribute + Export_system_includes bazel.StringListAttribute + Local_includes bazel.StringListAttribute + Absolute_includes bazel.StringListAttribute + Hdrs bazel.LabelListAttribute Strip stripAttributes Additional_linker_inputs bazel.LabelListAttribute @@ -2602,15 +2586,3 @@ type bazelCcLibrarySharedAttributes struct { Features bazel.StringListAttribute } - -func CcLibrarySharedBp2Build(ctx android.TopDownMutatorContext) { - isLibraryShared := ctx.ModuleType() == "cc_library_shared" - if b, ok := ctx.Module().(android.Bazelable); ok { - // This is created by a custom soong config module type, so its ctx.ModuleType() is not - // cc_library_shared. Check its BaseModuleType. - isLibraryShared = isLibraryShared || b.BaseModuleType() == "cc_library_shared" - } - if isLibraryShared { - ccSharedOrStaticBp2BuildMutator(ctx, "cc_library_shared") - } -} diff --git a/cc/library_headers.go b/cc/library_headers.go index 141a2a56b..70e4715ad 100644 --- a/cc/library_headers.go +++ b/cc/library_headers.go @@ -25,7 +25,6 @@ func init() { // Register sdk member types. android.RegisterSdkMemberType(headersLibrarySdkMemberType) - android.RegisterBp2BuildMutator("cc_library_headers", CcLibraryHeadersBp2Build) } var headersLibrarySdkMemberType = &librarySdkMemberType{ @@ -96,6 +95,7 @@ func LibraryHeaderFactory() android.Module { module, library := NewLibrary(android.HostAndDeviceSupported) library.HeaderOnly() module.sdkMemberTypes = []android.SdkMemberType{headersLibrarySdkMemberType} + module.bazelable = true module.bazelHandler = &libraryHeaderBazelHander{module: module, library: library} return module.Init() } @@ -108,40 +108,28 @@ func prebuiltLibraryHeaderFactory() android.Module { } type bazelCcLibraryHeadersAttributes struct { - Hdrs bazel.LabelListAttribute - Export_includes bazel.StringListAttribute - Export_system_includes bazel.StringListAttribute - Deps bazel.LabelListAttribute - Implementation_deps bazel.LabelListAttribute - System_dynamic_deps bazel.LabelListAttribute + Hdrs bazel.LabelListAttribute + Export_includes bazel.StringListAttribute + Export_absolute_includes bazel.StringListAttribute + Export_system_includes bazel.StringListAttribute + Deps bazel.LabelListAttribute + Implementation_deps bazel.LabelListAttribute + System_dynamic_deps bazel.LabelListAttribute } -func CcLibraryHeadersBp2Build(ctx android.TopDownMutatorContext) { - module, ok := ctx.Module().(*Module) - if !ok { - // Not a cc module - return - } - - if !module.ConvertWithBp2build(ctx) { - return - } - - if ctx.ModuleType() != "cc_library_headers" { - return - } - - exportedIncludes := bp2BuildParseExportedIncludes(ctx, module) +func libraryHeadersBp2Build(ctx android.TopDownMutatorContext, module *Module) { baseAttributes := bp2BuildParseBaseProps(ctx, module) + exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, baseAttributes.includes) linkerAttrs := baseAttributes.linkerAttributes attrs := &bazelCcLibraryHeadersAttributes{ - Export_includes: exportedIncludes.Includes, - Export_system_includes: exportedIncludes.SystemIncludes, - Implementation_deps: linkerAttrs.implementationDeps, - Deps: linkerAttrs.deps, - System_dynamic_deps: linkerAttrs.systemDynamicDeps, - Hdrs: baseAttributes.hdrs, + Export_includes: exportedIncludes.Includes, + Export_absolute_includes: exportedIncludes.AbsoluteIncludes, + Export_system_includes: exportedIncludes.SystemIncludes, + Implementation_deps: linkerAttrs.implementationDeps, + Deps: linkerAttrs.deps, + System_dynamic_deps: linkerAttrs.systemDynamicDeps, + Hdrs: baseAttributes.hdrs, } props := bazel.BazelTargetModuleProperties{ diff --git a/cc/object.go b/cc/object.go index 0327a451a..bd43e3670 100644 --- a/cc/object.go +++ b/cc/object.go @@ -29,7 +29,6 @@ func init() { android.RegisterModuleType("cc_object", ObjectFactory) android.RegisterSdkMemberType(ccObjectSdkMemberType) - android.RegisterBp2BuildMutator("cc_object", ObjectBp2Build) } var ccObjectSdkMemberType = &librarySdkMemberType{ @@ -117,6 +116,7 @@ func ObjectFactory() android.Module { module.sdkMemberTypes = []android.SdkMemberType{ccObjectSdkMemberType} + module.bazelable = true return module.Init() } @@ -135,19 +135,9 @@ type bazelObjectAttributes struct { Linker_script bazel.LabelAttribute } -// ObjectBp2Build is the bp2build converter from cc_object modules to the +// objectBp2Build is the bp2build converter from cc_object modules to the // Bazel equivalent target, plus any necessary include deps for the cc_object. -func ObjectBp2Build(ctx android.TopDownMutatorContext) { - m, ok := ctx.Module().(*Module) - if !ok || !m.ConvertWithBp2build(ctx) { - return - } - - // a Module can be something other than a cc_object. - if ctx.ModuleType() != "cc_object" { - return - } - +func objectBp2Build(ctx android.TopDownMutatorContext, m *Module) { if m.compiler == nil { // a cc_object must have access to the compiler decorator for its props. ctx.ModuleErrorf("compiler must not be nil for a cc_object module") diff --git a/cc/prebuilt.go b/cc/prebuilt.go index c303fda99..feae81266 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -32,8 +32,6 @@ func RegisterPrebuiltBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory) ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory) ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory) - - android.RegisterBp2BuildMutator("cc_prebuilt_library_shared", PrebuiltLibrarySharedBp2Build) } type prebuiltLinkerInterface interface { @@ -299,6 +297,7 @@ func PrebuiltSharedTestLibraryFactory() android.Module { func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { module, library := NewPrebuiltLibrary(hod, "srcs") library.BuildOnlyShared() + module.bazelable = true // Prebuilt shared libraries can be included in APEXes android.InitApexModule(module) @@ -316,31 +315,41 @@ func PrebuiltStaticLibraryFactory() android.Module { func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { module, library := NewPrebuiltLibrary(hod, "srcs") library.BuildOnlyStatic() + module.bazelable = true module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library} return module, library } -type bazelPrebuiltLibrarySharedAttributes struct { - Shared_library bazel.LabelAttribute +type bazelPrebuiltLibraryStaticAttributes struct { + Static_library bazel.LabelAttribute + Export_includes bazel.StringListAttribute + Export_system_includes bazel.StringListAttribute } -func PrebuiltLibrarySharedBp2Build(ctx android.TopDownMutatorContext) { - module, ok := ctx.Module().(*Module) - if !ok { - // Not a cc module - return - } - if !module.ConvertWithBp2build(ctx) { - return +func prebuiltLibraryStaticBp2Build(ctx android.TopDownMutatorContext, module *Module) { + prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module) + exportedIncludes := Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx, module) + + attrs := &bazelPrebuiltLibraryStaticAttributes{ + Static_library: prebuiltAttrs.Src, + Export_includes: exportedIncludes.Includes, + Export_system_includes: exportedIncludes.SystemIncludes, } - if ctx.ModuleType() != "cc_prebuilt_library_shared" { - return + + props := bazel.BazelTargetModuleProperties{ + Rule_class: "prebuilt_library_static", + Bzl_load_location: "//build/bazel/rules:prebuilt_library_static.bzl", } - prebuiltLibrarySharedBp2BuildInternal(ctx, module) + name := android.RemoveOptionalPrebuiltPrefix(module.Name()) + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs) +} + +type bazelPrebuiltLibrarySharedAttributes struct { + Shared_library bazel.LabelAttribute } -func prebuiltLibrarySharedBp2BuildInternal(ctx android.TopDownMutatorContext, module *Module) { +func prebuiltLibrarySharedBp2Build(ctx android.TopDownMutatorContext, module *Module) { prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module) attrs := &bazelPrebuiltLibrarySharedAttributes{ @@ -543,7 +552,7 @@ func prebuiltBinaryFactory() android.Module { } func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { - module, binary := NewBinary(hod) + module, binary := newBinary(hod, false) module.compiler = nil prebuilt := &prebuiltBinaryLinker{ diff --git a/cc/test.go b/cc/test.go index 0ca96f751..d8b7833ba 100644 --- a/cc/test.go +++ b/cc/test.go @@ -461,7 +461,7 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { } func NewTest(hod android.HostOrDeviceSupported) *Module { - module, binary := NewBinary(hod) + module, binary := newBinary(hod, false) module.multilib = android.MultilibBoth binary.baseInstaller = NewTestInstaller() @@ -551,6 +551,10 @@ type benchmarkDecorator struct { testConfig android.Path } +func (benchmark *benchmarkDecorator) benchmarkBinary() bool { + return true +} + func (benchmark *benchmarkDecorator) linkerInit(ctx BaseModuleContext) { runpath := "../../lib" if ctx.toolchain().Is64Bit() { @@ -588,7 +592,7 @@ func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Pat } func NewBenchmark(hod android.HostOrDeviceSupported) *Module { - module, binary := NewBinary(hod) + module, binary := newBinary(hod, false) module.multilib = android.MultilibBoth binary.baseInstaller = NewBaseInstaller("benchmarktest", "benchmarktest64", InstallInData) diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index c81d4bc6a..f07eafabe 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -537,6 +537,7 @@ func runBp2Build(configuration android.Config, extraNinjaDeps []string) { // for queryview, since that's a total repo-wide conversion and there's a // 1:1 mapping for each module. metrics.Print() + writeBp2BuildMetrics(&metrics, configuration) ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...) ninjaDeps = append(ninjaDeps, symlinkForestDeps...) @@ -546,3 +547,13 @@ func runBp2Build(configuration android.Config, extraNinjaDeps []string) { // Create an empty bp2build marker file. touch(shared.JoinPath(topDir, bp2buildMarker)) } + +// Write Bp2Build metrics into $LOG_DIR +func writeBp2BuildMetrics(metrics *bp2build.CodegenMetrics, configuration android.Config) { + metricsDir := configuration.Getenv("LOG_DIR") + if len(metricsDir) < 1 { + fmt.Fprintf(os.Stderr, "\nMissing required env var for generating bp2build metrics: LOG_DIR\n") + os.Exit(1) + } + metrics.Write(metricsDir) +} diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index 2865ffad2..80ab41be6 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -63,7 +63,6 @@ func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("prebuilt_defaults", defaultsFactory) - android.RegisterBp2BuildMutator("prebuilt_etc", PrebuiltEtcBp2Build) } var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents) @@ -663,20 +662,14 @@ type bazelPrebuiltEtcAttributes struct { Installable bazel.BoolAttribute } -func PrebuiltEtcBp2Build(ctx android.TopDownMutatorContext) { - module, ok := ctx.Module().(*PrebuiltEtc) - if !ok { - // Not an prebuilt_etc - return - } - if !module.ConvertWithBp2build(ctx) { - return - } +// ConvertWithBp2build performs bp2build conversion of PrebuiltEtc +func (p *PrebuiltEtc) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + // All prebuilt_* modules are PrebuiltEtc, but at this time, we only convert prebuilt_etc modules. if ctx.ModuleType() != "prebuilt_etc" { return } - prebuiltEtcBp2BuildInternal(ctx, module) + prebuiltEtcBp2BuildInternal(ctx, p) } func prebuiltEtcBp2BuildInternal(ctx android.TopDownMutatorContext, module *PrebuiltEtc) { diff --git a/genrule/genrule.go b/genrule/genrule.go index e7343a22d..6a91e012d 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -67,13 +67,6 @@ func RegisterGenruleBuildComponents(ctx android.RegistrationContext) { ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel() }) - - android.RegisterBp2BuildMutator("genrule", GenruleBp2Build) - android.RegisterBp2BuildMutator("cc_genrule", CcGenruleBp2Build) -} - -func RegisterGenruleBp2BuildDeps(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("genrule_tool_deps", toolDepsMutator) } var ( @@ -833,38 +826,8 @@ type bazelGenruleAttributes struct { Cmd string } -// CcGenruleBp2Build is for cc_genrule. -func CcGenruleBp2Build(ctx android.TopDownMutatorContext) { - m, ok := ctx.Module().(*Module) - if !ok || !m.ConvertWithBp2build(ctx) { - return - } - - if ctx.ModuleType() != "cc_genrule" { - // Not a cc_genrule. - return - } - - genruleBp2Build(ctx) -} - -// GenruleBp2Build is used for genrule. -func GenruleBp2Build(ctx android.TopDownMutatorContext) { - m, ok := ctx.Module().(*Module) - if !ok || !m.ConvertWithBp2build(ctx) { - return - } - - if ctx.ModuleType() != "genrule" { - // Not a regular genrule. - return - } - - genruleBp2Build(ctx) -} - -func genruleBp2Build(ctx android.TopDownMutatorContext) { - m, _ := ctx.Module().(*Module) +// ConvertWithBp2build converts a Soong module -> Bazel target. +func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { // Bazel only has the "tools" attribute. tools_prop := android.BazelLabelForModuleDeps(ctx, m.properties.Tools) tool_files_prop := android.BazelLabelForModuleSrc(ctx, m.properties.Tool_files) diff --git a/java/app.go b/java/app.go index b43e53226..b753c0cb8 100755 --- a/java/app.go +++ b/java/app.go @@ -43,9 +43,6 @@ func RegisterAppBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory) ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory) ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory) - - android.RegisterBp2BuildMutator("android_app_certificate", AndroidAppCertificateBp2Build) - android.RegisterBp2BuildMutator("android_app", AppBp2Build) } // AndroidManifest.xml merging @@ -945,6 +942,7 @@ func AndroidAppFactory() android.Module { android.InitDefaultableModule(module) android.InitOverridableModule(module, &module.appProperties.Overrides) android.InitApexModule(module) + android.InitBazelModule(module) return module } @@ -1407,23 +1405,11 @@ type bazelAndroidAppCertificateAttributes struct { Certificate string } -func AndroidAppCertificateBp2Build(ctx android.TopDownMutatorContext) { - module, ok := ctx.Module().(*AndroidAppCertificate) - if !ok { - // Not an Android app certificate - return - } - if !module.ConvertWithBp2build(ctx) { - return - } - if ctx.ModuleType() != "android_app_certificate" { - return - } - - androidAppCertificateBp2BuildInternal(ctx, module) +func (m *AndroidAppCertificate) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + androidAppCertificateBp2Build(ctx, m) } -func androidAppCertificateBp2BuildInternal(ctx android.TopDownMutatorContext, module *AndroidAppCertificate) { +func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *AndroidAppCertificate) { var certificate string if module.properties.Certificate != nil { certificate = *module.properties.Certificate @@ -1448,16 +1434,8 @@ type bazelAndroidAppAttributes struct { Resource_files bazel.LabelListAttribute } -// AppBp2Build is used for android_app. -func AppBp2Build(ctx android.TopDownMutatorContext) { - a, ok := ctx.Module().(*AndroidApp) - if !ok || !a.ConvertWithBp2build(ctx) { - return - } - if ctx.ModuleType() != "android_app" { - return - } - +// ConvertWithBp2build is used to convert android_app to Bazel. +func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { //TODO(b/209577426): Support multiple arch variants srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Srcs, a.properties.Exclude_srcs)) diff --git a/java/base.go b/java/base.go index c0da21523..c45ef641e 100644 --- a/java/base.go +++ b/java/base.go @@ -372,6 +372,7 @@ type Module struct { android.DefaultableModuleBase android.ApexModuleBase android.SdkBase + android.BazelModuleBase // Functionality common to Module and Import. embeddableInModuleAndImport @@ -1952,3 +1953,17 @@ type ModuleWithStem interface { } var _ ModuleWithStem = (*Module)(nil) + +func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + switch ctx.ModuleType() { + case "java_library", "java_library_host": + if lib, ok := ctx.Module().(*Library); ok { + javaLibraryBp2Build(ctx, lib) + } + case "java_binary_host": + if binary, ok := ctx.Module().(*Binary); ok { + javaBinaryHostBp2Build(ctx, binary) + } + } + +} diff --git a/java/java.go b/java/java.go index e7b1f4fe3..f77c694ba 100644 --- a/java/java.go +++ b/java/java.go @@ -21,7 +21,9 @@ package java import ( "fmt" "path/filepath" + "strings" + "android/soong/bazel" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -756,6 +758,7 @@ func LibraryFactory() android.Module { android.InitApexModule(module) android.InitSdkAwareModule(module) + android.InitBazelModule(module) InitJavaModule(module, android.HostAndDeviceSupported) return module } @@ -778,6 +781,7 @@ func LibraryHostFactory() android.Module { android.InitApexModule(module) android.InitSdkAwareModule(module) + android.InitBazelModule(module) InitJavaModule(module, android.HostSupported) return module } @@ -1228,6 +1232,8 @@ func BinaryFactory() android.Module { android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) android.InitDefaultableModule(module) + android.InitBazelModule(module) + return module } @@ -1245,6 +1251,7 @@ func BinaryHostFactory() android.Module { android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) android.InitDefaultableModule(module) + android.InitBazelModule(module) return module } @@ -1961,3 +1968,103 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) } } + +type javaLibraryAttributes struct { + Srcs bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Javacopts bazel.StringListAttribute +} + +func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { + srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)) + attrs := &javaLibraryAttributes{ + Srcs: srcs, + } + + if m.properties.Javacflags != nil { + attrs.Javacopts = bazel.MakeStringListAttribute(m.properties.Javacflags) + } + + if m.properties.Libs != nil { + attrs.Deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.properties.Libs)) + } + + props := bazel.BazelTargetModuleProperties{ + Rule_class: "java_library", + Bzl_load_location: "//build/bazel/rules/java:library.bzl", + } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) +} + +type javaBinaryHostAttributes struct { + Srcs bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Main_class string + Jvm_flags bazel.StringListAttribute +} + +// JavaBinaryHostBp2Build is for java_binary_host bp2build. +func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { + mainClass := "" + if m.binaryProperties.Main_class != nil { + mainClass = *m.binaryProperties.Main_class + } + if m.properties.Manifest != nil { + mainClassInManifest, err := android.GetMainClassInManifest(ctx.Config(), android.PathForModuleSrc(ctx, *m.properties.Manifest).String()) + if err != nil { + return + } + mainClass = mainClassInManifest + } + srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)) + attrs := &javaBinaryHostAttributes{ + Srcs: srcs, + Main_class: mainClass, + } + + // Attribute deps + deps := []string{} + if m.properties.Static_libs != nil { + deps = append(deps, m.properties.Static_libs...) + } + if m.binaryProperties.Jni_libs != nil { + deps = append(deps, m.binaryProperties.Jni_libs...) + } + if len(deps) > 0 { + attrs.Deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, deps)) + } + + // Attribute jvm_flags + if m.binaryProperties.Jni_libs != nil { + jniLibPackages := map[string]bool{} + for _, jniLibLabel := range android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs).Includes { + jniLibPackage := jniLibLabel.Label + indexOfColon := strings.Index(jniLibLabel.Label, ":") + if indexOfColon > 0 { + // JNI lib from other package + jniLibPackage = jniLibLabel.Label[2:indexOfColon] + } else if indexOfColon == 0 { + // JNI lib in the same package of java_binary + packageOfCurrentModule := m.GetBazelLabel(ctx, m) + jniLibPackage = packageOfCurrentModule[2:strings.Index(packageOfCurrentModule, ":")] + } + if _, inMap := jniLibPackages[jniLibPackage]; !inMap { + jniLibPackages[jniLibPackage] = true + } + } + jniLibPaths := []string{} + for jniLibPackage, _ := range jniLibPackages { + // See cs/f:.*/third_party/bazel/.*java_stub_template.txt for the use of RUNPATH + jniLibPaths = append(jniLibPaths, "$${RUNPATH}"+jniLibPackage) + } + attrs.Jvm_flags = bazel.MakeStringListAttribute([]string{"-Djava.library.path=" + strings.Join(jniLibPaths, ":")}) + } + + props := bazel.BazelTargetModuleProperties{ + Rule_class: "java_binary", + } + + // Create the BazelTargetModule. + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) +} diff --git a/python/binary.go b/python/binary.go index af02de63d..99c625916 100644 --- a/python/binary.go +++ b/python/binary.go @@ -27,7 +27,6 @@ import ( func init() { registerPythonBinaryComponents(android.InitRegistrationContext) - android.RegisterBp2BuildMutator("python_binary_host", PythonBinaryBp2Build) } func registerPythonBinaryComponents(ctx android.RegistrationContext) { @@ -41,17 +40,7 @@ type bazelPythonBinaryAttributes struct { Python_version *string } -func PythonBinaryBp2Build(ctx android.TopDownMutatorContext) { - m, ok := ctx.Module().(*Module) - if !ok || !m.ConvertWithBp2build(ctx) { - return - } - - // a Module can be something other than a python_binary_host - if ctx.ModuleType() != "python_binary_host" { - return - } - +func pythonBinaryBp2Build(ctx android.TopDownMutatorContext, m *Module) { var main *string for _, propIntf := range m.GetProperties() { if props, ok := propIntf.(*BinaryProperties); ok { diff --git a/python/library.go b/python/library.go index 9c92ebd5c..d026c1323 100644 --- a/python/library.go +++ b/python/library.go @@ -17,8 +17,6 @@ package python // This file contains the module types for building Python library. import ( - "fmt" - "android/soong/android" "android/soong/bazel" @@ -27,8 +25,6 @@ import ( func init() { registerPythonLibraryComponents(android.InitRegistrationContext) - android.RegisterBp2BuildMutator("python_library_host", PythonLibraryHostBp2Build) - android.RegisterBp2BuildMutator("python_library", PythonLibraryBp2Build) } func registerPythonLibraryComponents(ctx android.RegistrationContext) { @@ -50,25 +46,7 @@ type bazelPythonLibraryAttributes struct { Srcs_version *string } -func PythonLibraryHostBp2Build(ctx android.TopDownMutatorContext) { - pythonLibBp2Build(ctx, "python_library_host") -} - -func PythonLibraryBp2Build(ctx android.TopDownMutatorContext) { - pythonLibBp2Build(ctx, "python_library") -} - -func pythonLibBp2Build(ctx android.TopDownMutatorContext, modType string) { - m, ok := ctx.Module().(*Module) - if !ok || !m.ConvertWithBp2build(ctx) { - return - } - - // a Module can be something other than a `modType` - if ctx.ModuleType() != modType { - return - } - +func pythonLibBp2Build(ctx android.TopDownMutatorContext, m *Module) { // TODO(b/182306917): this doesn't fully handle all nested props versioned // by the python version, which would have been handled by the version split // mutator. This is sufficient for very simple python_library modules under @@ -81,9 +59,7 @@ func pythonLibBp2Build(ctx android.TopDownMutatorContext, modType string) { } else if !py2Enabled && py3Enabled { python_version = &pyVersion3 } else if !py2Enabled && !py3Enabled { - panic(fmt.Errorf( - "error for '%s' module: bp2build's %s converter doesn't understand having "+ - "neither py2 nor py3 enabled", m.Name(), modType)) + ctx.ModuleErrorf("bp2build converter doesn't understand having neither py2 nor py3 enabled") } else { // do nothing, since python_version defaults to PY2ANDPY3 } diff --git a/python/python.go b/python/python.go index 401d91fe3..734ac57f1 100644 --- a/python/python.go +++ b/python/python.go @@ -23,6 +23,7 @@ import ( "strings" "android/soong/bazel" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -667,18 +668,25 @@ func (p *Module) createSrcsZip(ctx android.ModuleContext, pkgPath string) androi } // isPythonLibModule returns whether the given module is a Python library Module or not -// This is distinguished by the fact that Python libraries are not installable, while other Python -// modules are. func isPythonLibModule(module blueprint.Module) bool { if m, ok := module.(*Module); ok { - // Python library has no bootstrapper or installer - if m.bootstrapper == nil && m.installer == nil { - return true - } + return m.isLibrary() } return false } +// This is distinguished by the fact that Python libraries are not installable, while other Python +// modules are. +func (p *Module) isLibrary() bool { + // Python library has no bootstrapper or installer + return p.bootstrapper == nil && p.installer == nil +} + +func (p *Module) isBinary() bool { + _, ok := p.bootstrapper.(*binaryDecorator) + return ok +} + // collectPathsFromTransitiveDeps checks for source/data files for duplicate paths // for module and its transitive dependencies and collects list of data/source file // zips for transitive dependencies. @@ -752,6 +760,14 @@ func (p *Module) InstallInData() bool { return true } +func (p *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + if p.isLibrary() { + pythonLibBp2Build(ctx, p) + } else if p.isBinary() { + pythonBinaryBp2Build(ctx, p) + } +} + var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var String = proptools.String diff --git a/rust/config/global.go b/rust/config/global.go index 2821e311c..bfb2d1ff5 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -26,7 +26,7 @@ var pctx = android.NewPackageContext("android/soong/rust/config") var ( RustDefaultVersion = "1.57.0" RustDefaultBase = "prebuilts/rust/" - DefaultEdition = "2018" + DefaultEdition = "2021" Stdlibs = []string{ "libstd", } diff --git a/rust/test.go b/rust/test.go index 3eea0ada4..250b7657e 100644 --- a/rust/test.go +++ b/rust/test.go @@ -210,6 +210,12 @@ func init() { func RustTestFactory() android.Module { module, _ := NewRustTest(android.HostAndDeviceSupported) + + // NewRustTest will set MultilibBoth true, however the host variant + // cannot produce the non-primary target. Therefore, add the + // rustTestHostMultilib load hook to set MultilibFirst for the + // host target. + android.AddLoadHook(module, rustTestHostMultilib) return module.Init() } @@ -236,3 +242,16 @@ func (test *testDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { func (test *testDecorator) testBinary() bool { return true } + +func rustTestHostMultilib(ctx android.LoadHookContext) { + type props struct { + Target struct { + Host struct { + Compile_multilib *string + } + } + } + p := &props{} + p.Target.Host.Compile_multilib = proptools.StringPtr("first") + ctx.AppendProperties(p) +} diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh deleted file mode 100755 index 1e3f6ce78..000000000 --- a/scripts/build-mainline-modules.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash -e - -# Non exhaustive list of modules where we want prebuilts. More can be added as -# needed. -MAINLINE_MODULES=( - com.android.art - com.android.art.debug - com.android.art.testing - com.android.conscrypt - com.android.i18n - com.android.os.statsd - com.android.runtime - com.android.tzdata -) - -# List of SDKs and module exports we know of. -MODULES_SDK_AND_EXPORTS=( - art-module-sdk - art-module-test-exports - conscrypt-module-host-exports - conscrypt-module-sdk - conscrypt-module-test-exports - i18n-module-host-exports - i18n-module-sdk - i18n-module-test-exports - platform-mainline-sdk - platform-mainline-test-exports - runtime-module-host-exports - runtime-module-sdk - statsd-module-sdk - tzdata-module-test-exports -) - -# List of libraries installed on the platform that are needed for ART chroot -# testing. -PLATFORM_LIBRARIES=( - heapprofd_client_api - libartpalette-system - liblog -) - -# We want to create apex modules for all supported architectures. -PRODUCTS=( - aosp_arm - aosp_arm64 - aosp_x86 - aosp_x86_64 -) - -if [ ! -e "build/make/core/Makefile" ]; then - echo "$0 must be run from the top of the tree" - exit 1 -fi - -echo_and_run() { - echo "$*" - "$@" -} - -lib_dir() { - case $1 in - (aosp_arm|aosp_x86) echo "lib";; - (aosp_arm64|aosp_x86_64) echo "lib64";; - esac -} - -# Make sure this build builds from source, regardless of the default. -export SOONG_CONFIG_art_module_source_build=true - -# This script does not intend to handle compressed APEX -export OVERRIDE_PRODUCT_COMPRESSED_APEX=false - -OUT_DIR=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT= get_build_var OUT_DIR) -DIST_DIR=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT= get_build_var DIST_DIR) - -for product in "${PRODUCTS[@]}"; do - echo_and_run build/soong/soong_ui.bash --make-mode $@ \ - TARGET_PRODUCT=${product} \ - ${MAINLINE_MODULES[@]} \ - ${PLATFORM_LIBRARIES[@]} - - PRODUCT_OUT=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT=${product} get_build_var PRODUCT_OUT) - TARGET_ARCH=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT=${product} get_build_var TARGET_ARCH) - rm -rf ${DIST_DIR}/${TARGET_ARCH}/ - mkdir -p ${DIST_DIR}/${TARGET_ARCH}/ - for module in "${MAINLINE_MODULES[@]}"; do - echo_and_run cp ${PWD}/${PRODUCT_OUT}/system/apex/${module}.apex ${DIST_DIR}/${TARGET_ARCH}/ - done - for library in "${PLATFORM_LIBRARIES[@]}"; do - libdir=$(lib_dir $product) - echo_and_run cp ${PWD}/${PRODUCT_OUT}/system/${libdir}/${library}.so ${DIST_DIR}/${TARGET_ARCH}/ - done -done - -# We use force building LLVM components flag (even though we actually don't -# compile them) because we don't have bionic host prebuilts -# for them. -export FORCE_BUILD_LLVM_COMPONENTS=true - -# Create multi-archs SDKs in a different out directory. The multi-arch script -# uses Soong in --soong-only mode which cannot use the same directory as normal -# mode with make. -export OUT_DIR=${OUT_DIR}/aml -echo_and_run build/soong/scripts/build-aml-prebuilts.sh \ - TARGET_PRODUCT=mainline_sdk ${MODULES_SDK_AND_EXPORTS[@]} - -rm -rf ${DIST_DIR}/mainline-sdks -echo_and_run cp -R ${OUT_DIR}/soong/mainline-sdks ${DIST_DIR} diff --git a/scripts/gen_java_usedby_apex.sh b/scripts/gen_java_usedby_apex.sh index 251d7aa5f..e3985414b 100755 --- a/scripts/gen_java_usedby_apex.sh +++ b/scripts/gen_java_usedby_apex.sh @@ -30,9 +30,11 @@ genUsedByList() { shift rm -f "$out" touch "$out" + echo "<externals>" >> "$out" for x in "$@"; do - "$dexdeps" "$x" >> "$out" || true + "$dexdeps" "$x" >> "$out" || echo "</external>" >> "$out" done + echo "</externals>" >> "$out" } if [[ "$1" == "help" ]] diff --git a/sh/sh_binary.go b/sh/sh_binary.go index a87b9cf4c..2d98e8be0 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -42,8 +42,6 @@ func init() { pctx.Import("android/soong/android") registerShBuildComponents(android.InitRegistrationContext) - - android.RegisterBp2BuildMutator("sh_binary", ShBinaryBp2Build) } func registerShBuildComponents(ctx android.RegistrationContext) { @@ -540,12 +538,7 @@ type bazelShBinaryAttributes struct { // visibility } -func ShBinaryBp2Build(ctx android.TopDownMutatorContext) { - m, ok := ctx.Module().(*ShBinary) - if !ok || !m.ConvertWithBp2build(ctx) { - return - } - +func (m *ShBinary) ConvertWithBp2build(ctx android.TopDownMutatorContext) { srcs := bazel.MakeLabelListAttribute( android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src})) diff --git a/shared/Android.bp b/shared/Android.bp index deb17f8f6..3c84f5532 100644 --- a/shared/Android.bp +++ b/shared/Android.bp @@ -9,11 +9,13 @@ bootstrap_go_package { "env.go", "paths.go", "debug.go", + "proto.go", ], testSrcs: [ "paths_test.go", ], deps: [ "soong-bazel", + "golang-protobuf-proto", ], } diff --git a/shared/proto.go b/shared/proto.go new file mode 100644 index 000000000..232656ba4 --- /dev/null +++ b/shared/proto.go @@ -0,0 +1,41 @@ +// Copyright 2021 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 shared + +import ( + "io/ioutil" + "os" + + "google.golang.org/protobuf/proto" +) + +// Save takes a protobuf message, marshals to an array of bytes +// and is then saved to a file. +func Save(pb proto.Message, filepath string) (err error) { + data, err := proto.Marshal(pb) + if err != nil { + return err + } + tempFilepath := filepath + ".tmp" + if err := ioutil.WriteFile(tempFilepath, []byte(data), 0644 /* rw-r--r-- */); err != nil { + return err + } + + if err := os.Rename(tempFilepath, filepath); err != nil { + return err + } + + return nil +} diff --git a/ui/build/config.go b/ui/build/config.go index c30663349..4c26d3ea5 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -1255,16 +1255,22 @@ func (c *configImpl) MetricsUploaderApp() string { return c.metricsUploader } -// LogsDir returns the logs directory where build log and metrics -// files are located. By default, the logs directory is the out +// LogsDir returns the absolute path to the logs directory where build log and +// metrics files are located. By default, the logs directory is the out // directory. If the argument dist is specified, the logs directory // is <dist_dir>/logs. func (c *configImpl) LogsDir() string { + dir := c.OutDir() if c.Dist() { // Always write logs to the real dist dir, even if Bazel is using a rigged dist dir for other files - return filepath.Join(c.RealDistDir(), "logs") + dir = filepath.Join(c.RealDistDir(), "logs") } - return c.OutDir() + absDir, err := filepath.Abs(dir) + if err != nil { + fmt.Fprintf(os.Stderr, "\nError making log dir '%s' absolute: %s\n", dir, err.Error()) + os.Exit(1) + } + return absDir } // BazelMetricsDir returns the <logs dir>/bazel_metrics directory diff --git a/ui/build/soong.go b/ui/build/soong.go index ae9a2ce25..5360342eb 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -373,6 +373,7 @@ func runSoong(ctx Context, config Config) { soongBuildEnv.Set("BAZEL_OUTPUT_BASE", filepath.Join(config.BazelOutDir(), "output")) soongBuildEnv.Set("BAZEL_WORKSPACE", absPath(ctx, ".")) soongBuildEnv.Set("BAZEL_METRICS_DIR", config.BazelMetricsDir()) + soongBuildEnv.Set("LOG_DIR", config.LogsDir()) // For Soong bootstrapping tests if os.Getenv("ALLOW_MISSING_DEPENDENCIES") == "true" { diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp index 96f6389e8..3ba3907a6 100644 --- a/ui/metrics/Android.bp +++ b/ui/metrics/Android.bp @@ -25,6 +25,7 @@ bootstrap_go_package { "soong-ui-metrics_proto", "soong-ui-bp2build_metrics_proto", "soong-ui-tracer", + "soong-shared", ], srcs: [ "metrics.go", diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go index f1bb862bd..80f8c1ad0 100644 --- a/ui/metrics/metrics.go +++ b/ui/metrics/metrics.go @@ -32,12 +32,12 @@ package metrics // of what an event is and how the metrics system is a stack based system. import ( - "io/ioutil" "os" "runtime" "strings" "time" + "android/soong/shared" "google.golang.org/protobuf/proto" soong_metrics_proto "android/soong/ui/metrics/metrics_proto" @@ -196,7 +196,7 @@ func (m *Metrics) Dump(out string) error { } m.metrics.HostOs = proto.String(runtime.GOOS) - return save(&m.metrics, out) + return shared.Save(&m.metrics, out) } // SetSoongBuildMetrics sets the metrics collected from the soong_build @@ -228,25 +228,5 @@ func (c *CriticalUserJourneysMetrics) Add(name string, metrics *Metrics) { // Dump saves the collected CUJs metrics to the raw protobuf file. func (c *CriticalUserJourneysMetrics) Dump(filename string) (err error) { - return save(&c.cujs, filename) -} - -// save takes a protobuf message, marshals to an array of bytes -// and is then saved to a file. -func save(pb proto.Message, filename string) (err error) { - data, err := proto.Marshal(pb) - if err != nil { - return err - } - - tempFilename := filename + ".tmp" - if err := ioutil.WriteFile(tempFilename, []byte(data), 0644 /* rw-r--r-- */); err != nil { - return err - } - - if err := os.Rename(tempFilename, filename); err != nil { - return err - } - - return nil + return shared.Save(&c.cujs, filename) } |