diff options
45 files changed, 1453 insertions, 342 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 872e6a0ca..cad9ec783 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -37,6 +37,7 @@ const ( var ( Bp2buildDefaultConfig = Bp2BuildConfig{ + "art": Bp2BuildDefaultTrue, "art/libartbase": Bp2BuildDefaultTrueRecursively, "art/libartpalette": Bp2BuildDefaultTrueRecursively, "art/libdexfile": Bp2BuildDefaultTrueRecursively, @@ -54,6 +55,7 @@ var ( "build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir "build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue, "build/soong/cc/symbolfile": Bp2BuildDefaultTrue, + "build/soong/licenses": Bp2BuildDefaultTrue, "build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively, "build/soong/scripts": Bp2BuildDefaultTrueRecursively, @@ -98,6 +100,7 @@ var ( "external/aac": Bp2BuildDefaultTrueRecursively, "external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively, "external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively, + "external/auto": Bp2BuildDefaultTrue, "external/auto/common": Bp2BuildDefaultTrueRecursively, "external/auto/service": Bp2BuildDefaultTrueRecursively, "external/boringssl": Bp2BuildDefaultTrueRecursively, @@ -162,10 +165,12 @@ var ( "frameworks/av/media/liberror": Bp2BuildDefaultTrueRecursively, "frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively, "frameworks/av/media/module/minijail": Bp2BuildDefaultTrueRecursively, + "frameworks/base/libs/androidfw": Bp2BuildDefaultTrue, "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, "frameworks/base/services/tests/servicestests/aidl": Bp2BuildDefaultTrue, "frameworks/base/startop/apps/test": Bp2BuildDefaultTrue, "frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively, + "frameworks/base/tools/aapt2": Bp2BuildDefaultTrue, "frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/arect": Bp2BuildDefaultTrueRecursively, "frameworks/native/libs/math": Bp2BuildDefaultTrueRecursively, @@ -213,6 +218,7 @@ var ( "packages/apps/DevCamera": Bp2BuildDefaultTrue, "packages/apps/HTMLViewer": Bp2BuildDefaultTrue, "packages/apps/Protips": Bp2BuildDefaultTrue, + "packages/apps/SafetyRegulatoryInfo": Bp2BuildDefaultTrue, "packages/apps/WallpaperPicker": Bp2BuildDefaultTrue, "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively, "packages/modules/adb": Bp2BuildDefaultTrue, @@ -234,6 +240,7 @@ var ( "prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively, "prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue, "prebuilts/sdk/current/support": Bp2BuildDefaultTrue, + "prebuilts/tools": Bp2BuildDefaultTrue, "prebuilts/tools/common/m2": Bp2BuildDefaultTrue, "system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures @@ -256,6 +263,7 @@ var ( "system/core/libvndksupport": Bp2BuildDefaultTrueRecursively, "system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively, "system/core/property_service/libpropertyinfoserializer": Bp2BuildDefaultTrueRecursively, + "system/incremental_delivery/incfs": Bp2BuildDefaultTrue, "system/libartpalette": Bp2BuildDefaultTrueRecursively, "system/libbase": Bp2BuildDefaultTrueRecursively, "system/libfmq": Bp2BuildDefaultTrue, @@ -275,6 +283,7 @@ var ( "system/libprocinfo": Bp2BuildDefaultTrue, "system/libziparchive": Bp2BuildDefaultTrueRecursively, "system/logging": Bp2BuildDefaultTrueRecursively, + "system/media": Bp2BuildDefaultTrue, "system/media/audio": Bp2BuildDefaultTrueRecursively, "system/media/audio_utils": Bp2BuildDefaultTrueRecursively, "system/memory/libion": Bp2BuildDefaultTrueRecursively, @@ -283,8 +292,8 @@ var ( "system/testing/gtest_extras": Bp2BuildDefaultTrueRecursively, "system/timezone/apex": Bp2BuildDefaultTrueRecursively, "system/timezone/output_data": Bp2BuildDefaultTrueRecursively, - "system/tools/sysprop": Bp2BuildDefaultTrue, "system/tools/aidl/build/tests_bp2build": Bp2BuildDefaultTrue, + "system/tools/sysprop": Bp2BuildDefaultTrue, "system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively, "tools/apksig": Bp2BuildDefaultTrue, @@ -306,6 +315,7 @@ var ( // external/bazelbuild-rules_android/... is needed by mixed builds, otherwise mixed builds analysis fails // e.g. ERROR: Analysis of target '@soong_injection//mixed_builds:buildroot' failed "external/bazelbuild-rules_android":/* recursive = */ true, + "external/bazelbuild-rules_license":/* recursive = */ true, "external/bazelbuild-kotlin-rules":/* recursive = */ true, "external/bazel-skylib":/* recursive = */ true, "external/guava":/* recursive = */ true, @@ -330,6 +340,8 @@ var ( } Bp2buildModuleAlwaysConvertList = []string{ + "libidmap2_policies", + "libSurfaceFlingerProp", // cc mainline modules "code_coverage.policy", "code_coverage.policy.other", @@ -371,7 +383,6 @@ var ( "libgraphicsenv", "libhardware", "libhardware_headers", - "libincfs_headers", "libnativeloader-headers", "libnativewindow_headers", "libneuralnetworks_headers", @@ -494,6 +505,7 @@ var ( } Bp2buildModuleTypeAlwaysConvertList = []string{ + "license", "linker_config", "java_import", "java_import_host", @@ -553,15 +565,16 @@ var ( "auto_value_plugin_resources", // TODO(b/210751803), we don't handle path property for filegroups // go deps: + "aapt2-protos", // depends on soong_zip, a go binary "analyze_bcpf", // depends on bpmodify a blueprint_go_binary. "apex-protos", // depends on soong_zip, a go binary "generated_android_icu4j_src_files", "generated_android_icu4j_test_files", "icu4c_test_data", // depends on unconverted modules: soong_zip "host_bionic_linker_asm", // depends on extract_linker, a go binary. "host_bionic_linker_script", // depends on extract_linker, a go binary. "libc_musl_sysroot_bionic_arch_headers", // depends on soong_zip - "libc_musl_sysroot_zlib_headers", // depends on soong_zip and zip2zip "libc_musl_sysroot_bionic_headers", // 218405924, depends on soong_zip and generates duplicate srcs "libc_musl_sysroot_libc++_headers", "libc_musl_sysroot_libc++abi_headers", // depends on soong_zip, zip2zip + "libc_musl_sysroot_zlib_headers", // depends on soong_zip and zip2zip "robolectric-sqlite4java-native", // depends on soong_zip, a go binary "robolectric_tzdata", // depends on soong_zip, a go binary @@ -618,6 +631,9 @@ var ( // '//bionic/libc:libc_bp2build_cc_library_static' is duplicated in the 'deps' attribute of rule "toybox-static", + // aidl files not created + "overlayable_policy_aidl_interface", + // cc_test related. // Failing host cc_tests "memunreachable_unit_test", @@ -642,6 +658,8 @@ var ( "libnativebridge6-test-case", "libnativebridge6prezygotefork", + "libandroidfw_tests", "aapt2_tests", // failing due to data path issues + // cc_test with unconverted deps, or are device-only (and not verified to pass yet) "AMRWBEncTest", "AmrnbDecoderTest", // depends on unconverted modules: libaudioutils, libsndfile diff --git a/android/apex.go b/android/apex.go index 00b724137..3c945ae6a 100644 --- a/android/apex.go +++ b/android/apex.go @@ -454,8 +454,6 @@ func CheckAvailableForApex(what string, apex_available []string) bool { } return InList(what, apex_available) || (what != AvailableToPlatform && InList(AvailableToAnyApex, apex_available)) || - (what == "com.android.btservices" && InList("com.android.bluetooth", apex_available)) || // TODO b/243054261 - (what == "com.android.bluetooth" && InList("com.android.btservices", apex_available)) || // TODO b/243054261 (strings.HasPrefix(what, "com.android.gki.") && InList(AvailableToGkiApex, apex_available)) } diff --git a/android/license.go b/android/license.go index ebee05576..cde5e6e6e 100644 --- a/android/license.go +++ b/android/license.go @@ -15,7 +15,10 @@ package android import ( + "android/soong/bazel" + "fmt" "github.com/google/blueprint" + "os" ) type licenseKindDependencyTag struct { @@ -48,14 +51,55 @@ type licenseProperties struct { Visibility []string } +var _ Bazelable = &licenseModule{} + type licenseModule struct { ModuleBase DefaultableModuleBase SdkBase + BazelModuleBase properties licenseProperties } +type bazelLicenseAttributes struct { + License_kinds []string + Copyright_notice *string + License_text bazel.LabelAttribute + Package_name *string + Visibility []string +} + +func (m *licenseModule) ConvertWithBp2build(ctx TopDownMutatorContext) { + attrs := &bazelLicenseAttributes{ + License_kinds: m.properties.License_kinds, + Copyright_notice: m.properties.Copyright_notice, + Package_name: m.properties.Package_name, + Visibility: m.properties.Visibility, + } + + // TODO(asmundak): Soong supports multiple license texts while Bazel's license + // rule does not. Have android_license create a genrule to concatenate multiple + // license texts. + if len(m.properties.License_text) > 1 && ctx.Config().IsEnvTrue("BP2BUILD_VERBOSE") { + fmt.Fprintf(os.Stderr, "warning: using only the first license_text item from //%s:%s\n", + ctx.ModuleDir(), m.Name()) + } + if len(m.properties.License_text) >= 1 { + attrs.License_text.SetValue(BazelLabelForModuleSrcSingle(ctx, m.properties.License_text[0])) + } + + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "android_license", + Bzl_load_location: "//build/bazel/rules/license:license.bzl", + }, + CommonAttributes{ + Name: m.Name(), + }, + attrs) +} + func (m *licenseModule) DepsMutator(ctx BottomUpMutatorContext) { ctx.AddVariationDependencies(nil, licenseKindTag, m.properties.License_kinds...) } @@ -78,7 +122,7 @@ func LicenseFactory() Module { module := &licenseModule{} base := module.base() - module.AddProperties(&base.nameProperties, &module.properties) + module.AddProperties(&base.nameProperties, &module.properties, &base.commonProperties.BazelConversionStatus) // The visibility property needs to be checked and parsed by the visibility module. setPrimaryVisibilityProperty(module, "visibility", &module.properties.Visibility) @@ -86,6 +130,7 @@ func LicenseFactory() Module { InitSdkAwareModule(module) initAndroidModuleBase(module) InitDefaultableModule(module) + InitBazelModule(module) return module } diff --git a/android/license_kind.go b/android/license_kind.go index 838deddd2..24b91e4c2 100644 --- a/android/license_kind.go +++ b/android/license_kind.go @@ -14,6 +14,8 @@ package android +import "android/soong/bazel" + func init() { RegisterLicenseKindBuildComponents(InitRegistrationContext) } @@ -32,13 +34,39 @@ type licenseKindProperties struct { Visibility []string } +var _ Bazelable = &licenseKindModule{} + type licenseKindModule struct { ModuleBase DefaultableModuleBase + BazelModuleBase properties licenseKindProperties } +type bazelLicenseKindAttributes struct { + Conditions []string + Url string + Visibility []string +} + +func (m *licenseKindModule) ConvertWithBp2build(ctx TopDownMutatorContext) { + attrs := &bazelLicenseKindAttributes{ + Conditions: m.properties.Conditions, + Url: m.properties.Url, + Visibility: m.properties.Visibility, + } + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "license_kind", + Bzl_load_location: "@rules_license//rules:license_kind.bzl", + }, + CommonAttributes{ + Name: m.Name(), + }, + attrs) +} + func (m *licenseKindModule) DepsMutator(ctx BottomUpMutatorContext) { // Nothing to do. } @@ -51,13 +79,14 @@ func LicenseKindFactory() Module { module := &licenseKindModule{} base := module.base() - module.AddProperties(&base.nameProperties, &module.properties) + module.AddProperties(&base.nameProperties, &module.properties, &base.commonProperties.BazelConversionStatus) // The visibility property needs to be checked and parsed by the visibility module. setPrimaryVisibilityProperty(module, "visibility", &module.properties.Visibility) initAndroidModuleBase(module) InitDefaultableModule(module) + InitBazelModule(module) return module } diff --git a/android/module.go b/android/module.go index 5908233a2..5d520f407 100644 --- a/android/module.go +++ b/android/module.go @@ -917,6 +917,8 @@ type CommonAttributes struct { Name string // Data mapped from: Required Data bazel.LabelListAttribute + + Tags bazel.StringListAttribute } // constraintAttributes represents Bazel attributes pertaining to build constraints, @@ -1169,7 +1171,9 @@ func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutator mod := ctx.Module().base() // Assert passed-in attributes include Name if len(attrs.Name) == 0 { - ctx.ModuleErrorf("CommonAttributes in fillCommonBp2BuildModuleAttrs expects a `.Name`!") + if ctx.ModuleType() != "package" { + ctx.ModuleErrorf("CommonAttributes in fillCommonBp2BuildModuleAttrs expects a `.Name`!") + } } depsToLabelList := func(deps []string) bazel.LabelListAttribute { diff --git a/android/namespace.go b/android/namespace.go index fc7bc290f..a3ff76125 100644 --- a/android/namespace.go +++ b/android/namespace.go @@ -166,10 +166,10 @@ func (r *NameResolver) findNamespace(path string) (namespace *Namespace) { return namespace } -// A NamelessModule can never be looked up by name. It must still implement Name(), but the return -// value doesn't have to be unique. -type NamelessModule interface { - Nameless() +// A NamespacelessModule can never be looked up by name. It must still implement Name(), and the name +// still has to be unique. +type NamespacelessModule interface { + Namespaceless() } func (r *NameResolver) NewModule(ctx blueprint.NamespaceContext, moduleGroup blueprint.ModuleGroup, module blueprint.Module) (namespace blueprint.Namespace, errs []error) { @@ -183,7 +183,7 @@ func (r *NameResolver) NewModule(ctx blueprint.NamespaceContext, moduleGroup blu return nil, nil } - if _, ok := module.(NamelessModule); ok { + if _, ok := module.(NamespacelessModule); ok { return nil, nil } diff --git a/android/package.go b/android/package.go index 878e4c4ed..2bf652126 100644 --- a/android/package.go +++ b/android/package.go @@ -15,6 +15,7 @@ package android import ( + "android/soong/bazel" "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -37,12 +38,33 @@ type packageProperties struct { Default_applicable_licenses []string } +type bazelPackageAttributes struct { + Default_visibility []string + Default_applicable_licenses bazel.LabelListAttribute +} + type packageModule struct { ModuleBase + BazelModuleBase properties packageProperties } +var _ Bazelable = &packageModule{} + +func (p *packageModule) ConvertWithBp2build(ctx TopDownMutatorContext) { + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "package", + }, + CommonAttributes{}, + &bazelPackageAttributes{ + Default_applicable_licenses: bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, p.properties.Default_applicable_licenses)), + // FIXME(asmundak): once b/221436821 is resolved + Default_visibility: []string{"//visibility:public"}, + }) +} + func (p *packageModule) GenerateAndroidBuildActions(ModuleContext) { // Nothing to do. } @@ -59,7 +81,7 @@ func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModule func PackageFactory() Module { module := &packageModule{} - module.AddProperties(&module.properties) + module.AddProperties(&module.properties, &module.commonProperties.BazelConversionStatus) // The name is the relative path from build root to the directory containing this // module. Set that name at the earliest possible moment that information is available @@ -76,5 +98,7 @@ func PackageFactory() Module { // its checking and parsing phases so make it the primary licenses property. setPrimaryLicensesProperty(module, "default_applicable_licenses", &module.properties.Default_applicable_licenses) + InitBazelModule(module) + return module } diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go index cd36ae066..c0f452396 100644 --- a/android/soong_config_modules.go +++ b/android/soong_config_modules.go @@ -172,7 +172,7 @@ func (m *soongConfigModuleTypeImport) Name() string { "soong_config_module_type_import_" + fmt.Sprintf("%p", m) } -func (*soongConfigModuleTypeImport) Nameless() {} +func (*soongConfigModuleTypeImport) Namespaceless() {} func (*soongConfigModuleTypeImport) GenerateAndroidBuildActions(ModuleContext) {} // Create dummy modules for soong_config_module_type and soong_config_*_variable @@ -280,9 +280,9 @@ func SoongConfigModuleTypeFactory() Module { } func (m *soongConfigModuleTypeModule) Name() string { - return m.properties.Name + return m.properties.Name + fmt.Sprintf("%p", m) } -func (*soongConfigModuleTypeModule) Nameless() {} +func (*soongConfigModuleTypeModule) Namespaceless() {} func (*soongConfigModuleTypeModule) GenerateAndroidBuildActions(ctx ModuleContext) {} type soongConfigStringVariableDummyModule struct { @@ -315,15 +315,15 @@ func SoongConfigBoolVariableDummyFactory() Module { } func (m *soongConfigStringVariableDummyModule) Name() string { - return m.properties.Name + return m.properties.Name + fmt.Sprintf("%p", m) } -func (*soongConfigStringVariableDummyModule) Nameless() {} +func (*soongConfigStringVariableDummyModule) Namespaceless() {} func (*soongConfigStringVariableDummyModule) GenerateAndroidBuildActions(ctx ModuleContext) {} func (m *soongConfigBoolVariableDummyModule) Name() string { - return m.properties.Name + return m.properties.Name + fmt.Sprintf("%p", m) } -func (*soongConfigBoolVariableDummyModule) Nameless() {} +func (*soongConfigBoolVariableDummyModule) Namespaceless() {} func (*soongConfigBoolVariableDummyModule) GenerateAndroidBuildActions(ctx ModuleContext) {} // importModuleTypes registers the module factories for a list of module types defined diff --git a/apex/apex.go b/apex/apex.go index 949809ad9..2e54e7e6a 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -3054,36 +3054,6 @@ func makeApexAvailableBaseline() map[string][]string { // // Module separator // - m["com.android.bluetooth"] = []string{ - "bluetooth-protos-lite", - "internal_include_headers", - "libaudio-a2dp-hw-utils", - "libaudio-hearing-aid-hw-utils", - "libbluetooth", - "libbluetooth-types", - "libbluetooth-types-header", - "libbluetooth_gd", - "libbluetooth_headers", - "libbluetooth_jni", - "libbt-audio-hal-interface", - "libbt-bta", - "libbt-common", - "libbt-hci", - "libbt-platform-protos-lite", - "libbt-protos-lite", - "libbt-sbc-decoder", - "libbt-sbc-encoder", - "libbt-stack", - "libbt-utils", - "libbtcore", - "libbtdevice", - "libbte", - "libbtif", - "libchrome", - } - // - // Module separator - // m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"} // // Module separator diff --git a/bazel/configurability.go b/bazel/configurability.go index 7ff202bf2..b6bbd67c4 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -69,6 +69,9 @@ const ( AndroidAndInApex = "android-in_apex" AndroidAndNonApex = "android-non_apex" + + InApex = "in_apex" + NonApex = "non_apex" ) func PowerSetWithoutEmptySet[T any](items []T) [][]T { @@ -198,6 +201,12 @@ var ( AndroidAndNonApex: "//build/bazel/rules/apex:android-non_apex", ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, } + + inApexMap = map[string]string{ + InApex: "//build/bazel/rules/apex:in_apex", + NonApex: "//build/bazel/rules/apex:non_apex", + ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, + } ) // basic configuration types @@ -210,6 +219,7 @@ const ( osArch productVariables osAndInApex + inApex ) func osArchString(os string, arch string) string { @@ -224,6 +234,7 @@ func (ct configurationType) String() string { osArch: "arch_os", productVariables: "product_variables", osAndInApex: "os_in_apex", + inApex: "in_apex", }[ct] } @@ -251,6 +262,10 @@ func (ct configurationType) validateConfig(config string) { if _, ok := osAndInApexMap[config]; !ok { panic(fmt.Errorf("Unknown os+in_apex config: %s", config)) } + case inApex: + if _, ok := inApexMap[config]; !ok { + panic(fmt.Errorf("Unknown in_apex config: %s", config)) + } default: panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct)) } @@ -276,6 +291,8 @@ func (ca ConfigurationAxis) SelectKey(config string) string { return fmt.Sprintf("%s:%s", productVariableBazelPackage, config) case osAndInApex: return osAndInApexMap[config] + case inApex: + return inApexMap[config] default: panic(fmt.Errorf("Unrecognized ConfigurationType %d", ca.configurationType)) } @@ -292,6 +309,8 @@ var ( OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch} // An axis for os+in_apex-specific configurations OsAndInApexAxis = ConfigurationAxis{configurationType: osAndInApex} + // An axis for in_apex-specific configurations + InApexAxis = ConfigurationAxis{configurationType: inApex} ) // ProductVariableConfigurationAxis returns an axis for the given product variable diff --git a/bazel/properties.go b/bazel/properties.go index 11f62477d..c329e4197 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -720,7 +720,7 @@ func (lla *LabelListAttribute) SetSelectValue(axis ConfigurationAxis, config str switch axis.configurationType { case noConfig: lla.Value = list - case arch, os, osArch, productVariables, osAndInApex: + case arch, os, osArch, productVariables, osAndInApex, inApex: if lla.ConfigurableValues == nil { lla.ConfigurableValues = make(configurableLabelLists) } @@ -736,7 +736,7 @@ func (lla *LabelListAttribute) SelectValue(axis ConfigurationAxis, config string switch axis.configurationType { case noConfig: return lla.Value - case arch, os, osArch, productVariables, osAndInApex: + case arch, os, osArch, productVariables, osAndInApex, inApex: return lla.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) diff --git a/bp2build/Android.bp b/bp2build/Android.bp index 3d9fc5a2b..7c9af1a82 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -63,8 +63,11 @@ bootstrap_go_package { "java_library_host_conversion_test.go", "java_plugin_conversion_test.go", "java_proto_conversion_test.go", + "license_conversion_test.go", + "license_kind_conversion_test.go", "linker_config_conversion_test.go", "ndk_headers_conversion_test.go", + "package_conversion_test.go", "performance_test.go", "prebuilt_etc_conversion_test.go", "python_binary_conversion_test.go", diff --git a/bp2build/androidbp_to_build_templates.go b/bp2build/androidbp_to_build_templates.go index 5fed4fab5..9b21c3278 100644 --- a/bp2build/androidbp_to_build_templates.go +++ b/bp2build/androidbp_to_build_templates.go @@ -23,7 +23,7 @@ load("//build/bazel/queryview_rules:soong_module.bzl", "soong_module") // A macro call in the BUILD file representing a Soong module, with space // for expanding more attributes. - soongModuleTarget = `soong_module( + soongModuleTargetTemplate = `soong_module( name = "%s", soong_module_name = "%s", soong_module_type = "%s", @@ -31,10 +31,13 @@ load("//build/bazel/queryview_rules:soong_module.bzl", "soong_module") soong_module_deps = %s, %s)` - bazelTarget = `%s( + ruleTargetTemplate = `%s( name = "%s", %s)` + unnamedRuleTargetTemplate = `%s( +%s)` + // A simple provider to mark and differentiate Soong module rule shims from // regular Bazel rules. Every Soong module rule shim returns a // SoongModuleInfo provider, and can only depend on rules returning diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go index ca8185e57..ee162b263 100644 --- a/bp2build/build_conversion.go +++ b/bp2build/build_conversion.go @@ -64,7 +64,16 @@ func (t BazelTarget) Label() string { // BazelTargets is a typedef for a slice of BazelTarget objects. type BazelTargets []BazelTarget -// sort a list of BazelTargets in-place by name +func (targets BazelTargets) packageRule() *BazelTarget { + for _, target := range targets { + if target.ruleClass == "package" { + return &target + } + } + return nil +} + +// sort a list of BazelTargets in-place, by name, and by generated/handcrafted types. func (targets BazelTargets) sort() { sort.Slice(targets, func(i, j int) bool { return targets[i].name < targets[j].name @@ -77,7 +86,9 @@ func (targets BazelTargets) sort() { func (targets BazelTargets) String() string { var res string for i, target := range targets { - res += target.content + if target.ruleClass != "package" { + res += target.content + } if i != len(targets)-1 { res += "\n\n" } @@ -391,18 +402,19 @@ func generateBazelTarget(ctx bpToBuildContext, m bp2buildModule) (BazelTarget, e // Return the Bazel target with rule class and attributes, ready to be // code-generated. attributes := propsToAttributes(props.Attrs) + var content string targetName := m.TargetName() + if targetName != "" { + content = fmt.Sprintf(ruleTargetTemplate, ruleClass, targetName, attributes) + } else { + content = fmt.Sprintf(unnamedRuleTargetTemplate, ruleClass, attributes) + } return BazelTarget{ name: targetName, packageName: m.TargetPackage(), ruleClass: ruleClass, bzlLoadLocation: bzlLoadLocation, - content: fmt.Sprintf( - bazelTarget, - ruleClass, - targetName, - attributes, - ), + content: content, }, nil } @@ -436,7 +448,7 @@ func generateSoongModuleTarget(ctx bpToBuildContext, m blueprint.Module) (BazelT return BazelTarget{ name: targetName, content: fmt.Sprintf( - soongModuleTarget, + soongModuleTargetTemplate, targetName, ctx.ModuleName(m), canonicalizeModuleType(ctx.ModuleType(m)), diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 67d4a1c96..1c9fba20f 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -45,6 +45,7 @@ func generateBazelTargetsForTest(targets []testBazelTarget, hod android.HostOrDe type ccBinaryBp2buildTestCase struct { description string + filesystem map[string]string blueprint string targets []testBazelTarget } @@ -79,6 +80,7 @@ func runCcBinaryTestCase(t *testing.T, testCase ccBinaryBp2buildTestCase) { ModuleTypeUnderTestFactory: cc.BinaryFactory, Description: description, Blueprint: binaryReplacer.Replace(testCase.blueprint), + Filesystem: testCase.filesystem, }) }) } @@ -94,6 +96,7 @@ func runCcHostBinaryTestCase(t *testing.T, testCase ccBinaryBp2buildTestCase) { ModuleTypeUnderTestFactory: cc.BinaryHostFactory, Description: description, Blueprint: hostBinaryReplacer.Replace(testCase.blueprint), + Filesystem: testCase.filesystem, }) }) } @@ -101,6 +104,9 @@ func runCcHostBinaryTestCase(t *testing.T, testCase ccBinaryBp2buildTestCase) { func TestBasicCcBinary(t *testing.T) { runCcBinaryTests(t, ccBinaryBp2buildTestCase{ description: "basic -- properties -> attrs with little/no transformation", + filesystem: map[string]string{ + soongCcVersionLibBpPath: soongCcVersionLibBp, + }, blueprint: ` {rule_name} { name: "foo", @@ -146,9 +152,10 @@ func TestBasicCcBinary(t *testing.T) { "keep_symbols_list": ["symbol"], "none": True, }`, - "sdk_version": `"current"`, - "min_sdk_version": `"29"`, - "use_version_lib": `True`, + "sdk_version": `"current"`, + "min_sdk_version": `"29"`, + "use_version_lib": `True`, + "whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`, }, }, }, diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 12cffc304..f581706a1 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -27,7 +27,16 @@ const ( soongCcLibraryPreamble = ` cc_defaults { name: "linux_bionic_supported", -}` +} +` + + soongCcVersionLibBpPath = "build/soong/cc/libbuildversion/Android.bp" + soongCcVersionLibBp = ` +cc_library_static { + name: "libbuildversion", + bazel_module: { bp2build_available: false }, +} +` soongCcProtoLibraries = ` cc_library { @@ -62,9 +71,10 @@ func TestCcLibrarySimple(t *testing.T) { ModuleTypeUnderTest: "cc_library", ModuleTypeUnderTestFactory: cc.LibraryFactory, Filesystem: map[string]string{ - "android.cpp": "", - "bionic.cpp": "", - "darwin.cpp": "", + soongCcVersionLibBpPath: soongCcVersionLibBp, + "android.cpp": "", + "bionic.cpp": "", + "darwin.cpp": "", // Refer to cc.headerExts for the supported header extensions in Soong. "header.h": "", "header.hh": "", @@ -143,9 +153,10 @@ cc_library { "//build/bazel/platforms/os:linux_bionic": ["bionic.cpp"], "//conditions:default": [], })`, - "sdk_version": `"current"`, - "min_sdk_version": `"29"`, - "use_version_lib": `True`, + "sdk_version": `"current"`, + "min_sdk_version": `"29"`, + "use_version_lib": `True`, + "implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`, }), }) } @@ -1337,6 +1348,7 @@ func makeCcLibraryTargets(name string, attrs AttrNameToString) []string { "strip": true, "inject_bssl_hash": true, "has_stubs": true, + "use_version_lib": true, } sharedAttrs := AttrNameToString{} @@ -2078,7 +2090,8 @@ func TestCcLibraryProtoSimple(t *testing.T) { "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, "deps": `[":libprotobuf-cpp-lite"]`, }), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, }), }, }) @@ -2104,7 +2117,8 @@ func TestCcLibraryProtoNoCanonicalPathFromRoot(t *testing.T) { "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, "deps": `[":libprotobuf-cpp-lite"]`, }), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, }), }, }) @@ -2129,7 +2143,8 @@ func TestCcLibraryProtoExplicitCanonicalPathFromRoot(t *testing.T) { "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, "deps": `[":libprotobuf-cpp-lite"]`, }), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, }), }, }) @@ -2156,7 +2171,8 @@ func TestCcLibraryProtoFull(t *testing.T) { "implementation_whole_archive_deps": `[":foo_cc_proto"]`, "deps": `[":libprotobuf-cpp-full"]`, }), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "dynamic_deps": `[":libprotobuf-cpp-full"]`, + "dynamic_deps": `[":libprotobuf-cpp-full"]`, + "implementation_whole_archive_deps": `[":foo_cc_proto"]`, }), }, }) @@ -2183,7 +2199,8 @@ func TestCcLibraryProtoLite(t *testing.T) { "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, "deps": `[":libprotobuf-cpp-lite"]`, }), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, }), }, }) @@ -2239,7 +2256,8 @@ func TestCcLibraryProtoIncludeDirs(t *testing.T) { "deps": `[":libprotobuf-cpp-lite"]`, "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, }), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "dynamic_deps": `[":libprotobuf-cpp-lite"]`, + "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, }), }, }) @@ -2684,6 +2702,40 @@ cc_library { ) } +func TestCcLibraryStubsAcrossConfigsDuplicatesRemoved(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "stub target generation of the same lib across configs should not result in duplicates", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Filesystem: map[string]string{ + "bar.map.txt": "", + }, + Blueprint: ` +cc_library { + name: "barlib", + stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] }, + bazel_module: { bp2build_available: false }, +} +cc_library { + name: "foolib", + shared_libs: ["barlib"], + target: { + android: { + shared_libs: ["barlib"], + }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{ + "implementation_dynamic_deps": `select({ + "//build/bazel/rules/apex:android-in_apex": [":barlib_stub_libs_current"], + "//conditions:default": [":barlib"], + })`, + "local_includes": `["."]`, + }), + }) +} + func TestCcLibraryEscapeLdflags(t *testing.T) { runCcLibraryTestCase(t, Bp2buildTestCase{ ModuleTypeUnderTest: "cc_library", @@ -2920,10 +2972,9 @@ cc_library { "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, "local_includes": `["."]`, }), - // TODO(b/239311679) Add implementation_whole_archive_deps to cc_library_shared - // for bp2build to be fully correct. This fallback is affecting proto as well. MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "local_includes": `["."]`, + "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, }), }, }) @@ -2957,10 +3008,9 @@ cc_library { "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, "local_includes": `["."]`, }), - // TODO(b/239311679) Add implementation_whole_archive_deps to cc_library_shared - // for bp2build to be fully correct. This fallback is affecting proto as well. MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "local_includes": `["."]`, + "local_includes": `["."]`, + "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, }), }, }) @@ -2999,3 +3049,86 @@ cc_library { }, }) } + +func TestCcLibraryWithTargetApex(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library with target.apex", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + shared_libs: ["bar", "baz"], + static_libs: ["baz", "buh"], + target: { + apex: { + exclude_shared_libs: ["bar"], + exclude_static_libs: ["buh"], + } + } +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "implementation_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({ + "//build/bazel/rules/apex:non_apex": [":buh__BP2BUILD__MISSING__DEP"], + "//conditions:default": [], + })`, + "implementation_dynamic_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({ + "//build/bazel/rules/apex:non_apex": [":bar__BP2BUILD__MISSING__DEP"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "implementation_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({ + "//build/bazel/rules/apex:non_apex": [":buh__BP2BUILD__MISSING__DEP"], + "//conditions:default": [], + })`, + "implementation_dynamic_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({ + "//build/bazel/rules/apex:non_apex": [":bar__BP2BUILD__MISSING__DEP"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryWithTargetApexAndExportLibHeaders(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library with target.apex and export_shared|static_lib_headers", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library_static { + name: "foo", + shared_libs: ["bar", "baz"], + static_libs: ["abc"], + export_shared_lib_headers: ["baz"], + export_static_lib_headers: ["abc"], + target: { + apex: { + exclude_shared_libs: ["baz", "bar"], + exclude_static_libs: ["abc"], + } + } +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "implementation_dynamic_deps": `select({ + "//build/bazel/rules/apex:non_apex": [":bar__BP2BUILD__MISSING__DEP"], + "//conditions:default": [], + })`, + "dynamic_deps": `select({ + "//build/bazel/rules/apex:non_apex": [":baz__BP2BUILD__MISSING__DEP"], + "//conditions:default": [], + })`, + "deps": `select({ + "//build/bazel/rules/apex:non_apex": [":abc__BP2BUILD__MISSING__DEP"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 4d8e59b30..6aa8ebe8d 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -454,6 +454,9 @@ func TestCcLibrarySharedProto(t *testing.T) { func TestCcLibrarySharedUseVersionLib(t *testing.T) { runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Filesystem: map[string]string{ + soongCcVersionLibBpPath: soongCcVersionLibBp, + }, Blueprint: soongCcProtoPreamble + `cc_library_shared { name: "foo", use_version_lib: true, @@ -461,7 +464,8 @@ func TestCcLibrarySharedUseVersionLib(t *testing.T) { }`, ExpectedBazelTargets: []string{ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "use_version_lib": "True", + "use_version_lib": "True", + "implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`, }), }, }) diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index 316fa3e4c..37722ed04 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -1485,14 +1485,37 @@ func TestCcLibraryStaticProto(t *testing.T) { func TestCcLibraryStaticUseVersionLib(t *testing.T) { runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Filesystem: map[string]string{ + soongCcVersionLibBpPath: soongCcVersionLibBp, + }, + Blueprint: soongCcProtoPreamble + `cc_library_static { + name: "foo", + use_version_lib: true, + static_libs: ["libbuildversion"], + include_build_directory: false, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`, + }), + }, + }) +} + +func TestCcLibraryStaticUseVersionLibHasDep(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Filesystem: map[string]string{ + soongCcVersionLibBpPath: soongCcVersionLibBp, + }, Blueprint: soongCcProtoPreamble + `cc_library_static { name: "foo", use_version_lib: true, + whole_static_libs: ["libbuildversion"], include_build_directory: false, }`, ExpectedBazelTargets: []string{ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ - "use_version_lib": "True", + "whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`, }), }, }) diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go index 9b7748f10..8c2d30d24 100644 --- a/bp2build/cc_test_conversion_test.go +++ b/bp2build/cc_test_conversion_test.go @@ -148,3 +148,27 @@ cc_test { }, }) } + +func TestCcTest_TestOptions_Tags(t *testing.T) { + runCcTestTestCase(t, ccTestBp2buildTestCase{ + description: "cc test with test_options.tags converted to tags", + blueprint: ` +cc_test { + name: "mytest", + host_supported: true, + srcs: ["test.cpp"], + test_options: { tags: ["no-remote"] }, +} +`, + targets: []testBazelTarget{ + {"cc_test", "mytest", AttrNameToString{ + "tags": `["no-remote"]`, + "local_includes": `["."]`, + "srcs": `["test.cpp"]`, + "gtest": "True", + "isolated": "True", + }, + }, + }, + }) +} diff --git a/bp2build/conversion.go b/bp2build/conversion.go index 731b17e3a..b6190c695 100644 --- a/bp2build/conversion.go +++ b/bp2build/conversion.go @@ -96,10 +96,14 @@ func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) # This file was automatically generated by bp2build for the Bazel migration project. # Feel free to edit or test it, but do *not* check it into your version control system. ` - - // Hardcode the default visibility. - content += "package(default_visibility = [\"//visibility:public\"])\n" content += targets.LoadStatements() + content += "\n\n" + // Get package rule from the handcrafted BUILD file, otherwise emit the default one. + prText := "package(default_visibility = [\"//visibility:public\"])\n" + if pr := targets.packageRule(); pr != nil { + prText = pr.content + } + content += prText } else if mode == QueryView { content = soongModuleLoad } @@ -160,7 +164,7 @@ func shouldSkipStructField(field reflect.StructField) bool { // internal to Soong only, and these fields do not have PkgPath. return true } - // fields with tag `blueprint:"mutated"` are exported to enable modification in mutators, etc + // fields with tag `blueprint:"mutated"` are exported to enable modification in mutators, etc. // but cannot be set in a .bp file if proptools.HasTag(field, "blueprint", "mutated") { return true diff --git a/bp2build/license_conversion_test.go b/bp2build/license_conversion_test.go new file mode 100644 index 000000000..ea6b27a17 --- /dev/null +++ b/bp2build/license_conversion_test.go @@ -0,0 +1,81 @@ +// Copyright 2022 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "android/soong/android" + "testing" +) + +func registerLicenseModuleTypes(_ android.RegistrationContext) {} + +func TestLicenseBp2Build(t *testing.T) { + tests := []struct { + description string + module string + expected ExpectedRuleTarget + }{ + { + description: "license kind and text notice", + module: ` +license { + name: "my_license", + license_kinds: [ "SPDX-license-identifier-Apache-2.0"], + license_text: [ "NOTICE"], +}`, + expected: ExpectedRuleTarget{ + "android_license", + "my_license", + AttrNameToString{ + "license_kinds": `["SPDX-license-identifier-Apache-2.0"]`, + "license_text": `"NOTICE"`, + }, + android.HostAndDeviceDefault, + }, + }, + { + description: "visibility, package_name, copyright_notice", + module: ` +license { + name: "my_license", + package_name: "my_package", + visibility: [":__subpackages__"], + copyright_notice: "Copyright © 2022", +}`, + expected: ExpectedRuleTarget{ + "android_license", + "my_license", + AttrNameToString{ + "copyright_notice": `"Copyright © 2022"`, + "package_name": `"my_package"`, + "visibility": `[":__subpackages__"]`, + }, + android.HostAndDeviceDefault, + }, + }, + } + + for _, test := range tests { + RunBp2BuildTestCase(t, + registerLicenseModuleTypes, + Bp2buildTestCase{ + Description: test.description, + ModuleTypeUnderTest: "license", + ModuleTypeUnderTestFactory: android.LicenseFactory, + Blueprint: test.module, + ExpectedBazelTargets: []string{test.expected.String()}, + }) + } +} diff --git a/bp2build/license_kind_conversion_test.go b/bp2build/license_kind_conversion_test.go new file mode 100644 index 000000000..eda116c5a --- /dev/null +++ b/bp2build/license_kind_conversion_test.go @@ -0,0 +1,69 @@ +// Copyright 2022 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "android/soong/android" + "testing" +) + +func registerLicenseKindModuleTypes(_ android.RegistrationContext) {} + +func TestLicenseKindBp2Build(t *testing.T) { + tests := []struct { + description string + module string + expected ExpectedRuleTarget + }{ + { + description: "license_kind", + module: ` +license_kind { + name: "my_license", + conditions: [ + "by_exception_only", + "not_allowed", + ], + url: "https://spdx.org/licenses/0BSD", + visibility: ["//visibility:public"], +}`, + expected: ExpectedRuleTarget{ + "license_kind", + "my_license", + AttrNameToString{ + "conditions": `[ + "by_exception_only", + "not_allowed", + ]`, + "url": `"https://spdx.org/licenses/0BSD"`, + "visibility": `["//visibility:public"]`, + }, + android.HostAndDeviceDefault, + }, + }, + } + + for _, test := range tests { + RunBp2BuildTestCase(t, + registerLicenseKindModuleTypes, + Bp2buildTestCase{ + Description: test.description, + ModuleTypeUnderTest: "license_kind", + ModuleTypeUnderTestFactory: android.LicenseKindFactory, + Blueprint: test.module, + ExpectedBazelTargets: []string{test.expected.String()}, + }) + } +} diff --git a/bp2build/package_conversion_test.go b/bp2build/package_conversion_test.go new file mode 100644 index 000000000..3704b2d7b --- /dev/null +++ b/bp2build/package_conversion_test.go @@ -0,0 +1,85 @@ +// Copyright 2022 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "android/soong/android" + "android/soong/genrule" + "testing" +) + +func registerDependentModules(ctx android.RegistrationContext) { + ctx.RegisterModuleType("license", android.LicenseFactory) + ctx.RegisterModuleType("genrule", genrule.GenRuleFactory) +} + +func TestPackage(t *testing.T) { + tests := []struct { + description string + modules string + expected []ExpectedRuleTarget + }{ + { + description: "with default applicable licenses", + modules: ` +license { + name: "my_license", + visibility: [":__subpackages__"], + license_kinds: ["SPDX-license-identifier-Apache-2.0"], + license_text: ["NOTICE"], +} + +package { + default_applicable_licenses: ["my_license"], +} +`, + expected: []ExpectedRuleTarget{ + { + "package", + "", + AttrNameToString{ + "default_applicable_licenses": `[":my_license"]`, + "default_visibility": `["//visibility:public"]`, + }, + android.HostAndDeviceDefault, + }, + { + "android_license", + "my_license", + AttrNameToString{ + "license_kinds": `["SPDX-license-identifier-Apache-2.0"]`, + "license_text": `"NOTICE"`, + "visibility": `[":__subpackages__"]`, + }, + android.HostAndDeviceDefault, + }, + }, + }, + } + for _, test := range tests { + expected := make([]string, 0, len(test.expected)) + for _, e := range test.expected { + expected = append(expected, e.String()) + } + RunBp2BuildTestCase(t, registerDependentModules, + Bp2buildTestCase{ + Description: test.description, + ModuleTypeUnderTest: "package", + ModuleTypeUnderTestFactory: android.PackageFactory, + Blueprint: test.modules, + ExpectedBazelTargets: expected, + }) + } +} diff --git a/bp2build/testing.go b/bp2build/testing.go index ac1268cb5..edc5c4a99 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -141,7 +141,7 @@ 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 (%s), got `%d`` (%s)", + t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)", tc.Description, expectedCount, tc.ExpectedBazelTargets, actualCount, bazelTargets) } else { for i, target := range bazelTargets { @@ -429,7 +429,9 @@ func makeBazelTargetHostOrDevice(typ, name string, attrs AttrNameToString, hod a } attrStrings := make([]string, 0, len(attrs)+1) - attrStrings = append(attrStrings, fmt.Sprintf(` name = "%s",`, name)) + if name != "" { + attrStrings = append(attrStrings, fmt.Sprintf(` name = "%s",`, name)) + } for _, k := range android.SortedStringKeys(attrs) { attrStrings = append(attrStrings, fmt.Sprintf(" %s = %s,", k, attrs[k])) } @@ -450,3 +452,14 @@ func MakeBazelTargetNoRestrictions(typ, name string, attrs AttrNameToString) str func MakeBazelTarget(typ, name string, attrs AttrNameToString) string { return makeBazelTargetHostOrDevice(typ, name, attrs, android.DeviceSupported) } + +type ExpectedRuleTarget struct { + Rule string + Name string + Attrs AttrNameToString + Hod android.HostOrDeviceSupported +} + +func (ebr ExpectedRuleTarget) String() string { + return makeBazelTargetHostOrDevice(ebr.Rule, ebr.Name, ebr.Attrs, ebr.Hod) +} diff --git a/cc/Android.bp b/cc/Android.bp index 2963c77b5..91a3fb0df 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -45,7 +45,6 @@ bootstrap_go_package { "snapshot_utils.go", "stl.go", "strip.go", - "sysprop.go", "tidy.go", "util.go", "vendor_snapshot.go", @@ -99,6 +98,7 @@ bootstrap_go_package { "library_headers_test.go", "library_stub_test.go", "library_test.go", + "lto_test.go", "ndk_test.go", "object_test.go", "prebuilt_test.go", diff --git a/cc/bp2build.go b/cc/bp2build.go index 51d8e2270..95ac598af 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -746,77 +746,57 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) } } -func bp2buildAidlLibraries( - ctx android.Bp2buildMutatorContext, - m *Module, - aidlSrcs bazel.LabelListAttribute, -) bazel.LabelList { - var aidlLibraries bazel.LabelList - var directAidlSrcs bazel.LabelList - - // Make a list of labels that correspond to filegroups that are already converted to aidl_library - for _, aidlSrc := range aidlSrcs.Value.Includes { - src := aidlSrc.OriginalModuleName - if fg, ok := android.ToFileGroupAsLibrary(ctx, src); ok && - fg.ShouldConvertToAidlLibrary(ctx) { - aidlLibraries.Add(&bazel.Label{ - Label: fg.GetAidlLibraryLabel(ctx), - }) - } else { - directAidlSrcs.Add(&aidlSrc) - } - } - - if len(directAidlSrcs.Includes) > 0 { - aidlLibraryLabel := m.Name() + "_aidl_library" - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "aidl_library", - Bzl_load_location: "//build/bazel/rules/aidl:library.bzl", - }, - android.CommonAttributes{Name: aidlLibraryLabel}, - &aidlLibraryAttributes{ - Srcs: bazel.MakeLabelListAttribute(directAidlSrcs), - }, - ) - aidlLibraries.Add(&bazel.Label{ - Label: ":" + aidlLibraryLabel, - }) - } - return aidlLibraries -} - func bp2buildCcAidlLibrary( ctx android.Bp2buildMutatorContext, m *Module, - aidlSrcs bazel.LabelListAttribute, + aidlLabelList bazel.LabelListAttribute, ) *bazel.LabelAttribute { - suffix := "_cc_aidl_library" - ccAidlLibrarylabel := m.Name() + suffix + if !aidlLabelList.IsEmpty() { + aidlLibs, aidlSrcs := aidlLabelList.Partition(func(src bazel.Label) bool { + if fg, ok := android.ToFileGroupAsLibrary(ctx, src.OriginalModuleName); ok && + fg.ShouldConvertToAidlLibrary(ctx) { + return true + } + return false + }) - aidlLibraries := bp2buildAidlLibraries(ctx, m, aidlSrcs) + if !aidlSrcs.IsEmpty() { + aidlLibName := m.Name() + "_aidl_library" + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "aidl_library", + Bzl_load_location: "//build/bazel/rules/aidl:library.bzl", + }, + android.CommonAttributes{Name: aidlLibName}, + &aidlLibraryAttributes{ + Srcs: aidlSrcs, + }, + ) + aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) + } - if aidlLibraries.IsEmpty() { - return nil + if !aidlLibs.IsEmpty() { + ccAidlLibrarylabel := m.Name() + "_cc_aidl_library" + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "cc_aidl_library", + Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl", + }, + android.CommonAttributes{Name: ccAidlLibrarylabel}, + &ccAidlLibraryAttributes{ + Deps: aidlLibs, + }, + ) + label := &bazel.LabelAttribute{ + Value: &bazel.Label{ + Label: ":" + ccAidlLibrarylabel, + }, + } + return label + } } - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "cc_aidl_library", - Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl", - }, - android.CommonAttributes{Name: ccAidlLibrarylabel}, - &ccAidlLibraryAttributes{ - Deps: bazel.MakeLabelListAttribute(aidlLibraries), - }, - ) - - label := &bazel.LabelAttribute{ - Value: &bazel.Label{ - Label: ":" + ccAidlLibrarylabel, - }, - } - return label + return nil } func bp2BuildParseSdkAttributes(module *Module) sdkAttributes { @@ -858,19 +838,77 @@ type linkerAttributes struct { var ( soongSystemSharedLibs = []string{"libc", "libm", "libdl"} + versionLib = "libbuildversion" ) +// resolveTargetApex re-adds the shared and static libs in target.apex.exclude_shared|static_libs props to non-apex variant +// since all libs are already excluded by default +func (la *linkerAttributes) resolveTargetApexProp(ctx android.BazelConversionPathContext, isBinary bool, props *BaseLinkerProperties) { + sharedLibsForNonApex := maybePartitionExportedAndImplementationsDeps( + ctx, + true, + props.Target.Apex.Exclude_shared_libs, + props.Export_shared_lib_headers, + bazelLabelForSharedDeps, + ) + dynamicDeps := la.dynamicDeps.SelectValue(bazel.InApexAxis, bazel.NonApex) + implDynamicDeps := la.implementationDynamicDeps.SelectValue(bazel.InApexAxis, bazel.NonApex) + (&dynamicDeps).Append(sharedLibsForNonApex.export) + (&implDynamicDeps).Append(sharedLibsForNonApex.implementation) + la.dynamicDeps.SetSelectValue(bazel.InApexAxis, bazel.NonApex, dynamicDeps) + la.implementationDynamicDeps.SetSelectValue(bazel.InApexAxis, bazel.NonApex, implDynamicDeps) + + staticLibsForNonApex := maybePartitionExportedAndImplementationsDeps( + ctx, + !isBinary, + props.Target.Apex.Exclude_static_libs, + props.Export_static_lib_headers, + bazelLabelForSharedDeps, + ) + deps := la.deps.SelectValue(bazel.InApexAxis, bazel.NonApex) + implDeps := la.implementationDeps.SelectValue(bazel.InApexAxis, bazel.NonApex) + (&deps).Append(staticLibsForNonApex.export) + (&implDeps).Append(staticLibsForNonApex.implementation) + la.deps.SetSelectValue(bazel.InApexAxis, bazel.NonApex, deps) + la.implementationDeps.SetSelectValue(bazel.InApexAxis, bazel.NonApex, implDeps) +} + func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, isBinary bool, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) { // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module var axisFeatures []string wholeStaticLibs := android.FirstUniqueStrings(props.Whole_static_libs) - la.wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, props.Exclude_static_libs)) + staticLibs := android.FirstUniqueStrings(android.RemoveListFromList(props.Static_libs, wholeStaticLibs)) + if axis == bazel.NoConfigAxis { + la.useVersionLib.SetSelectValue(axis, config, props.Use_version_lib) + if proptools.Bool(props.Use_version_lib) { + versionLibAlreadyInDeps := android.InList(versionLib, wholeStaticLibs) + // remove from static libs so there is no duplicate dependency + _, staticLibs = android.RemoveFromList(versionLib, staticLibs) + // only add the dep if it is not in progress + if !versionLibAlreadyInDeps { + if isBinary { + wholeStaticLibs = append(wholeStaticLibs, versionLib) + } else { + la.implementationWholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, []string{versionLib}, props.Exclude_static_libs)) + } + } + } + } + // Excludes to parallel Soong: // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0 - staticLibs := android.FirstUniqueStrings(android.RemoveListFromList(props.Static_libs, wholeStaticLibs)) + la.wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, props.Exclude_static_libs)) - staticDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, staticLibs, props.Exclude_static_libs, props.Export_static_lib_headers, bazelLabelForStaticDepsExcludes) + staticDeps := maybePartitionExportedAndImplementationsDepsExcludes( + ctx, + !isBinary, + staticLibs, + // Exclude static libs in Exclude_static_libs and Target.Apex.Exclude_static_libs props + append(props.Exclude_static_libs, props.Target.Apex.Exclude_static_libs...), + props.Export_static_lib_headers, + bazelLabelForStaticDepsExcludes, + ) headerLibs := android.FirstUniqueStrings(props.Header_libs) hDeps := maybePartitionExportedAndImplementationsDeps(ctx, !isBinary, headerLibs, props.Export_header_lib_headers, bazelLabelForHeaderDeps) @@ -902,9 +940,19 @@ func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversion la.usedSystemDynamicDepAsDynamicDep[el] = true } - sharedDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, sharedLibs, props.Exclude_shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes) + sharedDeps := maybePartitionExportedAndImplementationsDepsExcludes( + ctx, + !isBinary, + sharedLibs, + // Exclude shared libs in Exclude_shared_libs and Target.Apex.Exclude_shared_libs props + append(props.Exclude_shared_libs, props.Target.Apex.Exclude_shared_libs...), + props.Export_shared_lib_headers, + bazelLabelForSharedDepsExcludes, + ) la.dynamicDeps.SetSelectValue(axis, config, sharedDeps.export) la.implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation) + la.resolveTargetApexProp(ctx, isBinary, props) + if axis == bazel.NoConfigAxis || (axis == bazel.OsConfigurationAxis && config == bazel.OsAndroid) { // If a dependency in la.implementationDynamicDeps has stubs, its stub variant should be // used when the dependency is linked in a APEX. The dependencies in NoConfigAxis and @@ -933,14 +981,14 @@ func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversion (&inApexSelectValue).Append(bazel.MakeLabelList(stubLibLabels)) (&nonApexSelectValue).Append(bazel.MakeLabelList(depsWithStubs)) (&defaultSelectValue).Append(bazel.MakeLabelList(depsWithStubs)) - la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, inApexSelectValue) - la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, nonApexSelectValue) - la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey, defaultSelectValue) + la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.FirstUniqueBazelLabelList(inApexSelectValue)) + la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue)) + la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey, bazel.FirstUniqueBazelLabelList(defaultSelectValue)) } else if config == bazel.OsAndroid { (&inApexSelectValue).Append(bazel.MakeLabelList(stubLibLabels)) (&nonApexSelectValue).Append(bazel.MakeLabelList(depsWithStubs)) - la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, inApexSelectValue) - la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, nonApexSelectValue) + la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.FirstUniqueBazelLabelList(inApexSelectValue)) + la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue)) } } } @@ -976,10 +1024,6 @@ func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversion la.linkopts.SetSelectValue(axis, config, parseCommandLineFlags(linkerFlags, false, filterOutClangUnknownCflags)) 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 { @@ -51,7 +51,6 @@ func RegisterCCBuildComponents(ctx android.RegistrationContext) { ctx.BottomUp("test_per_src", TestPerSrcMutator).Parallel() ctx.BottomUp("version", versionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() - ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel() }) ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { @@ -2392,18 +2391,8 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { } } - // sysprop_library has to support both C++ and Java. So sysprop_library internally creates one - // C++ implementation library and one Java implementation library. When a module links against - // sysprop_library, the C++ implementation library has to be linked. syspropImplLibraries is a - // map from sysprop_library to implementation library; it will be used in whole_static_libs, - // static_libs, and shared_libs. - syspropImplLibraries := syspropImplLibraries(actx.Config()) - for _, lib := range deps.WholeStaticLibs { depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true, reexportFlags: true} - if impl, ok := syspropImplLibraries[lib]; ok { - lib = impl - } lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) @@ -2421,10 +2410,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag.excludeInApex = true } - if impl, ok := syspropImplLibraries[lib]; ok { - lib = impl - } - lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs) actx.AddVariationDependencies([]blueprint.Variation{ @@ -2454,10 +2439,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { depTag.excludeInApex = true } - if impl, ok := syspropImplLibraries[lib]; ok { - lib = impl - } - name, version := StubsLibNameAndVersion(lib) sharedLibNames = append(sharedLibNames, name) diff --git a/cc/config/global.go b/cc/config/global.go index f920471f2..a7701b950 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -316,9 +316,6 @@ var ( "device/", "vendor/", } - - // Directories with warnings from Android.mk files. - WarningAllowedOldProjects = []string{} ) // BazelCcToolchainVars generates bzl file content containing variables for diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go index 1b126dea1..07b95e112 100644 --- a/cc/config/x86_linux_host.go +++ b/cc/config/x86_linux_host.go @@ -109,7 +109,7 @@ var ( }, "-l") muslCrtBeginStaticBinary, muslCrtEndStaticBinary = []string{"libc_musl_crtbegin_static"}, []string{"libc_musl_crtend"} - muslCrtBeginSharedBinary, muslCrtEndSharedBinary = []string{"libc_musl_crtbegin_dynamic", "musl_linker_script"}, []string{"libc_musl_crtend"} + muslCrtBeginSharedBinary, muslCrtEndSharedBinary = []string{"libc_musl_crtbegin_dynamic"}, []string{"libc_musl_crtend"} muslCrtBeginSharedLibrary, muslCrtEndSharedLibrary = []string{"libc_musl_crtbegin_so"}, []string{"libc_musl_crtend_so"} muslDefaultSharedLibraries = []string{"libc_musl"} diff --git a/cc/library.go b/cc/library.go index 8804bbb8f..a8653a0a9 100644 --- a/cc/library.go +++ b/cc/library.go @@ -339,14 +339,15 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { Copts: *compilerAttrs.copts.Clone().Append(sharedAttrs.Copts), Hdrs: *compilerAttrs.hdrs.Clone().Append(sharedAttrs.Hdrs), - Deps: *linkerAttrs.deps.Clone().Append(sharedAttrs.Deps), - Implementation_deps: *linkerAttrs.implementationDeps.Clone().Append(sharedAttrs.Implementation_deps), - Dynamic_deps: *linkerAttrs.dynamicDeps.Clone().Append(sharedAttrs.Dynamic_deps), - Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(sharedAttrs.Implementation_dynamic_deps), - Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(sharedAttrs.Whole_archive_deps), - System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(sharedAttrs.System_dynamic_deps), - Runtime_deps: linkerAttrs.runtimeDeps, - sdkAttributes: bp2BuildParseSdkAttributes(m), + Deps: *linkerAttrs.deps.Clone().Append(sharedAttrs.Deps), + Implementation_deps: *linkerAttrs.implementationDeps.Clone().Append(sharedAttrs.Implementation_deps), + Dynamic_deps: *linkerAttrs.dynamicDeps.Clone().Append(sharedAttrs.Dynamic_deps), + Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(sharedAttrs.Implementation_dynamic_deps), + Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(sharedAttrs.Whole_archive_deps), + Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps, + System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(sharedAttrs.System_dynamic_deps), + Runtime_deps: linkerAttrs.runtimeDeps, + sdkAttributes: bp2BuildParseSdkAttributes(m), } staticTargetAttrs := &bazelCcLibraryStaticAttributes{ @@ -366,7 +367,6 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { Stl: compilerAttrs.stl, Cpp_std: compilerAttrs.cppStd, C_std: compilerAttrs.cStd, - Use_version_lib: linkerAttrs.useVersionLib, Features: baseAttributes.features, } @@ -2630,8 +2630,7 @@ func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Mo attrs = &bazelCcLibraryStaticAttributes{ staticOrSharedAttributes: commonAttrs, - Use_libcrt: linkerAttrs.useLibcrt, - Use_version_lib: linkerAttrs.useVersionLib, + Use_libcrt: linkerAttrs.useLibcrt, Rtti: compilerAttrs.rtti, Stl: compilerAttrs.stl, diff --git a/cc/lto_test.go b/cc/lto_test.go new file mode 100644 index 000000000..b52f2b6a3 --- /dev/null +++ b/cc/lto_test.go @@ -0,0 +1,90 @@ +// 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 cc + +import ( + "android/soong/android" + "strings" + "testing" + + "github.com/google/blueprint" +) + +func TestThinLtoDeps(t *testing.T) { + bp := ` + cc_library { + name: "lto_enabled", + srcs: ["src.c"], + static_libs: ["foo"], + shared_libs: ["bar"], + lto: { + thin: true, + } + } + cc_library { + name: "foo", + static_libs: ["baz"], + } + cc_library { + name: "bar", + static_libs: ["qux"], + } + cc_library { + name: "baz", + } + cc_library { + name: "qux", + } +` + + result := android.GroupFixturePreparers( + prepareForCcTest, + ).RunTestWithBp(t, bp) + + libLto := result.ModuleForTests("lto_enabled", "android_arm64_armv8-a_shared").Module() + libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static_lto-thin").Module() + libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin").Module() + + hasDep := func(m android.Module, wantDep android.Module) bool { + var found bool + result.VisitDirectDeps(m, func(dep blueprint.Module) { + if dep == wantDep { + found = true + } + }) + return found + } + + if !hasDep(libLto, libFoo) { + t.Errorf("'lto_enabled' missing dependency on thin lto variant of 'foo'") + } + + if !hasDep(libFoo, libBaz) { + t.Errorf("'lto_enabled' missing dependency on thin lto variant of transitive dep 'baz'") + } + + barVariants := result.ModuleVariantsForTests("bar") + for _, v := range barVariants { + if strings.Contains(v, "lto-thin") { + t.Errorf("Expected variants for 'bar' to not contain 'lto-thin', but found %q", v) + } + } + quxVariants := result.ModuleVariantsForTests("qux") + for _, v := range quxVariants { + if strings.Contains(v, "lto-thin") { + t.Errorf("Expected variants for 'qux' to not contain 'lto-thin', but found %q", v) + } + } +} diff --git a/cc/makevars.go b/cc/makevars.go index 815443626..de8a8f21c 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -53,7 +53,6 @@ func makeStringOfKeys(ctx android.MakeVarsContext, key android.OnceKey) string { func makeStringOfWarningAllowedProjects() string { allProjects := append([]string{}, config.WarningAllowedProjects...) - allProjects = append(allProjects, config.WarningAllowedOldProjects...) sort.Strings(allProjects) // Makefile rules use pattern "path/%" to match module paths. if len(allProjects) > 0 { diff --git a/cc/object.go b/cc/object.go index 65a11e005..1a96b7205 100644 --- a/cc/object.go +++ b/cc/object.go @@ -16,6 +16,7 @@ package cc import ( "fmt" + "strings" "android/soong/android" "android/soong/bazel" @@ -254,22 +255,31 @@ func (object *objectLinker) link(ctx ModuleContext, var outputFile android.Path builderFlags := flagsToBuilderFlags(flags) + outputName := ctx.ModuleName() + if !strings.HasSuffix(outputName, objectExtension) { + outputName += objectExtension + } if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" { - outputFile = objs.objFiles[0] + output := android.PathForModuleOut(ctx, outputName) + outputFile = output if String(object.Properties.Prefix_symbols) != "" { - output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension) - transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), outputFile, + transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), objs.objFiles[0], builderFlags, output) - outputFile = output + } else { + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, + Input: objs.objFiles[0], + Output: output, + }) } } else { - output := android.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension) + output := android.PathForModuleOut(ctx, outputName) outputFile = output if String(object.Properties.Prefix_symbols) != "" { - input := android.PathForModuleOut(ctx, "unprefixed", ctx.ModuleName()+objectExtension) + input := android.PathForModuleOut(ctx, "unprefixed", outputName) transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), input, builderFlags, output) output = input diff --git a/cc/object_test.go b/cc/object_test.go index 259a892ab..5359a357a 100644 --- a/cc/object_test.go +++ b/cc/object_test.go @@ -15,6 +15,7 @@ package cc import ( + "fmt" "testing" "android/soong/android" @@ -107,3 +108,65 @@ cc_object { expectedOutputFiles := []string{"outputbase/execroot/__main__/bazel_out.o"} android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings()) } + +func TestCcObjectOutputFile(t *testing.T) { + testcases := []struct { + name string + moduleName string + bp string + }{ + { + name: "normal", + moduleName: "foo", + bp: ` + srcs: ["bar.c"], + `, + }, + { + name: "suffix", + moduleName: "foo.o", + bp: ` + srcs: ["bar.c"], + `, + }, + { + name: "keep symbols", + moduleName: "foo", + bp: ` + srcs: ["bar.c"], + prefix_symbols: "foo_", + `, + }, + { + name: "partial linking", + moduleName: "foo", + bp: ` + srcs: ["bar.c", "baz.c"], + `, + }, + { + name: "partial linking and prefix symbols", + moduleName: "foo", + bp: ` + srcs: ["bar.c", "baz.c"], + prefix_symbols: "foo_", + `, + }, + } + + for _, testcase := range testcases { + bp := fmt.Sprintf(` + cc_object { + name: "%s", + %s + } + `, testcase.moduleName, testcase.bp) + t.Run(testcase.name, func(t *testing.T) { + ctx := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp) + android.AssertPathRelativeToTopEquals(t, "expected output file foo.o", + fmt.Sprintf("out/soong/.intermediates/%s/android_arm64_armv8-a/foo.o", testcase.moduleName), + ctx.ModuleForTests(testcase.moduleName, "android_arm64_armv8-a").Output("foo.o").Output) + }) + } + +} diff --git a/cc/sysprop.go b/cc/sysprop.go deleted file mode 100644 index f578b507a..000000000 --- a/cc/sysprop.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2019 The Android Open Source Project -// -// 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 cc - -// This file contains a map to redirect dependencies towards sysprop_library. -// As sysprop_library has to support both Java and C++, sysprop_library internally -// generates cc_library and java_library. For example, the following sysprop_library -// -// sysprop_library { -// name: "foo", -// } -// -// will internally generate with prefix "lib" -// -// cc_library { -// name: "libfoo", -// } -// -// When a cc module links against "foo", build system will redirect the -// dependency to "libfoo". To do that, SyspropMutator gathers all sysprop_library, -// records their cc implementation library names to a map. The map will be used in -// cc.Module.DepsMutator. - -import ( - "sync" - - "android/soong/android" -) - -type syspropLibraryInterface interface { - BaseModuleName() string - CcImplementationModuleName() string -} - -var ( - syspropImplLibrariesKey = android.NewOnceKey("syspropImplLibirares") - syspropImplLibrariesLock sync.Mutex -) - -func syspropImplLibraries(config android.Config) map[string]string { - return config.Once(syspropImplLibrariesKey, func() interface{} { - return make(map[string]string) - }).(map[string]string) -} - -// gather list of sysprop libraries -func SyspropMutator(mctx android.BottomUpMutatorContext) { - if m, ok := mctx.Module().(syspropLibraryInterface); ok { - syspropImplLibraries := syspropImplLibraries(mctx.Config()) - syspropImplLibrariesLock.Lock() - defer syspropImplLibrariesLock.Unlock() - - // BaseModuleName is the name of sysprop_library - // CcImplementationModuleName is the name of cc_library generated by sysprop_library - syspropImplLibraries[m.BaseModuleName()] = m.CcImplementationModuleName() - } -} diff --git a/cc/test.go b/cc/test.go index 28a0e5ebf..715c537c7 100644 --- a/cc/test.go +++ b/cc/test.go @@ -659,6 +659,7 @@ func testBinaryBp2build(ctx android.TopDownMutatorContext, m *Module) { testBinaryAttrs.binaryAttributes = binaryBp2buildAttrs(ctx, m) var data bazel.LabelListAttribute + var tags bazel.StringListAttribute testBinaryProps := m.GetArchVariantProperties(ctx, &TestBinaryProperties{}) for axis, configToProps := range testBinaryProps { @@ -670,6 +671,7 @@ func testBinaryBp2build(ctx android.TopDownMutatorContext, m *Module) { combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_bins)) combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_libs)) data.SetSelectValue(axis, config, combinedData) + tags.SetSelectValue(axis, config, p.Test_options.Tags) } } } @@ -690,6 +692,7 @@ func testBinaryBp2build(ctx android.TopDownMutatorContext, m *Module) { android.CommonAttributes{ Name: m.Name(), Data: data, + Tags: tags, }, &testBinaryAttrs) } diff --git a/cmd/extract_apks/main.go b/cmd/extract_apks/main.go index 1cf64de8b..c420567e4 100644 --- a/cmd/extract_apks/main.go +++ b/cmd/extract_apks/main.go @@ -29,6 +29,7 @@ import ( "google.golang.org/protobuf/proto" + "android/soong/cmd/extract_apks/bundle_proto" android_bundle_proto "android/soong/cmd/extract_apks/bundle_proto" "android/soong/third_party/zip" ) @@ -75,7 +76,7 @@ func (apkSet *ApkSet) getToc() (Toc, error) { return nil, err } bytes := make([]byte, tocFile.FileHeader.UncompressedSize64) - if _, err := rc.Read(bytes); err != io.EOF { + if _, err := rc.Read(bytes); err != nil && err != io.EOF { return nil, err } rc.Close() @@ -197,6 +198,49 @@ type multiAbiTargetingMatcher struct { *android_bundle_proto.MultiAbiTargeting } +type multiAbiValue []*bundle_proto.Abi + +func (m multiAbiValue) compare(other multiAbiValue) int { + min := func(a, b int) int { + if a < b { + return a + } + return b + } + + sortAbis := func(abiSlice multiAbiValue) func(i, j int) bool { + return func(i, j int) bool { + // sort priorities greatest to least + return multiAbiPriorities[abiSlice[i].Alias] > multiAbiPriorities[abiSlice[j].Alias] + } + } + + m = append(multiAbiValue{}, m...) + sort.Slice(m, sortAbis(m)) + other = append(multiAbiValue{}, other...) + sort.Slice(other, sortAbis(other)) + + for i := 0; i < min(len(m), len(other)); i++ { + if multiAbiPriorities[m[i].Alias] > multiAbiPriorities[other[i].Alias] { + return 1 + } + if multiAbiPriorities[m[i].Alias] < multiAbiPriorities[other[i].Alias] { + return -1 + } + } + + if len(m) == len(other) { + return 0 + } + if len(m) > len(other) { + return 1 + } + return -1 +} + +// this logic should match the logic in bundletool at +// https://github.com/google/bundletool/blob/ae0fc0162fd80d92ef8f4ef4527c066f0106942f/src/main/java/com/android/tools/build/bundletool/device/MultiAbiMatcher.java#L43 +// (note link is the commit at time of writing; but logic should always match the latest) func (t multiAbiTargetingMatcher) matches(config TargetConfig) bool { if t.MultiAbiTargeting == nil { return true @@ -204,31 +248,45 @@ func (t multiAbiTargetingMatcher) matches(config TargetConfig) bool { if _, ok := config.abis[android_bundle_proto.Abi_UNSPECIFIED_CPU_ARCHITECTURE]; ok { return true } - // Find the one with the highest priority. - highestPriority := 0 - for _, v := range t.GetValue() { - for _, a := range v.GetAbi() { - if _, ok := config.abis[a.Alias]; ok { - if highestPriority < multiAbiPriorities[a.Alias] { - highestPriority = multiAbiPriorities[a.Alias] - } + + multiAbiIsValid := func(m multiAbiValue) bool { + for _, abi := range m { + if _, ok := config.abis[abi.Alias]; !ok { + return false } } + return true + } + + // ensure that the current value is valid for our config + valueSetContainsViableAbi := false + multiAbiSet := t.GetValue() + for _, multiAbi := range multiAbiSet { + if multiAbiIsValid(multiAbi.GetAbi()) { + valueSetContainsViableAbi = true + } } - if highestPriority == 0 { + + if !valueSetContainsViableAbi { return false } + // See if there are any matching alternatives with a higher priority. - for _, v := range t.GetAlternatives() { - for _, a := range v.GetAbi() { - if _, ok := config.abis[a.Alias]; ok { - if highestPriority < multiAbiPriorities[a.Alias] { - // There's a better one. Skip this one. - return false - } + for _, altMultiAbi := range t.GetAlternatives() { + if !multiAbiIsValid(altMultiAbi.GetAbi()) { + continue + } + + for _, multiAbi := range multiAbiSet { + valueAbis := multiAbiValue(multiAbi.GetAbi()) + altAbis := multiAbiValue(altMultiAbi.GetAbi()) + if valueAbis.compare(altAbis) < 0 { + // An alternative has a higher priority, don't use this one + return false } } } + return true } diff --git a/cmd/extract_apks/main_test.go b/cmd/extract_apks/main_test.go index f5e40466a..c1d712df4 100644 --- a/cmd/extract_apks/main_test.go +++ b/cmd/extract_apks/main_test.go @@ -420,6 +420,370 @@ bundletool { } } +func TestSelectApks_ApexSet_Variants(t *testing.T) { + testCases := []testDesc{ + { + protoText: ` +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + path: "standalones/standalone-armeabi_v7a.apex" + } + } + variant_number: 0 +} +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value {abi {alias: ARM64_V8A}} + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value {abi {alias: ARM64_V8A}} + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + path: "standalones/standalone-arm64_v8a.apex" + } + } + variant_number: 1 +} +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARMEABI_V7A}} + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARMEABI_V7A}} + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + path: "standalones/standalone-armeabi_v7a.arm64_v8a.apex" + } + } + variant_number: 2 +} +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value {abi {alias: X86}} + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value {abi {alias: X86}} + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + path: "standalones/standalone-x86.apex" + } + } + variant_number: 3 +} +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value { + abi {alias: X86} + abi {alias: X86_64} + } + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value { + abi {alias: X86} + abi {alias: X86_64} + } + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + } + } + path: "standalones/standalone-x86.x86_64.apex" + } + } + variant_number: 4 +} +`, + configs: []testConfigDesc{ + { + name: "multi-variant multi-target ARM", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_ARM64_V8A: 0, + bp.Abi_ARMEABI_V7A: 1, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-armeabi_v7a.arm64_v8a.apex", + }, + }, + }, + { + name: "multi-variant single-target arm", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_ARMEABI_V7A: 0, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-armeabi_v7a.apex", + }, + }, + }, + { + name: "multi-variant single-target arm64", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_ARM64_V8A: 0, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-arm64_v8a.apex", + }, + }, + }, + { + name: "multi-variant multi-target x86", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_X86: 0, + bp.Abi_X86_64: 1, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-x86.x86_64.apex", + }, + }, + }, + { + name: "multi-variant single-target x86", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_X86: 0, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-x86.apex", + }, + }, + }, + { + name: "multi-variant single-target x86_64", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_X86_64: 0, + }, + }, + expected: SelectionResult{}, + }, + { + name: "multi-variant multi-target cross-target", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_ARM64_V8A: 0, + bp.Abi_X86_64: 1, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-arm64_v8a.apex", + }, + }, + }, + }, + }, + } + for _, testCase := range testCases { + var toc bp.BuildApksResult + if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil { + t.Fatal(err) + } + for _, config := range testCase.configs { + t.Run(config.name, func(t *testing.T) { + actual := selectApks(&toc, config.targetConfig) + if !reflect.DeepEqual(config.expected, actual) { + t.Errorf("expected %v, got %v", config.expected, actual) + } + }) + } + } +} + type testZip2ZipWriter struct { entries map[string]string } diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index d8011d69f..fdfd22e1b 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -201,6 +201,11 @@ func GetSystemServerDexLocation(ctx android.PathContext, global *GlobalConfig, l if apex := global.AllApexSystemServerJars(ctx).ApexOfJar(lib); apex != "" { return fmt.Sprintf("/apex/%s/javalib/%s.jar", apex, lib) } + + if apex := global.AllPlatformSystemServerJars(ctx).ApexOfJar(lib); apex == "system_ext" { + return fmt.Sprintf("/system_ext/framework/%s.jar", lib) + } + return fmt.Sprintf("/system/framework/%s.jar", lib) } diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go index 07e4fad01..429b5ff1e 100644 --- a/dexpreopt/dexpreopt_test.go +++ b/dexpreopt/dexpreopt_test.go @@ -59,6 +59,15 @@ func testPlatformSystemServerModuleConfig(ctx android.PathContext, name string) android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name))) } +func testSystemExtSystemServerModuleConfig(ctx android.PathContext, name string) *ModuleConfig { + return createTestModuleConfig( + name, + fmt.Sprintf("/system_ext/framework/%s.jar", name), + android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)), + android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)), + android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name))) +} + func createTestModuleConfig(name, dexLocation string, buildPath, dexPath, enforceUsesLibrariesStatusFile android.OutputPath) *ModuleConfig { return &ModuleConfig{ Name: name, @@ -213,6 +222,29 @@ func TestDexPreoptStandaloneSystemServerJars(t *testing.T) { android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String()) } +func TestDexPreoptSystemExtSystemServerJars(t *testing.T) { + config := android.TestConfig("out", nil, "", nil) + ctx := android.BuilderContextForTesting(config) + globalSoong := globalSoongConfigForTests() + global := GlobalConfigForTests(ctx) + module := testSystemExtSystemServerModuleConfig(ctx, "service-A") + + global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList( + []string{"system_ext:service-A"}) + + rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module) + if err != nil { + t.Fatal(err) + } + + wantInstalls := android.RuleBuilderInstalls{ + {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system_ext/framework/oat/arm/service-A.odex"}, + {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system_ext/framework/oat/arm/service-A.vdex"}, + } + + android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String()) +} + func TestDexPreoptApexStandaloneSystemServerJars(t *testing.T) { config := android.TestConfig("out", nil, "", nil) ctx := android.BuilderContextForTesting(config) diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 93168070e..42a11fb75 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -840,22 +840,7 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul // isTestFragment returns true if the current module is a test bootclasspath_fragment. func (b *BootclasspathFragmentModule) isTestFragment() bool { - if b.testFragment { - return true - } - - // TODO(b/194063708): Once test fragments all use bootclasspath_fragment_test - // Some temporary exceptions until all test fragments use the - // bootclasspath_fragment_test module type. - name := b.BaseModuleName() - if strings.HasPrefix(name, "test_") { - return true - } - if name == "apex.apexd_test_bootclasspath-fragment" { - return true - } - - return false + return b.testFragment } // produceHiddenAPIOutput produces the hidden API all-flags.csv file (and supporting files) diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go index c63df599a..2541f14ff 100644 --- a/java/bootclasspath_fragment_test.go +++ b/java/bootclasspath_fragment_test.go @@ -408,22 +408,6 @@ func TestBootclasspathFragment_Test(t *testing.T) { }, } - bootclasspath_fragment { - name: "test_fragment", - contents: ["mysdklibrary"], - hidden_api: { - split_packages: [], - }, - } - - bootclasspath_fragment { - name: "apex.apexd_test_bootclasspath-fragment", - contents: ["mysdklibrary"], - hidden_api: { - split_packages: [], - }, - } - bootclasspath_fragment_test { name: "a_test_fragment", contents: ["mysdklibrary"], @@ -445,12 +429,6 @@ func TestBootclasspathFragment_Test(t *testing.T) { fragment := result.Module("myfragment", "android_common").(*BootclasspathFragmentModule) android.AssertBoolEquals(t, "not a test fragment", false, fragment.isTestFragment()) - fragment = result.Module("test_fragment", "android_common").(*BootclasspathFragmentModule) - android.AssertBoolEquals(t, "is a test fragment by prefix", true, fragment.isTestFragment()) - fragment = result.Module("a_test_fragment", "android_common").(*BootclasspathFragmentModule) android.AssertBoolEquals(t, "is a test fragment by type", true, fragment.isTestFragment()) - - fragment = result.Module("apex.apexd_test_bootclasspath-fragment", "android_common").(*BootclasspathFragmentModule) - android.AssertBoolEquals(t, "is a test fragment by name", true, fragment.isTestFragment()) } diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go index 0785f89f0..578dc2b7f 100644 --- a/sysprop/sysprop_library.go +++ b/sysprop/sysprop_library.go @@ -365,7 +365,10 @@ func (m *syspropLibrary) ShouldSupportSdkVersion(ctx android.BaseModuleContext, // sysprop_library creates schematized APIs from sysprop description files (.sysprop). // Both Java and C++ modules can link against sysprop_library, and API stability check // against latest APIs (see build/soong/scripts/freeze-sysprop-api-files.sh) -// is performed. +// is performed. Note that the generated C++ module has its name prefixed with +// `lib`, and it is this module that should be depended on from other C++ +// modules; i.e., if the sysprop_library module is named `foo`, C++ modules +// should depend on `libfoo`. func syspropLibraryFactory() android.Module { m := &syspropLibrary{} diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go index 88ef61524..80b86e059 100644 --- a/sysprop/sysprop_test.go +++ b/sysprop/sysprop_test.go @@ -209,32 +209,32 @@ func TestSyspropLibrary(t *testing.T) { cc_library { name: "cc-client-platform", srcs: ["d.cpp"], - static_libs: ["sysprop-platform"], + static_libs: ["libsysprop-platform"], } cc_library_static { name: "cc-client-platform-static", srcs: ["d.cpp"], - whole_static_libs: ["sysprop-platform"], + whole_static_libs: ["libsysprop-platform"], } cc_library { name: "cc-client-product", srcs: ["d.cpp"], product_specific: true, - static_libs: ["sysprop-platform-on-product", "sysprop-vendor-on-product"], + static_libs: ["libsysprop-platform-on-product", "libsysprop-vendor-on-product"], } cc_library { name: "cc-client-vendor", srcs: ["d.cpp"], soc_specific: true, - static_libs: ["sysprop-platform", "sysprop-vendor"], + static_libs: ["libsysprop-platform", "libsysprop-vendor"], } cc_binary_host { name: "hostbin", - static_libs: ["sysprop-platform"], + static_libs: ["libsysprop-platform"], } `) diff --git a/tests/lib.sh b/tests/lib.sh index 7248adeb3..4b4d9085c 100644 --- a/tests/lib.sh +++ b/tests/lib.sh @@ -123,6 +123,7 @@ function create_mock_bazel { symlink_directory prebuilts/jdk symlink_directory external/bazel-skylib symlink_directory external/bazelbuild-rules_android + symlink_directory external/bazelbuild-rules_license symlink_directory external/bazelbuild-kotlin-rules symlink_file WORKSPACE |