diff options
73 files changed, 1476 insertions, 420 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 1ece9fa7d..e3e4dba90 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -201,6 +201,7 @@ var ( "frameworks/base/libs/androidfw": Bp2BuildDefaultTrue, "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, "frameworks/base/services/tests/servicestests/aidl": Bp2BuildDefaultTrue, + "frameworks/base/proto": Bp2BuildDefaultTrue, "frameworks/base/startop/apps/test": Bp2BuildDefaultTrue, "frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively, "frameworks/base/tools/aapt2": Bp2BuildDefaultTrue, @@ -296,14 +297,17 @@ var ( "platform_testing/tests/example": Bp2BuildDefaultTrueRecursively, - "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, - "prebuilts/gradle-plugin": Bp2BuildDefaultTrueRecursively, - "prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively, - "prebuilts/sdk/current/androidx": Bp2BuildDefaultTrue, - "prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue, - "prebuilts/sdk/current/support": Bp2BuildDefaultTrue, - "prebuilts/tools": Bp2BuildDefaultTrue, - "prebuilts/tools/common/m2": Bp2BuildDefaultTrue, + "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, + "prebuilts/gradle-plugin": Bp2BuildDefaultTrueRecursively, + "prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively, + "prebuilts/sdk/current/androidx": Bp2BuildDefaultTrue, + "prebuilts/sdk/current/androidx-legacy": Bp2BuildDefaultTrue, + "prebuilts/sdk/current/extras/constraint-layout-x": Bp2BuildDefaultTrue, + "prebuilts/sdk/current/extras/material-design-x": Bp2BuildDefaultTrue, + "prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue, + "prebuilts/sdk/current/support": Bp2BuildDefaultTrue, + "prebuilts/tools": Bp2BuildDefaultTrue, + "prebuilts/tools/common/m2": Bp2BuildDefaultTrue, "sdk/dumpeventlog": Bp2BuildDefaultTrue, "sdk/eventanalyzer": Bp2BuildDefaultTrue, @@ -365,6 +369,8 @@ var ( "system/testing/gtest_extras": Bp2BuildDefaultTrueRecursively, "system/timezone/apex": Bp2BuildDefaultTrueRecursively, "system/timezone/output_data": Bp2BuildDefaultTrueRecursively, + "system/timezone/testdata": Bp2BuildDefaultTrueRecursively, + "system/timezone/testing": Bp2BuildDefaultTrueRecursively, "system/tools/aidl/build/tests_bp2build": Bp2BuildDefaultTrue, "system/tools/aidl/metadata": Bp2BuildDefaultTrue, "system/tools/hidl/metadata": Bp2BuildDefaultTrue, @@ -373,8 +379,10 @@ var ( "system/tools/xsdc/utils": Bp2BuildDefaultTrueRecursively, "system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively, - "tools/apksig": Bp2BuildDefaultTrue, - "tools/metalava": Bp2BuildDefaultTrue, + "tools/apifinder": Bp2BuildDefaultTrue, + "tools/apksig": Bp2BuildDefaultTrue, + "tools/external_updater": Bp2BuildDefaultTrueRecursively, + "tools/metalava": Bp2BuildDefaultTrue, "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively, } @@ -406,8 +414,6 @@ var ( // this BUILD file is globbed by //external/icu/icu4c/source:icu4c_test_data's "data/**/*". "external/icu/icu4c/source/data/unidata/norm2":/* recursive = */ false, - "frameworks/ex/common":/* recursive = */ true, - // Building manually due to b/179889880: resource files cross package boundary "packages/apps/Music":/* recursive = */ true, @@ -453,7 +459,6 @@ var ( "framework-connectivity-protos", "gemmlowp_headers", "gl_headers", - "ipconnectivity-proto-src", "libandroid_runtime_lazy", "libandroid_runtime_vm_headers", "libaudioclient_aidl_conversion_util", @@ -473,6 +478,7 @@ var ( "libgralloctypes", "libnativewindow", "libneuralnetworks", + "libneuralnetworks_static", "libgraphicsenv", "libhardware", "libhardware_headers", @@ -687,7 +693,6 @@ var ( "libcodec2_soft_common", // kotlin srcs in java libs - "CtsPkgInstallerConstants", "kotlinx_atomicfu", // kotlin srcs in java binary @@ -700,6 +705,9 @@ var ( //kotlin srcs in android_binary "MusicKotlin", + // java_library with prebuilt sdk_version + "android-common", + // checked in current.txt for merged_txts "non-updatable-current.txt", "non-updatable-system-current.txt", @@ -722,7 +730,9 @@ var ( // min_sdk_version in android_app "CtsShimUpgrade", - "fake-framework", + + // Mainline Module Apps + "CaptivePortalLogin", } Bp2buildModuleTypeAlwaysConvertList = []string{ @@ -776,7 +786,8 @@ var ( "tjbench", // TODO(b/240563612): Stem property // java bugs - "libbase_ndk", // TODO(b/186826477): fails to link libctscamera2_jni for device (required for CtsCameraTestCases) + "libbase_ndk", // TODO(b/186826477): fails to link libctscamera2_jni for device (required for CtsCameraTestCases) + "bouncycastle", // TODO(b/274474005): Need support for custom system_modules. // python protos "libprotobuf-python", // Has a handcrafted alternative @@ -802,6 +813,7 @@ var ( // go deps: "analyze_bcpf", // depends on bpmodify a blueprint_go_binary. + "analyze_bcpf_test", // depends on bpmodify a blueprint_go_binary. "host_bionic_linker_asm", // depends on extract_linker, a go binary. "host_bionic_linker_script", // depends on extract_linker, a go binary. @@ -812,13 +824,15 @@ var ( "libtombstoned_client_rust_bridge_code", "libtombstoned_client_wrapper", // rust conversions are not supported // unconverted deps - "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib + "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi "android_icu4j_srcgen", // depends on unconverted modules: currysrc "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc + "apex_compression_test", // depends on unconverted modules: soong_zip, com.android.example.apex "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full "art-script", // depends on unconverted modules: dalvikvm, dex2oat "bin2c_fastdeployagent", // depends on unconverted modules: deployagent + "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9 "dex2oat-script", // depends on unconverted modules: dex2oat @@ -843,12 +857,12 @@ var ( "libgmock_ndk", // depends on unconverted modules: libgtest_ndk_c++ "libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libnativetesthelper_jni, libgmock_ndk "libnativetesthelper_jni", // depends on unconverted modules: libgtest_ndk_c++ - "libprotobuf-java-nano", // b/220869005, depends on non-public_current SDK "libstatslog", // depends on unconverted modules: libstatspull, statsd-aidl-ndk "libstatslog_art", // depends on unconverted modules: statslog_art.cpp, statslog_art.h "linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_* "malloc-rss-benchmark", // depends on unconverted modules: libmeminfo "pbtombstone", "crash_dump", // depends on libdebuggerd, libunwindstack + "releasetools_test", // depends on unconverted modules: com.android.apex.compressed.v1 "robolectric-sqlite4java-0.282", // depends on unconverted modules: robolectric-sqlite4java-import, robolectric-sqlite4java-native "static_crasher", // depends on unconverted modules: libdebuggerd_handler "test_fips", // depends on unconverted modules: adb @@ -1393,6 +1407,26 @@ var ( // TODO(b/266459895): depends on libunwindstack "libutils_test", + + // Has dependencies on other tools like ziptool, bp2build'd data properties don't work with these tests atm + "ziparchive_tests_large", + "mkbootimg_test", + "certify_bootimg_test", + + // Despite being _host module types, these require devices to run + "logd_integration_test", + "mobly-hello-world-test", + "mobly-multidevice-test", + + // TODO(b/274805756): Support core_platform and current java APIs + "fake-framework", + + // TODO(b/277616982): These modules depend on private java APIs, but maybe they don't need to. + "StreamingProtoTest", + "textclassifierprotoslite", + "styleprotoslite", + "CtsPkgInstallerConstants", + "guava-android-testlib", } MixedBuildsDisabledList = []string{ @@ -1471,6 +1505,7 @@ var ( // M5: tzdata launch "com.android.tzdata", "test1_com.android.tzdata", + "test3_com.android.tzdata", // M7: adbd launch "com.android.adbd", "test_com.android.adbd", @@ -1490,6 +1525,8 @@ var ( // also be built - do not add them to this list. StagingMixedBuildsEnabledList = []string{ "com.android.neuralnetworks", + "libneuralnetworks", + "libneuralnetworks_static", } // These should be the libs that are included by the apexes in the ProdMixedBuildsEnabledList diff --git a/android/apex.go b/android/apex.go index 87bff74c3..5bbc02e51 100644 --- a/android/apex.go +++ b/android/apex.go @@ -356,9 +356,18 @@ func (m *ApexModuleBase) apexModuleBase() *ApexModuleBase { return m } +var ( + availableToPlatformList = []string{AvailableToPlatform} +) + // Implements ApexModule func (m *ApexModuleBase) ApexAvailable() []string { - return m.ApexProperties.Apex_available + aa := m.ApexProperties.Apex_available + if len(aa) > 0 { + return aa + } + // Default is availability to platform + return CopyOf(availableToPlatformList) } // Implements ApexModule diff --git a/android/bazel_handler.go b/android/bazel_handler.go index 44dc0559e..9c273d9a3 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -63,6 +63,8 @@ var ( "LLVM_NEXT", "ALLOW_UNKNOWN_WARNING_OPTION", + "UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT", + // Overrides the version in the apex_manifest.json. The version is unique for // each branch (internal, aosp, mainline releases, dessert releases). This // enables modules built on an older branch to be installed against a newer @@ -84,8 +86,12 @@ func RegisterMixedBuildsMutator(ctx RegistrationContext) { func mixedBuildsPrepareMutator(ctx BottomUpMutatorContext) { if m := ctx.Module(); m.Enabled() { if mixedBuildMod, ok := m.(MixedBuildBuildable); ok { - if mixedBuildMod.IsMixedBuildSupported(ctx) && MixedBuildsEnabled(ctx) { + queueMixedBuild := mixedBuildMod.IsMixedBuildSupported(ctx) && MixedBuildsEnabled(ctx) + if queueMixedBuild { mixedBuildMod.QueueBazelCall(ctx) + } else if _, ok := ctx.Config().bazelForceEnabledModules[m.Name()]; ok { + // TODO(b/273910287) - remove this once --ensure_allowlist_integrity is added + ctx.ModuleErrorf("Attempted to force enable an unready module: %s. Did you forget to Bp2BuildDefaultTrue its directory?\n", m.Name()) } } } @@ -960,9 +966,13 @@ func indent(original string) string { // request type. func (context *mixedBuildBazelContext) cqueryStarlarkFileContents() []byte { requestTypeToCqueryIdEntries := map[cqueryRequest][]string{} + requestTypes := []cqueryRequest{} for _, val := range context.requests { cqueryId := getCqueryId(val) mapEntryString := fmt.Sprintf("%q : True", cqueryId) + if _, seenKey := requestTypeToCqueryIdEntries[val.requestType]; !seenKey { + requestTypes = append(requestTypes, val.requestType) + } requestTypeToCqueryIdEntries[val.requestType] = append(requestTypeToCqueryIdEntries[val.requestType], mapEntryString) } @@ -984,7 +994,7 @@ def %s(target, id_string): return id_string + ">>" + %s(target, id_string) ` - for requestType := range requestTypeToCqueryIdEntries { + for _, requestType := range requestTypes { labelMapName := requestType.Name() + "_Labels" functionName := requestType.Name() + "_Fn" labelRegistrationMapSection += fmt.Sprintf(mapDeclarationFormatString, diff --git a/android/config.go b/android/config.go index 6765f1f71..032172d6e 100644 --- a/android/config.go +++ b/android/config.go @@ -420,6 +420,8 @@ func saveToBazelConfigFile(config *productVariables, outDir string) error { fmt.Sprintf(`_arch_variant_product_var_constraints = %s`, archVariantProductVariablesJson), "\n", ` product_vars = _product_vars + +# TODO(b/269577299) Remove these when everything switches over to loading them from product_variable_constants.bzl product_var_constraints = _product_var_constraints arch_variant_product_var_constraints = _arch_variant_product_var_constraints `, @@ -429,6 +431,13 @@ arch_variant_product_var_constraints = _arch_variant_product_var_constraints if err != nil { return fmt.Errorf("Could not write .bzl config file %s", err) } + err = pathtools.WriteFileIfChanged(filepath.Join(dir, "product_variable_constants.bzl"), []byte(fmt.Sprintf(` +product_var_constraints = %s +arch_variant_product_var_constraints = %s +`, nonArchVariantProductVariablesJson, archVariantProductVariablesJson)), 0644) + if err != nil { + return fmt.Errorf("Could not write .bzl config file %s", err) + } err = pathtools.WriteFileIfChanged(filepath.Join(dir, "BUILD"), []byte(bazel.GeneratedBazelFileWarning), 0644) if err != nil { @@ -583,12 +592,11 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) setBazelMode(cmdArgs.BazelMode, "--bazel-mode", BazelProdMode) setBazelMode(cmdArgs.BazelModeStaging, "--bazel-mode-staging", BazelStagingMode) - config.BazelContext, err = NewBazelContext(config) - config.Bp2buildPackageConfig = GetBp2BuildAllowList() - for _, module := range strings.Split(cmdArgs.BazelForceEnabledModules, ",") { config.bazelForceEnabledModules[module] = struct{}{} } + config.BazelContext, err = NewBazelContext(config) + config.Bp2buildPackageConfig = GetBp2BuildAllowList() return Config{config}, err } @@ -824,6 +832,10 @@ func (c *config) PlatformSdkVersion() ApiLevel { return uncheckedFinalApiLevel(*c.productVariables.Platform_sdk_version) } +func (c *config) RawPlatformSdkVersion() *int { + return c.productVariables.Platform_sdk_version +} + func (c *config) PlatformSdkFinal() bool { return Bool(c.productVariables.Platform_sdk_final) } @@ -1921,3 +1933,8 @@ func (c *config) BuildFromTextStub() bool { func (c *config) SetBuildFromTextStub(b bool) { c.buildFromTextStub = b } +func (c *config) AddForceEnabledModules(forceEnabled []string) { + for _, forceEnabledModule := range forceEnabled { + c.bazelForceEnabledModules[forceEnabledModule] = struct{}{} + } +} diff --git a/android/filegroup.go b/android/filegroup.go index c259f2106..0ca5dc50e 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -81,6 +81,7 @@ type bazelFilegroupAttributes struct { type bazelAidlLibraryAttributes struct { Srcs bazel.LabelListAttribute Strip_import_prefix *string + Deps bazel.LabelListAttribute } // api srcs can be contained in filegroups. @@ -119,9 +120,12 @@ func (fg *fileGroup) ConvertWithBp2build(ctx TopDownMutatorContext) { // and then convert if fg.ShouldConvertToAidlLibrary(ctx) { tags := []string{"apex_available=//apex_available:anyapex"} + deps := bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, fg.properties.Aidl.Deps)) + attrs := &bazelAidlLibraryAttributes{ Srcs: srcs, Strip_import_prefix: fg.properties.Path, + Deps: deps, } props := bazel.BazelTargetModuleProperties{ @@ -187,6 +191,14 @@ type fileGroupProperties struct { // Create a make variable with the specified name that contains the list of files in the // filegroup, relative to the root of the source tree. Export_to_make_var *string + + // aidl is explicitly provided for implicit aidl dependencies + // TODO(b/278298615): aidl prop is a no-op in Soong and is an escape hatch + // to include implicit aidl dependencies for bazel migration compatibility + Aidl struct { + // List of aidl files or filegroup depended on by srcs + Deps []string `android:"path"` + } } type fileGroup struct { diff --git a/android/mutator.go b/android/mutator.go index 676f8a511..4ec960472 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -747,7 +747,13 @@ func ApexAvailableTags(mod Module) bazel.StringListAttribute { // TODO(b/218841706): hidl_interface has the apex_available prop, but it's // defined directly as a prop and not via ApexModule, so this doesn't // pick those props up. - attr.Value = ConvertApexAvailableToTags(am.apexModuleBase().ApexAvailable()) + apexAvailable := am.apexModuleBase().ApexAvailable() + // If a user does not specify apex_available in Android.bp, then soong provides a default. + // To avoid verbosity of BUILD files, remove this default from user-facing BUILD files. + if len(am.apexModuleBase().ApexProperties.Apex_available) == 0 { + apexAvailable = []string{} + } + attr.Value = ConvertApexAvailableToTags(apexAvailable) } return attr } diff --git a/android/test_config.go b/android/test_config.go index 07ca33d56..28d9ec403 100644 --- a/android/test_config.go +++ b/android/test_config.go @@ -65,6 +65,7 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string BuildMode: BazelProdMode, mixedBuildDisabledModules: make(map[string]struct{}), mixedBuildEnabledModules: make(map[string]struct{}), + bazelForceEnabledModules: make(map[string]struct{}), } config.deviceConfig = &deviceConfig{ config: config, diff --git a/apex/apex.go b/apex/apex.go index 5451a0400..4fda5058f 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1659,7 +1659,6 @@ func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, h if ccMod.Target().NativeBridge == android.NativeBridgeEnabled { dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath) } - dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath()) if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) { // Special case for Bionic libs and other libs installed with them. This is to // prevent those libs from being included in the search path @@ -1672,6 +1671,10 @@ func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, h // loading of them, which isn't supported. dirInApex = filepath.Join(dirInApex, "bionic") } + // This needs to go after the runtime APEX handling because otherwise we would get + // weird paths like lib64/rel_install_path/bionic rather than + // lib64/bionic/rel_install_path. + dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath()) fileToCopy := android.OutputFileForModule(ctx, ccMod, "") androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName diff --git a/apex/apex_test.go b/apex/apex_test.go index 8a02a4a7f..4e063cb73 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -1001,7 +1001,7 @@ func TestApexWithStubs(t *testing.T) { // Ensure that stub dependency from a rust module is not included ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so") // The rust module is linked to the stub cc library - rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"] + rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"] ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so") ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so") @@ -1077,7 +1077,7 @@ func TestApexCanUsePrivateApis(t *testing.T) { mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"] ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so") ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so") - rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"] + rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"] ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so") ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so") } @@ -5281,7 +5281,16 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { apex_set { name: "myapex", set: "myapex.apks", + exported_java_libs: ["myjavalib"], exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], + exported_systemserverclasspath_fragments: ["my-systemserverclasspath-fragment"], + } + + java_import { + name: "myjavalib", + jars: ["myjavalib.jar"], + apex_available: ["myapex"], + permitted_packages: ["javalib"], } prebuilt_bootclasspath_fragment { @@ -5298,6 +5307,12 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { }, } + prebuilt_systemserverclasspath_fragment { + name: "my-systemserverclasspath-fragment", + contents: ["libbaz"], + apex_available: ["myapex"], + } + java_import { name: "libfoo", jars: ["libfoo.jar"], @@ -5314,6 +5329,16 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { shared_library: false, permitted_packages: ["bar"], } + + java_sdk_library_import { + name: "libbaz", + public: { + jars: ["libbaz.jar"], + }, + apex_available: ["myapex"], + shared_library: false, + permitted_packages: ["baz"], + } ` ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) @@ -5326,6 +5351,24 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { my-bootclasspath-fragment/index.csv out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv `) + + myApex := ctx.ModuleForTests("myapex", "android_common_myapex").Module() + + overrideNames := []string{ + "", + "myjavalib.myapex", + "libfoo.myapex", + "libbar.myapex", + "libbaz.myapex", + } + mkEntries := android.AndroidMkEntriesForTest(t, ctx, myApex) + for i, e := range mkEntries { + g := e.OverrideName + if w := overrideNames[i]; w != g { + t.Errorf("Expected override name %q, got %q", w, g) + } + } + }) t.Run("prebuilt with source library preferred", func(t *testing.T) { @@ -5646,6 +5689,58 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { }) } +func TestPrebuiltSkipsSymbols(t *testing.T) { + testCases := []struct { + name string + usePrebuilt bool + installSymbolFiles bool + }{ + { + name: "Source module build rule doesn't install symbol files", + usePrebuilt: true, + installSymbolFiles: false, + }, + { + name: "Source module is installed with symbols", + usePrebuilt: false, + installSymbolFiles: true, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + preferProperty := "prefer: false" + if tc.usePrebuilt { + preferProperty = "prefer: true" + } + ctx := testApex(t, ` + // Source module + apex { + name: "myapex", + key: "myapex.key", + updatable: false, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + apex_set { + name: "myapex", + set: "myapex.apks", + `+preferProperty+` + } + `) + // Symbol files are installed by installing entries under ${OUT}/apex/{apex name} + android.AssertStringListContainsEquals(t, "Implicits", + ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule").Implicits.Strings(), + "out/soong/target/product/test_device/apex/myapex/apex_manifest.pb", + tc.installSymbolFiles) + }) + } +} + func TestApexWithTests(t *testing.T) { ctx := testApex(t, ` apex_test { @@ -7515,6 +7610,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi "some-updatable-apex", ], permitted_packages: ["some.updatable.apex.lib"], + min_sdk_version: "33", } java_library { @@ -7554,6 +7650,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi ], hostdex: true, compile_dex: true, + min_sdk_version: "33", } apex { @@ -7561,7 +7658,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi key: "some-updatable-apex.key", java_libs: ["some-updatable-apex-lib"], updatable: true, - min_sdk_version: "current", + min_sdk_version: "33", } apex { @@ -7584,7 +7681,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi key: "com.android.art.debug.key", bootclasspath_fragments: ["art-bootclasspath-fragment"], updatable: true, - min_sdk_version: "current", + min_sdk_version: "33", } bootclasspath_fragment { diff --git a/apex/builder.go b/apex/builder.go index 94aef496e..2f8a4ec09 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -468,6 +468,10 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { imageDir := android.PathForModuleOut(ctx, "image"+suffix) installSymbolFiles := (!ctx.Config().KatiEnabled() || a.ExportedToMake()) && a.installable() + // We can't install symbol files when prebuilt is used. + if a.IsReplacedByPrebuilt() { + installSymbolFiles = false + } // set of dependency module:location mappings installMapSet := make(map[string]bool) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index cae507e5d..31cecf111 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -316,31 +316,29 @@ func prebuiltApexModuleCreatorMutator(ctx android.TopDownMutatorContext) { } } -func (p *prebuiltCommon) getExportedDependencies() map[string]exportedDependencyTag { - dependencies := make(map[string]exportedDependencyTag) +func (p *prebuiltCommon) hasExportedDeps() bool { + return len(p.prebuiltCommonProperties.Exported_java_libs) > 0 || + len(p.prebuiltCommonProperties.Exported_bootclasspath_fragments) > 0 || + len(p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments) > 0 +} + +// prebuiltApexContentsDeps adds dependencies onto the prebuilt apex module's contents. +func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorContext) { + module := ctx.Module() for _, dep := range p.prebuiltCommonProperties.Exported_java_libs { - dependencies[dep] = exportedJavaLibTag + prebuiltDep := android.PrebuiltNameFromSource(dep) + ctx.AddDependency(module, exportedJavaLibTag, prebuiltDep) } for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments { - dependencies[dep] = exportedBootclasspathFragmentTag + prebuiltDep := android.PrebuiltNameFromSource(dep) + ctx.AddDependency(module, exportedBootclasspathFragmentTag, prebuiltDep) } for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments { - dependencies[dep] = exportedSystemserverclasspathFragmentTag - } - - return dependencies -} - -// prebuiltApexContentsDeps adds dependencies onto the prebuilt apex module's contents. -func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorContext) { - module := ctx.Module() - - for dep, tag := range p.getExportedDependencies() { prebuiltDep := android.PrebuiltNameFromSource(dep) - ctx.AddDependency(module, tag, prebuiltDep) + ctx.AddDependency(module, exportedSystemserverclasspathFragmentTag, prebuiltDep) } } @@ -608,7 +606,7 @@ func createApexSelectorModule(ctx android.TopDownMutatorContext, name string, ap // the listed modules need access to files from within the prebuilt .apex file. func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) { // Only create the deapexer module if it is needed. - if len(p.getExportedDependencies()) == 0 { + if !p.hasExportedDeps() { return } diff --git a/bp2build/Android.bp b/bp2build/Android.bp index 598ca323d..b6635c430 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -76,6 +76,7 @@ bootstrap_go_package { "prebuilt_etc_conversion_test.go", "python_binary_conversion_test.go", "python_library_conversion_test.go", + "python_test_conversion_test.go", "sh_conversion_test.go", "soong_config_module_type_conversion_test.go", ], diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go index 6020ee599..09d9dc103 100644 --- a/bp2build/aar_conversion_test.go +++ b/bp2build/aar_conversion_test.go @@ -66,9 +66,12 @@ android_library { "resource_files": `["res/res.png"]`, "deps": `[":static_lib_dep"]`, "exports": `[":static_lib_dep"]`, - "javacopts": `["-source 1.7 -target 1.7"]`, + "java_version": `"7"`, }), - MakeNeverlinkDuplicateTarget("android_library", "TestLib"), + MakeNeverlinkDuplicateTargetWithAttrs( + "android_library", + "TestLib", + AttrNameToString{"java_version": `"7"`}), }}) } diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go index ef3f12472..928a1f2e1 100644 --- a/bp2build/android_app_conversion_test.go +++ b/bp2build/android_app_conversion_test.go @@ -53,6 +53,7 @@ android_app { "srcs": `["app.java"]`, "manifest": `"AndroidManifest.xml"`, "resource_files": `["res/res.png"]`, + "sdk_version": `"current"`, }), }}) } @@ -91,7 +92,8 @@ android_app { ]`, "custom_package": `"com.google"`, "deps": `[":static_lib_dep"]`, - "javacopts": `["-source 1.7 -target 1.7"]`, + "java_version": `"7"`, + "sdk_version": `"current"`, "certificate_name": `"foocert"`, }), }}) @@ -131,6 +133,7 @@ android_app { })`, "manifest": `"AndroidManifest.xml"`, "resource_files": `["res/res.png"]`, + "sdk_version": `"current"`, }), }}) } @@ -365,6 +368,7 @@ android_app { "manifest_values": `{ "minSdkVersion": "24", }`, + "sdk_version": `"current"`, }), }}) } @@ -388,6 +392,7 @@ android_app { "manifest_values": `{ "minSdkVersion": "30", }`, + "sdk_version": `"30"`, }), }}) } diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go index ab2f821d3..3abef9db1 100644 --- a/bp2build/bp2build_product_config.go +++ b/bp2build/bp2build_product_config.go @@ -68,16 +68,6 @@ package(default_visibility = [ "@//build/bazel/product_config:__subpackages__", "@soong_injection//product_config_platforms:__subpackages__", ]) - -# TODO(b/249685973): Remove this. It was only added for a platform_mappings file, -# which can possibly be replaced with autogenerating the platform_mappings file, -# or removing that file entirely. -alias( - name = "current_android_platform", - # TODO: When we start generating the platforms for more than just the - # currently lunched, product, turn this into a select with an arm for each product. - actual = "@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}", -) `)), newFile( "product_config_platforms", diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go index fde9b6949..b7678a469 100644 --- a/bp2build/build_conversion.go +++ b/bp2build/build_conversion.go @@ -321,6 +321,9 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers // target, each of a different rule class. metrics.IncrementRuleClassCount(t.ruleClass) } + } else if _, ok := ctx.Config().BazelModulesForceEnabledByFlag()[m.Name()]; ok && m.Name() != "" { + err := fmt.Errorf("Force Enabled Module %s not converted", m.Name()) + errs = append(errs, err) } else { metrics.AddUnconvertedModule(moduleType) return diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index d31216922..73ee26b60 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -1175,6 +1175,8 @@ func TestAllowlistingBp2buildTargetsWithConfig(t *testing.T) { bp2buildConfig allowlists.Bp2BuildConfig checkDir string fs map[string]string + forceEnabledModules []string + expectedErrorMessages []string }{ { description: "test bp2build config package and subpackages config", @@ -1237,6 +1239,24 @@ filegroup { name: "opt-out-h", bazel_module: { bp2build_available: false } } `, }, }, + { + description: "test force-enabled errors out", + moduleTypeUnderTest: "filegroup", + moduleTypeUnderTestFactory: android.FileGroupFactory, + expectedCount: map[string]int{ + "migrated": 0, + "not_migrated": 0, + }, + bp2buildConfig: allowlists.Bp2BuildConfig{ + "migrated/but_not_really": allowlists.Bp2BuildDefaultFalse, + "not_migrated": allowlists.Bp2BuildDefaultFalse, + }, + fs: map[string]string{ + "migrated/Android.bp": `filegroup { name: "a" }`, + }, + forceEnabledModules: []string{"a"}, + expectedErrorMessages: []string{"Force Enabled Module a not converted"}, + }, } dir := "." @@ -1252,6 +1272,7 @@ filegroup { name: "opt-out-h", bazel_module: { bp2build_available: false } } fs[f] = []byte(content) } config := android.TestConfig(buildDir, nil, "", fs) + config.AddForceEnabledModules(testCase.forceEnabledModules) ctx := android.NewTestContext(config) ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory) allowlist := android.NewBp2BuildAllowlist().SetDefaultConfig(testCase.bp2buildConfig) @@ -1268,7 +1289,7 @@ filegroup { name: "opt-out-h", bazel_module: { bp2build_available: false } } // For each directory, test that the expected number of generated targets is correct. for dir, expectedCount := range testCase.expectedCount { bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir) - android.FailIfErrored(t, err) + android.CheckErrorsAgainstExpectations(t, err, testCase.expectedErrorMessages) if actualCount := len(bazelTargets); actualCount != expectedCount { t.Fatalf( "%s: Expected %d bazel target for %s package, got %d", diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 8e0a728ab..cbea943e1 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -36,6 +36,7 @@ func registerCcLibrarySharedModuleTypes(ctx android.RegistrationContext) { func runCcLibrarySharedTestCase(t *testing.T, tc Bp2buildTestCase) { t.Helper() + t.Parallel() (&tc).ModuleTypeUnderTest = "cc_library_shared" (&tc).ModuleTypeUnderTestFactory = cc.LibrarySharedFactory RunBp2BuildTestCase(t, registerCcLibrarySharedModuleTypes, tc) diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go index c5a6dfd6a..b88960e0e 100644 --- a/bp2build/cc_prebuilt_library_conversion_test.go +++ b/bp2build/cc_prebuilt_library_conversion_test.go @@ -20,12 +20,17 @@ import ( "android/soong/cc" ) +func runCcPrebuiltLibraryTestCase(t *testing.T, tc Bp2buildTestCase) { + t.Helper() + (&tc).ModuleTypeUnderTest = "cc_prebuilt_library" + (&tc).ModuleTypeUnderTestFactory = cc.PrebuiltLibraryFactory + RunBp2BuildTestCaseSimple(t, tc) +} + func TestPrebuiltLibraryStaticAndSharedSimple(t *testing.T) { - RunBp2BuildTestCaseSimple(t, + runCcPrebuiltLibraryTestCase(t, Bp2buildTestCase{ - Description: "prebuilt library static and shared simple", - ModuleTypeUnderTest: "cc_prebuilt_library", - ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory, + Description: "prebuilt library static and shared simple", Filesystem: map[string]string{ "libf.so": "", }, @@ -51,11 +56,9 @@ cc_prebuilt_library { } func TestPrebuiltLibraryWithArchVariance(t *testing.T) { - RunBp2BuildTestCaseSimple(t, + runCcPrebuiltLibraryTestCase(t, Bp2buildTestCase{ - Description: "prebuilt library with arch variance", - ModuleTypeUnderTest: "cc_prebuilt_library", - ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory, + Description: "prebuilt library with arch variance", Filesystem: map[string]string{ "libf.so": "", "libg.so": "", @@ -95,11 +98,9 @@ cc_prebuilt_library { } func TestPrebuiltLibraryAdditionalAttrs(t *testing.T) { - RunBp2BuildTestCaseSimple(t, + runCcPrebuiltLibraryTestCase(t, Bp2buildTestCase{ - Description: "prebuilt library additional attributes", - ModuleTypeUnderTest: "cc_prebuilt_library", - ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory, + Description: "prebuilt library additional attributes", Filesystem: map[string]string{ "libf.so": "", "testdir/1/include.h": "", @@ -125,20 +126,19 @@ cc_prebuilt_library { "export_system_includes": `["testdir/2/"]`, "alwayslink": "True", }), - // TODO(b/229374533): When fixed, update this test MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{ - "shared_library": `"libf.so"`, + "shared_library": `"libf.so"`, + "export_includes": `["testdir/1/"]`, + "export_system_includes": `["testdir/2/"]`, }), }, }) } func TestPrebuiltLibrarySharedStanzaFails(t *testing.T) { - RunBp2BuildTestCaseSimple(t, + runCcPrebuiltLibraryTestCase(t, Bp2buildTestCase{ - Description: "prebuilt library with shared stanza fails because multiple sources", - ModuleTypeUnderTest: "cc_prebuilt_library", - ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory, + Description: "prebuilt library with shared stanza fails because multiple sources", Filesystem: map[string]string{ "libf.so": "", "libg.so": "", @@ -180,11 +180,9 @@ cc_prebuilt_library { } func TestPrebuiltLibrarySharedAndStaticStanzas(t *testing.T) { - RunBp2BuildTestCaseSimple(t, + runCcPrebuiltLibraryTestCase(t, Bp2buildTestCase{ - Description: "prebuilt library with both shared and static stanzas", - ModuleTypeUnderTest: "cc_prebuilt_library", - ModuleTypeUnderTestFactory: cc.PrebuiltLibraryFactory, + Description: "prebuilt library with both shared and static stanzas", Filesystem: map[string]string{ "libf.so": "", "libg.so": "", @@ -217,11 +215,9 @@ cc_prebuilt_library { // TODO(b/228623543): When this bug is fixed, enable this test //func TestPrebuiltLibraryOnlyShared(t *testing.T) { -// RunBp2BuildTestCaseSimple(t, +// runCcPrebuiltLibraryTestCase(t, // bp2buildTestCase{ // description: "prebuilt library shared only", -// moduleTypeUnderTest: "cc_prebuilt_library", -// moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory, // filesystem: map[string]string{ // "libf.so": "", // }, @@ -244,11 +240,9 @@ cc_prebuilt_library { // TODO(b/228623543): When this bug is fixed, enable this test //func TestPrebuiltLibraryOnlyStatic(t *testing.T) { -// RunBp2BuildTestCaseSimple(t, +// runCcPrebuiltLibraryTestCase(t, // bp2buildTestCase{ // description: "prebuilt library static only", -// moduleTypeUnderTest: "cc_prebuilt_library", -// moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory, // filesystem: map[string]string{ // "libf.so": "", // }, @@ -272,3 +266,97 @@ cc_prebuilt_library { // }, // }) //} + +func TestPrebuiltLibraryWithExportIncludesArchVariant(t *testing.T) { + runCcPrebuiltLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_prebuilt_library correctly translates export_includes with arch variance", + Filesystem: map[string]string{ + "libf.so": "", + "libg.so": "", + }, + Blueprint: ` +cc_prebuilt_library { + name: "libtest", + srcs: ["libf.so"], + arch: { + arm: { export_include_dirs: ["testdir/1/"], }, + arm64: { export_include_dirs: ["testdir/2/"], }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{ + "shared_library": `"libf.so"`, + "export_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{ + "static_library": `"libf.so"`, + "export_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static_alwayslink", AttrNameToString{ + "alwayslink": "True", + "static_library": `"libf.so"`, + "export_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + }, + }) +} + +func TestPrebuiltLibraryWithExportSystemIncludesArchVariant(t *testing.T) { + runCcPrebuiltLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_prebuilt_ibrary correctly translates export_system_includes with arch variance", + Filesystem: map[string]string{ + "libf.so": "", + "libg.so": "", + }, + Blueprint: ` +cc_prebuilt_library { + name: "libtest", + srcs: ["libf.so"], + arch: { + arm: { export_system_include_dirs: ["testdir/1/"], }, + arm64: { export_system_include_dirs: ["testdir/2/"], }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{ + "shared_library": `"libf.so"`, + "export_system_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{ + "static_library": `"libf.so"`, + "export_system_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static_alwayslink", AttrNameToString{ + "alwayslink": "True", + "static_library": `"libf.so"`, + "export_system_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + }, + }) +} diff --git a/bp2build/cc_prebuilt_library_shared_conversion_test.go b/bp2build/cc_prebuilt_library_shared_conversion_test.go new file mode 100644 index 000000000..9e975aea3 --- /dev/null +++ b/bp2build/cc_prebuilt_library_shared_conversion_test.go @@ -0,0 +1,165 @@ +// 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 ( + "testing" + + "android/soong/cc" +) + +func runCcPrebuiltLibrarySharedTestCase(t *testing.T, tc Bp2buildTestCase) { + t.Parallel() + t.Helper() + (&tc).ModuleTypeUnderTest = "cc_prebuilt_library_shared" + (&tc).ModuleTypeUnderTestFactory = cc.PrebuiltSharedLibraryFactory + RunBp2BuildTestCaseSimple(t, tc) +} + +func TestPrebuiltLibrarySharedSimple(t *testing.T) { + runCcPrebuiltLibrarySharedTestCase(t, + Bp2buildTestCase{ + Description: "prebuilt library shared simple", + Filesystem: map[string]string{ + "libf.so": "", + }, + Blueprint: ` +cc_prebuilt_library_shared { + name: "libtest", + srcs: ["libf.so"], + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{ + "shared_library": `"libf.so"`, + }), + }, + }) +} + +func TestPrebuiltLibrarySharedWithArchVariance(t *testing.T) { + runCcPrebuiltLibrarySharedTestCase(t, + Bp2buildTestCase{ + Description: "prebuilt library shared with arch variance", + Filesystem: map[string]string{ + "libf.so": "", + "libg.so": "", + }, + Blueprint: ` +cc_prebuilt_library_shared { + name: "libtest", + arch: { + arm64: { srcs: ["libf.so"], }, + arm: { srcs: ["libg.so"], }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{ + "shared_library": `select({ + "//build/bazel/platforms/arch:arm": "libg.so", + "//build/bazel/platforms/arch:arm64": "libf.so", + "//conditions:default": None, + })`, + }), + }, + }) +} + +func TestPrebuiltLibrarySharedAdditionalAttrs(t *testing.T) { + runCcPrebuiltLibrarySharedTestCase(t, + Bp2buildTestCase{ + Description: "prebuilt library shared additional attributes", + Filesystem: map[string]string{ + "libf.so": "", + "testdir/1/include.h": "", + "testdir/2/other.h": "", + }, + Blueprint: ` +cc_prebuilt_library_shared { + name: "libtest", + srcs: ["libf.so"], + export_include_dirs: ["testdir/1/"], + export_system_include_dirs: ["testdir/2/"], + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{ + "shared_library": `"libf.so"`, + "export_includes": `["testdir/1/"]`, + "export_system_includes": `["testdir/2/"]`, + }), + }, + }) +} + +func TestPrebuiltLibrarySharedWithExportIncludesArchVariant(t *testing.T) { + runCcPrebuiltLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_prebuilt_library_shared correctly translates export_includes with arch variance", + Filesystem: map[string]string{ + "libf.so": "", + "libg.so": "", + }, + Blueprint: ` +cc_prebuilt_library_shared { + name: "libtest", + srcs: ["libf.so"], + arch: { + arm: { export_include_dirs: ["testdir/1/"], }, + arm64: { export_include_dirs: ["testdir/2/"], }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{ + "shared_library": `"libf.so"`, + "export_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + }, + }) +} + +func TestPrebuiltLibrarySharedWithExportSystemIncludesArchVariant(t *testing.T) { + runCcPrebuiltLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_prebuilt_library_shared correctly translates export_system_includes with arch variance", + Filesystem: map[string]string{ + "libf.so": "", + "libg.so": "", + }, + Blueprint: ` +cc_prebuilt_library_shared { + name: "libtest", + srcs: ["libf.so"], + arch: { + arm: { export_system_include_dirs: ["testdir/1/"], }, + arm64: { export_system_include_dirs: ["testdir/2/"], }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{ + "shared_library": `"libf.so"`, + "export_system_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + }, + }) +} diff --git a/bp2build/cc_prebuilt_library_static_conversion_test.go b/bp2build/cc_prebuilt_library_static_conversion_test.go new file mode 100644 index 000000000..77562e726 --- /dev/null +++ b/bp2build/cc_prebuilt_library_static_conversion_test.go @@ -0,0 +1,199 @@ +// 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 ( + "testing" + + "android/soong/cc" +) + +func runCcPrebuiltLibraryStaticTestCase(t *testing.T, tc Bp2buildTestCase) { + t.Parallel() + t.Helper() + (&tc).ModuleTypeUnderTest = "cc_prebuilt_library_static" + (&tc).ModuleTypeUnderTestFactory = cc.PrebuiltStaticLibraryFactory + RunBp2BuildTestCaseSimple(t, tc) +} + +func TestPrebuiltLibraryStaticSimple(t *testing.T) { + runCcPrebuiltLibraryStaticTestCase(t, + Bp2buildTestCase{ + Description: "prebuilt library static simple", + Filesystem: map[string]string{ + "libf.so": "", + }, + Blueprint: ` +cc_prebuilt_library_static { + name: "libtest", + srcs: ["libf.so"], + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_static", "libtest", AttrNameToString{ + "static_library": `"libf.so"`, + }), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_alwayslink", AttrNameToString{ + "static_library": `"libf.so"`, + "alwayslink": "True", + }), + }, + }) +} + +func TestPrebuiltLibraryStaticWithArchVariance(t *testing.T) { + runCcPrebuiltLibraryStaticTestCase(t, + Bp2buildTestCase{ + Description: "prebuilt library with arch variance", + Filesystem: map[string]string{ + "libf.so": "", + "libg.so": "", + }, + Blueprint: ` +cc_prebuilt_library_static { + name: "libtest", + arch: { + arm64: { srcs: ["libf.so"], }, + arm: { srcs: ["libg.so"], }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_static", "libtest", AttrNameToString{ + "static_library": `select({ + "//build/bazel/platforms/arch:arm": "libg.so", + "//build/bazel/platforms/arch:arm64": "libf.so", + "//conditions:default": None, + })`}), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_alwayslink", AttrNameToString{ + "alwayslink": "True", + "static_library": `select({ + "//build/bazel/platforms/arch:arm": "libg.so", + "//build/bazel/platforms/arch:arm64": "libf.so", + "//conditions:default": None, + })`}), + }, + }) +} + +func TestPrebuiltLibraryStaticAdditionalAttrs(t *testing.T) { + runCcPrebuiltLibraryStaticTestCase(t, + Bp2buildTestCase{ + Description: "prebuilt library additional attributes", + Filesystem: map[string]string{ + "libf.so": "", + "testdir/1/include.h": "", + "testdir/2/other.h": "", + }, + Blueprint: ` +cc_prebuilt_library_static { + name: "libtest", + srcs: ["libf.so"], + export_include_dirs: ["testdir/1/"], + export_system_include_dirs: ["testdir/2/"], + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_static", "libtest", AttrNameToString{ + "static_library": `"libf.so"`, + "export_includes": `["testdir/1/"]`, + "export_system_includes": `["testdir/2/"]`, + }), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_alwayslink", AttrNameToString{ + "static_library": `"libf.so"`, + "export_includes": `["testdir/1/"]`, + "export_system_includes": `["testdir/2/"]`, + "alwayslink": "True", + }), + }, + }) +} + +func TestPrebuiltLibraryStaticWithExportIncludesArchVariant(t *testing.T) { + runCcPrebuiltLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_prebuilt_library_static correctly translates export_includes with arch variance", + Filesystem: map[string]string{ + "libf.so": "", + "libg.so": "", + }, + Blueprint: ` +cc_prebuilt_library_static { + name: "libtest", + srcs: ["libf.so"], + arch: { + arm: { export_include_dirs: ["testdir/1/"], }, + arm64: { export_include_dirs: ["testdir/2/"], }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_static", "libtest", AttrNameToString{ + "static_library": `"libf.so"`, + "export_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_alwayslink", AttrNameToString{ + "alwayslink": "True", + "static_library": `"libf.so"`, + "export_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + }, + }) +} + +func TestPrebuiltLibraryStaticWithExportSystemIncludesArchVariant(t *testing.T) { + runCcPrebuiltLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_prebuilt_library_static correctly translates export_system_includes with arch variance", + Filesystem: map[string]string{ + "libf.so": "", + "libg.so": "", + }, + Blueprint: ` +cc_prebuilt_library_static { + name: "libtest", + srcs: ["libf.so"], + arch: { + arm: { export_system_include_dirs: ["testdir/1/"], }, + arm64: { export_system_include_dirs: ["testdir/2/"], }, + }, + bazel_module: { bp2build_available: true }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_prebuilt_library_static", "libtest", AttrNameToString{ + "static_library": `"libf.so"`, + "export_system_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("cc_prebuilt_library_static", "libtest_alwayslink", AttrNameToString{ + "alwayslink": "True", + "static_library": `"libf.so"`, + "export_system_includes": `select({ + "//build/bazel/platforms/arch:arm": ["testdir/1/"], + "//build/bazel/platforms/arch:arm64": ["testdir/2/"], + "//conditions:default": [], + })`, + }), + }, + }) +} diff --git a/bp2build/conversion.go b/bp2build/conversion.go index 6a39e256a..608fcd879 100644 --- a/bp2build/conversion.go +++ b/bp2build/conversion.go @@ -1,8 +1,11 @@ package bp2build import ( + "android/soong/starlark_fmt" "encoding/json" + "fmt" "reflect" + "strconv" "strings" "android/soong/android" @@ -48,7 +51,9 @@ func soongInjectionFiles(cfg android.Config, metrics CodegenMetrics) ([]BazelFil if err != nil { panic(err) } + files = append(files, newFile("metrics", GeneratedBuildFileName, "")) // Creates a //metrics package. files = append(files, newFile("metrics", "converted_modules_path_map.json", string(convertedModulePathMap))) + files = append(files, newFile("metrics", "converted_modules_path_map.bzl", "modules = "+strings.ReplaceAll(string(convertedModulePathMap), "\\", "\\\\"))) files = append(files, newFile("product_config", "soong_config_variables.bzl", cfg.Bp2buildSoongConfigDefinitions.String())) @@ -62,6 +67,7 @@ func soongInjectionFiles(cfg android.Config, metrics CodegenMetrics) ([]BazelFil // TODO(b/269691302) value of apiLevelsContent is product variable dependent and should be avoided for soong injection files = append(files, newFile("api_levels", "api_levels.json", string(apiLevelsContent))) files = append(files, newFile("api_levels", "api_levels.bzl", android.StarlarkApiLevelConfigs(cfg))) + files = append(files, newFile("api_levels", "platform_versions.bzl", platformVersionContents(cfg))) files = append(files, newFile("allowlists", GeneratedBuildFileName, "")) files = append(files, newFile("allowlists", "env.bzl", android.EnvironmentVarsFile(cfg))) @@ -72,6 +78,31 @@ func soongInjectionFiles(cfg android.Config, metrics CodegenMetrics) ([]BazelFil return files, nil } +func platformVersionContents(cfg android.Config) string { + // Despite these coming from cfg.productVariables, they are actually hardcoded in global + // makefiles, not set in individual product config makesfiles, so they're safe to just export + // and load() directly. + + platformVersionActiveCodenames := make([]string, 0, len(cfg.PlatformVersionActiveCodenames())) + for _, codename := range cfg.PlatformVersionActiveCodenames() { + platformVersionActiveCodenames = append(platformVersionActiveCodenames, fmt.Sprintf("%q", codename)) + } + + platformSdkVersion := "None" + if cfg.RawPlatformSdkVersion() != nil { + platformSdkVersion = strconv.Itoa(*cfg.RawPlatformSdkVersion()) + } + + return fmt.Sprintf(` +platform_versions = struct( + platform_sdk_final = %s, + platform_sdk_version = %s, + platform_sdk_codename = %q, + platform_version_active_codenames = [%s], +) +`, starlark_fmt.PrintBool(cfg.PlatformSdkFinal()), platformSdkVersion, cfg.PlatformSdkCodename(), strings.Join(platformVersionActiveCodenames, ", ")) +} + func CreateBazelFiles( cfg android.Config, ruleShims map[string]RuleShim, diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go index 8c1d2ae5b..2f5dc3cb7 100644 --- a/bp2build/conversion_test.go +++ b/bp2build/conversion_test.go @@ -131,9 +131,17 @@ func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) { }, { dir: "metrics", + basename: "BUILD.bazel", + }, + { + dir: "metrics", basename: "converted_modules_path_map.json", }, { + dir: "metrics", + basename: "converted_modules_path_map.bzl", + }, + { dir: "product_config", basename: "soong_config_variables.bzl", }, @@ -154,6 +162,10 @@ func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) { basename: "api_levels.bzl", }, { + dir: "api_levels", + basename: "platform_versions.bzl", + }, + { dir: "allowlists", basename: GeneratedBuildFileName, }, diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go index 7ce559d9b..273d55636 100644 --- a/bp2build/filegroup_conversion_test.go +++ b/bp2build/filegroup_conversion_test.go @@ -105,6 +105,42 @@ func TestFilegroupWithAidlSrcs(t *testing.T) { } } +func TestFilegroupWithAidlDeps(t *testing.T) { + bp := ` + filegroup { + name: "bar", + srcs: ["bar.aidl"], + } + filegroup { + name: "foo", + srcs: ["aidl/foo.aidl"], + path: "aidl", + aidl: { + deps: [":bar"], + } + }` + + t.Run("filegroup with aidl deps", func(t *testing.T) { + expectedBazelTargets := []string{ + MakeBazelTargetNoRestrictions("aidl_library", "bar", AttrNameToString{ + "srcs": `["bar.aidl"]`, + "tags": `["apex_available=//apex_available:anyapex"]`, + }), + MakeBazelTargetNoRestrictions("aidl_library", "foo", AttrNameToString{ + "srcs": `["aidl/foo.aidl"]`, + "strip_import_prefix": `"aidl"`, + "deps": `[":bar"]`, + "tags": `["apex_available=//apex_available:anyapex"]`, + }), + } + runFilegroupTestCase(t, Bp2buildTestCase{ + Description: "filegroup with aidl deps", + Blueprint: bp, + ExpectedBazelTargets: expectedBazelTargets, + }) + }) +} + func TestFilegroupWithAidlAndNonAidlSrcs(t *testing.T) { runFilegroupTestCase(t, Bp2buildTestCase{ Description: "filegroup with aidl and non-aidl srcs", diff --git a/bp2build/java_binary_host_conversion_test.go b/bp2build/java_binary_host_conversion_test.go index 1b9777cae..c821f590e 100644 --- a/bp2build/java_binary_host_conversion_test.go +++ b/bp2build/java_binary_host_conversion_test.go @@ -57,24 +57,24 @@ func TestJavaBinaryHost(t *testing.T) { }`, ExpectedBazelTargets: []string{ MakeBazelTarget("java_library", "java-binary-host-1_lib", AttrNameToString{ - "srcs": `["a.java"]`, - "deps": `["//other:jni-lib-1"]`, - "javacopts": `[ - "-Xdoclint:all/protected", - "-source 1.8 -target 1.8", - ]`, + "srcs": `["a.java"]`, + "deps": `["//other:jni-lib-1"]`, + "java_version": `"8"`, + "javacopts": `["-Xdoclint:all/protected"]`, "target_compatible_with": `select({ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], - })`}), + })`, + }), MakeBazelTarget("java_binary", "java-binary-host-1", AttrNameToString{ - "main_class": `"com.android.test.MainClass"`, - "jvm_flags": `["-Djava.library.path=$${RUNPATH}other"]`, - "runtime_deps": `[":java-binary-host-1_lib"]`, + "main_class": `"com.android.test.MainClass"`, + "jvm_flags": `["-Djava.library.path=$${RUNPATH}other"]`, "target_compatible_with": `select({ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], - })`}), + })`, + "runtime_deps": `[":java-binary-host-1_lib"]`, + }), }, }) } diff --git a/bp2build/java_host_for_device_conversion_test.go b/bp2build/java_host_for_device_conversion_test.go index d908d0002..448cba461 100644 --- a/bp2build/java_host_for_device_conversion_test.go +++ b/bp2build/java_host_for_device_conversion_test.go @@ -51,9 +51,11 @@ java_library { }`, ExpectedBazelTargets: []string{ MakeBazelTarget("java_host_for_device", "java-lib-1", AttrNameToString{ - "deps": `[":java-lib-2"]`, + "exports": `[":java-lib-2"]`, + }), + MakeNeverlinkDuplicateTargetWithAttrs("java_library", "java-lib-1", AttrNameToString{ + "sdk_version": `"none"`, }), - MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"), MakeBazelTarget("java_library", "java-lib-2", AttrNameToString{ "srcs": `["b.java"]`, }), diff --git a/bp2build/java_import_conversion_test.go b/bp2build/java_import_conversion_test.go index a5c01cb4f..5661620e2 100644 --- a/bp2build/java_import_conversion_test.go +++ b/bp2build/java_import_conversion_test.go @@ -49,8 +49,9 @@ java_import { "jars": `["import.jar"]`, }), MakeBazelTarget("java_library", "example_import-neverlink", AttrNameToString{ - "exports": `[":example_import"]`, - "neverlink": `True`, + "exports": `[":example_import"]`, + "neverlink": `True`, + "sdk_version": `"none"`, }), }}) } @@ -86,8 +87,9 @@ java_import { })`, }), MakeBazelTarget("java_library", "example_import-neverlink", AttrNameToString{ - "exports": `[":example_import"]`, - "neverlink": `True`, + "exports": `[":example_import"]`, + "neverlink": `True`, + "sdk_version": `"none"`, }), }}) } @@ -112,8 +114,9 @@ java_import_host { "jars": `["import.jar"]`, }), MakeBazelTarget("java_library", "example_import-neverlink", AttrNameToString{ - "exports": `[":example_import"]`, - "neverlink": `True`, + "exports": `[":example_import"]`, + "neverlink": `True`, + "sdk_version": `"none"`, }), }}) } diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go index 683ee27cc..24b763bcf 100644 --- a/bp2build/java_library_conversion_test.go +++ b/bp2build/java_library_conversion_test.go @@ -172,10 +172,13 @@ func TestJavaLibraryJavaVersion(t *testing.T) { }`, ExpectedBazelTargets: []string{ MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{ - "srcs": `["a.java"]`, - "javacopts": `["-source 11 -target 11"]`, + "srcs": `["a.java"]`, + "java_version": `"11"`, }), - MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"), + MakeNeverlinkDuplicateTargetWithAttrs( + "java_library", + "java-lib-1", + AttrNameToString{"java_version": `"11"`}), }, }) } diff --git a/bp2build/java_library_host_conversion_test.go b/bp2build/java_library_host_conversion_test.go index 14854c06a..9e47b0972 100644 --- a/bp2build/java_library_host_conversion_test.go +++ b/bp2build/java_library_host_conversion_test.go @@ -63,8 +63,8 @@ java_library_host { })`, }), MakeBazelTarget("java_library", "java-lib-host-2", AttrNameToString{ - "javacopts": `["-source 1.9 -target 1.9"]`, - "srcs": `["c.java"]`, + "java_version": `"9"`, + "srcs": `["c.java"]`, "target_compatible_with": `select({ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], @@ -77,6 +77,7 @@ java_library_host { "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], })`, + "java_version": `"9"`, }), }, }) diff --git a/bp2build/java_plugin_conversion_test.go b/bp2build/java_plugin_conversion_test.go index 8c6337b49..f2b6f20a4 100644 --- a/bp2build/java_plugin_conversion_test.go +++ b/bp2build/java_plugin_conversion_test.go @@ -67,7 +67,7 @@ java_library { "a.java", "b.java", ]`, - "javacopts": `["-source 1.7 -target 1.7"]`, + "java_version": `"7"`, }), }, }) diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go index d25b7c4ee..f546cf45d 100644 --- a/bp2build/java_proto_conversion_test.go +++ b/bp2build/java_proto_conversion_test.go @@ -114,13 +114,17 @@ func TestJavaProtoDefault(t *testing.T) { "java_lite_proto_library", "java-protos_java_proto_lite", AttrNameToString{ - "deps": `[":java-protos_proto"]`, + "deps": `[":java-protos_proto"]`, + "java_version": `"7"`, }), MakeBazelTarget("java_library", "java-protos", AttrNameToString{ - "exports": `[":java-protos_java_proto_lite"]`, - "javacopts": `["-source 1.7 -target 1.7"]`, + "exports": `[":java-protos_java_proto_lite"]`, + "java_version": `"7"`, }), - MakeNeverlinkDuplicateTarget("java_library", "java-protos"), + MakeNeverlinkDuplicateTargetWithAttrs( + "java_library", + "java-protos", + AttrNameToString{"java_version": `"7"`}), }, }) } diff --git a/bp2build/python_test_conversion_test.go b/bp2build/python_test_conversion_test.go new file mode 100644 index 000000000..4ff1fa16d --- /dev/null +++ b/bp2build/python_test_conversion_test.go @@ -0,0 +1,66 @@ +// Copyright 2023 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/python" + "testing" +) + +func TestPythonTestHostSimple(t *testing.T) { + runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{ + Description: "simple python_test_host converts to a native py_test", + ModuleTypeUnderTest: "python_test_host", + ModuleTypeUnderTestFactory: python.PythonTestHostFactory, + Filesystem: map[string]string{ + "a.py": "", + "b/c.py": "", + "b/d.py": "", + "b/e.py": "", + "files/data.txt": "", + }, + Blueprint: `python_test_host { + name: "foo", + main: "a.py", + srcs: ["**/*.py"], + exclude_srcs: ["b/e.py"], + data: ["files/data.txt",], + libs: ["bar"], + bazel_module: { bp2build_available: true }, +} + python_library_host { + name: "bar", + srcs: ["b/e.py"], + bazel_module: { bp2build_available: false }, + }`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("py_test", "foo", AttrNameToString{ + "data": `["files/data.txt"]`, + "deps": `[":bar"]`, + "main": `"a.py"`, + "imports": `["."]`, + "srcs": `[ + "a.py", + "b/c.py", + "b/d.py", + ]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + }, + }) +} diff --git a/bp2build/testing.go b/bp2build/testing.go index 856b6eed9..6e919db2b 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -642,10 +642,14 @@ func makeCcStubSuiteTargets(name string, attrs AttrNameToString) string { } func MakeNeverlinkDuplicateTarget(moduleType string, name string) string { - return MakeBazelTarget(moduleType, name+"-neverlink", AttrNameToString{ - "neverlink": `True`, - "exports": `[":` + name + `"]`, - }) + return MakeNeverlinkDuplicateTargetWithAttrs(moduleType, name, AttrNameToString{}) +} + +func MakeNeverlinkDuplicateTargetWithAttrs(moduleType string, name string, extraAttrs AttrNameToString) string { + attrs := extraAttrs + attrs["neverlink"] = `True` + attrs["exports"] = `[":` + name + `"]` + return MakeBazelTarget(moduleType, name+"-neverlink", attrs) } func getTargetName(targetContent string) string { @@ -1475,7 +1475,7 @@ func isBionic(name string) bool { func InstallToBootstrap(name string, config android.Config) bool { // NOTE: also update //build/bazel/rules/apex/cc.bzl#_installed_to_bootstrap // if this list is updated. - if name == "libclang_rt.hwasan" { + if name == "libclang_rt.hwasan" || name == "libc_hwasan" { return true } return isBionic(name) @@ -1858,6 +1858,10 @@ func GetSubnameProperty(actx android.ModuleContext, c LinkableInterface) string if c.SplitPerApiLevel() { subName += "." + c.SdkVersion() } + } else if c.IsStubs() && c.IsSdkVariant() { + // Public API surface (NDK) + // Add a suffix to this stub variant to distinguish it from the module-lib stub variant. + subName = sdkSuffix } return subName diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go index 76c8e5dca..a63d5c237 100644 --- a/cc/config/riscv64_device.go +++ b/cc/config/riscv64_device.go @@ -26,8 +26,6 @@ var ( // Help catch common 32/64-bit errors. "-Werror=implicit-function-declaration", "-fno-emulated-tls", - // For -fsanitize=shadow-call-stack. - "-ffixed-x18", // A temporary fix for SExtWRemoval miscompilation bug. "-mllvm", "-riscv-disable-sextw-removal=true", @@ -37,8 +35,6 @@ var ( riscv64Ldflags = []string{ "-Wl,--hash-style=gnu", - // For -fsanitize=shadow-call-stack. - "-ffixed-x18", } riscv64Lldflags = append(riscv64Ldflags, diff --git a/cc/library.go b/cc/library.go index 7504302fd..172ca6459 100644 --- a/cc/library.go +++ b/cc/library.go @@ -2193,7 +2193,16 @@ func (library *libraryDecorator) toc() android.OptionalPath { func (library *libraryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) { dir := library.baseInstaller.installDir(ctx) dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir) - target := "/" + filepath.Join("apex", "com.android.runtime", dir.Base(), "bionic", file.Base()) + // libc_hwasan has relative_install_dir set, which would mess up the dir.Base() logic. + // hardcode here because it's the only target, if we have other targets that use this + // we can generalise this. + var target string + if ctx.baseModuleName() == "libc_hwasan" { + target = "/" + filepath.Join("apex", "com.android.runtime", "lib64", "bionic", "hwasan", file.Base()) + } else { + base := dir.Base() + target = "/" + filepath.Join("apex", "com.android.runtime", base, "bionic", file.Base()) + } ctx.InstallAbsoluteSymlink(dir, file.Base(), target) library.postInstallCmds = append(library.postInstallCmds, makeSymlinkCmd(dirOnDevice, file.Base(), target)) } diff --git a/cc/prebuilt.go b/cc/prebuilt.go index 4470f5496..0b5841ef0 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -376,6 +376,7 @@ func prebuiltLibraryStaticBp2Build(ctx android.TopDownMutatorContext, module *Mo Static_library: prebuiltAttrs.Src, Export_includes: exportedIncludes.Includes, Export_system_includes: exportedIncludes.SystemIncludes, + // TODO: ¿Alwayslink? } props := bazel.BazelTargetModuleProperties{ @@ -398,14 +399,19 @@ func prebuiltLibraryStaticBp2Build(ctx android.TopDownMutatorContext, module *Mo } type bazelPrebuiltLibrarySharedAttributes struct { - Shared_library bazel.LabelAttribute + Shared_library bazel.LabelAttribute + Export_includes bazel.StringListAttribute + Export_system_includes bazel.StringListAttribute } func prebuiltLibrarySharedBp2Build(ctx android.TopDownMutatorContext, module *Module) { prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module, false) + exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, nil) attrs := &bazelPrebuiltLibrarySharedAttributes{ - Shared_library: prebuiltAttrs.Src, + Shared_library: prebuiltAttrs.Src, + Export_includes: exportedIncludes.Includes, + Export_system_includes: exportedIncludes.SystemIncludes, } props := bazel.BazelTargetModuleProperties{ diff --git a/cc/sanitize.go b/cc/sanitize.go index f19659cc7..45d7fab4f 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -64,12 +64,13 @@ var ( cfiBlocklistPath = "external/compiler-rt/lib/cfi" cfiBlocklistFilename = "cfi_blocklist.txt" - cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso", + cfiCrossDsoFlag = "-fsanitize-cfi-cross-dso" + cfiCflags = []string{"-flto", cfiCrossDsoFlag, "-fsanitize-ignorelist=" + cfiBlocklistPath + "/" + cfiBlocklistFilename} // -flto and -fvisibility are required by clang when -fsanitize=cfi is // used, but have no effect on assembly files cfiAsflags = []string{"-flto", "-fvisibility=default"} - cfiLdflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fsanitize=cfi", + cfiLdflags = []string{"-flto", cfiCrossDsoFlag, "-fsanitize=cfi", "-Wl,-plugin-opt,O1"} cfiExportsMapPath = "build/soong/cc/config" cfiExportsMapFilename = "cfi_exports.map" @@ -393,11 +394,13 @@ func init() { exportedVars.ExportStringList("DeviceOnlySanitizeFlags", deviceOnlySanitizeFlags) // Leave out "-flto" from the slices exported to bazel, as we will use the - // dedicated LTO feature for this - exportedVars.ExportStringList("CfiCFlags", cfiCflags[1:]) + // dedicated LTO feature for this. For C Flags and Linker Flags, also leave + // out the cross DSO flag which will be added separately by transitions. + exportedVars.ExportStringList("CfiCFlags", cfiCflags[2:]) + exportedVars.ExportStringList("CfiLdFlags", cfiLdflags[2:]) exportedVars.ExportStringList("CfiAsFlags", cfiAsflags[1:]) - exportedVars.ExportStringList("CfiLdFlags", cfiLdflags[1:]) + exportedVars.ExportString("CfiCrossDsoFlag", cfiCrossDsoFlag) exportedVars.ExportString("CfiBlocklistPath", cfiBlocklistPath) exportedVars.ExportString("CfiBlocklistFilename", cfiBlocklistFilename) exportedVars.ExportString("CfiExportsMapPath", cfiExportsMapPath) @@ -613,6 +616,10 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { if (ctx.Arch().ArchType != android.Arm64 && ctx.Arch().ArchType != android.Riscv64) || !ctx.toolchain().Bionic() { s.Scs = nil } + // ...but temporarily globally disabled on riscv64 (http://b/277909695). + if ctx.Arch().ArchType == android.Riscv64 { + s.Scs = nil + } // Memtag_heap is only implemented on AArch64. // Memtag ABI is Android specific for now, so disable for host. @@ -785,6 +792,13 @@ func (s *sanitize) flags(ctx ModuleContext, flags Flags) Flags { if Bool(sanProps.Writeonly) { flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm", "-hwasan-instrument-reads=0") } + if !ctx.staticBinary() && !ctx.Host() { + if ctx.bootstrap() { + flags.DynamicLinker = "/system/bin/bootstrap/linker_hwasan64" + } else { + flags.DynamicLinker = "/system/bin/linker_hwasan64" + } + } } if Bool(sanProps.Fuzzer) { diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go index 718186d92..29b17d415 100644 --- a/cc/sanitize_test.go +++ b/cc/sanitize_test.go @@ -1166,3 +1166,83 @@ func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) { checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync) checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync) } + +func TestCfi(t *testing.T) { + t.Parallel() + + bp := ` + cc_library_shared { + name: "shared_with_cfi", + static_libs: [ + "static_dep_with_cfi", + "static_dep_no_cfi", + ], + sanitize: { + cfi: true, + }, + } + + cc_library_shared { + name: "shared_no_cfi", + static_libs: [ + "static_dep_with_cfi", + "static_dep_no_cfi", + ], + } + + cc_library_static { + name: "static_dep_with_cfi", + sanitize: { + cfi: true, + }, + } + + cc_library_static { + name: "static_dep_no_cfi", + } + + cc_library_shared { + name: "shared_rdep_no_cfi", + static_libs: ["static_dep_with_cfi_2"], + } + + cc_library_static { + name: "static_dep_with_cfi_2", + sanitize: { + cfi: true, + }, + } +` + preparer := android.GroupFixturePreparers( + prepareForCcTest, + ) + result := preparer.RunTestWithBp(t, bp) + ctx := result.TestContext + + buildOs := "android_arm64_armv8-a" + shared_suffix := "_shared" + cfi_suffix := "_cfi" + static_suffix := "_static" + + sharedWithCfiLib := result.ModuleForTests("shared_with_cfi", buildOs+shared_suffix+cfi_suffix) + sharedNoCfiLib := result.ModuleForTests("shared_no_cfi", buildOs+shared_suffix) + staticWithCfiLib := result.ModuleForTests("static_dep_with_cfi", buildOs+static_suffix) + staticWithCfiLibCfiVariant := result.ModuleForTests("static_dep_with_cfi", buildOs+static_suffix+cfi_suffix) + staticNoCfiLib := result.ModuleForTests("static_dep_no_cfi", buildOs+static_suffix) + staticNoCfiLibCfiVariant := result.ModuleForTests("static_dep_no_cfi", buildOs+static_suffix+cfi_suffix) + sharedRdepNoCfi := result.ModuleForTests("shared_rdep_no_cfi", buildOs+shared_suffix) + staticDepWithCfi2Lib := result.ModuleForTests("static_dep_with_cfi_2", buildOs+static_suffix) + + // Confirm assumptions about propagation of CFI enablement + expectStaticLinkDep(t, ctx, sharedWithCfiLib, staticWithCfiLibCfiVariant) + expectStaticLinkDep(t, ctx, sharedNoCfiLib, staticWithCfiLib) + expectStaticLinkDep(t, ctx, sharedWithCfiLib, staticNoCfiLibCfiVariant) + expectStaticLinkDep(t, ctx, sharedNoCfiLib, staticNoCfiLib) + expectStaticLinkDep(t, ctx, sharedRdepNoCfi, staticDepWithCfi2Lib) + + // Confirm that non-CFI variants do not add CFI flags + bazLibCflags := staticWithCfiLib.Rule("cc").Args["cFlags"] + if strings.Contains(bazLibCflags, "-fsanitize-cfi-cross-dso") { + t.Errorf("non-CFI variant of baz not expected to contain CFI flags ") + } +} diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index 9b12bfa18..aed37753a 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -157,6 +157,7 @@ type snapshotJsonFlags struct { // extra config files InitRc []string `json:",omitempty"` VintfFragments []string `json:",omitempty"` + MinSdkVersion string `json:",omitempty"` } var ccSnapshotAction snapshot.GenerateSnapshotAction = func(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) android.Paths { @@ -249,6 +250,7 @@ var ccSnapshotAction snapshot.GenerateSnapshotAction = func(s snapshot.SnapshotS for _, path := range m.VintfFragments() { prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base())) } + prop.MinSdkVersion = m.MinSdkVersion() // install config files. ignores any duplicates. for _, path := range append(m.InitRc(), m.VintfFragments()...) { diff --git a/cc/vndk.go b/cc/vndk.go index be66cd79f..30bfdd89f 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -706,6 +706,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex // json struct to export snapshot information prop := struct { + MinSdkVersion string `json:",omitempty"` LicenseKinds []string `json:",omitempty"` LicenseTexts []string `json:",omitempty"` ExportedDirs []string `json:",omitempty"` @@ -716,6 +717,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex prop.LicenseKinds = m.EffectiveLicenseKinds() prop.LicenseTexts = m.EffectiveLicenseFiles().Strings() + prop.MinSdkVersion = m.MinSdkVersion() if ctx.Config().VndkSnapshotBuildArtifacts() { exportedInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo) diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go index 8175a3742..79d241279 100644 --- a/fuzz/fuzz_common.go +++ b/fuzz/fuzz_common.go @@ -338,6 +338,8 @@ type FuzzConfig struct { IsJni *bool `json:"is_jni,omitempty"` // List of modules for monitoring coverage drops in directories (e.g. "libicu") Target_modules []string `json:"target_modules,omitempty"` + // Specifies a bug assignee to replace default ISE assignment + Assignee string `json:"assignee,omitempty"` } type FuzzFrameworks struct { diff --git a/java/aar.go b/java/aar.go index 47e6efae3..f1b137de1 100644 --- a/java/aar.go +++ b/java/aar.go @@ -1015,9 +1015,10 @@ type bazelAndroidLibrary struct { } type bazelAndroidLibraryImport struct { - Aar bazel.Label - Deps bazel.LabelListAttribute - Exports bazel.LabelListAttribute + Aar bazel.Label + Deps bazel.LabelListAttribute + Exports bazel.LabelListAttribute + Sdk_version bazel.StringAttribute } func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) *bazelAapt { @@ -1059,9 +1060,10 @@ func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) { }, android.CommonAttributes{Name: name}, &bazelAndroidLibraryImport{ - Aar: aars.Includes[0], - Deps: bazel.MakeLabelListAttribute(deps), - Exports: bazel.MakeLabelListAttribute(exports), + Aar: aars.Includes[0], + Deps: bazel.MakeLabelListAttribute(deps), + Exports: bazel.MakeLabelListAttribute(exports), + Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version}, }, ) @@ -1073,6 +1075,9 @@ func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) { javaLibraryAttributes: &javaLibraryAttributes{ Neverlink: bazel.BoolAttribute{Value: &neverlink}, Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: a.properties.Sdk_version}, + }, }, }, ) @@ -1119,6 +1124,10 @@ func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) javaLibraryAttributes: &javaLibraryAttributes{ Neverlink: bazel.BoolAttribute{Value: &neverlink}, Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: a.deviceProperties.Sdk_version}, + Java_version: bazel.StringAttribute{Value: a.properties.Java_version}, + }, }, }, ) diff --git a/java/app.go b/java/app.go index 52caf6d38..03e233059 100755 --- a/java/app.go +++ b/java/app.go @@ -1565,6 +1565,9 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { appAttrs.bazelAapt = &bazelAapt{Manifest: aapt.Manifest} appAttrs.Deps = bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + ktName}) + appAttrs.javaCommonAttributes = &javaCommonAttributes{ + Sdk_version: commonAttrs.Sdk_version, + } } ctx.CreateBazelTargetModule( diff --git a/java/app_import.go b/java/app_import.go index c1de66745..85b35ebaa 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -17,9 +17,10 @@ package java // This file contains the module implementations for android_app_import and android_test_import. import ( - "github.com/google/blueprint" "reflect" + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" "android/soong/android" @@ -177,10 +178,6 @@ func MergePropertiesFromVariant(ctx android.EarlyModuleContext, } } -func (a *AndroidAppImport) isPrebuiltFrameworkRes() bool { - return a.Name() == "prebuilt_framework-res" -} - func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) { cert := android.SrcIsModule(String(a.properties.Certificate)) if cert != "" { @@ -197,7 +194,7 @@ func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) { } } - a.usesLibrary.deps(ctx, !a.isPrebuiltFrameworkRes()) + a.usesLibrary.deps(ctx, true) } func (a *AndroidAppImport) uncompressEmbeddedJniLibs( @@ -243,6 +240,10 @@ func (a *AndroidAppImport) InstallApkName() string { } func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) { + if a.Name() == "prebuilt_framework-res" { + ctx.ModuleErrorf("prebuilt_framework-res found. This used to have special handling in soong, but was removed due to prebuilt_framework-res no longer existing. This check is to ensure it doesn't come back without readding the special handling.") + } + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if !apexInfo.IsForPlatform() { a.hideApexVariantFromMake = true @@ -278,14 +279,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext var pathFragments []string relInstallPath := String(a.properties.Relative_install_path) - if a.isPrebuiltFrameworkRes() { - // framework-res.apk is installed as system/framework/framework-res.apk - if relInstallPath != "" { - ctx.PropertyErrorf("relative_install_path", "Relative_install_path cannot be set for framework-res") - } - pathFragments = []string{"framework"} - a.preprocessed = true - } else if Bool(a.properties.Privileged) { + if Bool(a.properties.Privileged) { pathFragments = []string{"priv-app", relInstallPath, a.BaseModuleName()} } else if ctx.InstallInTestcases() { pathFragments = []string{relInstallPath, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch()} @@ -323,13 +317,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext // Sign or align the package if package has not been preprocessed - if a.isPrebuiltFrameworkRes() { - a.outputFile = srcApk - a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx) - if len(certificates) != 1 { - ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates) - } - } else if a.preprocessed { + if a.preprocessed { a.outputFile = srcApk a.certificate = PresignedCertificate } else if !Bool(a.properties.Presigned) { diff --git a/java/app_import_test.go b/java/app_import_test.go index 528fffe94..80930248e 100644 --- a/java/app_import_test.go +++ b/java/app_import_test.go @@ -505,67 +505,6 @@ func TestAndroidAppImport_overridesDisabledAndroidApp(t *testing.T) { } } -func TestAndroidAppImport_frameworkRes(t *testing.T) { - ctx, _ := testJava(t, ` - android_app_import { - name: "framework-res", - certificate: "platform", - apk: "package-res.apk", - prefer: true, - export_package_resources: true, - // Disable dexpreopt and verify_uses_libraries check as the app - // contains no Java code to be dexpreopted. - enforce_uses_libs: false, - dex_preopt: { - enabled: false, - }, - } - `) - - mod := ctx.ModuleForTests("prebuilt_framework-res", "android_common").Module() - a := mod.(*AndroidAppImport) - - if !a.preprocessed { - t.Errorf("prebuilt framework-res is not preprocessed") - } - - expectedInstallPath := "out/soong/target/product/test_device/system/framework/framework-res.apk" - - android.AssertPathRelativeToTopEquals(t, "prebuilt framework-res install location", expectedInstallPath, a.dexpreopter.installPath) - - entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0] - - expectedPath := "." - // From apk property above, in the root of the source tree. - expectedPrebuiltModuleFile := "package-res.apk" - // Verify that the apk is preprocessed: The export package is the same - // as the prebuilt. - expectedSoongResourceExportPackage := expectedPrebuiltModuleFile - - actualPath := entries.EntryMap["LOCAL_PATH"] - actualPrebuiltModuleFile := entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"] - actualSoongResourceExportPackage := entries.EntryMap["LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE"] - - if len(actualPath) != 1 { - t.Errorf("LOCAL_PATH incorrect len %d", len(actualPath)) - } else if actualPath[0] != expectedPath { - t.Errorf("LOCAL_PATH mismatch, actual: %s, expected: %s", actualPath[0], expectedPath) - } - - if len(actualPrebuiltModuleFile) != 1 { - t.Errorf("LOCAL_PREBUILT_MODULE_FILE incorrect len %d", len(actualPrebuiltModuleFile)) - } else if actualPrebuiltModuleFile[0] != expectedPrebuiltModuleFile { - t.Errorf("LOCAL_PREBUILT_MODULE_FILE mismatch, actual: %s, expected: %s", actualPrebuiltModuleFile[0], expectedPrebuiltModuleFile) - } - - if len(actualSoongResourceExportPackage) != 1 { - t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE incorrect len %d", len(actualSoongResourceExportPackage)) - } else if actualSoongResourceExportPackage[0] != expectedSoongResourceExportPackage { - t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE mismatch, actual: %s, expected: %s", actualSoongResourceExportPackage[0], expectedSoongResourceExportPackage) - } - android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "android_app_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) -} - func TestAndroidAppImport_relativeInstallPath(t *testing.T) { bp := ` android_app_import { @@ -582,13 +521,6 @@ func TestAndroidAppImport_relativeInstallPath(t *testing.T) { } android_app_import { - name: "framework-res", - apk: "prebuilts/apk/app.apk", - presigned: true, - prefer: true, - } - - android_app_import { name: "privileged_relative_install_path", apk: "prebuilts/apk/app.apk", presigned: true, @@ -612,11 +544,6 @@ func TestAndroidAppImport_relativeInstallPath(t *testing.T) { errorMessage: "Install path is not correct for app when relative_install_path is present", }, { - name: "prebuilt_framework-res", - expectedInstallPath: "out/soong/target/product/test_device/system/framework/framework-res.apk", - errorMessage: "Install path is not correct for framework-res", - }, - { name: "privileged_relative_install_path", expectedInstallPath: "out/soong/target/product/test_device/system/priv-app/my/path/privileged_relative_install_path/privileged_relative_install_path.apk", errorMessage: "Install path is not correct for privileged app when relative_install_path is present", diff --git a/java/device_host_converter.go b/java/device_host_converter.go index 656c866ed..3581040f8 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -21,6 +21,8 @@ import ( "android/soong/android" "android/soong/bazel" "android/soong/dexpreopt" + + "github.com/google/blueprint/proptools" ) type DeviceHostConverter struct { @@ -191,7 +193,7 @@ func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData { } type bazelDeviceHostConverterAttributes struct { - Deps bazel.LabelListAttribute + Exports bazel.LabelListAttribute } func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.TopDownMutatorContext) { @@ -202,13 +204,15 @@ func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.TopDownMutatorCont }, android.CommonAttributes{Name: d.Name()}, &bazelDeviceHostConverterAttributes{ - Deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, d.properties.Libs)), + Exports: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, d.properties.Libs)), }, ) - neverlinkProp := true neverLinkAttrs := &javaLibraryAttributes{ Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + d.Name()}), - Neverlink: bazel.BoolAttribute{Value: &neverlinkProp}, + Neverlink: bazel.BoolAttribute{Value: proptools.BoolPtr(true)}, + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: proptools.StringPtr("none")}, + }, } ctx.CreateBazelTargetModule( javaLibraryBazelTargetModuleProperties(), diff --git a/java/java.go b/java/java.go index d400b0cfb..2de4ea97e 100644 --- a/java/java.go +++ b/java/java.go @@ -2740,9 +2740,11 @@ func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorConte type javaCommonAttributes struct { *javaResourcesAttributes *kotlinAttributes - Srcs bazel.LabelListAttribute - Plugins bazel.LabelListAttribute - Javacopts bazel.StringListAttribute + Srcs bazel.LabelListAttribute + Plugins bazel.LabelListAttribute + Javacopts bazel.StringListAttribute + Sdk_version bazel.StringAttribute + Java_version bazel.StringAttribute } type javaDependencyLabels struct { @@ -2873,10 +2875,6 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) if m.properties.Javacflags != nil { javacopts = append(javacopts, m.properties.Javacflags...) } - if m.properties.Java_version != nil { - javaVersion := normalizeJavaVersion(ctx, *m.properties.Java_version).String() - javacopts = append(javacopts, fmt.Sprintf("-source %s -target %s", javaVersion, javaVersion)) - } epEnabled := m.properties.Errorprone.Enabled //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable @@ -2890,7 +2888,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) Plugins: bazel.MakeLabelListAttribute( android.BazelLabelForModuleDeps(ctx, m.properties.Plugins), ), - Javacopts: bazel.MakeStringListAttribute(javacopts), + Javacopts: bazel.MakeStringListAttribute(javacopts), + Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, + Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, } for axis, configToProps := range archVariantProps { @@ -2981,19 +2981,9 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { deps := depLabels.Deps if !commonAttrs.Srcs.IsEmpty() { deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them - - sdkVersion := m.SdkVersion(ctx) - if sdkVersion.Kind == android.SdkPublic && sdkVersion.ApiLevel == android.FutureApiLevel { - // TODO(b/220869005) remove forced dependency on current public android.jar - deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:public_current_android_sdk_java_import")) - } else if sdkVersion.Kind == android.SdkSystem && sdkVersion.ApiLevel == android.FutureApiLevel { - // TODO(b/215230098) remove forced dependency on current public android.jar - deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:system_current_android_sdk_java_import")) - } } else if !deps.IsEmpty() { ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") } - var props bazel.BazelTargetModuleProperties attrs := &javaLibraryAttributes{ javaCommonAttributes: commonAttrs, @@ -3013,6 +3003,10 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { neverLinkAttrs := &javaLibraryAttributes{ Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), Neverlink: bazel.BoolAttribute{Value: &neverlinkProp}, + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, + Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, + }, } ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name + "-neverlink"}, neverLinkAttrs) @@ -3152,6 +3146,9 @@ func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) { neverlinkAttrs := &javaLibraryAttributes{ Neverlink: bazel.BoolAttribute{Value: &neverlink}, Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), + javaCommonAttributes: &javaCommonAttributes{ + Sdk_version: bazel.StringAttribute{Value: proptools.StringPtr("none")}, + }, } ctx.CreateBazelTargetModule( javaLibraryBazelTargetModuleProperties(), diff --git a/java/proto.go b/java/proto.go index 5280077f1..c732d9842 100644 --- a/java/proto.go +++ b/java/proto.go @@ -143,7 +143,9 @@ func protoFlags(ctx android.ModuleContext, j *CommonProperties, p *android.Proto } type protoAttributes struct { - Deps bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Sdk_version bazel.StringAttribute + Java_version bazel.StringAttribute } func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) *bazel.Label { @@ -175,8 +177,11 @@ func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs baze } protoLabel := bazel.Label{Label: ":" + m.Name() + "_proto"} - var protoAttrs protoAttributes - protoAttrs.Deps.SetValue(bazel.LabelList{Includes: []bazel.Label{protoLabel}}) + protoAttrs := &protoAttributes{ + Deps: bazel.MakeSingleLabelListAttribute(protoLabel), + Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, + Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, + } name := m.Name() + suffix @@ -186,7 +191,7 @@ func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs baze Bzl_load_location: "//build/bazel/rules/java:proto.bzl", }, android.CommonAttributes{Name: name}, - &protoAttrs) + protoAttrs) return &bazel.Label{Label: ":" + name} } diff --git a/java/testing.go b/java/testing.go index 0764d264a..f68e12ff4 100644 --- a/java/testing.go +++ b/java/testing.go @@ -389,15 +389,16 @@ func gatherRequiredDepsForTest() string { } extraApiLibraryModules := map[string]string{ - "android_stubs_current.from-text": "api/current.txt", - "android_system_stubs_current.from-text": "api/system-current.txt", - "android_test_stubs_current.from-text": "api/test-current.txt", - "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt", - "android_system_server_stubs_current.from-text": "api/system-server-current.txt", - "core.current.stubs.from-text": "api/current.txt", - "legacy.core.platform.api.stubs.from-text": "api/current.txt", - "stable.core.platform.api.stubs.from-text": "api/current.txt", - "core-lambda-stubs.from-text": "api/current.txt", + "android_stubs_current.from-text": "api/current.txt", + "android_system_stubs_current.from-text": "api/system-current.txt", + "android_test_stubs_current.from-text": "api/test-current.txt", + "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt", + "android_module_lib_stubs_current_full.from-text": "api/module-lib-current.txt", + "android_system_server_stubs_current.from-text": "api/system-server-current.txt", + "core.current.stubs.from-text": "api/current.txt", + "legacy.core.platform.api.stubs.from-text": "api/current.txt", + "stable.core.platform.api.stubs.from-text": "api/current.txt", + "core-lambda-stubs.from-text": "api/current.txt", } for libName, apiFile := range extraApiLibraryModules { diff --git a/mk2rbc/soong_variables.go b/mk2rbc/soong_variables.go index a52ec4f2a..7a6aa5ffa 100644 --- a/mk2rbc/soong_variables.go +++ b/mk2rbc/soong_variables.go @@ -67,7 +67,11 @@ func (ctx context) NewSoongVariable(name, typeString string) { var valueType starlarkType switch typeString { case "bool": - valueType = starlarkTypeBool + // TODO: We run into several issues later on if we type this as a bool: + // - We still assign bool-typed variables to strings + // - When emitting the final results as make code, some bool's false values have to + // be an empty string, and some have to be false in order to match the make variables. + valueType = starlarkTypeString case "csv": // Only PLATFORM_VERSION_ALL_CODENAMES, and it's a list valueType = starlarkTypeList diff --git a/python/binary.go b/python/binary.go index 75135f345..a5db2f6ef 100644 --- a/python/binary.go +++ b/python/binary.go @@ -37,7 +37,7 @@ type BinaryProperties struct { // this file must also be listed in srcs. // If left unspecified, module name is used instead. // If name doesn’t match any filename in srcs, main must be specified. - Main *string `android:"arch_variant"` + Main *string // set the name of the output binary. Stem *string `android:"arch_variant"` diff --git a/python/bp2build.go b/python/bp2build.go index bdac2dc38..cd3f2a1a8 100644 --- a/python/bp2build.go +++ b/python/bp2build.go @@ -15,7 +15,6 @@ package python import ( - "fmt" "path/filepath" "strings" @@ -118,30 +117,45 @@ func (m *PythonLibraryModule) makeArchVariantBaseAttributes(ctx android.TopDownM return attrs } -func pythonLibBp2Build(ctx android.TopDownMutatorContext, m *PythonLibraryModule) { - // TODO(b/182306917): this doesn't fully handle all nested props versioned - // by the python version, which would have been handled by the version split - // mutator. This is sufficient for very simple python_library modules under - // Bionic. +func (m *PythonLibraryModule) bp2buildPythonVersion(ctx android.TopDownMutatorContext) *string { py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, true) py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false) - var python_version *string if py2Enabled && !py3Enabled { - python_version = &pyVersion2 + return &pyVersion2 } else if !py2Enabled && py3Enabled { - python_version = &pyVersion3 + return &pyVersion3 } else if !py2Enabled && !py3Enabled { ctx.ModuleErrorf("bp2build converter doesn't understand having neither py2 nor py3 enabled") + return &pyVersion3 } else { - // do nothing, since python_version defaults to PY2ANDPY3 + return &pyVersion2And3 } +} - baseAttrs := m.makeArchVariantBaseAttributes(ctx) +type bazelPythonBinaryAttributes struct { + Main *bazel.Label + Srcs bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Python_version *string + Imports bazel.StringListAttribute +} + +func (p *PythonLibraryModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + // TODO(b/182306917): this doesn't fully handle all nested props versioned + // by the python version, which would have been handled by the version split + // mutator. This is sufficient for very simple python_library modules under + // Bionic. + baseAttrs := p.makeArchVariantBaseAttributes(ctx) + pyVersion := p.bp2buildPythonVersion(ctx) + if *pyVersion == pyVersion2And3 { + // Libraries default to python 2 and 3 + pyVersion = nil + } attrs := &bazelPythonLibraryAttributes{ Srcs: baseAttrs.Srcs, Deps: baseAttrs.Deps, - Srcs_version: python_version, + Srcs_version: pyVersion, Imports: baseAttrs.Imports, } @@ -151,56 +165,46 @@ func pythonLibBp2Build(ctx android.TopDownMutatorContext, m *PythonLibraryModule } ctx.CreateBazelTargetModule(props, android.CommonAttributes{ - Name: m.Name(), + Name: p.Name(), Data: baseAttrs.Data, }, attrs) } -type bazelPythonBinaryAttributes struct { - Main *bazel.Label - Srcs bazel.LabelListAttribute - Deps bazel.LabelListAttribute - Python_version *string - Imports bazel.StringListAttribute -} - -func pythonBinaryBp2Build(ctx android.TopDownMutatorContext, m *PythonBinaryModule) { +func (p *PythonBinaryModule) bp2buildBinaryProperties(ctx android.TopDownMutatorContext) (*bazelPythonBinaryAttributes, bazel.LabelListAttribute) { // TODO(b/182306917): this doesn't fully handle all nested props versioned // by the python version, which would have been handled by the version split // mutator. This is sufficient for very simple python_binary_host modules // under Bionic. - py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, false) - py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false) - var python_version *string - if py3Enabled && py2Enabled { - panic(fmt.Errorf( - "error for '%s' module: bp2build's python_binary_host converter does not support "+ - "converting a module that is enabled for both Python 2 and 3 at the same time.", m.Name())) - } else if py2Enabled { - python_version = &pyVersion2 - } else { - // do nothing, since python_version defaults to PY3. + + baseAttrs := p.makeArchVariantBaseAttributes(ctx) + pyVersion := p.bp2buildPythonVersion(ctx) + if *pyVersion == pyVersion3 { + // Binaries default to python 3 + pyVersion = nil + } else if *pyVersion == pyVersion2And3 { + ctx.ModuleErrorf("error for '%s' module: bp2build's python_binary_host converter "+ + "does not support converting a module that is enabled for both Python 2 and 3 at the "+ + "same time.", p.Name()) } - baseAttrs := m.makeArchVariantBaseAttributes(ctx) attrs := &bazelPythonBinaryAttributes{ Main: nil, Srcs: baseAttrs.Srcs, Deps: baseAttrs.Deps, - Python_version: python_version, + Python_version: pyVersion, Imports: baseAttrs.Imports, } - for _, propIntf := range m.GetProperties() { - if props, ok := propIntf.(*BinaryProperties); ok { - // main is optional. - if props.Main != nil { - main := android.BazelLabelForModuleSrcSingle(ctx, *props.Main) - attrs.Main = &main - break - } - } + // main is optional. + if p.binaryProperties.Main != nil { + main := android.BazelLabelForModuleSrcSingle(ctx, *p.binaryProperties.Main) + attrs.Main = &main } + return attrs, baseAttrs.Data +} + +func (p *PythonBinaryModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + attrs, data := p.bp2buildBinaryProperties(ctx) props := bazel.BazelTargetModuleProperties{ // Use the native py_binary rule. @@ -208,19 +212,22 @@ func pythonBinaryBp2Build(ctx android.TopDownMutatorContext, m *PythonBinaryModu } ctx.CreateBazelTargetModule(props, android.CommonAttributes{ - Name: m.Name(), - Data: baseAttrs.Data, + Name: p.Name(), + Data: data, }, attrs) } -func (p *PythonLibraryModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { - pythonLibBp2Build(ctx, p) -} +func (p *PythonTestModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + // Python tests are currently exactly the same as binaries, but with a different module type + attrs, data := p.bp2buildBinaryProperties(ctx) -func (p *PythonBinaryModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { - pythonBinaryBp2Build(ctx, p) -} + props := bazel.BazelTargetModuleProperties{ + // Use the native py_binary rule. + Rule_class: "py_test", + } -func (p *PythonTestModule) ConvertWithBp2build(_ android.TopDownMutatorContext) { - // Tests are currently unsupported + ctx.CreateBazelTargetModule(props, android.CommonAttributes{ + Name: p.Name(), + Data: data, + }, attrs) } diff --git a/python/python.go b/python/python.go index c7c523dfb..1a129737a 100644 --- a/python/python.go +++ b/python/python.go @@ -239,6 +239,7 @@ var ( protoExt = ".proto" pyVersion2 = "PY2" pyVersion3 = "PY3" + pyVersion2And3 = "PY2ANDPY3" internalPath = "internal" ) diff --git a/rust/binary.go b/rust/binary.go index 056888ef2..2de92c17f 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -72,11 +72,14 @@ func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { flags = binary.baseCompiler.compilerFlags(ctx, flags) + if ctx.Os().Linux() { + flags.LinkFlags = append(flags.LinkFlags, "-Wl,--gc-sections") + } + if ctx.toolchain().Bionic() { // no-undefined-version breaks dylib compilation since __rust_*alloc* functions aren't defined, // but we can apply this to binaries. flags.LinkFlags = append(flags.LinkFlags, - "-Wl,--gc-sections", "-Wl,-z,nocopyreloc", "-Wl,--no-undefined-version") @@ -136,7 +139,7 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) - flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...) + flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...) if binary.stripper.NeedsStrip(ctx) { strippedOutputFile := outputFile diff --git a/rust/binary_test.go b/rust/binary_test.go index 7dac2490a..dd4f99314 100644 --- a/rust/binary_test.go +++ b/rust/binary_test.go @@ -123,7 +123,7 @@ func TestBootstrap(t *testing.T) { bootstrap: true, }`) - foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc") + foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustLink") flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64" if !strings.Contains(foo.Args["linkFlags"], flag) { @@ -140,10 +140,11 @@ func TestStaticBinaryFlags(t *testing.T) { }`) fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc") + fizzOutLink := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustLink") fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module) flags := fizzOut.Args["rustcFlags"] - linkFlags := fizzOut.Args["linkFlags"] + linkFlags := fizzOutLink.Args["linkFlags"] if !strings.Contains(flags, "-C relocation-model=static") { t.Errorf("static binary missing '-C relocation-model=static' in rustcFlags, found: %#v", flags) } @@ -173,7 +174,7 @@ func TestLinkObjects(t *testing.T) { name: "libfoo", }`) - fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustc") + fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustLink") linkFlags := fizzBuzz.Args["linkFlags"] if !strings.Contains(linkFlags, "/libfoo.so") { t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags) diff --git a/rust/builder.go b/rust/builder.go index 0aef13d44..0aa2225f7 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -26,14 +26,14 @@ import ( var ( _ = pctx.SourcePathVariable("rustcCmd", "${config.RustBin}/rustc") + _ = pctx.SourcePathVariable("mkcraterspCmd", "build/soong/scripts/mkcratersp.py") rustc = pctx.AndroidStaticRule("rustc", blueprint.RuleParams{ Command: "$envVars $rustcCmd " + - "-C linker=${config.RustLinker} " + - "-C link-args=\"${crtBegin} ${config.RustLinkerArgs} ${linkFlags} ${crtEnd}\" " + + "-C linker=$mkcraterspCmd " + "--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" + " && grep \"^$out:\" $out.d.raw > $out.d", - CommandDeps: []string{"$rustcCmd"}, + CommandDeps: []string{"$rustcCmd", "$mkcraterspCmd"}, // Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633 // Rustc emits unneeded dependency lines for the .d and input .rs files. // Those extra lines cause ninja warning: @@ -42,7 +42,12 @@ var ( Deps: blueprint.DepsGCC, Depfile: "$out.d", }, - "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars") + "rustcFlags", "libFlags", "envVars") + rustLink = pctx.AndroidStaticRule("rustLink", + blueprint.RuleParams{ + Command: "${config.RustLinker} -o $out ${crtBegin} ${config.RustLinkerArgs} @$in ${linkFlags} ${crtEnd}", + }, + "linkFlags", "crtBegin", "crtEnd") _ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc") rustdoc = pctx.AndroidStaticRule("rustdoc", @@ -101,14 +106,13 @@ var ( `KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` + `$rustExtractor $envVars ` + `$rustcCmd ` + - `-C linker=${config.RustLinker} ` + - `-C link-args="${crtBegin} ${config.RustLinkerArgs} ${linkFlags} ${crtEnd}" ` + + `-C linker=true ` + `$in ${libFlags} $rustcFlags`, CommandDeps: []string{"$rustExtractor", "$kytheVnames"}, Rspfile: "${out}.rsp", RspfileContent: "$in", }, - "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars") + "rustcFlags", "libFlags", "envVars") ) type buildOutput struct { @@ -220,11 +224,9 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl outputFile android.WritablePath, crateType string) buildOutput { var inputs android.Paths - var implicits android.Paths - var orderOnly android.Paths + var implicits, linkImplicits, linkOrderOnly android.Paths var output buildOutput var rustcFlags, linkFlags []string - var implicitOutputs android.WritablePaths output.outputFile = outputFile crateName := ctx.RustModule().CrateName() @@ -281,15 +283,15 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl implicits = append(implicits, rustLibsToPaths(deps.RLibs)...) implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...) implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...) - implicits = append(implicits, deps.StaticLibs...) - implicits = append(implicits, deps.SharedLibDeps...) - implicits = append(implicits, deps.srcProviderFiles...) implicits = append(implicits, deps.AfdoProfiles...) + implicits = append(implicits, deps.srcProviderFiles...) + implicits = append(implicits, deps.WholeStaticLibs...) - implicits = append(implicits, deps.CrtBegin...) - implicits = append(implicits, deps.CrtEnd...) + linkImplicits = append(linkImplicits, deps.LibDeps...) + linkImplicits = append(linkImplicits, deps.CrtBegin...) + linkImplicits = append(linkImplicits, deps.CrtEnd...) - orderOnly = append(orderOnly, deps.SharedLibs...) + linkOrderOnly = append(linkOrderOnly, deps.linkObjects...) if len(deps.SrcDeps) > 0 { moduleGenDir := ctx.RustModule().compiler.CargoOutDir() @@ -328,16 +330,16 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl } } + envVars = append(envVars, "AR=${cc_config.ClangBin}/llvm-ar") + if flags.Clippy { clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy") ctx.Build(pctx, android.BuildParams{ - Rule: clippyDriver, - Description: "clippy " + main.Rel(), - Output: clippyFile, - ImplicitOutputs: nil, - Inputs: inputs, - Implicits: implicits, - OrderOnly: orderOnly, + Rule: clippyDriver, + Description: "clippy " + main.Rel(), + Output: clippyFile, + Inputs: inputs, + Implicits: implicits, Args: map[string]string{ "rustcFlags": strings.Join(rustcFlags, " "), "libFlags": strings.Join(libFlags, " "), @@ -349,24 +351,41 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl implicits = append(implicits, clippyFile) } + rustcOutputFile := outputFile + usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro" + if usesLinker { + rustcOutputFile = android.PathForModuleOut(ctx, outputFile.Base()+".rsp") + } + ctx.Build(pctx, android.BuildParams{ - Rule: rustc, - Description: "rustc " + main.Rel(), - Output: outputFile, - ImplicitOutputs: implicitOutputs, - Inputs: inputs, - Implicits: implicits, - OrderOnly: orderOnly, + Rule: rustc, + Description: "rustc " + main.Rel(), + Output: rustcOutputFile, + Inputs: inputs, + Implicits: implicits, Args: map[string]string{ "rustcFlags": strings.Join(rustcFlags, " "), - "linkFlags": strings.Join(linkFlags, " "), "libFlags": strings.Join(libFlags, " "), - "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "), - "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "), "envVars": strings.Join(envVars, " "), }, }) + if usesLinker { + ctx.Build(pctx, android.BuildParams{ + Rule: rustLink, + Description: "rustLink " + main.Rel(), + Output: outputFile, + Inputs: android.Paths{rustcOutputFile}, + Implicits: linkImplicits, + OrderOnly: linkOrderOnly, + Args: map[string]string{ + "linkFlags": strings.Join(linkFlags, " "), + "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "), + "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "), + }, + }) + } + if flags.EmitXrefs { kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip") ctx.Build(pctx, android.BuildParams{ @@ -375,13 +394,9 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl Output: kytheFile, Inputs: inputs, Implicits: implicits, - OrderOnly: orderOnly, Args: map[string]string{ "rustcFlags": strings.Join(rustcFlags, " "), - "linkFlags": strings.Join(linkFlags, " "), "libFlags": strings.Join(libFlags, " "), - "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "), - "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "), "envVars": strings.Join(envVars, " "), }, }) diff --git a/rust/config/global.go b/rust/config/global.go index 88949386c..2d1f0c1f9 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -104,7 +104,7 @@ func init() { pctx.ImportAs("cc_config", "android/soong/cc/config") pctx.StaticVariable("RustLinker", "${cc_config.ClangBin}/clang++") - pctx.StaticVariable("RustLinkerArgs", "") + pctx.StaticVariable("RustLinkerArgs", "-Wl,--as-needed") pctx.StaticVariable("DeviceGlobalLinkFlags", strings.Join(deviceGlobalLinkFlags, " ")) diff --git a/rust/coverage.go b/rust/coverage.go index bc6504ddc..5216d6098 100644 --- a/rust/coverage.go +++ b/rust/coverage.go @@ -65,7 +65,7 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags "-C instrument-coverage", "-g") flags.LinkFlags = append(flags.LinkFlags, profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open") - deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path()) + deps.LibDeps = append(deps.LibDeps, coverage.OutputFile().Path()) // no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency. if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() { diff --git a/rust/coverage_test.go b/rust/coverage_test.go index 0f599d745..64077cf00 100644 --- a/rust/coverage_test.go +++ b/rust/coverage_test.go @@ -55,6 +55,10 @@ func TestCoverageFlags(t *testing.T) { libbarNoCov := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc") fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc") buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc") + libfooCovLink := ctx.ModuleForTests("libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustLink") + libbarNoCovLink := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustLink") + fizzCovLink := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustLink") + buzzNoCovLink := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustLink") rustcCoverageFlags := []string{"-C instrument-coverage", " -g "} for _, flag := range rustcCoverageFlags { @@ -80,17 +84,17 @@ func TestCoverageFlags(t *testing.T) { missingErrorStr := "missing rust linker flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v" containsErrorStr := "contains rust linker flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v" - if !strings.Contains(fizzCov.Args["linkFlags"], flag) { - t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCov.Args["linkFlags"]) + if !strings.Contains(fizzCovLink.Args["linkFlags"], flag) { + t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCovLink.Args["linkFlags"]) } - if !strings.Contains(libfooCov.Args["linkFlags"], flag) { - t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCov.Args["linkFlags"]) + if !strings.Contains(libfooCovLink.Args["linkFlags"], flag) { + t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCovLink.Args["linkFlags"]) } - if strings.Contains(buzzNoCov.Args["linkFlags"], flag) { - t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCov.Args["linkFlags"]) + if strings.Contains(buzzNoCovLink.Args["linkFlags"], flag) { + t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCovLink.Args["linkFlags"]) } - if strings.Contains(libbarNoCov.Args["linkFlags"], flag) { - t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCov.Args["linkFlags"]) + if strings.Contains(libbarNoCovLink.Args["linkFlags"], flag) { + t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCovLink.Args["linkFlags"]) } } @@ -103,7 +107,7 @@ func TestCoverageDeps(t *testing.T) { srcs: ["foo.rs"], }`) - fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustc") + fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustLink") if !strings.Contains(fizz.Args["linkFlags"], "libprofile-clang-extras.a") { t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.Args["linkFlags"]) } diff --git a/rust/library.go b/rust/library.go index bc9c9aa38..a3a567281 100644 --- a/rust/library.go +++ b/rust/library.go @@ -520,7 +520,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) - flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...) + flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...) if library.dylib() { // We need prefer-dynamic for now to avoid linking in the static stdlib. See: @@ -543,6 +543,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa if library.rlib() || library.dylib() { library.flagExporter.exportLinkDirs(deps.linkDirs...) library.flagExporter.exportLinkObjects(deps.linkObjects...) + library.flagExporter.exportLibDeps(deps.LibDeps...) } if library.static() || library.shared() { diff --git a/rust/library_test.go b/rust/library_test.go index e3e4d0f03..d4b525f2e 100644 --- a/rust/library_test.go +++ b/rust/library_test.go @@ -148,7 +148,7 @@ func TestSharedLibrary(t *testing.T) { libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared") - libfooOutput := libfoo.Rule("rustc") + libfooOutput := libfoo.Rule("rustLink") if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") { t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v", libfooOutput.Args["linkFlags"]) diff --git a/rust/rust.go b/rust/rust.go index 56b463160..7b520cdb0 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -420,13 +420,12 @@ type Deps struct { } type PathDeps struct { - DyLibs RustLibraries - RLibs RustLibraries - SharedLibs android.Paths - SharedLibDeps android.Paths - StaticLibs android.Paths - ProcMacros RustLibraries - AfdoProfiles android.Paths + DyLibs RustLibraries + RLibs RustLibraries + LibDeps android.Paths + WholeStaticLibs android.Paths + ProcMacros RustLibraries + AfdoProfiles android.Paths // depFlags and depLinkFlags are rustc and linker (clang) flags. depFlags []string @@ -435,7 +434,7 @@ type PathDeps struct { // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker. // Both of these are exported and propagate to dependencies. linkDirs []string - linkObjects []string + linkObjects android.Paths // Used by bindgen modules which call clang depClangFlags []string @@ -498,7 +497,7 @@ type compiler interface { type exportedFlagsProducer interface { exportLinkDirs(...string) - exportLinkObjects(...string) + exportLinkObjects(...android.Path) } type xref interface { @@ -507,21 +506,27 @@ type xref interface { type flagExporter struct { linkDirs []string - linkObjects []string + linkObjects android.Paths + libDeps android.Paths } func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) { flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...)) } -func (flagExporter *flagExporter) exportLinkObjects(flags ...string) { - flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...)) +func (flagExporter *flagExporter) exportLinkObjects(flags ...android.Path) { + flagExporter.linkObjects = android.FirstUniquePaths(append(flagExporter.linkObjects, flags...)) +} + +func (flagExporter *flagExporter) exportLibDeps(paths ...android.Path) { + flagExporter.libDeps = android.FirstUniquePaths(append(flagExporter.libDeps, paths...)) } func (flagExporter *flagExporter) setProvider(ctx ModuleContext) { ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{ LinkDirs: flagExporter.linkDirs, LinkObjects: flagExporter.linkObjects, + LibDeps: flagExporter.libDeps, }) } @@ -534,7 +539,8 @@ func NewFlagExporter() *flagExporter { type FlagExporterInfo struct { Flags []string LinkDirs []string // TODO: this should be android.Paths - LinkObjects []string // TODO: this should be android.Paths + LinkObjects android.Paths + LibDeps android.Paths } var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{}) @@ -1250,6 +1256,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...) depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...) depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...) + depPaths.LibDeps = append(depPaths.LibDeps, exportedInfo.LibDeps...) } if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { @@ -1293,6 +1300,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", linkObject.Path().String(), "-Wl,--no-whole-archive"}...) } else if libName, ok := libNameFromFilePath(linkObject.Path()); ok { depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName) + depPaths.WholeStaticLibs = append(depPaths.WholeStaticLibs, linkObject.Path()) } else { ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName()) } @@ -1300,7 +1308,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Add this to linkObjects to pass the library directly to the linker as well. This propagates // to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant. - depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String()) + depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...) depPaths.linkDirs = append(depPaths.linkDirs, linkPath) exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo) @@ -1326,7 +1334,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { linkPath = linkPathFromFilePath(linkObject.Path()) depPaths.linkDirs = append(depPaths.linkDirs, linkPath) - depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String()) + depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...) depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) @@ -1352,7 +1360,9 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Make sure these dependencies are propagated if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep { lib.exportLinkDirs(linkPath) - lib.exportLinkObjects(linkObject.String()) + if linkObject.Valid() { + lib.exportLinkObjects(linkObject.Path()) + } } } else { switch { @@ -1384,19 +1394,16 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) } - var staticLibDepFiles android.Paths + var libDepFiles android.Paths for _, dep := range directStaticLibDeps { - staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path()) + libDepFiles = append(libDepFiles, dep.OutputFile().Path()) } - var sharedLibFiles android.Paths - var sharedLibDepFiles android.Paths for _, dep := range directSharedLibDeps { - sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary) if dep.TableOfContents.Valid() { - sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path()) + libDepFiles = append(libDepFiles, dep.TableOfContents.Path()) } else { - sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary) + libDepFiles = append(libDepFiles, dep.SharedLibrary) } } @@ -1412,15 +1419,13 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...) depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...) - depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibFiles...) - depPaths.SharedLibDeps = append(depPaths.SharedLibDeps, sharedLibDepFiles...) - depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...) + depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...) depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...) depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...) // Dedup exported flags from dependencies depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs) - depPaths.linkObjects = android.FirstUniqueStrings(depPaths.linkObjects) + depPaths.linkObjects = android.FirstUniquePaths(depPaths.linkObjects) depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags) depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags) depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths) diff --git a/rust/rust_test.go b/rust/rust_test.go index e8e58009b..2a38b8983 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -258,6 +258,7 @@ func TestDepsTracking(t *testing.T) { `) module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module) rustc := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc") + rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustLink") // Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up. if !android.InList("libdylib", module.Properties.AndroidMkDylibs) { @@ -284,16 +285,16 @@ func TestDepsTracking(t *testing.T) { t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"]) } - if !strings.Contains(rustc.Args["linkFlags"], "cc_stubs_dep.so") { - t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustc.Args["linkFlags"]) + if !strings.Contains(rustLink.Args["linkFlags"], "cc_stubs_dep.so") { + t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.Args["linkFlags"]) } - if !android.SuffixInList(rustc.OrderOnly.Strings(), "cc_stubs_dep.so") { - t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustc.OrderOnly.Strings()) + if !android.SuffixInList(rustLink.OrderOnly.Strings(), "cc_stubs_dep.so") { + t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustLink.OrderOnly.Strings()) } - if !android.SuffixInList(rustc.Implicits.Strings(), "cc_stubs_dep.so.toc") { - t.Errorf("shared cc dep TOC not being passed as implicit to rustc %#v", rustc.Implicits.Strings()) + if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so.toc") { + t.Errorf("shared cc dep TOC not being passed as implicit to rustc %#v", rustLink.Implicits.Strings()) } } diff --git a/rust/sanitize_test.go b/rust/sanitize_test.go index d6a14b295..43e95f477 100644 --- a/rust/sanitize_test.go +++ b/rust/sanitize_test.go @@ -35,7 +35,7 @@ func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNo note_sync := "note_memtag_heap_sync" found := None - implicits := m.Rule("rustc").Implicits + implicits := m.Rule("rustLink").Implicits for _, lib := range implicits { if strings.Contains(lib.Rel(), note_async) { found = Async diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go index e1b3c86a2..2e7a33027 100644 --- a/rust/vendor_snapshot_test.go +++ b/rust/vendor_snapshot_test.go @@ -941,7 +941,7 @@ func TestVendorSnapshotUse(t *testing.T) { ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31") // libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot - libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustc").Args["linkFlags"] + libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustLink").Args["linkFlags"] for _, input := range [][]string{ []string{sharedVariant, "libvndk.vndk.30.arm64"}, []string{staticVariant, "libvendor.vendor_static.30.arm64"}, @@ -997,7 +997,7 @@ func TestVendorSnapshotUse(t *testing.T) { t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkRlibName, expectedRustVendorSnapshotName) } - binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").Args["linkFlags"] + binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustLink").Args["linkFlags"] libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"}) if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) { t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v", diff --git a/scripts/Android.bp b/scripts/Android.bp index 26fe432c6..9367ff06a 100644 --- a/scripts/Android.bp +++ b/scripts/Android.bp @@ -189,6 +189,7 @@ python_binary_host { libs: [ "linker_config_proto", ], + visibility: ["//system/linkerconfig"], } python_test_host { diff --git a/scripts/mkcratersp.py b/scripts/mkcratersp.py new file mode 100755 index 000000000..86b4aa3fb --- /dev/null +++ b/scripts/mkcratersp.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2023 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. +# + +""" +This script is used as a replacement for the Rust linker. It converts a linker +command line into a rspfile that can be used during the link phase. +""" + +import os +import shutil +import subprocess +import sys + +def create_archive(out, objects, archives): + mricmd = f'create {out}\n' + for o in objects: + mricmd += f'addmod {o}\n' + for a in archives: + mricmd += f'addlib {a}\n' + mricmd += 'save\nend\n' + subprocess.run([os.getenv('AR'), '-M'], encoding='utf-8', input=mricmd, check=True) + +objects = [] +archives = [] +linkdirs = [] +libs = [] +temp_archives = [] +version_script = None + +for i, arg in enumerate(sys.argv): + if arg == '-o': + out = sys.argv[i+1] + if arg == '-L': + linkdirs.append(sys.argv[i+1]) + if arg.startswith('-l') or arg == '-shared': + libs.append(arg) + if arg.startswith('-Wl,--version-script='): + version_script = arg[21:] + if arg[0] == '-': + continue + if arg.endswith('.o') or arg.endswith('.rmeta'): + objects.append(arg) + if arg.endswith('.rlib'): + if arg.startswith(os.getenv('TMPDIR')): + temp_archives.append(arg) + else: + archives.append(arg) + +create_archive(f'{out}.whole.a', objects, []) +create_archive(f'{out}.a', [], temp_archives) + +with open(out, 'w') as f: + print(f'-Wl,--whole-archive', file=f) + print(f'{out}.whole.a', file=f) + print(f'-Wl,--no-whole-archive', file=f) + print(f'{out}.a', file=f) + for a in archives: + print(a, file=f) + for linkdir in linkdirs: + print(f'-L{linkdir}', file=f) + for l in libs: + print(l, file=f) + if version_script: + shutil.copyfile(version_script, f'{out}.version_script') + print(f'-Wl,--version-script={out}.version_script', file=f) diff --git a/starlark_fmt/format.go b/starlark_fmt/format.go index 064fc2169..a97f71b87 100644 --- a/starlark_fmt/format.go +++ b/starlark_fmt/format.go @@ -35,7 +35,11 @@ func Indention(level int) string { // PrintBool returns a Starlark compatible bool string. func PrintBool(item bool) string { - return strings.Title(fmt.Sprintf("%t", item)) + if item { + return "True" + } else { + return "False" + } } // PrintsStringList returns a Starlark-compatible string of a list of Strings/Labels. diff --git a/tests/mixed_mode_test.sh b/tests/mixed_mode_test.sh index 7b3151bfd..05d3a664f 100755 --- a/tests/mixed_mode_test.sh +++ b/tests/mixed_mode_test.sh @@ -63,4 +63,37 @@ EOF fi } +function test_force_enabled_modules { + setup + # b/273910287 - test force enable modules + mkdir -p soong_tests/a/b + cat > soong_tests/a/b/Android.bp <<'EOF' +genrule { + name: "touch-file", + out: ["fake-out.txt"], + cmd: "touch $(out)", + bazel_module: { bp2build_available: true }, +} + +genrule { + name: "unenabled-touch-file", + out: ["fake-out2.txt"], + cmd: "touch $(out)", + bazel_module: { bp2build_available: false }, +} +EOF + run_soong --bazel-mode-staging --bazel-force-enabled-modules=touch-file nothing + local bazel_contained=`grep out/soong/.intermediates/soong_tests/a/b/touch-file/gen/fake-out.txt out/soong/build.ninja` + if [[ $bazel_contained == '' ]]; then + fail "Bazel actions not found for force-enabled module" + fi + + local exit_code=`run_soong --bazel-force-enabled-modules=unenabled-touch-file nothing` + + if [[ $exit_code -ne 1 ]]; then + fail "Expected failure due to force-enabling an unenabled module " + fi +} + + scan_and_run_tests
\ No newline at end of file diff --git a/ui/build/build.go b/ui/build/build.go index edc595d16..6874ef74d 100644 --- a/ui/build/build.go +++ b/ui/build/build.go @@ -259,10 +259,16 @@ func Build(ctx Context, config Config) { startGoma(ctx, config) } + rbeCh := make(chan bool) if config.StartRBE() { cleanupRBELogsDir(ctx, config) - startRBE(ctx, config) + go func() { + startRBE(ctx, config) + close(rbeCh) + }() defer DumpRBEMetrics(ctx, config, filepath.Join(config.LogsDir(), "rbe_metrics.pb")) + } else { + close(rbeCh) } if what&RunProductConfig != 0 { @@ -315,11 +321,11 @@ func Build(ctx Context, config Config) { testForDanglingRules(ctx, config) } + <-rbeCh if what&RunNinja != 0 { if what&RunKati != 0 { installCleanIfNecessary(ctx, config) } - runNinjaForBuild(ctx, config) } diff --git a/ui/build/config.go b/ui/build/config.go index a755d14fd..bf4aec9b9 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -1374,6 +1374,15 @@ func (c *configImpl) rbeProxyLogsDir() string { return filepath.Join(buildTmpDir, "rbe") } +func (c *configImpl) rbeCacheDir() string { + for _, f := range []string{"RBE_cache_dir", "FLAG_cache_dir"} { + if v, ok := c.environ.Get(f); ok { + return v + } + } + return shared.JoinPath(c.SoongOutDir(), "rbe") +} + func (c *configImpl) shouldCleanupRBELogsDir() bool { // Perform a log directory cleanup only when the log directory // is auto created by the build rather than user-specified. diff --git a/ui/build/rbe.go b/ui/build/rbe.go index 1d1721623..6479925dd 100644 --- a/ui/build/rbe.go +++ b/ui/build/rbe.go @@ -60,6 +60,7 @@ func getRBEVars(ctx Context, config Config) map[string]string { "RBE_exec_root": config.rbeExecRoot(), "RBE_output_dir": config.rbeProxyLogsDir(), "RBE_proxy_log_dir": config.rbeProxyLogsDir(), + "RBE_cache_dir": config.rbeCacheDir(), "RBE_platform": "container-image=" + remoteexec.DefaultImage, } if config.StartRBE() { |