diff options
83 files changed, 1470 insertions, 481 deletions
@@ -105,31 +105,35 @@ Android.bp files can contain C-style multiline `/* */` and C++ style single-line ### Types -Variables and properties are strongly typed, variables dynamically based on the -first assignment, and properties statically by the module type. The supported -types are: +Variables and properties are strongly typed. Variables are dynamically typed +based on the first assignment, and properties are statically typed by the +module type. The supported types are: * Bool (`true` or `false`) * Integers (`int`) * Strings (`"string"`) * Lists of strings (`["string1", "string2"]`) * Maps (`{key1: "value1", key2: ["value2"]}`) -Maps may values of any type, including nested maps. Lists and maps may have -trailing commas after the last value. +Maps may contain values of any type, including nested maps. Lists and maps may +have trailing commas after the last value. Strings can contain double quotes using `\"`, for example `"cat \"a b\""`. ### Operators -Strings, lists of strings, and maps can be appended using the `+` operator. -Integers can be summed up using the `+` operator. Appending a map produces the -union of keys in both maps, appending the values of any keys that are present -in both maps. +The `+` operator: +* Sums integers. +* Concatenates strings and lists. +* Produces the union of maps. + +Concatenating maps produces a map whose keys are the union of the given maps' +keys, and whose mapped values are the union of the given maps' corresponding +mapped values. ### Defaults modules -A defaults module can be used to repeat the same properties in multiple modules. -For example: +A `defaults` module can be used to repeat the same properties in multiple +modules. For example: ``` cc_defaults { @@ -184,7 +188,7 @@ the same `.bp` file as the `package` module) to be visible to all the subpackage ``` package { - default_visibility: [":__subpackages"] + default_visibility: [":__subpackages__"] } ``` diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index e9e649c2f..eea3fb629 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -219,48 +219,51 @@ var ( "frameworks/native/services/batteryservice": Bp2BuildDefaultTrue, "frameworks/proto_logging/stats": Bp2BuildDefaultTrueRecursively, - "hardware/interfaces": Bp2BuildDefaultTrue, - "hardware/interfaces/audio/aidl": Bp2BuildDefaultTrue, - "hardware/interfaces/audio/aidl/common": Bp2BuildDefaultTrue, - "hardware/interfaces/bufferpool/aidl": Bp2BuildDefaultTrue, - "hardware/interfaces/common/aidl": Bp2BuildDefaultTrue, - "hardware/interfaces/common/fmq/aidl": Bp2BuildDefaultTrue, - "hardware/interfaces/configstore/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/configstore/1.1": Bp2BuildDefaultTrue, - "hardware/interfaces/configstore/utils": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/allocator/2.0": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/allocator/3.0": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/allocator/4.0": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/allocator/aidl": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/bufferqueue/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/bufferqueue/2.0": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/common/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/common/1.1": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/common/1.2": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/common/aidl": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/mapper/2.0": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/mapper/2.1": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/mapper/3.0": Bp2BuildDefaultTrue, - "hardware/interfaces/graphics/mapper/4.0": Bp2BuildDefaultTrue, - "hardware/interfaces/health/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/health/1.0/default": Bp2BuildDefaultTrue, - "hardware/interfaces/health/2.0": Bp2BuildDefaultTrue, - "hardware/interfaces/health/2.0/default": Bp2BuildDefaultTrue, - "hardware/interfaces/health/2.0/utils": Bp2BuildDefaultTrueRecursively, - "hardware/interfaces/health/2.1": Bp2BuildDefaultTrue, - "hardware/interfaces/health/aidl": Bp2BuildDefaultTrue, - "hardware/interfaces/health/utils": Bp2BuildDefaultTrueRecursively, - "hardware/interfaces/media/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/media/bufferpool/2.0": Bp2BuildDefaultTrue, - "hardware/interfaces/media/c2/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/media/c2/1.1": Bp2BuildDefaultTrue, - "hardware/interfaces/media/c2/1.2": Bp2BuildDefaultTrue, - "hardware/interfaces/media/omx/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/neuralnetworks/1.0": Bp2BuildDefaultTrue, - "hardware/interfaces/neuralnetworks/1.1": Bp2BuildDefaultTrue, - "hardware/interfaces/neuralnetworks/1.2": Bp2BuildDefaultTrue, - "hardware/interfaces/neuralnetworks/1.3": Bp2BuildDefaultTrue, - "hardware/interfaces/neuralnetworks/aidl": Bp2BuildDefaultTrue, + "hardware/interfaces": Bp2BuildDefaultTrue, + "hardware/interfaces/audio/aidl": Bp2BuildDefaultTrue, + "hardware/interfaces/audio/aidl/common": Bp2BuildDefaultTrue, + "hardware/interfaces/common/aidl": Bp2BuildDefaultTrue, + "hardware/interfaces/common/fmq/aidl": Bp2BuildDefaultTrue, + "hardware/interfaces/common/support": Bp2BuildDefaultTrue, + "hardware/interfaces/configstore/1.0": Bp2BuildDefaultTrue, + "hardware/interfaces/configstore/1.1": Bp2BuildDefaultTrue, + "hardware/interfaces/configstore/utils": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/allocator/2.0": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/allocator/3.0": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/allocator/4.0": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/allocator/aidl": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/bufferqueue/1.0": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/bufferqueue/2.0": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/common/1.0": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/common/1.1": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/common/1.2": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/common/aidl": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/mapper/2.0": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/mapper/2.1": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/mapper/3.0": Bp2BuildDefaultTrue, + "hardware/interfaces/graphics/mapper/4.0": Bp2BuildDefaultTrue, + "hardware/interfaces/health/1.0": Bp2BuildDefaultTrue, + "hardware/interfaces/health/1.0/default": Bp2BuildDefaultTrue, + "hardware/interfaces/health/2.0": Bp2BuildDefaultTrue, + "hardware/interfaces/health/2.0/default": Bp2BuildDefaultTrue, + "hardware/interfaces/health/2.0/utils": Bp2BuildDefaultTrueRecursively, + "hardware/interfaces/health/2.1": Bp2BuildDefaultTrue, + "hardware/interfaces/health/aidl": Bp2BuildDefaultTrue, + "hardware/interfaces/health/utils": Bp2BuildDefaultTrueRecursively, + "hardware/interfaces/media/1.0": Bp2BuildDefaultTrue, + "hardware/interfaces/media/bufferpool": Bp2BuildDefaultTrueRecursively, + "hardware/interfaces/media/bufferpool/aidl/default/tests": Bp2BuildDefaultFalseRecursively, + "hardware/interfaces/media/c2/1.0": Bp2BuildDefaultTrue, + "hardware/interfaces/media/c2/1.1": Bp2BuildDefaultTrue, + "hardware/interfaces/media/c2/1.2": Bp2BuildDefaultTrue, + "hardware/interfaces/media/omx/1.0": Bp2BuildDefaultTrue, + "hardware/interfaces/neuralnetworks": Bp2BuildDefaultTrueRecursively, + "hardware/interfaces/neuralnetworks/aidl/vts": Bp2BuildDefaultFalseRecursively, + "hardware/interfaces/neuralnetworks/1.0/vts": Bp2BuildDefaultFalseRecursively, + "hardware/interfaces/neuralnetworks/1.1/vts": Bp2BuildDefaultFalseRecursively, + "hardware/interfaces/neuralnetworks/1.2/vts": Bp2BuildDefaultFalseRecursively, + "hardware/interfaces/neuralnetworks/1.3/vts": Bp2BuildDefaultFalseRecursively, + "hardware/interfaces/neuralnetworks/1.4/vts": Bp2BuildDefaultFalseRecursively, "libnativehelper": Bp2BuildDefaultTrueRecursively, @@ -280,6 +283,7 @@ var ( "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively, "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively, "packages/modules/NetworkStack/common/captiveportal": Bp2BuildDefaultTrue, + "packages/modules/NeuralNetworks/apex": Bp2BuildDefaultTrue, "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultFalse, // TODO(b/242834374) "packages/screensavers/Basic": Bp2BuildDefaultTrue, "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321) @@ -432,16 +436,11 @@ var ( "com.android.media.swcodec-mediaswcodec.rc", "com.android.media.swcodec.certificate", "com.android.media.swcodec.key", - "com.android.neuralnetworks", - "com.android.neuralnetworks-androidManifest", - "com.android.neuralnetworks.certificate", - "com.android.neuralnetworks.key", "flatbuffer_headers", "framework-connectivity-protos", "gemmlowp_headers", "gl_headers", "ipconnectivity-proto-src", - "libaidlcommonsupport", "libandroid_runtime_lazy", "libandroid_runtime_vm_headers", "libaudioclient_aidl_conversion_util", @@ -503,13 +502,6 @@ var ( "mediaswcodec.policy", "mediaswcodec.xml", "neuralnetworks_types", - "neuralnetworks_utils_hal_aidl", - "neuralnetworks_utils_hal_common", - "neuralnetworks_utils_hal_service", - "neuralnetworks_utils_hal_1_0", - "neuralnetworks_utils_hal_1_1", - "neuralnetworks_utils_hal_1_2", - "neuralnetworks_utils_hal_1_3", "libneuralnetworks_common", // packagemanager_aidl_interface is created implicitly in packagemanager_aidl module "packagemanager_aidl_interface", @@ -712,6 +704,10 @@ var ( // for building com.android.neuralnetworks "libimapper_stablec", "libimapper_providerutils", + + // min_sdk_version in android_app + "CtsShimUpgrade", + "fake-framework", } Bp2buildModuleTypeAlwaysConvertList = []string{ @@ -734,15 +730,6 @@ var ( // the "prebuilt_" prefix to the name, so that it's differentiable from // the source versions within Soong's module graph. Bp2buildModuleDoNotConvertList = []string{ - // TODO(b/250876486): Created cc_aidl_library doesn't have static libs from parent cc module - "libgui_window_info_static", - "libgui", // Depends on unconverted libgui_window_info_static - "libdisplay", // Depends on uncovnerted libgui - // Depends on unconverted libdisplay - "libdvr_static.google", - "libdvr.google", - "libvrsensor", - "dvr_api-test", // Depends on unconverted libandroid, libgui "dvr_buffer_queue-test", "dvr_display-test", @@ -871,6 +858,9 @@ var ( "android.hardware.health-translate-java", // cc_test related. + // b/274164834 "Could not open Configuration file test.cfg" + "svcenc", "svcdec", + // Failing host cc_tests "memunreachable_unit_test", "libprocinfo_test", @@ -1420,25 +1410,29 @@ var ( "unwind", "unwind_info", "unwind_symbols", - "libc_malloc_debug", - "libfdtrack", - "mediaswcodec", - "libcodec2_hidl@1.0", "libEGL", - "libstagefright_bufferqueue_helper_novndk", "libGLESv2", + "libc_malloc_debug", + "libcodec2_hidl@1.0", "libcodec2_hidl@1.1", - "libmedia_codecserviceregistrant", "libcodec2_hidl@1.2", + "libfdtrack", + "libgui", + "libgui_bufferqueue_static", + "libmedia_codecserviceregistrant", + "libstagefright_bufferqueue_helper_novndk", "libutils_test", "libutilscallstack", + "mediaswcodec", } // Bazel prod-mode allowlist. Modules in this list are built by Bazel // in either prod mode or staging mode. ProdMixedBuildsEnabledList = []string{ + // M5: tzdata launch "com.android.tzdata", "test1_com.android.tzdata", + // M7: adbd launch "com.android.adbd", "test_com.android.adbd", "adbd_test", @@ -1446,6 +1440,8 @@ var ( "adb_pairing_auth_test", "adb_pairing_connection_test", "adb_tls_connection_test", + // M9: mixed builds for mainline trains launch + "api_fingerprint", } // Staging-mode allowlist. Modules in this list are only built @@ -1454,20 +1450,20 @@ var ( // It is implicit that all modules in ProdMixedBuildsEnabledList will // also be built - do not add them to this list. StagingMixedBuildsEnabledList = []string{ - "api_fingerprint", + "com.android.neuralnetworks", } // These should be the libs that are included by the apexes in the ProdMixedBuildsEnabledList - ProdDclaMixedBuildsEnabledList = []string{} - - // These should be the libs that are included by the apexes in the StagingMixedBuildsEnabledList - StagingDclaMixedBuildsEnabledList = []string{ + ProdDclaMixedBuildsEnabledList = []string{ "libbase", "libc++", "libcrypto", "libcutils", } + // These should be the libs that are included by the apexes in the StagingMixedBuildsEnabledList + StagingDclaMixedBuildsEnabledList = []string{} + // TODO(b/269342245): Enable the rest of the DCLA libs // "libssl", // "libstagefright_flacdec", diff --git a/android/androidmk.go b/android/androidmk.go index a7b69f668..aa411d116 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -560,8 +560,6 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", base.katiSymlinks.InstallPaths().Paths()) } - a.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", base.commonProperties.SkipInstall) - if am, ok := mod.(ApexModule); ok { a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform()) } diff --git a/android/apex.go b/android/apex.go index a0ac5b862..87bff74c3 100644 --- a/android/apex.go +++ b/android/apex.go @@ -603,7 +603,7 @@ func CreateApexVariations(mctx BottomUpMutatorContext, module ApexModule) []Modu // Do not install the module for platform, but still allow it to output // uninstallable AndroidMk entries in certain cases when they have side // effects. TODO(jiyong): move this routine to somewhere else - mod.SkipInstall() + mod.MakeUninstallable() } if !platformVariation { mctx.SetVariationProvider(mod, ApexInfoProvider, apexInfos[i-1]) @@ -845,7 +845,7 @@ type WalkPayloadDepsFunc func(ctx ModuleContext, do PayloadDepsCallback) // ModuleWithMinSdkVersionCheck represents a module that implements min_sdk_version checks type ModuleWithMinSdkVersionCheck interface { Module - MinSdkVersion(ctx EarlyModuleContext) SdkSpec + MinSdkVersion(ctx EarlyModuleContext) ApiLevel CheckMinSdkVersion(ctx ModuleContext) } diff --git a/android/api_levels.go b/android/api_levels.go index 9440ee9e7..0c0b2b433 100644 --- a/android/api_levels.go +++ b/android/api_levels.go @@ -55,6 +55,9 @@ type ApiLevel struct { } func (this ApiLevel) FinalInt() int { + if this.IsInvalid() { + panic(fmt.Errorf("%v is not a recognized api_level\n", this)) + } if this.IsPreview() { panic("Requested a final int from a non-final ApiLevel") } else { @@ -63,6 +66,9 @@ func (this ApiLevel) FinalInt() int { } func (this ApiLevel) FinalOrFutureInt() int { + if this.IsInvalid() { + panic(fmt.Errorf("%v is not a recognized api_level\n", this)) + } if this.IsPreview() { return FutureApiLevelInt } else { @@ -76,6 +82,9 @@ func (this ApiLevel) FinalOrFutureInt() int { // - preview codenames -> preview base (9000) + index // - otherwise -> cast to int func (this ApiLevel) FinalOrPreviewInt() int { + if this.IsInvalid() { + panic(fmt.Errorf("%v is not a recognized api_level\n", this)) + } if this.IsCurrent() { return this.number } @@ -97,6 +106,11 @@ func (this ApiLevel) IsPreview() bool { return this.isPreview } +// Returns true if the raw api level string is invalid +func (this ApiLevel) IsInvalid() bool { + return this.EqualTo(InvalidApiLevel) +} + // Returns true if this is the unfinalized "current" API level. This means // different things across Java and native. Java APIs do not use explicit // codenames, so all non-final codenames are grouped into "current". For native @@ -113,6 +127,72 @@ func (this ApiLevel) IsNone() bool { return this.number == -1 } +// Returns true if an app is compiling against private apis. +// e.g. if sdk_version = "" in Android.bp, then the ApiLevel of that "sdk" is at PrivateApiLevel. +func (this ApiLevel) IsPrivate() bool { + return this.number == PrivateApiLevel.number +} + +// EffectiveVersion converts an ApiLevel into the concrete ApiLevel that the module should use. For +// modules targeting an unreleased SDK (meaning it does not yet have a number) it returns +// FutureApiLevel(10000). +func (l ApiLevel) EffectiveVersion(ctx EarlyModuleContext) (ApiLevel, error) { + if l.EqualTo(InvalidApiLevel) { + return l, fmt.Errorf("invalid version in sdk_version %q", l.value) + } + if !l.IsPreview() { + return l, nil + } + ret := ctx.Config().DefaultAppTargetSdk(ctx) + if ret.IsPreview() { + return FutureApiLevel, nil + } + return ret, nil +} + +// EffectiveVersionString converts an SdkSpec into the concrete version string that the module +// should use. For modules targeting an unreleased SDK (meaning it does not yet have a number) +// it returns the codename (P, Q, R, etc.) +func (l ApiLevel) EffectiveVersionString(ctx EarlyModuleContext) (string, error) { + if l.EqualTo(InvalidApiLevel) { + return l.value, fmt.Errorf("invalid version in sdk_version %q", l.value) + } + if !l.IsPreview() { + return l.String(), nil + } + // Determine the default sdk + ret := ctx.Config().DefaultAppTargetSdk(ctx) + if !ret.IsPreview() { + // If the default sdk has been finalized, return that + return ret.String(), nil + } + // There can be more than one active in-development sdks + // If an app is targeting an active sdk, but not the default one, return the requested active sdk. + // e.g. + // SETUP + // In-development: UpsideDownCake, VanillaIceCream + // Default: VanillaIceCream + // Android.bp + // min_sdk_version: `UpsideDownCake` + // RETURN + // UpsideDownCake and not VanillaIceCream + for _, preview := range ctx.Config().PreviewApiLevels() { + if l.String() == preview.String() { + return preview.String(), nil + } + } + // Otherwise return the default one + return ret.String(), nil +} + +// Specified returns true if the module is targeting a recognzized api_level. +// It returns false if either +// 1. min_sdk_version is not an int or a recognized codename +// 2. both min_sdk_version and sdk_version are empty. In this case, MinSdkVersion() defaults to SdkSpecPrivate.ApiLevel +func (this ApiLevel) Specified() bool { + return !this.IsInvalid() && !this.IsPrivate() +} + // Returns -1 if the current API level is less than the argument, 0 if they // are equal, and 1 if it is greater than the argument. func (this ApiLevel) CompareTo(other ApiLevel) int { @@ -166,6 +246,19 @@ var NoneApiLevel = ApiLevel{ isPreview: true, } +// Sentinel ApiLevel to validate that an apiLevel is either an int or a recognized codename. +var InvalidApiLevel = NewInvalidApiLevel("invalid") + +// Returns an apiLevel object at the same level as InvalidApiLevel. +// The object contains the raw string provied in bp file, and can be used for error handling. +func NewInvalidApiLevel(raw string) ApiLevel { + return ApiLevel{ + value: raw, + number: -2, // One less than NoneApiLevel + isPreview: true, + } +} + // The first version that introduced 64-bit ABIs. var FirstLp64Version = uncheckedFinalApiLevel(21) @@ -204,6 +297,16 @@ func ReplaceFinalizedCodenames(config Config, raw string) string { return strconv.Itoa(num) } +// ApiLevelFrom converts the given string `raw` to an ApiLevel. +// If `raw` is invalid (empty string, unrecognized codename etc.) it returns an invalid ApiLevel +func ApiLevelFrom(ctx PathContext, raw string) ApiLevel { + ret, err := ApiLevelFromUser(ctx, raw) + if err != nil { + return NewInvalidApiLevel(raw) + } + return ret +} + // ApiLevelFromUser converts the given string `raw` to an ApiLevel, possibly returning an error. // // `raw` must be non-empty. Passing an empty string results in a panic. diff --git a/android/arch.go b/android/arch.go index 6acf9cf51..4b4691b3d 100644 --- a/android/arch.go +++ b/android/arch.go @@ -1694,6 +1694,7 @@ func getNdkAbisConfig() []archConfig { return []archConfig{ {"arm64", "armv8-a-branchprot", "", []string{"arm64-v8a"}}, {"arm", "armv7-a-neon", "", []string{"armeabi-v7a"}}, + {"riscv64", "", "", []string{"riscv64"}}, {"x86_64", "", "", []string{"x86_64"}}, {"x86", "", "", []string{"x86"}}, } diff --git a/android/arch_test.go b/android/arch_test.go index e445ec66f..5021a67af 100644 --- a/android/arch_test.go +++ b/android/arch_test.go @@ -401,7 +401,7 @@ func TestArchMutator(t *testing.T) { { name: "same arch host and host cross", preparer: FixtureModifyConfig(func(config Config) { - modifyTestConfigForMusl(config) + ModifyTestConfigForMusl(config) modifyTestConfigForMuslArm64HostCross(config) }), fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"}, @@ -705,7 +705,7 @@ func TestArchProperties(t *testing.T) { { name: "linux_musl", goOS: "linux", - preparer: FixtureModifyConfig(modifyTestConfigForMusl), + preparer: FixtureModifyConfig(ModifyTestConfigForMusl), results: []result{ { module: "foo", diff --git a/android/bazel.go b/android/bazel.go index 782632b0b..164688396 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -357,6 +357,8 @@ func MixedBuildsEnabled(ctx BaseModuleContext) bool { mixedBuildEnabled := ctx.Config().IsMixedBuildsEnabled() && ctx.Os() != Windows && // Windows toolchains are not currently supported. ctx.Os() != LinuxBionic && // Linux Bionic toolchains are not currently supported. + ctx.Os() != LinuxMusl && // Linux musl toolchains are not currently supported (b/259266326). + ctx.Arch().ArchType != Riscv64 && // TODO(b/262192655) Riscv64 toolchains are not currently supported. module.Enabled() && convertedToBazel(ctx, module) && ctx.Config().BazelContext.IsModuleNameAllowed(module.Name(), withinApex) diff --git a/android/bazel_handler.go b/android/bazel_handler.go index 66832d5e7..44dc0559e 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -736,15 +736,6 @@ func (r *builtinBazelRunner) createBazelCommand(config Config, paths *bazelPaths // TODO(asmundak): is it needed in every build? "--profile=" + shared.BazelMetricsFilename(paths, runName), - // Set default platforms to canonicalized values for mixed builds requests. - // If these are set in the bazelrc, they will have values that are - // non-canonicalized to @sourceroot labels, and thus be invalid when - // referenced from the buildroot. - // - // The actual platform values here may be overridden by configuration - // transitions from the buildroot. - fmt.Sprintf("--extra_toolchains=%s", "//prebuilts/clang/host/linux-x86:all"), - // We don't need to set --host_platforms because it's set in bazelrc files // that the bazel shell script wrapper passes @@ -1009,39 +1000,6 @@ def %s(target, id_string): formatString := ` # This file is generated by soong_build. Do not edit. -# a drop-in replacement for json.encode(), not available in cquery environment -# TODO(cparsons): bring json module in and remove this function -def json_encode(input): - # Avoiding recursion by limiting - # - a dict to contain anything except a dict - # - a list to contain only primitives - def encode_primitive(p): - t = type(p) - if t == "string" or t == "int": - return repr(p) - fail("unsupported value '%s' of type '%s'" % (p, type(p))) - - def encode_list(list): - items = [] - for item in list: - if type(item) == "dict": - # support encoding dict of primitive keys and values. not list currently, because calling encode_list again is recursive. - kv_pairs = [("%s: %s" % (encode_primitive(k), encode_primitive(v))) for (k, v) in item.items()] - items.append("{ %s }" % ", ".join(kv_pairs)) - else: - items.append(encode_primitive(item)) - return "[%s]" % ", ".join(items) - - def encode_list_or_primitive(v): - return encode_list(v) if type(v) == "list" else encode_primitive(v) - - if type(input) == "dict": - # TODO(juu): the result is read line by line so can't use '\n' yet - kv_pairs = [("%s: %s" % (encode_primitive(k), encode_list_or_primitive(v))) for (k, v) in input.items()] - return "{ %s }" % ", ".join(kv_pairs) - else: - return encode_list_or_primitive(input) - {LABEL_REGISTRATION_MAP_SECTION} {FUNCTION_DEF_SECTION} diff --git a/android/config.go b/android/config.go index 292fcf2fe..e0b661bb7 100644 --- a/android/config.go +++ b/android/config.go @@ -52,6 +52,15 @@ var StringDefault = proptools.StringDefault // FutureApiLevelInt is a placeholder constant for unreleased API levels. const FutureApiLevelInt = 10000 +// PrivateApiLevel represents the api level of SdkSpecPrivate (sdk_version: "") +// This api_level exists to differentiate user-provided "" from "current" sdk_version +// The differentiation is necessary to enable different validation rules for these two possible values. +var PrivateApiLevel = ApiLevel{ + value: "current", // The value is current since aidl expects `current` as the default (TestAidlFlagsWithMinSdkVersion) + number: FutureApiLevelInt + 1, // This is used to differentiate it from FutureApiLevel + isPreview: true, +} + // FutureApiLevel represents unreleased API levels. var FutureApiLevel = ApiLevel{ value: "current", @@ -1376,6 +1385,11 @@ func (c *deviceConfig) NativeCoverageEnabledForPath(path string) bool { } } if coverage && len(c.config.productVariables.NativeCoverageExcludePaths) > 0 { + // Workaround coverage boot failure. + // http://b/269981180 + if strings.HasPrefix(path, "external/protobuf") { + coverage = false + } if HasAnyPrefix(path, c.config.productVariables.NativeCoverageExcludePaths) { coverage = false } diff --git a/android/filegroup.go b/android/filegroup.go index 278d46d07..38de8558f 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -118,6 +118,7 @@ func (fg *fileGroup) ConvertWithBp2build(ctx TopDownMutatorContext) { // If the module has a mixed bag of AIDL and non-AIDL files, split the filegroup manually // and then convert if fg.ShouldConvertToAidlLibrary(ctx) { + tags := []string{"apex_available=//apex_available:anyapex"} attrs := &bazelAidlLibraryAttributes{ Srcs: srcs, Strip_import_prefix: fg.properties.Path, @@ -128,17 +129,25 @@ func (fg *fileGroup) ConvertWithBp2build(ctx TopDownMutatorContext) { Bzl_load_location: "//build/bazel/rules/aidl:library.bzl", } - ctx.CreateBazelTargetModule(props, CommonAttributes{Name: fg.Name()}, attrs) + ctx.CreateBazelTargetModule( + props, + CommonAttributes{ + Name: fg.Name(), + Tags: bazel.MakeStringListAttribute(tags), + }, + attrs) } else { if fg.ShouldConvertToProtoLibrary(ctx) { - // TODO(b/246997908): we can remove this tag if we could figure out a - // solution for this bug. attrs := &ProtoAttrs{ Srcs: srcs, Strip_import_prefix: fg.properties.Path, } - tags := []string{"manual"} + tags := []string{ + "apex_available=//apex_available:anyapex", + // TODO(b/246997908): we can remove this tag if we could figure out a solution for this bug. + "manual", + } ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{Rule_class: "proto_library"}, CommonAttributes{ diff --git a/android/fixture.go b/android/fixture.go index c2b16f66e..dbc3bc5e0 100644 --- a/android/fixture.go +++ b/android/fixture.go @@ -16,6 +16,7 @@ package android import ( "fmt" + "runtime" "strings" "testing" ) @@ -379,6 +380,12 @@ func FixtureModifyProductVariables(mutator func(variables FixtureProductVariable }) } +var PrepareForSkipTestOnMac = newSimpleFixturePreparer(func(fixture *fixture) { + if runtime.GOOS != "linux" { + fixture.t.Skip("Test is only supported on linux.") + } +}) + // PrepareForDebug_DO_NOT_SUBMIT puts the fixture into debug which will cause it to output its // state before running the test. // diff --git a/android/module.go b/android/module.go index b45ed9530..76fe8dc45 100644 --- a/android/module.go +++ b/android/module.go @@ -37,26 +37,64 @@ var ( DeviceStaticLibrary = "static_library" ) +// BuildParameters describes the set of potential parameters to build a Ninja rule. +// In general, these correspond to a Ninja concept. type BuildParams struct { - Rule blueprint.Rule - Deps blueprint.Deps - Depfile WritablePath - Description string - Output WritablePath - Outputs WritablePaths - SymlinkOutput WritablePath - SymlinkOutputs WritablePaths - ImplicitOutput WritablePath + // A Ninja Rule that will be written to the Ninja file. This allows factoring out common code + // among multiple modules to reduce repetition in the Ninja file of action requirements. A rule + // can contain variables that should be provided in Args. + Rule blueprint.Rule + // Deps represents the depfile format. When using RuleBuilder, this defaults to GCC when depfiles + // are used. + Deps blueprint.Deps + // Depfile is a writeable path that allows correct incremental builds when the inputs have not + // been fully specified by the Ninja rule. Ninja supports a subset of the Makefile depfile syntax. + Depfile WritablePath + // A description of the build action. + Description string + // Output is an output file of the action. When using this field, references to $out in the Ninja + // command will refer to this file. + Output WritablePath + // Outputs is a slice of output file of the action. When using this field, references to $out in + // the Ninja command will refer to these files. + Outputs WritablePaths + // SymlinkOutput is an output file specifically that is a symlink. + SymlinkOutput WritablePath + // SymlinkOutputs is a slice of output files specifically that is a symlink. + SymlinkOutputs WritablePaths + // ImplicitOutput is an output file generated by the action. Note: references to `$out` in the + // Ninja command will NOT include references to this file. + ImplicitOutput WritablePath + // ImplicitOutputs is a slice of output files generated by the action. Note: references to `$out` + // in the Ninja command will NOT include references to these files. ImplicitOutputs WritablePaths - Input Path - Inputs Paths - Implicit Path - Implicits Paths - OrderOnly Paths - Validation Path - Validations Paths - Default bool - Args map[string]string + // Input is an input file to the Ninja action. When using this field, references to $in in the + // Ninja command will refer to this file. + Input Path + // Inputs is a slice of input files to the Ninja action. When using this field, references to $in + // in the Ninja command will refer to these files. + Inputs Paths + // Implicit is an input file to the Ninja action. Note: references to `$in` in the Ninja command + // will NOT include references to this file. + Implicit Path + // Implicits is a slice of input files to the Ninja action. Note: references to `$in` in the Ninja + // command will NOT include references to these files. + Implicits Paths + // OrderOnly are Ninja order-only inputs to the action. When these are out of date, the output is + // not rebuilt until they are built, but changes in order-only dependencies alone do not cause the + // output to be rebuilt. + OrderOnly Paths + // Validation is an output path for a validation action. Validation outputs imply lower + // non-blocking priority to building non-validation outputs. + Validation Path + // Validations is a slice of output path for a validation action. Validation outputs imply lower + // non-blocking priority to building non-validation outputs. + Validations Paths + // Whether to skip outputting a default target statement which will be built by Ninja when no + // targets are specified on Ninja's command line. + Default bool + // Args is a key value mapping for replacements of variables within the Rule + Args map[string]string } type ModuleBuildParams BuildParams @@ -505,8 +543,8 @@ type Module interface { PartitionTag(DeviceConfig) string HideFromMake() IsHideFromMake() bool - SkipInstall() IsSkipInstall() bool + MakeUninstallable() ReplacedByPrebuilt() IsReplacedByPrebuilt() bool ExportedToMake() bool @@ -1964,6 +2002,15 @@ func (m *ModuleBase) IsSkipInstall() bool { return m.commonProperties.SkipInstall } +// Similar to HideFromMake, but if the AndroidMk entry would set +// LOCAL_UNINSTALLABLE_MODULE then this variant may still output that entry +// rather than leaving it out altogether. That happens in cases where it would +// have other side effects, in particular when it adds a NOTICE file target, +// which other install targets might depend on. +func (m *ModuleBase) MakeUninstallable() { + m.HideFromMake() +} + func (m *ModuleBase) ReplacedByPrebuilt() { m.commonProperties.ReplacedByPrebuilt = true m.HideFromMake() diff --git a/android/packaging_test.go b/android/packaging_test.go index f32d1c396..91ac1f386 100644 --- a/android/packaging_test.go +++ b/android/packaging_test.go @@ -15,7 +15,6 @@ package android import ( - "strings" "testing" "github.com/google/blueprint" @@ -29,8 +28,6 @@ type componentTestModule struct { Deps []string Skip_install *bool } - - builtFile Path } // dep tag used in this test. All dependencies are considered as installable. @@ -51,21 +48,13 @@ func (m *componentTestModule) DepsMutator(ctx BottomUpMutatorContext) { } func (m *componentTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { - m.builtFile = PathForModuleOut(ctx, m.Name()) + builtFile := PathForModuleOut(ctx, m.Name()) dir := ctx.Target().Arch.ArchType.Multilib installDir := PathForModuleInstall(ctx, dir) if proptools.Bool(m.props.Skip_install) { m.SkipInstall() } - ctx.InstallFile(installDir, m.Name(), m.builtFile) -} - -func (m *componentTestModule) AndroidMkEntries() []AndroidMkEntries { - return []AndroidMkEntries{ - { - OutputFile: OptionalPathForPath(m.builtFile), - }, - } + ctx.InstallFile(installDir, m.Name(), builtFile) } // Module that itself is a package @@ -262,35 +251,6 @@ func TestPackagingBaseMultiTarget(t *testing.T) { `, []string{"lib32/foo", "lib64/foo", "lib64/bar"}) } -func TestSkipInstallProducesLocalUninstallableModule(t *testing.T) { - result := GroupFixturePreparers( - PrepareForTestWithArchMutator, - FixtureRegisterWithContext(func(ctx RegistrationContext) { - ctx.RegisterModuleType("component", componentTestModuleFactory) - ctx.RegisterModuleType("package_module", packageTestModuleFactory) - }), - FixtureWithRootAndroidBp(` -component { - name: "foo", - skip_install: true, -} - -package_module { - name: "package", - deps: ["foo"], -} -`), - ).RunTest(t) - module := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*componentTestModule) - entries := AndroidMkEntriesForTest(t, result.TestContext, module) - builder := &strings.Builder{} - entries[0].write(builder) - androidMkString := builder.String() - if !strings.Contains(androidMkString, "LOCAL_UNINSTALLABLE_MODULE := true") { - t.Errorf("Expected android mk entries to contain \"LOCAL_UNINSTALLABLE_MODULE := true\", got: \n%s", androidMkString) - } -} - func TestPackagingBaseSingleTarget(t *testing.T) { multiTarget := false runPackagingTest(t, multiTarget, diff --git a/android/sdk.go b/android/sdk.go index 8b23d63a9..63e0bbeec 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -25,7 +25,7 @@ import ( // minApiLevelForSdkSnapshot provides access to the min_sdk_version for MinApiLevelForSdkSnapshot type minApiLevelForSdkSnapshot interface { - MinSdkVersion(ctx EarlyModuleContext) SdkSpec + MinSdkVersion(ctx EarlyModuleContext) ApiLevel } // MinApiLevelForSdkSnapshot returns the ApiLevel of the min_sdk_version of the supplied module. @@ -34,7 +34,7 @@ type minApiLevelForSdkSnapshot interface { func MinApiLevelForSdkSnapshot(ctx EarlyModuleContext, module Module) ApiLevel { minApiLevel := NoneApiLevel if m, ok := module.(minApiLevelForSdkSnapshot); ok { - minApiLevel = m.MinSdkVersion(ctx).ApiLevel + minApiLevel = m.MinSdkVersion(ctx) } if minApiLevel == NoneApiLevel { // The default min API level is 1. diff --git a/android/sdk_version.go b/android/sdk_version.go index a7e03dcd8..7ace638b5 100644 --- a/android/sdk_version.go +++ b/android/sdk_version.go @@ -25,15 +25,15 @@ type SdkContext interface { SdkVersion(ctx EarlyModuleContext) SdkSpec // SystemModules returns the system_modules property of the current module, or an empty string if it is not set. SystemModules() string - // MinSdkVersion returns SdkSpec that corresponds to the min_sdk_version property of the current module, + // MinSdkVersion returns ApiLevel that corresponds to the min_sdk_version property of the current module, // or from sdk_version if it is not set. - MinSdkVersion(ctx EarlyModuleContext) SdkSpec + MinSdkVersion(ctx EarlyModuleContext) ApiLevel // ReplaceMaxSdkVersionPlaceholder returns SdkSpec to replace the maxSdkVersion property of permission and // uses-permission tags if it is set. ReplaceMaxSdkVersionPlaceholder(ctx EarlyModuleContext) SdkSpec - // TargetSdkVersion returns the SdkSpec that corresponds to the target_sdk_version property of the current module, + // TargetSdkVersion returns the ApiLevel that corresponds to the target_sdk_version property of the current module, // or from sdk_version if it is not set. - TargetSdkVersion(ctx EarlyModuleContext) SdkSpec + TargetSdkVersion(ctx EarlyModuleContext) ApiLevel } // SdkKind represents a particular category of an SDK spec like public, system, test, etc. @@ -84,6 +84,40 @@ func (k SdkKind) String() string { } } +// JavaLibraryName returns the soong module containing the Java APIs of that API surface. +func (k SdkKind) JavaLibraryName(c Config) string { + name := k.defaultJavaLibraryName() + return JavaLibraryNameFromText(c, name) +} + +// JavaLibraryNameFromText returns the name of .txt equivalent of a java_library, but does +// not check if either module exists. +// TODO: Return .txt (single-tree or multi-tree equivalents) based on config +func JavaLibraryNameFromText(c Config, name string) string { + // This returns the default for now. + // TODO: Implement this + return name +} + +func (k SdkKind) defaultJavaLibraryName() string { + switch k { + case SdkPublic: + return "android_stubs_current" + case SdkSystem: + return "android_system_stubs_current" + case SdkTest: + return "android_test_stubs_current" + case SdkCore: + return "core.current.stubs" + case SdkModule: + return "android_module_lib_stubs_current" + case SdkSystemServer: + return "android_system_server_stubs_current" + default: + panic(fmt.Errorf("APIs of API surface %v cannot be provided by a single Soong module\n", k)) + } +} + // SdkSpec represents the kind and the version of an SDK for a module to build against type SdkSpec struct { Kind SdkKind @@ -187,14 +221,7 @@ func (s SdkSpec) EffectiveVersion(ctx EarlyModuleContext) (ApiLevel, error) { if ctx.DeviceSpecific() || ctx.SocSpecific() { s = s.ForVendorPartition(ctx) } - if !s.ApiLevel.IsPreview() { - return s.ApiLevel, nil - } - ret := ctx.Config().DefaultAppTargetSdk(ctx) - if ret.IsPreview() { - return FutureApiLevel, nil - } - return ret, nil + return s.ApiLevel.EffectiveVersion(ctx) } // EffectiveVersionString converts an SdkSpec into the concrete version string that the module @@ -208,37 +235,12 @@ func (s SdkSpec) EffectiveVersionString(ctx EarlyModuleContext) (string, error) if ctx.DeviceSpecific() || ctx.SocSpecific() { s = s.ForVendorPartition(ctx) } - if !s.ApiLevel.IsPreview() { - return s.ApiLevel.String(), nil - } - // Determine the default sdk - ret := ctx.Config().DefaultAppTargetSdk(ctx) - if !ret.IsPreview() { - // If the default sdk has been finalized, return that - return ret.String(), nil - } - // There can be more than one active in-development sdks - // If an app is targeting an active sdk, but not the default one, return the requested active sdk. - // e.g. - // SETUP - // In-development: UpsideDownCake, VanillaIceCream - // Default: VanillaIceCream - // Android.bp - // min_sdk_version: `UpsideDownCake` - // RETURN - // UpsideDownCake and not VanillaIceCream - for _, preview := range ctx.Config().PreviewApiLevels() { - if s.ApiLevel.String() == preview.String() { - return preview.String(), nil - } - } - // Otherwise return the default one - return ret.String(), nil + return s.ApiLevel.EffectiveVersionString(ctx) } var ( SdkSpecNone = SdkSpec{SdkNone, NoneApiLevel, "(no version)"} - SdkSpecPrivate = SdkSpec{SdkPrivate, FutureApiLevel, ""} + SdkSpecPrivate = SdkSpec{SdkPrivate, PrivateApiLevel, ""} SdkSpecCorePlatform = SdkSpec{SdkCorePlatform, FutureApiLevel, "core_platform"} ) @@ -261,7 +263,7 @@ func SdkSpecFromWithConfig(config Config, str string) SdkSpec { var kindString string if sep == 0 { - return SdkSpec{SdkInvalid, NoneApiLevel, str} + return SdkSpec{SdkInvalid, NewInvalidApiLevel(str), str} } else if sep == -1 { kindString = "" } else { @@ -289,7 +291,7 @@ func SdkSpecFromWithConfig(config Config, str string) SdkSpec { apiLevel, err := ApiLevelFromUserWithConfig(config, versionString) if err != nil { - return SdkSpec{SdkInvalid, apiLevel, str} + return SdkSpec{SdkInvalid, NewInvalidApiLevel(versionString), str} } return SdkSpec{kind, apiLevel, str} } @@ -316,3 +318,18 @@ func (s SdkSpec) ValidateSystemSdk(ctx EarlyModuleContext) bool { } return true } + +func init() { + RegisterMakeVarsProvider(pctx, javaSdkMakeVars) +} + +// Export the name of the soong modules representing the various Java API surfaces. +func javaSdkMakeVars(ctx MakeVarsContext) { + ctx.Strict("ANDROID_PUBLIC_STUBS", SdkPublic.JavaLibraryName(ctx.Config())) + ctx.Strict("ANDROID_SYSTEM_STUBS", SdkSystem.JavaLibraryName(ctx.Config())) + ctx.Strict("ANDROID_TEST_STUBS", SdkTest.JavaLibraryName(ctx.Config())) + ctx.Strict("ANDROID_MODULE_LIB_STUBS", SdkModule.JavaLibraryName(ctx.Config())) + ctx.Strict("ANDROID_SYSTEM_SERVER_STUBS", SdkSystemServer.JavaLibraryName(ctx.Config())) + // TODO (jihoonkang): Create a .txt equivalent for core.current.stubs + ctx.Strict("ANDROID_CORE_STUBS", SdkCore.JavaLibraryName(ctx.Config())) +} diff --git a/android/sdk_version_test.go b/android/sdk_version_test.go index ec81782f0..ea99c4d62 100644 --- a/android/sdk_version_test.go +++ b/android/sdk_version_test.go @@ -37,11 +37,11 @@ func TestSdkSpecFrom(t *testing.T) { }, { input: "_", - expected: "invalid_(no version)", + expected: "invalid__", }, { input: "_31", - expected: "invalid_(no version)", + expected: "invalid__31", }, { input: "system_R", diff --git a/android/test_asserts.go b/android/test_asserts.go index 064f6562b..4143f150d 100644 --- a/android/test_asserts.go +++ b/android/test_asserts.go @@ -160,6 +160,7 @@ func AssertStringListDoesNotContain(t *testing.T, message string, list []string, // the value of the expected bool. If the expectation does not hold it reports an error prefixed with // the supplied message and including a reason for why it failed. func AssertStringListContainsEquals(t *testing.T, message string, list []string, s string, expected bool) { + t.Helper() if expected { AssertStringListContains(t, message, list, s) } else { diff --git a/android/test_config.go b/android/test_config.go index 70c319a59..07ca33d56 100644 --- a/android/test_config.go +++ b/android/test_config.go @@ -109,7 +109,8 @@ func modifyTestConfigToSupportArchMutator(testConfig Config) { config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon") } -func modifyTestConfigForMusl(config Config) { +// ModifyTestConfigForMusl takes a Config returned by TestConfig and changes the host targets from glibc to musl. +func ModifyTestConfigForMusl(config Config) { delete(config.Targets, config.BuildOS) config.productVariables.HostMusl = boolPtr(true) determineBuildOS(config.config) diff --git a/apex/apex.go b/apex/apex.go index b2ca6c480..1f700c6d8 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -993,6 +993,9 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) { if !useVndk { mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes") } + if a.minSdkVersionValue(mctx) != "" { + mctx.PropertyErrorf("use_vndk_as_stable", "not supported when min_sdk_version is set") + } mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) { if c, ok := dep.(*cc.Module); ok && c.IsVndk() { mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name()) @@ -1939,7 +1942,7 @@ func (f fsType) string() string { var _ android.MixedBuildBuildable = (*apexBundle)(nil) func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool { - return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex + return a.properties.ApexType == imageApex } func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) { @@ -2946,12 +2949,8 @@ func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string { } // Returns apex's min_sdk_version SdkSpec, honoring overrides -func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return android.SdkSpec{ - Kind: android.SdkNone, - ApiLevel: a.minSdkVersion(ctx), - Raw: a.minSdkVersionValue(ctx), - } +func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return a.minSdkVersion(ctx) } // Returns apex's min_sdk_version ApiLevel, honoring overrides @@ -3025,8 +3024,8 @@ func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) { if a.UsePlatformApis() { ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs") } - if a.SocSpecific() || a.DeviceSpecific() { - ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable") + if proptools.Bool(a.properties.Use_vndk_as_stable) { + ctx.PropertyErrorf("use_vndk_as_stable", "updatable APEXes can't use external VNDK libs") } if a.FutureUpdatable() { ctx.PropertyErrorf("future_updatable", "Already updatable. Remove `future_updatable: true:`") diff --git a/apex/apex_test.go b/apex/apex_test.go index 1f33eca70..c9665a4b8 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -1927,13 +1927,13 @@ func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) { expectNoLink("libx", "shared_apex10000", "libz", "shared") } -func TestApexMinSdkVersion_crtobjectInVendorApex(t *testing.T) { +func TestApexMinSdkVersion_InVendorApex(t *testing.T) { ctx := testApex(t, ` apex { name: "myapex", key: "myapex.key", native_shared_libs: ["mylib"], - updatable: false, + updatable: true, vendor: true, min_sdk_version: "29", } @@ -1946,20 +1946,34 @@ func TestApexMinSdkVersion_crtobjectInVendorApex(t *testing.T) { cc_library { name: "mylib", + srcs: ["mylib.cpp"], vendor_available: true, - system_shared_libs: [], - stl: "none", - apex_available: [ "myapex" ], min_sdk_version: "29", + shared_libs: ["libbar"], + } + + cc_library { + name: "libbar", + stubs: { versions: ["29", "30"] }, + llndk: { symbol_file: "libbar.map.txt" }, } `) vendorVariant := "android_vendor.29_arm64_armv8-a" - // First check that the correct variant of crtbegin_so is used. - ldRule := ctx.ModuleForTests("mylib", vendorVariant+"_shared_apex29").Rule("ld") - crtBegin := names(ldRule.Args["crtBegin"]) - ensureListContains(t, crtBegin, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"crtbegin_so/"+vendorVariant+"_apex29/crtbegin_so.o") + mylib := ctx.ModuleForTests("mylib", vendorVariant+"_shared_myapex") + + // Ensure that mylib links with "current" LLNDK + libFlags := names(mylib.Rule("ld").Args["libFlags"]) + ensureListContains(t, libFlags, "out/soong/.intermediates/libbar/"+vendorVariant+"_shared_current/libbar.so") + + // Ensure that mylib is targeting 29 + ccRule := ctx.ModuleForTests("mylib", vendorVariant+"_static_apex29").Output("obj/mylib.o") + ensureContains(t, ccRule.Args["cFlags"], "-target aarch64-linux-android29") + + // Ensure that the correct variant of crtbegin_so is used. + crtBegin := mylib.Rule("ld").Args["crtBegin"] + ensureContains(t, crtBegin, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"crtbegin_so/"+vendorVariant+"_apex29/crtbegin_so.o") // Ensure that the crtbegin_so used by the APEX is targeting 29 cflags := ctx.ModuleForTests("crtbegin_so", vendorVariant+"_apex29").Rule("cc").Args["cFlags"] @@ -7860,12 +7874,13 @@ func TestUpdatableDefault_should_set_min_sdk_version(t *testing.T) { `) } -func TestUpdatable_cannot_be_vendor_apex(t *testing.T) { - testApexError(t, `"myapex" .*: updatable: vendor APEXes are not updatable`, ` +func Test_use_vndk_as_stable_shouldnt_be_used_for_updatable_vendor_apexes(t *testing.T) { + testApexError(t, `"myapex" .*: use_vndk_as_stable: updatable APEXes can't use external VNDK libs`, ` apex { name: "myapex", key: "myapex.key", updatable: true, + use_vndk_as_stable: true, soc_specific: true, } @@ -7877,6 +7892,42 @@ func TestUpdatable_cannot_be_vendor_apex(t *testing.T) { `) } +func Test_use_vndk_as_stable_shouldnt_be_used_with_min_sdk_version(t *testing.T) { + testApexError(t, `"myapex" .*: use_vndk_as_stable: not supported when min_sdk_version is set`, ` + apex { + name: "myapex", + key: "myapex.key", + updatable: false, + min_sdk_version: "29", + use_vndk_as_stable: true, + vendor: true, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) +} + +func Test_use_vndk_as_stable_shouldnt_be_used_for_non_vendor_apexes(t *testing.T) { + testApexError(t, `"myapex" .*: use_vndk_as_stable: not supported for system/system_ext APEXes`, ` + apex { + name: "myapex", + key: "myapex.key", + updatable: false, + use_vndk_as_stable: true, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) +} + func TestUpdatable_should_not_set_generate_classpaths_proto(t *testing.T) { testApexError(t, `"mysystemserverclasspathfragment" .* it must not set generate_classpaths_proto to false`, ` apex { diff --git a/apex/builder.go b/apex/builder.go index ee6c473bd..e3b6f8e48 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -1063,10 +1063,10 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { } else { toMinSdkVersion := "(no version)" if m, ok := to.(interface { - MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec + MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel }); ok { - if v := m.MinSdkVersion(ctx); !v.ApiLevel.IsNone() { - toMinSdkVersion = v.ApiLevel.String() + if v := m.MinSdkVersion(ctx); !v.IsNone() { + toMinSdkVersion = v.String() } } else if m, ok := to.(interface{ MinSdkVersion() string }); ok { // TODO(b/175678607) eliminate the use of MinSdkVersion returning @@ -1087,7 +1087,7 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { return !externalDep }) - a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).Raw, depInfos) + a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).String(), depInfos) ctx.Build(pctx, android.BuildParams{ Rule: android.Phony, @@ -1167,7 +1167,7 @@ func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.Outp if a.properties.Canned_fs_config != nil { cmd.Text("cat").Input(android.PathForModuleSrc(ctx, *a.properties.Canned_fs_config)) } - cmd.Text(") | LC_ALL=C sort ").FlagWithOutput("> ", cannedFsConfig) + cmd.Text(")").FlagWithOutput("> ", cannedFsConfig) builder.Build("generateFsConfig", fmt.Sprintf("Generating canned fs config for %s", a.BaseModuleName())) return cannedFsConfig.OutputPath diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 0997a68eb..cae507e5d 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -35,11 +35,12 @@ var ( blueprint.RuleParams{ Command: `rm -rf "$out" && ` + `${extract_apks} -o "${out}" -allow-prereleased=${allow-prereleased} ` + - `-sdk-version=${sdk-version} -abis=${abis} -screen-densities=all -extract-single ` + + `-sdk-version=${sdk-version} -skip-sdk-check=${skip-sdk-check} -abis=${abis} ` + + `-screen-densities=all -extract-single ` + `${in}`, CommandDeps: []string{"${extract_apks}"}, }, - "abis", "allow-prereleased", "sdk-version") + "abis", "allow-prereleased", "sdk-version", "skip-sdk-check") ) type prebuilt interface { @@ -845,6 +846,7 @@ func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.Mo "abis": strings.Join(abis, ","), "allow-prereleased": strconv.FormatBool(proptools.BoolDefault(p.properties.Prerelease, defaultAllowPrerelease)), "sdk-version": ctx.Config().PlatformSdkVersion().String(), + "skip-sdk-check": strconv.FormatBool(ctx.Config().IsEnvTrue("SOONG_SKIP_APPSET_SDK_CHECK")), }, }) } diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go index cf649a47e..bf3a6b5c6 100644 --- a/bazel/cquery/request_type.go +++ b/bazel/cquery/request_type.go @@ -197,7 +197,7 @@ if androidmk_tag in p: local_whole_static_libs = androidmk_info.local_whole_static_libs local_shared_libs = androidmk_info.local_shared_libs -return json_encode({ +return json.encode({ "OutputFiles": outputFiles, "CcObjectFiles": ccObjectFiles, "CcSharedLibraryFiles": sharedLibraries, @@ -266,7 +266,7 @@ clang_tidy_info = providers(target).get("//build/bazel/rules/cc:clang_tidy.bzl%C if clang_tidy_info: tidy_files = [v.path for v in clang_tidy_info.transitive_tidy_files.to_list()] -return json_encode({ +return json.encode({ "signed_output": info.signed_output.path, "signed_compressed_output": signed_compressed_output, "unsigned_output": info.unsigned_output.path, @@ -335,7 +335,7 @@ unstripped = output_path unstripped_tag = "//build/bazel/rules/cc:stripped_cc_common.bzl%CcUnstrippedInfo" if unstripped_tag in p: unstripped_info = p[unstripped_tag] - unstripped = unstripped_info.unstripped.files.to_list()[0].path + unstripped = unstripped_info.unstripped[0].files.to_list()[0].path local_static_libs = [] local_whole_static_libs = [] @@ -352,7 +352,7 @@ clang_tidy_info = p.get("//build/bazel/rules/cc:clang_tidy.bzl%ClangTidyInfo") if clang_tidy_info: tidy_files = [v.path for v in clang_tidy_info.transitive_tidy_files.to_list()] -return json_encode({ +return json.encode({ "OutputFile": output_path, "UnstrippedOutput": unstripped, "LocalStaticLibs": [l for l in local_static_libs], diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go index 03b3d2b6c..ef3f12472 100644 --- a/bp2build/android_app_conversion_test.go +++ b/bp2build/android_app_conversion_test.go @@ -344,3 +344,50 @@ android_app { }), }}) } + +func TestAndroidAppMinSdkProvided(t *testing.T) { + runAndroidAppTestCase(t, Bp2buildTestCase{ + Description: "Android app with value for min_sdk_version", + ModuleTypeUnderTest: "android_app", + ModuleTypeUnderTestFactory: java.AndroidAppFactory, + Filesystem: map[string]string{}, + Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + ` +android_app { + name: "foo", + sdk_version: "current", + min_sdk_version: "24", +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("android_binary", "foo", AttrNameToString{ + "manifest": `"AndroidManifest.xml"`, + "resource_files": `[]`, + "manifest_values": `{ + "minSdkVersion": "24", + }`, + }), + }}) +} + +func TestAndroidAppMinSdkDefaultToSdkVersion(t *testing.T) { + runAndroidAppTestCase(t, Bp2buildTestCase{ + Description: "Android app with value for sdk_version", + ModuleTypeUnderTest: "android_app", + ModuleTypeUnderTestFactory: java.AndroidAppFactory, + Filesystem: map[string]string{}, + Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + ` +android_app { + name: "foo", + sdk_version: "30", +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("android_binary", "foo", AttrNameToString{ + "manifest": `"AndroidManifest.xml"`, + "resource_files": `[]`, + "manifest_values": `{ + "minSdkVersion": "30", + }`, + }), + }}) +} diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go index 3eec43905..d915d6b64 100644 --- a/bp2build/bp2build_product_config.go +++ b/bp2build/bp2build_product_config.go @@ -53,7 +53,7 @@ package(default_visibility=[ "@//build/bazel/product_config:__subpackages__", ]) load(":soong.variables.bzl", _soong_variables = "variables") -load("@//build/bazel/product_config:utils.bzl", "android_product") +load("@//build/bazel/product_config:android_product.bzl", "android_product") android_product( name = "{PRODUCT}-{VARIANT}", diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 7ea1c1c48..d2c463dbb 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -2425,7 +2425,10 @@ cc_library { "whole_archive_deps": `[":a_cc_proto_lite"]`, }), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{ "srcs": `["a_fg.proto"]`, - "tags": `["manual"]`, + "tags": `[ + "apex_available=//apex_available:anyapex", + "manual", + ]`, }), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{ "srcs": `["a_fg.proto"]`, }), @@ -2464,7 +2467,10 @@ cc_library { "whole_archive_deps": `[":a_cc_proto_lite"]`, }), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{ "srcs": `["a_fg.proto"]`, - "tags": `["manual"]`, + "tags": `[ + "apex_available=//apex_available:anyapex", + "manual", + ]`, }), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{ "srcs": `["a_fg.proto"]`, }), @@ -3032,6 +3038,7 @@ cc_library { }, }, bazel_module: { bp2build_available: true }, + apex_available: ["foo"], }`, ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{ "implementation_dynamic_deps": `select({ @@ -3039,6 +3046,7 @@ cc_library { "//conditions:default": [":barlib"], })`, "local_includes": `["."]`, + "tags": `["apex_available=foo"]`, }), }) } @@ -3072,6 +3080,7 @@ cc_library { }, include_build_directory: false, bazel_module: { bp2build_available: true }, + apex_available: ["foo"], }`, ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{ "implementation_dynamic_deps": `select({ @@ -3096,6 +3105,7 @@ cc_library { ":quxlib", ], })`, + "tags": `["apex_available=foo"]`, }), }) } @@ -3322,6 +3332,7 @@ cc_library { MakeBazelTargetNoRestrictions("aidl_library", "A_aidl", AttrNameToString{ "srcs": `["aidl/A.aidl"]`, "strip_import_prefix": `"aidl"`, + "tags": `["apex_available=//apex_available:anyapex"]`, }), MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{ "srcs": `["B.aidl"]`, @@ -3591,42 +3602,57 @@ cc_library { }) } -func TestCcLibraryWithAidlAndSharedLibs(t *testing.T) { +func TestCcLibraryWithAidlAndLibs(t *testing.T) { runCcLibraryTestCase(t, Bp2buildTestCase{ - Description: "cc_aidl_library depends on shared libs from parent cc_library_static", + Description: "cc_aidl_library depends on libs from parent cc_library_static", ModuleTypeUnderTest: "cc_library", ModuleTypeUnderTestFactory: cc.LibraryFactory, Blueprint: ` cc_library_static { - name: "foo", - srcs: [ - "Foo.aidl", - ], + name: "foo", + srcs: [ + "Foo.aidl", + ], + static_libs: [ + "bar-static", + "baz-static", + ], shared_libs: [ - "bar", - "baz", + "bar-shared", + "baz-shared", + ], + export_static_lib_headers: [ + "baz-static", ], export_shared_lib_headers: [ - "baz", + "baz-shared", ], }` + - simpleModuleDoNotConvertBp2build("cc_library", "bar") + - simpleModuleDoNotConvertBp2build("cc_library", "baz"), + simpleModuleDoNotConvertBp2build("cc_library_static", "bar-static") + + simpleModuleDoNotConvertBp2build("cc_library_static", "baz-static") + + simpleModuleDoNotConvertBp2build("cc_library", "bar-shared") + + simpleModuleDoNotConvertBp2build("cc_library", "baz-shared"), ExpectedBazelTargets: []string{ MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{ "srcs": `["Foo.aidl"]`, }), MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ "deps": `[":foo_aidl_library"]`, + "implementation_deps": `[ + ":baz-static", + ":bar-static", + ]`, "implementation_dynamic_deps": `[ - ":baz", - ":bar", + ":baz-shared", + ":bar-shared", ]`, }), MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, - "dynamic_deps": `[":baz"]`, - "implementation_dynamic_deps": `[":bar"]`, + "deps": `[":baz-static"]`, + "implementation_deps": `[":bar-static"]`, + "dynamic_deps": `[":baz-shared"]`, + "implementation_dynamic_deps": `[":bar-shared"]`, "local_includes": `["."]`, }), }, diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index b685a2c30..8e0a728ab 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -556,6 +556,151 @@ cc_library_shared { }) } +func TestCcLibrarySharedStubs_UseImplementationInSameApex(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared stubs", + ModuleTypeUnderTest: "cc_library_shared", + ModuleTypeUnderTestFactory: cc.LibrarySharedFactory, + Blueprint: soongCcLibrarySharedPreamble + ` +cc_library_shared { + name: "a", + stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] }, + bazel_module: { bp2build_available: false }, + include_build_directory: false, + apex_available: ["made_up_apex"], +} +cc_library_shared { + name: "b", + shared_libs: [":a"], + include_build_directory: false, + apex_available: ["made_up_apex"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "b", AttrNameToString{ + "implementation_dynamic_deps": `[":a"]`, + "tags": `["apex_available=made_up_apex"]`, + }), + }, + }) +} + +func TestCcLibrarySharedStubs_UseStubsInDifferentApex(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared stubs", + ModuleTypeUnderTest: "cc_library_shared", + ModuleTypeUnderTestFactory: cc.LibrarySharedFactory, + Blueprint: soongCcLibrarySharedPreamble + ` +cc_library_shared { + name: "a", + stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] }, + bazel_module: { bp2build_available: false }, + include_build_directory: false, + apex_available: ["apex_a"], +} +cc_library_shared { + name: "b", + shared_libs: [":a"], + include_build_directory: false, + apex_available: ["apex_b"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "b", AttrNameToString{ + "implementation_dynamic_deps": `select({ + "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"], + "//conditions:default": [":a"], + })`, + "tags": `["apex_available=apex_b"]`, + }), + }, + }) +} + +func TestCcLibrarySharedStubs_IgnorePlatformAvailable(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared stubs", + ModuleTypeUnderTest: "cc_library_shared", + ModuleTypeUnderTestFactory: cc.LibrarySharedFactory, + Blueprint: soongCcLibrarySharedPreamble + ` +cc_library_shared { + name: "a", + stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] }, + bazel_module: { bp2build_available: false }, + include_build_directory: false, + apex_available: ["//apex_available:platform", "apex_a"], +} +cc_library_shared { + name: "b", + shared_libs: [":a"], + include_build_directory: false, + apex_available: ["//apex_available:platform", "apex_b"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "b", AttrNameToString{ + "implementation_dynamic_deps": `select({ + "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"], + "//conditions:default": [":a"], + })`, + "tags": `[ + "apex_available=//apex_available:platform", + "apex_available=apex_b", + ]`, + }), + }, + }) +} + +func TestCcLibrarySharedStubs_MultipleApexAvailable(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + ModuleTypeUnderTest: "cc_library_shared", + ModuleTypeUnderTestFactory: cc.LibrarySharedFactory, + Blueprint: soongCcLibrarySharedPreamble + ` +cc_library_shared { + name: "a", + stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] }, + bazel_module: { bp2build_available: false }, + include_build_directory: false, + apex_available: ["//apex_available:platform", "apex_a", "apex_b"], +} +cc_library_shared { + name: "b", + shared_libs: [":a"], + include_build_directory: false, + apex_available: ["//apex_available:platform", "apex_b"], +} + +cc_library_shared { + name: "c", + shared_libs: [":a"], + include_build_directory: false, + apex_available: ["//apex_available:platform", "apex_a", "apex_b"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "b", AttrNameToString{ + "implementation_dynamic_deps": `select({ + "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"], + "//conditions:default": [":a"], + })`, + "tags": `[ + "apex_available=//apex_available:platform", + "apex_available=apex_b", + ]`, + }), + MakeBazelTarget("cc_library_shared", "c", AttrNameToString{ + "implementation_dynamic_deps": `[":a"]`, + "tags": `[ + "apex_available=//apex_available:platform", + "apex_available=apex_a", + "apex_available=apex_b", + ]`, + }), + }, + }) +} + func TestCcLibrarySharedSystemSharedLibsSharedEmpty(t *testing.T) { runCcLibrarySharedTestCase(t, Bp2buildTestCase{ Description: "cc_library_shared system_shared_libs empty shared default", diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index 7c1803712..cd4cf51a1 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -1517,12 +1517,14 @@ cc_library_static { }, }, include_build_directory: false, + apex_available: ["foo"], } cc_library_static { name: "all", shared_libs: ["libc"], include_build_directory: false, + apex_available: ["foo"], } cc_library_static { @@ -1530,12 +1532,14 @@ cc_library_static { shared_libs: ["libc"], system_shared_libs: [], include_build_directory: false, + apex_available: ["foo"], } cc_library_static { name: "used_with_stubs", shared_libs: ["libm"], include_build_directory: false, + apex_available: ["foo"], } cc_library_static { @@ -1543,13 +1547,17 @@ cc_library_static { shared_libs: ["libm"], system_shared_libs: [], include_build_directory: false, + apex_available: ["foo"], } `, ExpectedBazelTargets: []string{ - MakeBazelTarget("cc_library_static", "all", AttrNameToString{}), + MakeBazelTarget("cc_library_static", "all", AttrNameToString{ + "tags": `["apex_available=foo"]`, + }), MakeBazelTarget("cc_library_static", "keep_for_empty_system_shared_libs", AttrNameToString{ "implementation_dynamic_deps": `[":libc"]`, "system_dynamic_deps": `[]`, + "tags": `["apex_available=foo"]`, }), MakeBazelTarget("cc_library_static", "keep_with_stubs", AttrNameToString{ "implementation_dynamic_deps": `select({ @@ -1557,9 +1565,14 @@ cc_library_static { "//conditions:default": [":libm"], })`, "system_dynamic_deps": `[]`, + "tags": `["apex_available=foo"]`, + }), + MakeBazelTarget("cc_library_static", "used_in_bionic_oses", AttrNameToString{ + "tags": `["apex_available=foo"]`, + }), + MakeBazelTarget("cc_library_static", "used_with_stubs", AttrNameToString{ + "tags": `["apex_available=foo"]`, }), - MakeBazelTarget("cc_library_static", "used_in_bionic_oses", AttrNameToString{}), - MakeBazelTarget("cc_library_static", "used_with_stubs", AttrNameToString{}), }, }) } diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go index e978fb319..7ce559d9b 100644 --- a/bp2build/filegroup_conversion_test.go +++ b/bp2build/filegroup_conversion_test.go @@ -74,6 +74,7 @@ func TestFilegroupWithAidlSrcs(t *testing.T) { expectedBazelAttrs: AttrNameToString{ "srcs": `["aidl/foo.aidl"]`, "strip_import_prefix": `"aidl"`, + "tags": `["apex_available=//apex_available:anyapex"]`, }, }, { @@ -85,18 +86,21 @@ func TestFilegroupWithAidlSrcs(t *testing.T) { }`, expectedBazelAttrs: AttrNameToString{ "srcs": `["aidl/foo.aidl"]`, + "tags": `["apex_available=//apex_available:anyapex"]`, }, }, } for _, test := range testcases { - expectedBazelTargets := []string{ - MakeBazelTargetNoRestrictions("aidl_library", "foo", test.expectedBazelAttrs), - } - runFilegroupTestCase(t, Bp2buildTestCase{ - Description: test.name, - Blueprint: test.bp, - ExpectedBazelTargets: expectedBazelTargets, + t.Run(test.name, func(t *testing.T) { + expectedBazelTargets := []string{ + MakeBazelTargetNoRestrictions("aidl_library", "foo", test.expectedBazelAttrs), + } + runFilegroupTestCase(t, Bp2buildTestCase{ + Description: test.name, + Blueprint: test.bp, + ExpectedBazelTargets: expectedBazelTargets, + }) }) } } @@ -136,7 +140,11 @@ filegroup { MakeBazelTargetNoRestrictions("proto_library", "foo_bp2build_converted", AttrNameToString{ "srcs": `["proto/foo.proto"]`, "strip_import_prefix": `"proto"`, - "tags": `["manual"]`}), + "tags": `[ + "apex_available=//apex_available:anyapex", + "manual", + ]`, + }), MakeBazelTargetNoRestrictions("filegroup", "foo", AttrNameToString{ "srcs": `["proto/foo.proto"]`}), }}) diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go index e3c485766..69d0db91c 100644 --- a/bp2build/java_library_conversion_test.go +++ b/bp2build/java_library_conversion_test.go @@ -493,6 +493,7 @@ java_library { "a.aidl", "b.aidl", ]`, + "tags": `["apex_available=//apex_available:anyapex"]`, }), MakeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{ "deps": `[":aidl_files"]`, diff --git a/bp2build/testing.go b/bp2build/testing.go index ee2ab0872..856b6eed9 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -228,6 +228,7 @@ type BazelTestResult struct { // // If ignoreUnexpected=true then it will ignore directories for which there are no expected targets. func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, description string, expectedTargets map[string][]string, ignoreUnexpected bool) { + t.Helper() actualTargets := b.buildFileToTargets // Generate the sorted set of directories to check. diff --git a/cc/binary.go b/cc/binary.go index 496c610c2..097f82252 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -512,7 +512,7 @@ func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) { } binary.baseInstaller.subDir = "bootstrap" } - binary.baseInstaller.install(ctx, file) + binary.baseInstaller.installExecutable(ctx, file) var preferredArchSymlinkPath android.OptionalPath for _, symlink := range binary.symlinks { diff --git a/cc/bp2build.go b/cc/bp2build.go index 67a697aac..7c817a2b1 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -65,6 +65,8 @@ type staticOrSharedAttributes struct { Native_coverage *bool + Apex_available []string + sdkAttributes tidyAttributes @@ -220,7 +222,7 @@ func bp2BuildPropParseHelper(ctx android.ArchVariantContext, module *Module, pro } // Parses properties common to static and shared libraries. Also used for prebuilt libraries. -func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, _ *libraryDecorator, isStatic bool) staticOrSharedAttributes { +func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes { attrs := staticOrSharedAttributes{} setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) { @@ -244,13 +246,16 @@ func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, mo // empty list -> no values specified attrs.System_dynamic_deps.ForceSpecifyEmptyList = true + var apexAvailable []string if isStatic { + apexAvailable = lib.StaticProperties.Static.Apex_available bp2BuildPropParseHelper(ctx, module, &StaticProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) { if staticOrSharedProps, ok := props.(*StaticProperties); ok { setAttrs(axis, config, staticOrSharedProps.Static) } }) } else { + apexAvailable = lib.SharedProperties.Shared.Apex_available bp2BuildPropParseHelper(ctx, module, &SharedProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) { if staticOrSharedProps, ok := props.(*SharedProperties); ok { setAttrs(axis, config, staticOrSharedProps.Shared) @@ -263,6 +268,8 @@ func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, mo attrs.Srcs_c = partitionedSrcs[cSrcPartition] attrs.Srcs_as = partitionedSrcs[asSrcPartition] + attrs.Apex_available = android.ConvertApexAvailableToTags(apexAvailable) + if !partitionedSrcs[protoSrcPartition].IsEmpty() { // TODO(b/208815215): determine whether this is used and add support if necessary ctx.ModuleErrorf("Migrating static/shared only proto srcs is not currently supported") @@ -732,7 +739,7 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) if baseLinkerProps, ok := archVariantLinkerProps[axis][cfg].(*BaseLinkerProperties); ok { exportHdrs = baseLinkerProps.Export_generated_headers - (&linkerAttrs).bp2buildForAxisAndConfig(ctx, module.Binary(), axis, cfg, baseLinkerProps) + (&linkerAttrs).bp2buildForAxisAndConfig(ctx, module, axis, cfg, baseLinkerProps) } headers := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrs, exportHdrs, android.BazelLabelForModuleDeps) implementationHdrs.SetSelectValue(axis, cfg, headers.implementation) @@ -900,6 +907,9 @@ func bp2buildCcAidlLibrary( return false }) + apexAvailableTags := android.ApexAvailableTags(ctx.Module()) + sdkAttrs := bp2BuildParseSdkAttributes(m) + if !aidlSrcs.IsEmpty() { aidlLibName := m.Name() + "_aidl_library" ctx.CreateBazelTargetModule( @@ -910,6 +920,7 @@ func bp2buildCcAidlLibrary( android.CommonAttributes{Name: aidlLibName}, &aidlLibraryAttributes{ Srcs: aidlSrcs, + Tags: apexAvailableTags, }, ) aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) @@ -917,15 +928,12 @@ func bp2buildCcAidlLibrary( if !aidlLibs.IsEmpty() { ccAidlLibrarylabel := m.Name() + "_cc_aidl_library" - // Since cc_aidl_library only needs the dynamic deps (aka shared libs) from the parent cc library for compiling, - // we err on the side of not re-exporting the headers of the dynamic deps from cc_aidl_lirary - // because the parent cc library already has all the dynamic deps - implementationDynamicDeps := bazel.MakeLabelListAttribute( - bazel.AppendBazelLabelLists( - linkerAttrs.dynamicDeps.Value, - linkerAttrs.implementationDynamicDeps.Value, - ), - ) + // Since parent cc_library already has these dependencies, we can add them as implementation + // deps so that they don't re-export + implementationDeps := linkerAttrs.deps.Clone() + implementationDeps.Append(linkerAttrs.implementationDeps) + implementationDynamicDeps := linkerAttrs.dynamicDeps.Clone() + implementationDynamicDeps.Append(linkerAttrs.implementationDynamicDeps) ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{ @@ -935,7 +943,10 @@ func bp2buildCcAidlLibrary( android.CommonAttributes{Name: ccAidlLibrarylabel}, &ccAidlLibraryAttributes{ Deps: aidlLibs, - Implementation_dynamic_deps: implementationDynamicDeps, + Implementation_deps: *implementationDeps, + Implementation_dynamic_deps: *implementationDynamicDeps, + Tags: apexAvailableTags, + sdkAttributes: sdkAttrs, }, ) label := &bazel.LabelAttribute{ @@ -1010,7 +1021,8 @@ func (la *linkerAttributes) resolveTargetApexProp(ctx android.BazelConversionPat la.implementationDeps.Append(staticExcludesLabelList) } -func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, isBinary bool, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) { +func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, module *Module, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) { + isBinary := module.Binary() // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module var axisFeatures []string @@ -1094,8 +1106,9 @@ func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversion // dependencies in NoConfigAxis and OsConfigurationAxis/OsAndroid are grouped by // having stubs or not, so Bazel select() statement can be used to choose // source/stub variants of them. - setStubsForDynamicDeps(ctx, axis, config, sharedDeps.export, &la.dynamicDeps, 0) - setStubsForDynamicDeps(ctx, axis, config, sharedDeps.implementation, &la.implementationDynamicDeps, 1) + apexAvailable := module.ApexAvailable() + setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, 0) + setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, 1) } if !BoolDefault(props.Pack_relocations, packRelocationsDefault) { @@ -1156,13 +1169,25 @@ var ( apiSurfaceModuleLibCurrentPackage = "@api_surfaces//" + android.ModuleLibApi.String() + "/current:" ) +func availableToSameApexes(a, b []string) bool { + if len(a) == 0 && len(b) == 0 { + return true + } + differ, _, _ := android.ListSetDifference(a, b) + return !differ +} + func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis, - config string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int) { + config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int) { + depsWithStubs := []bazel.Label{} for _, l := range dynamicLibs.Includes { dep, _ := ctx.ModuleFromName(l.OriginalModuleName) - if m, ok := dep.(*Module); ok && m.HasStubsVariants() { - depsWithStubs = append(depsWithStubs, l) + if d, ok := dep.(*Module); ok && d.HasStubsVariants() { + depApexAvailable := d.ApexAvailable() + if !availableToSameApexes(apexAvailable, depApexAvailable) { + depsWithStubs = append(depsWithStubs, l) + } } } if len(depsWithStubs) > 0 { @@ -1172,7 +1197,7 @@ func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.C stubLibLabels := []bazel.Label{} for _, l := range depsWithStubs { stubLabelInApiSurfaces := bazel.Label{ - Label: apiSurfaceModuleLibCurrentPackage + l.OriginalModuleName, + Label: apiSurfaceModuleLibCurrentPackage + strings.TrimPrefix(l.OriginalModuleName, ":"), } stubLibLabels = append(stubLibLabels, stubLabelInApiSurfaces) } @@ -609,6 +609,7 @@ type installer interface { inSanitizerDir() bool hostToolPath() android.OptionalPath relativeInstallPath() string + makeUninstallable(mod *Module) installInRoot() bool } @@ -2953,7 +2954,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { ctx.VisitDirectDeps(func(dep android.Module) { depName := ctx.OtherModuleName(dep) if apiLibrary, ok := targetOrigModuleList[depName]; ok { - if shouldUseStubForApex(ctx, dep) { + if ShouldUseStubForApex(ctx, dep) { skipModuleList[depName] = true } else { skipModuleList[apiLibrary] = true @@ -3306,7 +3307,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { return depPaths } -func shouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool { +func ShouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool { depName := ctx.OtherModuleName(dep) thisModule, ok := ctx.Module().(android.ApexModule) if !ok { @@ -3408,7 +3409,7 @@ func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibr if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedStubLibraries) > 0 { // when to use (unspecified) stubs, use the latest one. - if shouldUseStubForApex(ctx, dep) { + if ShouldUseStubForApex(ctx, dep) { stubs := sharedLibraryStubsInfo.SharedStubLibraries toUse := stubs[len(stubs)-1] sharedLibraryInfo = toUse.SharedLibraryInfo @@ -3524,6 +3525,14 @@ func (c *Module) InstallInRecovery() bool { return c.InRecovery() } +func (c *Module) MakeUninstallable() { + if c.installer == nil { + c.ModuleBase.MakeUninstallable() + return + } + c.installer.makeUninstallable(c) +} + func (c *Module) HostToolPath() android.OptionalPath { if c.installer == nil { return android.OptionalPath{} @@ -3861,6 +3870,7 @@ func (c *Module) UniqueApexVariations() bool { // When a vendor APEX needs a VNDK lib in it (use_vndk_as_stable: false), it should be a unique // APEX variation. Otherwise, another vendor APEX with use_vndk_as_stable:true may use a wrong // variation of the VNDK lib because APEX variations are merged/grouped. + // TODO(b/274401041) Find a way to merge APEX variations for vendor apexes. return c.UseVndk() && c.IsVndk() } diff --git a/cc/cc_test.go b/cc/cc_test.go index b02e037ed..b986511f0 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -3572,6 +3572,114 @@ func TestVersionedStubs(t *testing.T) { } } +func TestStubsForLibraryInMultipleApexes(t *testing.T) { + // TODO(b/275313114): Test exposes non-determinism which should be corrected and the test + // reenabled. + t.Skip() + t.Parallel() + ctx := testCc(t, ` + cc_library_shared { + name: "libFoo", + srcs: ["foo.c"], + stubs: { + symbol_file: "foo.map.txt", + versions: ["current"], + }, + apex_available: ["bar", "a1"], + } + + cc_library_shared { + name: "libBar", + srcs: ["bar.c"], + shared_libs: ["libFoo"], + apex_available: ["a1"], + } + + cc_library_shared { + name: "libA1", + srcs: ["a1.c"], + shared_libs: ["libFoo"], + apex_available: ["a1"], + } + + cc_library_shared { + name: "libBarA1", + srcs: ["bara1.c"], + shared_libs: ["libFoo"], + apex_available: ["bar", "a1"], + } + + cc_library_shared { + name: "libAnyApex", + srcs: ["anyApex.c"], + shared_libs: ["libFoo"], + apex_available: ["//apex_available:anyapex"], + } + + cc_library_shared { + name: "libBaz", + srcs: ["baz.c"], + shared_libs: ["libFoo"], + apex_available: ["baz"], + } + + cc_library_shared { + name: "libQux", + srcs: ["qux.c"], + shared_libs: ["libFoo"], + apex_available: ["qux", "bar"], + }`) + + variants := ctx.ModuleVariantsForTests("libFoo") + expectedVariants := []string{ + "android_arm64_armv8-a_shared", + "android_arm64_armv8-a_shared_current", + "android_arm_armv7-a-neon_shared", + "android_arm_armv7-a-neon_shared_current", + } + variantsMismatch := false + if len(variants) != len(expectedVariants) { + variantsMismatch = true + } else { + for _, v := range expectedVariants { + if !inList(v, variants) { + variantsMismatch = false + } + } + } + if variantsMismatch { + t.Errorf("variants of libFoo expected:\n") + for _, v := range expectedVariants { + t.Errorf("%q\n", v) + } + t.Errorf(", but got:\n") + for _, v := range variants { + t.Errorf("%q\n", v) + } + } + + linkAgainstFoo := []string{"libBarA1"} + linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"} + + libFooPath := "libFoo/android_arm64_armv8-a_shared/libFoo.so" + for _, lib := range linkAgainstFoo { + libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld") + libFlags := libLinkRule.Args["libFlags"] + if !strings.Contains(libFlags, libFooPath) { + t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags) + } + } + + libFooStubPath := "libFoo/android_arm64_armv8-a_shared_current/libFoo.so" + for _, lib := range linkAgainstFooStubs { + libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld") + libFlags := libLinkRule.Args["libFlags"] + if !strings.Contains(libFlags, libFooStubPath) { + t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags) + } + } +} + func TestVersioningMacro(t *testing.T) { t.Parallel() for _, tc := range []struct{ moduleName, expected string }{ diff --git a/cc/config/global.go b/cc/config/global.go index 6b45b1230..4d703e4c3 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -255,6 +255,7 @@ var ( "-Wno-bitwise-instead-of-logical", "-Wno-misleading-indentation", "-Wno-array-parameter", + "-Wno-gnu-offsetof-extensions", } // Extra cflags for external third-party projects to disable warnings that @@ -304,8 +305,8 @@ var ( // prebuilts/clang default settings. ClangDefaultBase = "prebuilts/clang/host" - ClangDefaultVersion = "clang-r475365b" - ClangDefaultShortVersion = "16.0.2" + ClangDefaultVersion = "clang-r487747" + ClangDefaultShortVersion = "17" // Directories with warnings from Android.bp files. WarningAllowedProjects = []string{ diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go index b3619c861..35c57f90f 100644 --- a/cc/config/riscv64_device.go +++ b/cc/config/riscv64_device.go @@ -26,12 +26,16 @@ var ( // Help catch common 32/64-bit errors. "-Werror=implicit-function-declaration", "-fno-emulated-tls", + // For -fsanitize=shadow-call-stack. + "-ffixed-x18", } riscv64ArchVariantCflags = map[string][]string{} riscv64Ldflags = []string{ "-Wl,--hash-style=gnu", + // For -fsanitize=shadow-call-stack. + "-ffixed-x18", } riscv64Lldflags = append(riscv64Ldflags, diff --git a/cc/coverage.go b/cc/coverage.go index a7356f879..c0f697398 100644 --- a/cc/coverage.go +++ b/cc/coverage.go @@ -219,10 +219,14 @@ func SetCoverageProperties(ctx android.BaseModuleContext, properties CoveragePro return properties } -// Coverage is an interface for non-CC modules to implement to be mutated for coverage -type Coverage interface { +type UseCoverage interface { android.Module IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool +} + +// Coverage is an interface for non-CC modules to implement to be mutated for coverage +type Coverage interface { + UseCoverage SetPreventInstall() HideFromMake() MarkAsCoverageVariant(bool) @@ -261,6 +265,11 @@ func coverageMutator(mctx android.BottomUpMutatorContext) { m[1].(Coverage).MarkAsCoverageVariant(true) m[1].(Coverage).EnableCoverageIfNeeded() + } else if cov, ok := mctx.Module().(UseCoverage); ok && cov.IsNativeCoverageNeeded(mctx) { + // Module itself doesn't have to have "cov" variant, but it should use "cov" variants of + // deps. + mctx.CreateVariations("cov") + mctx.AliasVariation("cov") } } diff --git a/cc/installer.go b/cc/installer.go index c3618b7c1..716a0dfc6 100644 --- a/cc/installer.go +++ b/cc/installer.go @@ -100,6 +100,10 @@ func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) { installer.path = ctx.InstallFile(installer.installDir(ctx), file.Base(), file) } +func (installer *baseInstaller) installExecutable(ctx ModuleContext, file android.Path) { + installer.path = ctx.InstallExecutable(installer.installDir(ctx), file.Base(), file) +} + func (installer *baseInstaller) everInstallable() bool { // Most cc modules are installable. return true @@ -121,6 +125,10 @@ func (installer *baseInstaller) relativeInstallPath() string { return String(installer.Properties.Relative_install_path) } +func (installer *baseInstaller) makeUninstallable(mod *Module) { + mod.ModuleBase.MakeUninstallable() +} + func (installer *baseInstaller) installInRoot() bool { return Bool(installer.Properties.Install_in_root) } diff --git a/cc/library.go b/cc/library.go index 842a05fcd..a9ada97d9 100644 --- a/cc/library.go +++ b/cc/library.go @@ -264,11 +264,15 @@ type bazelCcLibraryAttributes struct { type aidlLibraryAttributes struct { Srcs bazel.LabelListAttribute Include_dir *string + Tags bazel.StringListAttribute } type ccAidlLibraryAttributes struct { Deps bazel.LabelListAttribute + Implementation_deps bazel.LabelListAttribute Implementation_dynamic_deps bazel.LabelListAttribute + Tags bazel.StringListAttribute + sdkAttributes } type stripAttributes struct { @@ -427,8 +431,10 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { if compilerAttrs.stubsSymbolFile == nil && len(compilerAttrs.stubsVersions.Value) == 0 { tagsForStaticVariant = android.ApexAvailableTags(m) } + tagsForStaticVariant.Append(bazel.StringListAttribute{Value: staticAttrs.Apex_available}) tagsForSharedVariant := android.ApexAvailableTags(m) + tagsForSharedVariant.Append(bazel.StringListAttribute{Value: sharedAttrs.Apex_available}) ctx.CreateBazelTargetModuleWithRestrictions(staticProps, android.CommonAttributes{ @@ -2439,6 +2445,17 @@ func (library *libraryDecorator) installable() *bool { return nil } +func (library *libraryDecorator) makeUninstallable(mod *Module) { + if library.static() && library.buildStatic() && !library.buildStubs() { + // If we're asked to make a static library uninstallable we don't do + // anything since AndroidMkEntries always sets LOCAL_UNINSTALLABLE_MODULE + // for these entries. This is done to still get the make targets for NOTICE + // files from notice_files.mk, which other libraries might depend on. + return + } + mod.ModuleBase.MakeUninstallable() +} + func (library *libraryDecorator) getPartition() string { return library.path.Partition() } diff --git a/cc/prebuilt.go b/cc/prebuilt.go index c237d751f..5b7ba4346 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -214,7 +214,7 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext, // without the prefix hack below. if p.hasStubsVariants() && !p.buildStubs() && !ctx.Host() && !strings.HasPrefix(ctx.baseModuleName(), "libclang_rt.") { - ctx.Module().SkipInstall() + ctx.Module().MakeUninstallable() } return outputFile diff --git a/cc/sanitize.go b/cc/sanitize.go index d44573239..c899cc47e 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -254,7 +254,7 @@ type SanitizeUserProps struct { // This should not be used in Android 11+ : https://source.android.com/devices/tech/debug/scudo // deprecated Scudo *bool `android:"arch_variant"` - // shadow-call-stack sanitizer, only available on arm64 + // shadow-call-stack sanitizer, only available on arm64/riscv64. Scs *bool `android:"arch_variant"` // Memory-tagging, only available on arm64 // if diag.memtag unset or false, enables async memory tagging @@ -593,8 +593,8 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { s.Hwaddress = nil } - // SCS is only implemented on AArch64. - if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() { + // SCS is only implemented on AArch64/riscv64. + if (ctx.Arch().ArchType != android.Arm64 && ctx.Arch().ArchType != android.Riscv64) || !ctx.toolchain().Bionic() { s.Scs = nil } @@ -827,8 +827,13 @@ func (s *sanitize) flags(ctx ModuleContext, flags Flags) Flags { if Bool(sanProps.Memtag_stack) { flags.Local.CFlags = append(flags.Local.CFlags, memtagStackCommonFlags...) + // TODO(fmayer): remove -Wno-error once https://reviews.llvm.org/D127917 is in Android toolchain. + flags.Local.CFlags = append(flags.Local.CFlags, "-Wno-error=frame-larger-than") flags.Local.AsFlags = append(flags.Local.AsFlags, memtagStackCommonFlags...) flags.Local.LdFlags = append(flags.Local.LdFlags, memtagStackCommonFlags...) + // This works around LLD complaining about the stack frame size. + // TODO(fmayer): remove once https://reviews.llvm.org/D127917 is in Android toolchain. + flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-fatal-warnings") } if (Bool(sanProps.Memtag_heap) || Bool(sanProps.Memtag_stack)) && ctx.binary() { diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go index fe592dcb6..71c5a2298 100644 --- a/cc/sanitize_test.go +++ b/cc/sanitize_test.go @@ -28,12 +28,22 @@ import ( var prepareForAsanTest = android.FixtureAddFile("asan/Android.bp", []byte(` cc_library_shared { name: "libclang_rt.asan", + host_supported: true, + } + cc_library_static { + name: "libclang_rt.asan.static", + host_supported: true, + } + cc_library_static { + name: "libclang_rt.asan_cxx.static", + host_supported: true, } `)) var prepareForTsanTest = android.FixtureAddFile("tsan/Android.bp", []byte(` cc_library_shared { name: "libclang_rt.tsan", + host_supported: true, } `)) @@ -54,6 +64,19 @@ func expectSharedLinkDep(t *testing.T, ctx providerInterface, from, to android.T } } +// expectNoSharedLinkDep verifies that the from module links against the to module as a +// shared library. +func expectNoSharedLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) { + t.Helper() + fromLink := from.Description("link") + toInfo := ctx.ModuleProvider(to.Module(), SharedLibraryInfoProvider).(SharedLibraryInfo) + + if g, w := fromLink.OrderOnly.Strings(), toInfo.SharedLibrary.RelativeToTop().String(); android.InList(w, g) { + t.Errorf("%s should not link against %s, expected %q, got %q", + from.Module(), to.Module(), w, g) + } +} + // expectStaticLinkDep verifies that the from module links against the to module as a // static library. func expectStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) { @@ -68,6 +91,20 @@ func expectStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.T } +// expectNoStaticLinkDep verifies that the from module links against the to module as a +// static library. +func expectNoStaticLinkDep(t *testing.T, ctx providerInterface, from, to android.TestingModule) { + t.Helper() + fromLink := from.Description("link") + toInfo := ctx.ModuleProvider(to.Module(), StaticLibraryInfoProvider).(StaticLibraryInfo) + + if g, w := fromLink.Implicits.Strings(), toInfo.StaticLibrary.RelativeToTop().String(); android.InList(w, g) { + t.Errorf("%s should not link against %s, expected %q, got %q", + from.Module(), to.Module(), w, g) + } + +} + // expectInstallDep verifies that the install rule of the from module depends on the // install rule of the to module. func expectInstallDep(t *testing.T, from, to android.TestingModule) { @@ -85,6 +122,13 @@ func expectInstallDep(t *testing.T, from, to android.TestingModule) { } } +type expectedRuntimeLinkage int + +const ( + RUNTIME_LINKAGE_NONE = expectedRuntimeLinkage(0) + RUNTIME_LINKAGE_SHARED = iota +) + func TestAsan(t *testing.T) { t.Parallel() bp := ` @@ -162,12 +206,14 @@ func TestAsan(t *testing.T) { ` - result := android.GroupFixturePreparers( + preparer := android.GroupFixturePreparers( prepareForCcTest, prepareForAsanTest, - ).RunTestWithBp(t, bp) + ) + buildOS := preparer.RunTestWithBp(t, bp).Config.BuildOSTarget.String() - check := func(t *testing.T, result *android.TestResult, variant string) { + check := func(t *testing.T, variant string, runtimeLinkage expectedRuntimeLinkage, preparer android.FixturePreparer) { + result := preparer.RunTestWithBp(t, bp) ctx := result.TestContext asanVariant := variant + "_asan" sharedVariant := variant + "_shared" @@ -198,6 +244,8 @@ func TestAsan(t *testing.T) { libStaticAsan := result.ModuleForTests("libstatic_asan", staticAsanVariant) libStaticAsanNoAsanVariant := result.ModuleForTests("libstatic_asan", staticVariant) + libAsanSharedRuntime := result.ModuleForTests("libclang_rt.asan", sharedVariant) + expectSharedLinkDep(t, ctx, binWithAsan, libShared) expectSharedLinkDep(t, ctx, binWithAsan, libAsan) expectSharedLinkDep(t, ctx, libShared, libTransitive) @@ -227,10 +275,28 @@ func TestAsan(t *testing.T) { expectInstallDep(t, binNoAsan, libTransitive) expectInstallDep(t, libShared, libTransitive) expectInstallDep(t, libAsan, libTransitive) + + if runtimeLinkage == RUNTIME_LINKAGE_SHARED { + expectSharedLinkDep(t, ctx, binWithAsan, libAsanSharedRuntime) + expectNoSharedLinkDep(t, ctx, binNoAsan, libAsanSharedRuntime) + expectSharedLinkDep(t, ctx, libAsan, libAsanSharedRuntime) + expectNoSharedLinkDep(t, ctx, libShared, libAsanSharedRuntime) + expectNoSharedLinkDep(t, ctx, libTransitive, libAsanSharedRuntime) + } else { + expectNoSharedLinkDep(t, ctx, binWithAsan, libAsanSharedRuntime) + expectNoSharedLinkDep(t, ctx, binNoAsan, libAsanSharedRuntime) + expectNoSharedLinkDep(t, ctx, libAsan, libAsanSharedRuntime) + expectNoSharedLinkDep(t, ctx, libShared, libAsanSharedRuntime) + expectNoSharedLinkDep(t, ctx, libTransitive, libAsanSharedRuntime) + } } - t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) }) - t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") }) + t.Run("host", func(t *testing.T) { check(t, buildOS, RUNTIME_LINKAGE_NONE, preparer) }) + t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", RUNTIME_LINKAGE_SHARED, preparer) }) + t.Run("host musl", func(t *testing.T) { + check(t, "linux_musl_x86_64", RUNTIME_LINKAGE_SHARED, + android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl)) + }) } func TestTsan(t *testing.T) { @@ -278,12 +344,14 @@ func TestTsan(t *testing.T) { } ` - result := android.GroupFixturePreparers( + preparer := android.GroupFixturePreparers( prepareForCcTest, prepareForTsanTest, - ).RunTestWithBp(t, bp) + ) + buildOS := preparer.RunTestWithBp(t, bp).Config.BuildOSTarget.String() - check := func(t *testing.T, result *android.TestResult, variant string) { + check := func(t *testing.T, variant string, preparer android.FixturePreparer) { + result := preparer.RunTestWithBp(t, bp) ctx := result.TestContext tsanVariant := variant + "_tsan" sharedVariant := variant + "_shared" @@ -311,8 +379,11 @@ func TestTsan(t *testing.T) { expectSharedLinkDep(t, ctx, libTsan, libTransitive) } - t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) }) - t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") }) + t.Run("host", func(t *testing.T) { check(t, buildOS, preparer) }) + t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", preparer) }) + t.Run("host musl", func(t *testing.T) { + check(t, "linux_musl_x86_64", android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl)) + }) } func TestMiscUndefined(t *testing.T) { @@ -369,11 +440,13 @@ func TestMiscUndefined(t *testing.T) { } ` - result := android.GroupFixturePreparers( + preparer := android.GroupFixturePreparers( prepareForCcTest, - ).RunTestWithBp(t, bp) + ) + buildOS := preparer.RunTestWithBp(t, bp).Config.BuildOSTarget.String() - check := func(t *testing.T, result *android.TestResult, variant string) { + check := func(t *testing.T, variant string, preparer android.FixturePreparer) { + result := preparer.RunTestWithBp(t, bp) ctx := result.TestContext staticVariant := variant + "_static" @@ -415,8 +488,11 @@ func TestMiscUndefined(t *testing.T) { expectStaticLinkDep(t, ctx, binNoUbsan, libUbsan) } - t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) }) - t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") }) + t.Run("host", func(t *testing.T) { check(t, buildOS, preparer) }) + t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", preparer) }) + t.Run("host musl", func(t *testing.T) { + check(t, "linux_musl_x86_64", android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl)) + }) } func TestFuzz(t *testing.T) { @@ -647,11 +723,13 @@ func TestUbsan(t *testing.T) { } ` - result := android.GroupFixturePreparers( + preparer := android.GroupFixturePreparers( prepareForCcTest, - ).RunTestWithBp(t, bp) + ) + buildOS := preparer.RunTestWithBp(t, bp).Config.BuildOSTarget.String() - check := func(t *testing.T, result *android.TestResult, variant string) { + check := func(t *testing.T, variant string, preparer android.FixturePreparer) { + result := preparer.RunTestWithBp(t, bp) staticVariant := variant + "_static" sharedVariant := variant + "_shared" @@ -705,8 +783,11 @@ func TestUbsan(t *testing.T) { "-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base()) } - t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) }) - t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") }) + t.Run("host", func(t *testing.T) { check(t, buildOS, preparer) }) + t.Run("device", func(t *testing.T) { check(t, "android_arm64_armv8-a", preparer) }) + t.Run("host musl", func(t *testing.T) { + check(t, "linux_musl_x86_64", android.GroupFixturePreparers(preparer, PrepareForTestWithHostMusl)) + }) } type MemtagNoteType int diff --git a/cc/sysprop.go b/cc/sysprop.go index 2b1e354d3..0df290afa 100644 --- a/cc/sysprop.go +++ b/cc/sysprop.go @@ -22,11 +22,13 @@ import ( // TODO(b/240463568): Additional properties will be added for API validation type bazelSyspropLibraryAttributes struct { Srcs bazel.LabelListAttribute + Tags bazel.StringListAttribute } type bazelCcSyspropLibraryAttributes struct { Dep bazel.LabelAttribute Min_sdk_version *string + Tags bazel.StringListAttribute } type SyspropLibraryLabels struct { @@ -36,6 +38,7 @@ type SyspropLibraryLabels struct { } func Bp2buildSysprop(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLabels, srcs bazel.LabelListAttribute, minSdkVersion *string) { + apexAvailableTags := android.ApexAvailableTags(ctx.Module()) ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{ Rule_class: "sysprop_library", @@ -44,11 +47,14 @@ func Bp2buildSysprop(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLa android.CommonAttributes{Name: labels.SyspropLibraryLabel}, &bazelSyspropLibraryAttributes{ Srcs: srcs, - }) + Tags: apexAvailableTags, + }, + ) attrs := &bazelCcSyspropLibraryAttributes{ Dep: *bazel.MakeLabelAttribute(":" + labels.SyspropLibraryLabel), Min_sdk_version: minSdkVersion, + Tags: apexAvailableTags, } if labels.SharedLibraryLabel != "" { diff --git a/cc/testing.go b/cc/testing.go index 992069b5c..d38a57ca8 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -70,6 +70,7 @@ func commonDefaultModules() string { return ` cc_defaults { name: "toolchain_libs_defaults", + host_supported: true, vendor_available: true, product_available: true, recovery_available: true, @@ -135,6 +136,12 @@ func commonDefaultModules() string { } cc_prebuilt_library_static { + name: "libclang_rt.ubsan_standalone.static", + defaults: ["toolchain_libs_defaults"], + srcs: [""], + } + + cc_prebuilt_library_static { name: "libclang_rt.ubsan_minimal", defaults: ["toolchain_libs_defaults"], host_supported: true, @@ -151,6 +158,12 @@ func commonDefaultModules() string { linux_glibc_x86: { srcs: ["libclang_rt.ubsan_minimal.x86.a"], }, + linux_musl_x86_64: { + srcs: ["libclang_rt.ubsan_minimal.x86_64.a"], + }, + linux_musl_x86: { + srcs: ["libclang_rt.ubsan_minimal.x86.a"], + }, }, } @@ -619,6 +632,45 @@ var PrepareForTestWithCcIncludeVndk = android.GroupFixturePreparers( }), ) +// PrepareForTestWithHostMusl sets the host configuration to musl libc instead of glibc. It also disables the test +// on mac, which doesn't support musl libc, and adds musl modules. +var PrepareForTestWithHostMusl = android.GroupFixturePreparers( + android.FixtureModifyConfig(android.ModifyTestConfigForMusl), + android.PrepareForSkipTestOnMac, + android.FixtureAddTextFile("external/musl/Android.bp", ` + cc_defaults { + name: "libc_musl_crt_defaults", + host_supported: true, + device_supported: false, + } + + cc_object { + name: "libc_musl_crtbegin_so", + defaults: ["libc_musl_crt_defaults"], + } + + cc_object { + name: "libc_musl_crtend_so", + defaults: ["libc_musl_crt_defaults"], + } + + cc_object { + name: "libc_musl_crtbegin_dynamic", + defaults: ["libc_musl_crt_defaults"], + } + + cc_object { + name: "libc_musl_crtbegin_static", + defaults: ["libc_musl_crt_defaults"], + } + + cc_object { + name: "libc_musl_crtend", + defaults: ["libc_musl_crt_defaults"], + } + `), +) + // TestConfig is the legacy way of creating a test Config for testing cc modules. // // See testCc for an explanation as to how to stop using this deprecated method. diff --git a/cmd/extract_apks/main.go b/cmd/extract_apks/main.go index 82db634d0..2e71fe15e 100644 --- a/cmd/extract_apks/main.go +++ b/cmd/extract_apks/main.go @@ -41,6 +41,7 @@ type TargetConfig struct { abis map[android_bundle_proto.Abi_AbiAlias]int allowPrereleased bool stem string + skipSdkCheck bool } // An APK set is a zip archive. An entry 'toc.pb' describes its contents. @@ -322,6 +323,12 @@ type sdkVersionTargetingMatcher struct { func (m sdkVersionTargetingMatcher) matches(config TargetConfig) bool { const preReleaseVersion = 10000 + // TODO (b274518686) This check should only be used while SHA based targeting is active + // Once we have switched to an SDK version, this can be changed to throw an error if + // it was accidentally set + if config.skipSdkCheck == true { + return true + } if m.SdkVersionTargeting == nil { return true } @@ -572,7 +579,7 @@ func (s screenDensityFlagValue) Set(densityList string) error { func processArgs() { flag.Usage = func() { fmt.Fprintln(os.Stderr, `usage: extract_apks -o <output-file> [-zip <output-zip-file>] `+ - `-sdk-version value -abis value `+ + `-sdk-version value -abis value [-skip-sdk-check]`+ `-screen-densities value {-stem value | -extract-single} [-allow-prereleased] `+ `[-apkcerts <apkcerts output file> -partition <partition>] <APK set>`) flag.PrintDefaults() @@ -585,6 +592,7 @@ func processArgs() { "'all' or comma-separated list of screen density names (NODPI LDPI MDPI TVDPI HDPI XHDPI XXHDPI XXXHDPI)") flag.BoolVar(&targetConfig.allowPrereleased, "allow-prereleased", false, "allow prereleased") + flag.BoolVar(&targetConfig.skipSdkCheck, "skip-sdk-check", false, "Skip the SDK version check") flag.StringVar(&targetConfig.stem, "stem", "", "output entries base name in the output zip file") flag.Parse() if (*outputFile == "") || len(flag.Args()) != 1 || *version == 0 || diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go index 3d8458cf3..301246a88 100644 --- a/cmd/soong_ui/main.go +++ b/cmd/soong_ui/main.go @@ -169,7 +169,7 @@ func main() { // Create a new Status instance, which manages action counts and event output channels. stat := &status.Status{} - defer stat.Finish() + // Hook up the terminal output and tracer to Status. stat.AddOutput(output) stat.AddOutput(trace.StatusTracer()) @@ -221,13 +221,14 @@ func main() { trace.SetOutput(filepath.Join(logsDir, c.logsPrefix+"build.trace")) - if !config.SkipMetricsUpload() { - defer build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, bazelProfileFile, bazelMetricsFile, metricsFiles...) - } - defer met.Dump(soongMetricsFile) - // Should run before Metric.Dump - defer criticalPath.WriteToMetrics(met) - + defer func() { + stat.Finish() + criticalPath.WriteToMetrics(met) + met.Dump(soongMetricsFile) + if !config.SkipMetricsUpload() { + build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, bazelProfileFile, bazelMetricsFile, metricsFiles...) + } + }() c.run(buildCtx, config, args) } diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 25b8fe89c..023c69adf 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -22,6 +22,7 @@ import ( "strings" "android/soong/android" + "android/soong/cc" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -498,3 +499,11 @@ func sha1sum(values []string) string { } return fmt.Sprintf("%x", h.Sum(nil)) } + +// Base cc.UseCoverage + +var _ cc.UseCoverage = (*filesystem)(nil) + +func (*filesystem) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { + return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled() +} diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go index a65d9dd5f..aef475650 100644 --- a/filesystem/filesystem_test.go +++ b/filesystem/filesystem_test.go @@ -20,6 +20,9 @@ import ( "android/soong/android" "android/soong/cc" + "android/soong/etc" + + "github.com/google/blueprint/proptools" ) func TestMain(m *testing.M) { @@ -28,6 +31,7 @@ func TestMain(m *testing.M) { var fixture = android.GroupFixturePreparers( android.PrepareForIntegrationTestWithAndroid, + etc.PrepareForTestWithPrebuiltEtc, cc.PrepareForIntegrationTestWithCc, PrepareForTestWithFilesystemBuildComponents, ) @@ -225,3 +229,56 @@ func TestFileSystemShouldInstallCoreVariantIfTargetBuildAppsIsSet(t *testing.T) inputs.Strings(), "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so") } + +func TestFileSystemWithCoverageVariants(t *testing.T) { + context := android.GroupFixturePreparers( + fixture, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.GcovCoverage = proptools.BoolPtr(true) + variables.Native_coverage = proptools.BoolPtr(true) + }), + ) + + result := context.RunTestWithBp(t, ` + prebuilt_etc { + name: "prebuilt", + src: ":myfilesystem", + } + + android_system_image { + name: "myfilesystem", + deps: [ + "libfoo", + ], + linker_config_src: "linker.config.json", + } + + cc_library { + name: "libfoo", + shared_libs: [ + "libbar", + ], + stl: "none", + } + + cc_library { + name: "libbar", + stl: "none", + } + `) + + filesystem := result.ModuleForTests("myfilesystem", "android_common_cov") + inputs := filesystem.Output("deps.zip").Implicits + android.AssertStringListContains(t, "filesystem should have libfoo(cov)", + inputs.Strings(), + "out/soong/.intermediates/libfoo/android_arm64_armv8-a_shared_cov/libfoo.so") + android.AssertStringListContains(t, "filesystem should have libbar(cov)", + inputs.Strings(), + "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared_cov/libbar.so") + + filesystemOutput := filesystem.Output("myfilesystem.img").Output + prebuiltInput := result.ModuleForTests("prebuilt", "android_arm64_armv8-a").Rule("Cp").Input + if filesystemOutput != prebuiltInput { + t.Error("prebuilt should use cov variant of filesystem") + } +} diff --git a/java/aar.go b/java/aar.go index 4bc5465aa..f162a1722 100644 --- a/java/aar.go +++ b/java/aar.go @@ -220,12 +220,12 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkConte linkDeps = append(linkDeps, assetDeps...) // Returns the effective version for {min|target}_sdk_version - effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.SdkSpec) string { + effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.ApiLevel) string { // If {min|target}_sdk_version is current, use sdk_version to determine the effective level // This is necessary for vendor modules. // The effective version does not _only_ depend on {min|target}_sdk_version(level), // but also on the sdk_version (kind+level) - if minSdkVersion.ApiLevel.IsCurrent() { + if minSdkVersion.IsCurrent() { ret, err := sdkVersion.EffectiveVersionString(ctx) if err != nil { ctx.ModuleErrorf("invalid sdk_version: %s", err) @@ -689,7 +689,7 @@ type AARImport struct { jniPackages android.Paths sdkVersion android.SdkSpec - minSdkVersion android.SdkSpec + minSdkVersion android.ApiLevel } var _ android.OutputFileProducer = (*AARImport)(nil) @@ -714,19 +714,19 @@ func (a *AARImport) SystemModules() string { return "" } -func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { +func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { if a.properties.Min_sdk_version != nil { - return android.SdkSpecFrom(ctx, *a.properties.Min_sdk_version) + return android.ApiLevelFrom(ctx, *a.properties.Min_sdk_version) } - return a.SdkVersion(ctx) + return a.SdkVersion(ctx).ApiLevel } func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { return android.SdkSpecFrom(ctx, "") } -func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return a.SdkVersion(ctx) +func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return a.SdkVersion(ctx).ApiLevel } func (a *AARImport) javaVersion() string { diff --git a/java/android_manifest.go b/java/android_manifest.go index f6457a096..dbcf09830 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -44,14 +44,14 @@ var manifestMergerRule = pctx.AndroidStaticRule("manifestMerger", // When TARGET_BUILD_APPS is not empty, this method returns 10000 for modules targeting an unreleased SDK // This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK func targetSdkVersionForManifestFixer(ctx android.ModuleContext, params ManifestFixerParams) string { - targetSdkVersionSpec := params.SdkContext.TargetSdkVersion(ctx) + targetSdkVersionLevel := params.SdkContext.TargetSdkVersion(ctx) // Check if we want to return 10000 // TODO(b/240294501): Determine the rules for handling test apexes - if shouldReturnFinalOrFutureInt(ctx, targetSdkVersionSpec, params.EnforceDefaultTargetSdkVersion) { + if shouldReturnFinalOrFutureInt(ctx, targetSdkVersionLevel, params.EnforceDefaultTargetSdkVersion) { return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt()) } - targetSdkVersion, err := targetSdkVersionSpec.EffectiveVersionString(ctx) + targetSdkVersion, err := targetSdkVersionLevel.EffectiveVersionString(ctx) if err != nil { ctx.ModuleErrorf("invalid targetSdkVersion: %s", err) } @@ -62,11 +62,11 @@ func targetSdkVersionForManifestFixer(ctx android.ModuleContext, params Manifest // 1. The module is built in unbundled mode (TARGET_BUILD_APPS not empty) // 2. The module is run as part of MTS, and should be testable on stable branches // Do not return 10000 if we are enforcing default targetSdkVersion and sdk has been finalised -func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionSpec android.SdkSpec, enforceDefaultTargetSdkVersion bool) bool { +func shouldReturnFinalOrFutureInt(ctx android.ModuleContext, targetSdkVersionLevel android.ApiLevel, enforceDefaultTargetSdkVersion bool) bool { if enforceDefaultTargetSdkVersion && ctx.Config().PlatformSdkFinal() { return false } - return targetSdkVersionSpec.ApiLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module())) + return targetSdkVersionLevel.IsPreview() && (ctx.Config().UnbundledBuildApps() || includedInMts(ctx.Module())) } // Helper function that casts android.Module to java.androidTestApp diff --git a/java/androidmk.go b/java/androidmk.go index d73ff4616..a4dac80d4 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -76,6 +76,9 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { entriesList = append(entriesList, dexpreoptEntries...) } entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true}) + } else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) { + // Platform variant. If not available for the platform, we don't need Make module. + entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true}) } else { entriesList = append(entriesList, android.AndroidMkEntries{ Class: "JAVA_LIBRARIES", @@ -91,8 +94,7 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { entries.AddStrings("LOCAL_LOGTAGS_FILES", logtags...) } - if library.installFile == nil || !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) { - // If the ApexModule is not available for the platform, it shouldn't be installed. + if library.installFile == nil { entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", true) } if library.dexJarFile.IsSet() { diff --git a/java/app.go b/java/app.go index 4cc9e198e..52caf6d38 100755 --- a/java/app.go +++ b/java/app.go @@ -752,7 +752,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { type appDepsInterface interface { SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec - MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec + MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel RequiresStableAPIs(ctx android.BaseModuleContext) bool } @@ -865,10 +865,10 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { } else { toMinSdkVersion := "(no version)" if m, ok := to.(interface { - MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec + MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel }); ok { - if v := m.MinSdkVersion(ctx); !v.ApiLevel.IsNone() { - toMinSdkVersion = v.ApiLevel.String() + if v := m.MinSdkVersion(ctx); !v.IsNone() { + toMinSdkVersion = v.String() } } else if m, ok := to.(interface{ MinSdkVersion() string }); ok { // TODO(b/175678607) eliminate the use of MinSdkVersion returning @@ -1495,6 +1495,10 @@ func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *An ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs) } +type manifestValueAttribute struct { + MinSdkVersion *string +} + type bazelAndroidAppAttributes struct { *javaCommonAttributes *bazelAapt @@ -1502,6 +1506,7 @@ type bazelAndroidAppAttributes struct { Custom_package *string Certificate bazel.LabelAttribute Certificate_name bazel.StringAttribute + Manifest_values *manifestValueAttribute } // ConvertWithBp2build is used to convert android_app to Bazel. @@ -1516,11 +1521,23 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate) + manifestValues := &manifestValueAttribute{} + // TODO(b/274474008 ): Directly convert deviceProperties.Min_sdk_version in bp2build + // MinSdkVersion(ctx) calls SdkVersion(ctx) if no value for min_sdk_version is set + minSdkVersion := a.MinSdkVersion(ctx) + if !minSdkVersion.IsPreview() && !minSdkVersion.IsInvalid() { + minSdkStr, err := minSdkVersion.EffectiveVersionString(ctx) + if err == nil { + manifestValues.MinSdkVersion = &minSdkStr + } + } + appAttrs := &bazelAndroidAppAttributes{ // TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES Custom_package: a.overridableAppProperties.Package_name, Certificate: certificate, Certificate_name: certificateName, + Manifest_values: manifestValues, } props := bazel.BazelTargetModuleProperties{ diff --git a/java/app_import.go b/java/app_import.go index e24e7804e..c1de66745 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -426,8 +426,8 @@ func (a *AndroidAppImport) SdkVersion(ctx android.EarlyModuleContext) android.Sd return android.SdkSpecPrivate } -func (a *AndroidAppImport) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return android.SdkSpecPrivate +func (a *AndroidAppImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return android.SdkSpecPrivate.ApiLevel } func (a *AndroidAppImport) LintDepSets() LintDepSets { diff --git a/java/app_set.go b/java/app_set.go index 0f55b7791..d2d3b06ba 100644 --- a/java/app_set.go +++ b/java/app_set.go @@ -142,6 +142,7 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) "allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)), "screen-densities": screenDensities, "sdk-version": ctx.Config().PlatformSdkVersion().String(), + "skip-sdk-check": strconv.FormatBool(ctx.Config().IsEnvTrue("SOONG_SKIP_APPSET_SDK_CHECK")), "stem": as.BaseModuleName(), "apkcerts": as.apkcertsFile.String(), "partition": as.PartitionTag(ctx.DeviceConfig()), diff --git a/java/app_set_test.go b/java/app_set_test.go index 03eb66786..10bc5de92 100644 --- a/java/app_set_test.go +++ b/java/app_set_test.go @@ -89,6 +89,7 @@ func TestAndroidAppSet_Variants(t *testing.T) { "allow-prereleased": "false", "screen-densities": "LDPI,XXHDPI", "sdk-version": "29", + "skip-sdk-check": "false", "stem": "foo", }, }, @@ -105,6 +106,7 @@ func TestAndroidAppSet_Variants(t *testing.T) { "allow-prereleased": "false", "screen-densities": "all", "sdk-version": "30", + "skip-sdk-check": "false", "stem": "foo", }, }, diff --git a/java/app_test.go b/java/app_test.go index 5b16cea28..561be684e 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -3077,13 +3077,17 @@ func TestTargetSdkVersionManifestFixer(t *testing.T) { }, } for _, testCase := range testCases { + targetSdkVersionTemplate := "" + if testCase.targetSdkVersionInBp != "" { + targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp) + } bp := fmt.Sprintf(` android_app { name: "foo", sdk_version: "current", - target_sdk_version: "%v", + %s } - `, testCase.targetSdkVersionInBp) + `, targetSdkVersionTemplate) fixture := android.GroupFixturePreparers( prepareForJavaTest, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { @@ -3161,16 +3165,20 @@ func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) { }, } for _, testCase := range testCases { + targetSdkVersionTemplate := "" + if testCase.targetSdkVersionInBp != nil { + targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp) + } bp := fmt.Sprintf(` android_app { name: "foo", sdk_version: "current", min_sdk_version: "29", - target_sdk_version: "%v", + %s updatable: %t, enforce_default_target_sdk_version: %t } - `, proptools.String(testCase.targetSdkVersionInBp), testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable + `, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable fixture := android.GroupFixturePreparers( PrepareForTestWithJavaDefaultModules, diff --git a/java/base.go b/java/base.go index 85f4a5e06..2d213a192 100644 --- a/java/base.go +++ b/java/base.go @@ -489,7 +489,7 @@ type Module struct { hideApexVariantFromMake bool sdkVersion android.SdkSpec - minSdkVersion android.SdkSpec + minSdkVersion android.ApiLevel maxSdkVersion android.SdkSpec sourceExtensions []string @@ -665,11 +665,11 @@ func (j *Module) SystemModules() string { return proptools.String(j.deviceProperties.System_modules) } -func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { +func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { if j.deviceProperties.Min_sdk_version != nil { - return android.SdkSpecFrom(ctx, *j.deviceProperties.Min_sdk_version) + return android.ApiLevelFrom(ctx, *j.deviceProperties.Min_sdk_version) } - return j.SdkVersion(ctx) + return j.SdkVersion(ctx).ApiLevel } func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { @@ -685,14 +685,14 @@ func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) } func (j *Module) MinSdkVersionString() string { - return j.minSdkVersion.Raw + return j.minSdkVersion.String() } -func (j *Module) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { +func (j *Module) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { if j.deviceProperties.Target_sdk_version != nil { - return android.SdkSpecFrom(ctx, *j.deviceProperties.Target_sdk_version) + return android.ApiLevelFrom(ctx, *j.deviceProperties.Target_sdk_version) } - return j.SdkVersion(ctx) + return j.SdkVersion(ctx).ApiLevel } func (j *Module) AvailableFor(what string) bool { @@ -881,7 +881,7 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt j.ignoredAidlPermissionList = android.PathsForModuleSrcExcludes(ctx, exceptions, nil) } - aidlMinSdkVersion := j.MinSdkVersion(ctx).ApiLevel.String() + aidlMinSdkVersion := j.MinSdkVersion(ctx).String() flags = append(flags, "--min_sdk_version="+aidlMinSdkVersion) return strings.Join(flags, " "), deps @@ -1542,9 +1542,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { } if ctx.Device() { - lintSDKVersion := func(sdkSpec android.SdkSpec) int { - if v := sdkSpec.ApiLevel; !v.IsPreview() { - return v.FinalInt() + lintSDKVersion := func(apiLevel android.ApiLevel) int { + if !apiLevel.IsPreview() { + return apiLevel.FinalInt() } else { // When running metalava, we pass --version-codename. When that value // is not REL, metalava will add 1 to the --current-version argument. @@ -1576,7 +1576,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.linter.classes = j.implementationJarFile j.linter.minSdkVersion = lintSDKVersion(j.MinSdkVersion(ctx)) j.linter.targetSdkVersion = lintSDKVersion(j.TargetSdkVersion(ctx)) - j.linter.compileSdkVersion = lintSDKVersion(j.SdkVersion(ctx)) + j.linter.compileSdkVersion = lintSDKVersion(j.SdkVersion(ctx).ApiLevel) j.linter.compileSdkKind = j.SdkVersion(ctx).Kind j.linter.javaLanguageLevel = flags.javaVersion.String() j.linter.kotlinLanguageLevel = "1.3" @@ -1846,15 +1846,14 @@ func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu // Implements android.ApexModule func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { sdkVersionSpec := j.SdkVersion(ctx) - minSdkVersionSpec := j.MinSdkVersion(ctx) - if !minSdkVersionSpec.Specified() { + minSdkVersion := j.MinSdkVersion(ctx) + if !minSdkVersion.Specified() { return fmt.Errorf("min_sdk_version is not specified") } // If the module is compiling against core (via sdk_version), skip comparison check. if sdkVersionSpec.Kind == android.SdkCore { return nil } - minSdkVersion := minSdkVersionSpec.ApiLevel if minSdkVersion.GreaterThan(sdkVersion) { return fmt.Errorf("newer SDK(%v)", minSdkVersion) } @@ -1924,15 +1923,15 @@ func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret "stub-annotations", "private-stub-annotations-jar", "core-lambda-stubs", "core-generated-annotation-stubs": return javaCore, true - case "android_stubs_current": + case android.SdkPublic.JavaLibraryName(ctx.Config()): return javaSdk, true - case "android_system_stubs_current": + case android.SdkSystem.JavaLibraryName(ctx.Config()): return javaSystem, true - case "android_module_lib_stubs_current": + case android.SdkModule.JavaLibraryName(ctx.Config()): return javaModule, true - case "android_system_server_stubs_current": + case android.SdkSystemServer.JavaLibraryName(ctx.Config()): return javaSystemServer, true - case "android_test_stubs_current": + case android.SdkTest.JavaLibraryName(ctx.Config()): return javaSystem, true } diff --git a/java/builder.go b/java/builder.go index 6f8eec927..462626712 100644 --- a/java/builder.go +++ b/java/builder.go @@ -131,13 +131,13 @@ var ( blueprint.RuleParams{ Command: `rm -rf "$out" && ` + `${config.ExtractApksCmd} -o "${out}" -zip "${zip}" -allow-prereleased=${allow-prereleased} ` + - `-sdk-version=${sdk-version} -abis=${abis} ` + + `-sdk-version=${sdk-version} -skip-sdk-check=${skip-sdk-check} -abis=${abis} ` + `--screen-densities=${screen-densities} --stem=${stem} ` + `-apkcerts=${apkcerts} -partition=${partition} ` + `${in}`, CommandDeps: []string{"${config.ExtractApksCmd}"}, }, - "abis", "allow-prereleased", "screen-densities", "sdk-version", "stem", "apkcerts", "partition", "zip") + "abis", "allow-prereleased", "screen-densities", "sdk-version", "skip-sdk-check", "stem", "apkcerts", "partition", "zip") turbine, turbineRE = pctx.RemoteStaticRules("turbine", blueprint.RuleParams{ diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go index cf81ddb5d..45e6175f2 100644 --- a/java/classpath_fragment.go +++ b/java/classpath_fragment.go @@ -130,13 +130,13 @@ func configuredJarListToClasspathJars(ctx android.ModuleContext, configuredJars if s, ok := m.(*SdkLibrary); ok { // TODO(208456999): instead of mapping "current" to latest, min_sdk_version should never be set to "current" if s.minSdkVersion.Specified() { - if s.minSdkVersion.ApiLevel.IsCurrent() { + if s.minSdkVersion.IsCurrent() { jar.minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String() } else { - jar.minSdkVersion = s.minSdkVersion.ApiLevel.String() + jar.minSdkVersion = s.minSdkVersion.String() } } - if s.maxSdkVersion.Specified() { + if s.maxSdkVersion.ApiLevel.Specified() { if s.maxSdkVersion.ApiLevel.IsCurrent() { jar.maxSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String() } else { diff --git a/java/config/config.go b/java/config/config.go index 838d007a8..13670ee38 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -94,10 +94,12 @@ func init() { "-JXX:+TieredCompilation", "-JXX:TieredStopAtLevel=1", "-JDcom.android.tools.r8.emitRecordAnnotationsInDex", + "-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex", }, dexerJavaVmFlagsList...)) exportedVars.ExportStringListStaticVariable("R8Flags", append([]string{ "-JXmx2048M", "-JDcom.android.tools.r8.emitRecordAnnotationsInDex", + "-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex", }, dexerJavaVmFlagsList...)) exportedVars.ExportStringListStaticVariable("CommonJdkFlags", []string{ diff --git a/java/dex.go b/java/dex.go index 7b6a99a8a..4d6aa3456 100644 --- a/java/dex.go +++ b/java/dex.go @@ -343,7 +343,7 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Fl type compileDexParams struct { flags javaBuilderFlags sdkVersion android.SdkSpec - minSdkVersion android.SdkSpec + minSdkVersion android.ApiLevel classesJar android.Path jarName string } diff --git a/java/droiddoc.go b/java/droiddoc.go index e98b9ea29..c5a957e26 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -248,16 +248,16 @@ func (j *Javadoc) SystemModules() string { return proptools.String(j.properties.System_modules) } -func (j *Javadoc) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return j.SdkVersion(ctx) +func (j *Javadoc) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return j.SdkVersion(ctx).ApiLevel } func (j *Javadoc) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { return j.SdkVersion(ctx) } -func (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return j.SdkVersion(ctx) +func (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return j.SdkVersion(ctx).ApiLevel } func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) { @@ -304,7 +304,7 @@ func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Op flags = append(flags, "-I"+src.String()) } - minSdkVersion := j.MinSdkVersion(ctx).ApiLevel.FinalOrFutureInt() + minSdkVersion := j.MinSdkVersion(ctx).FinalOrFutureInt() flags = append(flags, fmt.Sprintf("--min_sdk_version=%v", minSdkVersion)) return strings.Join(flags, " "), deps diff --git a/java/hiddenapi.go b/java/hiddenapi.go index c4fc65f2e..d25096b15 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -73,7 +73,7 @@ type hiddenAPIModule interface { android.Module hiddenAPIIntf - MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec + MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel } type hiddenAPIIntf interface { @@ -157,7 +157,7 @@ func (h *hiddenAPI) hiddenAPIEncodeDex(ctx android.ModuleContext, dexJar android // Create a copy of the dex jar which has been encoded with hiddenapi flags. flagsCSV := hiddenAPISingletonPaths(ctx).flags outputDir := android.PathForModuleOut(ctx, "hiddenapi").OutputPath - encodedDex := hiddenAPIEncodeDex(ctx, dexJar, flagsCSV, uncompressDex, android.SdkSpecNone, outputDir) + encodedDex := hiddenAPIEncodeDex(ctx, dexJar, flagsCSV, uncompressDex, android.NoneApiLevel, outputDir) // Use the encoded dex jar from here onwards. return encodedDex @@ -253,7 +253,7 @@ var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", bluepr // The encode dex rule requires unzipping, encoding and rezipping the classes.dex files along with // all the resources from the input jar. It also ensures that if it was uncompressed in the input // it stays uncompressed in the output. -func hiddenAPIEncodeDex(ctx android.ModuleContext, dexInput, flagsCSV android.Path, uncompressDex bool, minSdkVersion android.SdkSpec, outputDir android.OutputPath) android.OutputPath { +func hiddenAPIEncodeDex(ctx android.ModuleContext, dexInput, flagsCSV android.Path, uncompressDex bool, minSdkVersion android.ApiLevel, outputDir android.OutputPath) android.OutputPath { // The output file has the same name as the input file and is in the output directory. output := outputDir.Join(ctx, dexInput.Base()) @@ -283,7 +283,7 @@ func hiddenAPIEncodeDex(ctx android.ModuleContext, dexInput, flagsCSV android.Pa // If the library is targeted for Q and/or R then make sure that they do not // have any S+ flags encoded as that will break the runtime. - minApiLevel := minSdkVersion.ApiLevel + minApiLevel := minSdkVersion if !minApiLevel.IsNone() { if minApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(ctx, "R")) { hiddenapiFlags = hiddenapiFlags + " --max-hiddenapi-level=max-target-r" diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index be4a48e5b..c6176e67c 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -236,9 +236,9 @@ func hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[*Hidden testStubModules = append(testStubModules, "sdk_test_current_android") } else { // Use stub modules built from source - publicStubModules = append(publicStubModules, "android_stubs_current") - systemStubModules = append(systemStubModules, "android_system_stubs_current") - testStubModules = append(testStubModules, "android_test_stubs_current") + publicStubModules = append(publicStubModules, android.SdkPublic.JavaLibraryName(config)) + systemStubModules = append(systemStubModules, android.SdkSystem.JavaLibraryName(config)) + testStubModules = append(testStubModules, android.SdkTest.JavaLibraryName(config)) } // We do not have prebuilts of the core platform api yet corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs") @@ -1278,7 +1278,7 @@ type bootDexInfo struct { uncompressDex bool // The minimum sdk version that the dex jar will be used on. - minSdkVersion android.SdkSpec + minSdkVersion android.ApiLevel } // bootDexInfoByModule is a map from module name (as returned by module.Name()) to the boot dex diff --git a/java/java.go b/java/java.go index 0841dad5e..370781599 100644 --- a/java/java.go +++ b/java/java.go @@ -811,7 +811,7 @@ func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberCo // If the min_sdk_version was set then add the canonical representation of the API level to the // snapshot. if j.deviceProperties.Min_sdk_version != nil { - canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.ApiLevel.String()) + canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String()) p.MinSdkVersion = proptools.StringPtr(canonical) } @@ -1874,7 +1874,7 @@ type Import struct { hideApexVariantFromMake bool sdkVersion android.SdkSpec - minSdkVersion android.SdkSpec + minSdkVersion android.ApiLevel } var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil) @@ -1891,11 +1891,11 @@ func (j *Import) SystemModules() string { return "none" } -func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { +func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { if j.properties.Min_sdk_version != nil { - return android.SdkSpecFrom(ctx, *j.properties.Min_sdk_version) + return android.ApiLevelFrom(ctx, *j.properties.Min_sdk_version) } - return j.SdkVersion(ctx) + return j.SdkVersion(ctx).ApiLevel } func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { @@ -1905,8 +1905,8 @@ func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) return android.SdkSpecFrom(ctx, "") } -func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return j.SdkVersion(ctx) +func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return j.SdkVersion(ctx).ApiLevel } func (j *Import) Prebuilt() *android.Prebuilt { @@ -2161,15 +2161,14 @@ func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { sdkVersionSpec := j.SdkVersion(ctx) - minSdkVersionSpec := j.MinSdkVersion(ctx) - if !minSdkVersionSpec.Specified() { + minSdkVersion := j.MinSdkVersion(ctx) + if !minSdkVersion.Specified() { return fmt.Errorf("min_sdk_version is not specified") } // If the module is compiling against core (via sdk_version), skip comparison check. if sdkVersionSpec.Kind == android.SdkCore { return nil } - minSdkVersion := minSdkVersionSpec.ApiLevel if minSdkVersion.GreaterThan(sdkVersion) { return fmt.Errorf("newer SDK(%v)", minSdkVersion) } @@ -2626,10 +2625,12 @@ type eventLogTagsAttributes struct { type aidlLibraryAttributes struct { Srcs bazel.LabelListAttribute + Tags bazel.StringListAttribute } type javaAidlLibraryAttributes struct { Deps bazel.LabelListAttribute + Tags bazel.StringListAttribute } // bp2BuildJavaInfo has information needed for the conversion of java*_modules @@ -2701,6 +2702,8 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) return android.IsConvertedToAidlLibrary(ctx, src.OriginalModuleName) }) + apexAvailableTags := android.ApexAvailableTags(ctx.Module()) + if !aidlSrcs.IsEmpty() { aidlLibName := m.Name() + "_aidl_library" ctx.CreateBazelTargetModule( @@ -2711,6 +2714,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) android.CommonAttributes{Name: aidlLibName}, &aidlLibraryAttributes{ Srcs: aidlSrcs, + Tags: apexAvailableTags, }, ) aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) @@ -2725,6 +2729,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) android.CommonAttributes{Name: javaAidlLibName}, &javaAidlLibraryAttributes{ Deps: aidlLibs, + Tags: apexAvailableTags, }, ) diff --git a/java/lint.go b/java/lint.go index 58b43dfdb..40ef48416 100644 --- a/java/lint.go +++ b/java/lint.go @@ -496,7 +496,6 @@ func (l *linter) lint(ctx android.ModuleContext) { FlagWithArg("--java-language-level ", l.javaLanguageLevel). FlagWithArg("--kotlin-language-level ", l.kotlinLanguageLevel). FlagWithArg("--url ", fmt.Sprintf(".=.,%s=out", android.PathForOutput(ctx).String())). - Flag("--exitcode"). Flag("--apply-suggestions"). // applies suggested fixes to files in the sandbox Flags(l.properties.Lint.Flags). Implicit(annotationsZipPath). @@ -505,6 +504,10 @@ func (l *linter) lint(ctx android.ModuleContext) { rule.Temporary(lintPaths.projectXML) rule.Temporary(lintPaths.configXML) + if exitCode := ctx.Config().Getenv("ANDROID_LINT_SUPPRESS_EXIT_CODE"); exitCode == "" { + cmd.Flag("--exitcode") + } + if checkOnly := ctx.Config().Getenv("ANDROID_LINT_CHECK"); checkOnly != "" { cmd.FlagWithArg("--check ", checkOnly) } diff --git a/java/rro.go b/java/rro.go index 9d0667cf0..6a9ad9aaa 100644 --- a/java/rro.go +++ b/java/rro.go @@ -175,19 +175,19 @@ func (r *RuntimeResourceOverlay) SystemModules() string { return "" } -func (r *RuntimeResourceOverlay) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { +func (r *RuntimeResourceOverlay) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { if r.properties.Min_sdk_version != nil { - return android.SdkSpecFrom(ctx, *r.properties.Min_sdk_version) + return android.ApiLevelFrom(ctx, *r.properties.Min_sdk_version) } - return r.SdkVersion(ctx) + return r.SdkVersion(ctx).ApiLevel } func (r *RuntimeResourceOverlay) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { return android.SdkSpecFrom(ctx, "") } -func (r *RuntimeResourceOverlay) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return r.SdkVersion(ctx) +func (r *RuntimeResourceOverlay) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return r.SdkVersion(ctx).ApiLevel } func (r *RuntimeResourceOverlay) Certificate() Certificate { diff --git a/java/sdk.go b/java/sdk.go index 1e7727b49..72a50067c 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -191,12 +191,8 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) bootclasspath: corePlatformBootclasspathLibraries(ctx), noFrameworksLibs: true, } - case android.SdkPublic: - return toModule("android_stubs_current", sdkFrameworkAidlPath(ctx)) - case android.SdkSystem: - return toModule("android_system_stubs_current", sdkFrameworkAidlPath(ctx)) - case android.SdkTest: - return toModule("android_test_stubs_current", sdkFrameworkAidlPath(ctx)) + case android.SdkPublic, android.SdkSystem, android.SdkTest: + return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), sdkFrameworkAidlPath(ctx)) case android.SdkCore: return sdkDep{ useModule: true, @@ -206,10 +202,10 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) } case android.SdkModule: // TODO(146757305): provide .apk and .aidl that have more APIs for modules - return toModule("android_module_lib_stubs_current", nonUpdatableFrameworkAidlPath(ctx)) + return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), nonUpdatableFrameworkAidlPath(ctx)) case android.SdkSystemServer: // TODO(146757305): provide .apk and .aidl that have more APIs for modules - return toModule("android_system_server_stubs_current", sdkFrameworkAidlPath(ctx)) + return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), sdkFrameworkAidlPath(ctx)) default: panic(fmt.Errorf("invalid sdk %q", sdkVersion.Raw)) } @@ -272,9 +268,9 @@ func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) { // Create framework.aidl by extracting anything that implements android.os.Parcelable from the SDK stubs modules. func createSdkFrameworkAidl(ctx android.SingletonContext) { stubsModules := []string{ - "android_stubs_current", - "android_test_stubs_current", - "android_system_stubs_current", + android.SdkPublic.JavaLibraryName(ctx.Config()), + android.SdkTest.JavaLibraryName(ctx.Config()), + android.SdkSystem.JavaLibraryName(ctx.Config()), } combinedAidl := sdkFrameworkAidlPath(ctx) @@ -289,7 +285,7 @@ func createSdkFrameworkAidl(ctx android.SingletonContext) { // Creates a version of framework.aidl for the non-updatable part of the platform. func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) { - stubsModules := []string{"android_module_lib_stubs_current"} + stubsModules := []string{android.SdkModule.JavaLibraryName(ctx.Config())} combinedAidl := nonUpdatableFrameworkAidlPath(ctx) tempPath := tempPathForRestat(ctx, combinedAidl) diff --git a/java/sdk_library.go b/java/sdk_library.go index d2fbfd953..5477ed664 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1231,7 +1231,7 @@ func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext) var _ android.ModuleWithMinSdkVersionCheck = (*SdkLibrary)(nil) func (module *SdkLibrary) CheckMinSdkVersion(ctx android.ModuleContext) { - android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx).ApiLevel, func(c android.ModuleContext, do android.PayloadDepsCallback) { + android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx), func(c android.ModuleContext, do android.PayloadDepsCallback) { ctx.WalkDeps(func(child android.Module, parent android.Module) bool { isExternal := !module.depIsInSameApex(ctx, child) if am, ok := child.(android.ApexModule); ok { @@ -1775,7 +1775,7 @@ func (module *SdkLibrary) UniqueApexVariations() bool { // Creates the xml file that publicizes the runtime library func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) { - moduleMinApiLevel := module.Library.MinSdkVersion(mctx).ApiLevel + moduleMinApiLevel := module.Library.MinSdkVersion(mctx) var moduleMinApiLevelStr = moduleMinApiLevel.String() if moduleMinApiLevel == android.NoneApiLevel { moduleMinApiLevelStr = "current" @@ -2414,8 +2414,8 @@ func (module *SdkLibraryImport) UniqueApexVariations() bool { } // MinSdkVersion - Implements hiddenAPIModule -func (module *SdkLibraryImport) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { - return android.SdkSpecNone +func (module *SdkLibraryImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { + return android.NoneApiLevel } var _ hiddenAPIModule = (*SdkLibraryImport)(nil) diff --git a/python/scripts/stub_template_host.txt b/python/scripts/stub_template_host.txt index 5eedc180c..2d1bd4a9b 100644 --- a/python/scripts/stub_template_host.txt +++ b/python/scripts/stub_template_host.txt @@ -3,6 +3,7 @@ import os import tempfile import shutil +import signal import sys import subprocess import zipfile @@ -43,7 +44,18 @@ def Main(): sys.stdout.flush() # close_fds=False so that you can run binaries with files provided on the command line: # my_python_app --file <(echo foo) - sys.exit(subprocess.call(args, close_fds=False)) + p = subprocess.Popen(args, close_fds=False) + + def handler(sig, frame): + p.send_signal(sig) + + # Redirect SIGINT and SIGTERM to subprocess + signal.signal(signal.SIGINT, handler) + signal.signal(signal.SIGTERM, handler) + + p.wait() + + sys.exit(p.returncode) finally: shutil.rmtree(runfiles_path, ignore_errors=True) diff --git a/python/test.go b/python/test.go index fb8e91806..31da17e61 100644 --- a/python/test.go +++ b/python/test.go @@ -15,6 +15,8 @@ package python import ( + "fmt" + "github.com/google/blueprint/proptools" "android/soong/android" @@ -63,7 +65,22 @@ type TestProperties struct { Java_data []string // Test options. - Test_options android.CommonTestOptions + Test_options TestOptions +} + +type TestOptions struct { + android.CommonTestOptions + + // Runner for the test. Supports "tradefed" and "mobly" (for multi-device tests). Default is "tradefed". + Runner *string + + // Metadata to describe the test configuration. + Metadata []Metadata +} + +type Metadata struct { + Name string + Value string } type PythonTestModule struct { @@ -94,14 +111,41 @@ func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext p.PythonLibraryModule.GenerateAndroidBuildActions(ctx) p.buildBinary(ctx) - p.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ - TestConfigProp: p.testProperties.Test_config, - TestConfigTemplateProp: p.testProperties.Test_config_template, - TestSuites: p.binaryProperties.Test_suites, - AutoGenConfig: p.binaryProperties.Auto_gen_config, - DeviceTemplate: "${PythonBinaryHostTestConfigTemplate}", - HostTemplate: "${PythonBinaryHostTestConfigTemplate}", - }) + var configs []tradefed.Option + for _, metadata := range p.testProperties.Test_options.Metadata { + configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: metadata.Name, Value: metadata.Value}) + } + + runner := proptools.StringDefault(p.testProperties.Test_options.Runner, "tradefed") + if runner == "tradefed" { + p.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ + TestConfigProp: p.testProperties.Test_config, + TestConfigTemplateProp: p.testProperties.Test_config_template, + TestSuites: p.binaryProperties.Test_suites, + OptionsForAutogenerated: configs, + AutoGenConfig: p.binaryProperties.Auto_gen_config, + DeviceTemplate: "${PythonBinaryHostTestConfigTemplate}", + HostTemplate: "${PythonBinaryHostTestConfigTemplate}", + }) + } else if runner == "mobly" { + if p.testProperties.Test_config != nil || p.testProperties.Test_config_template != nil || p.binaryProperties.Auto_gen_config != nil { + panic(fmt.Errorf("cannot set test_config, test_config_template or auto_gen_config for mobly test")) + } + + for _, testSuite := range p.binaryProperties.Test_suites { + if testSuite == "cts" { + configs = append(configs, tradefed.Option{Name: "test-suite-tag", Value: "cts"}) + break + } + } + p.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ + OptionsForAutogenerated: configs, + DeviceTemplate: "${PythonBinaryHostMoblyTestConfigTemplate}", + HostTemplate: "${PythonBinaryHostMoblyTestConfigTemplate}", + }) + } else { + panic(fmt.Errorf("unknown python test runner '%s', should be 'tradefed' or 'mobly'", runner)) + } p.installedDest = ctx.InstallFile(installDir(ctx, "nativetest", "nativetest64", ctx.ModuleName()), p.installSource.Base(), p.installSource) diff --git a/rust/bindgen.go b/rust/bindgen.go index 8cec918d3..13fa81e66 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -29,7 +29,7 @@ var ( defaultBindgenFlags = []string{""} // bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures. - bindgenClangVersion = "clang-r475365b" + bindgenClangVersion = "clang-r487747" _ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string { if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" { diff --git a/rust/config/global.go b/rust/config/global.go index 937502238..88949386c 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -24,7 +24,7 @@ import ( var pctx = android.NewPackageContext("android/soong/rust/config") var ( - RustDefaultVersion = "1.67.1" + RustDefaultVersion = "1.68.0" RustDefaultBase = "prebuilts/rust/" DefaultEdition = "2021" Stdlibs = []string{ diff --git a/rust/rust.go b/rust/rust.go index a200617de..018cdab98 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -26,6 +26,7 @@ import ( "android/soong/cc" cc_config "android/soong/cc/config" "android/soong/fuzz" + "android/soong/multitree" "android/soong/rust/config" "android/soong/snapshot" ) @@ -1147,10 +1148,56 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { mod.apexSdkVersion = android.FutureApiLevel } + skipModuleList := map[string]bool{} + + var apiImportInfo multitree.ApiImportInfo + hasApiImportInfo := false + + ctx.VisitDirectDeps(func(dep android.Module) { + if dep.Name() == "api_imports" { + apiImportInfo = ctx.OtherModuleProvider(dep, multitree.ApiImportsProvider).(multitree.ApiImportInfo) + hasApiImportInfo = true + } + }) + + if hasApiImportInfo { + targetStubModuleList := map[string]string{} + targetOrigModuleList := map[string]string{} + + // Search for dependency which both original module and API imported library with APEX stub exists + ctx.VisitDirectDeps(func(dep android.Module) { + depName := ctx.OtherModuleName(dep) + if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok { + targetStubModuleList[apiLibrary] = depName + } + }) + ctx.VisitDirectDeps(func(dep android.Module) { + depName := ctx.OtherModuleName(dep) + if origLibrary, ok := targetStubModuleList[depName]; ok { + targetOrigModuleList[origLibrary] = depName + } + }) + + // Decide which library should be used between original and API imported library + ctx.VisitDirectDeps(func(dep android.Module) { + depName := ctx.OtherModuleName(dep) + if apiLibrary, ok := targetOrigModuleList[depName]; ok { + if cc.ShouldUseStubForApex(ctx, dep) { + skipModuleList[depName] = true + } else { + skipModuleList[apiLibrary] = true + } + } + }) + } + ctx.VisitDirectDeps(func(dep android.Module) { depName := ctx.OtherModuleName(dep) depTag := ctx.OtherModuleDependencyTag(dep) + if _, exists := skipModuleList[depName]; exists { + return + } if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() { //Handle Rust Modules makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName) @@ -1406,6 +1453,16 @@ func linkPathFromFilePath(filepath android.Path) string { return strings.Split(filepath.String(), filepath.Base())[0] } +// usePublicApi returns true if the rust variant should link against NDK (publicapi) +func (r *Module) usePublicApi() bool { + return r.Device() && r.UseSdk() +} + +// useVendorApi returns true if the rust variant should link against LLNDK (vendorapi) +func (r *Module) useVendorApi() bool { + return r.Device() && (r.InVendor() || r.InProduct()) +} + func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { ctx := &depsContext{ BottomUpMutatorContext: actx, @@ -1416,8 +1473,10 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { var snapshotInfo *cc.SnapshotInfo apiImportInfo := cc.GetApiImports(mod, actx) - for idx, lib := range deps.SharedLibs { - deps.SharedLibs[idx] = cc.GetReplaceModuleName(lib, apiImportInfo.SharedLibs) + if mod.usePublicApi() || mod.useVendorApi() { + for idx, lib := range deps.SharedLibs { + deps.SharedLibs[idx] = cc.GetReplaceModuleName(lib, apiImportInfo.SharedLibs) + } } if ctx.Os() == android.Android { @@ -1497,7 +1556,15 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { variations := []blueprint.Variation{ {Mutator: "link", Variation: "shared"}, } - cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false) + // For core variant, add a dep on the implementation (if it exists) and its .apiimport (if it exists) + // GenerateAndroidBuildActions will pick the correct impl/stub based on the api_domain boundary + if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) { + cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false) + } + + if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok { + cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, apiLibraryName, version, false) + } } for _, lib := range deps.WholeStaticLibs { diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh index b57963b34..0d14019a5 100755 --- a/scripts/build-ndk-prebuilts.sh +++ b/scripts/build-ndk-prebuilts.sh @@ -19,7 +19,12 @@ if [ -z "${OUT_DIR}" ]; then exit 1 fi -TARGET_PRODUCT=ndk build/soong/soong_ui.bash --make-mode --soong-only ${OUT_DIR}/soong/ndk.timestamp +# TODO: remove ALLOW_MISSING_DEPENDENCIES=true when all the riscv64 +# dependencies exist (currently blocked by http://b/273792258). +# TODO: remove BUILD_BROKEN_DISABLE_BAZEL=1 when bazel supports riscv64 (http://b/262192655). +ALLOW_MISSING_DEPENDENCIES=true \ +BUILD_BROKEN_DISABLE_BAZEL=1 \ + TARGET_PRODUCT=ndk build/soong/soong_ui.bash --make-mode --soong-only ${OUT_DIR}/soong/ndk.timestamp if [ -n "${DIST_DIR}" ]; then mkdir -p ${DIST_DIR} || true diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index efb97be37..0d6496dd3 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -839,6 +839,7 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { compile_dex: true, public: {enabled: true}, permitted_packages: ["mysdklibrary"], + min_sdk_version: "current", } java_sdk_library { diff --git a/sdk/update.go b/sdk/update.go index 0820d62b8..d98ab683d 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -357,6 +357,12 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) { // If the minApiLevel of the member is greater than the target API level then exclude it from // this snapshot. exclude := memberVariantDep.minApiLevel.GreaterThan(targetApiLevel) + // Always include host variants (e.g. host tools) in the snapshot. + // Host variants should not be guarded by a min_sdk_version check. In fact, host variants + // do not have a `min_sdk_version`. + if memberVariantDep.Host() { + exclude = false + } addMember(name, export, exclude) @@ -1263,6 +1269,11 @@ type sdkMemberVariantDep struct { minApiLevel android.ApiLevel } +// Host returns true if the sdk member is a host variant (e.g. host tool) +func (s *sdkMemberVariantDep) Host() bool { + return s.variant.Target().Os.Class == android.Host +} + var _ android.SdkMember = (*sdkMember)(nil) // sdkMember groups all the variants of a specific member module together along with the name of the diff --git a/tests/dcla_apex_comparison_test.sh b/tests/dcla_apex_comparison_test.sh index 2ecb876fb..97ae97ecb 100755 --- a/tests/dcla_apex_comparison_test.sh +++ b/tests/dcla_apex_comparison_test.sh @@ -112,7 +112,7 @@ function compare_dcla_libs() { sha="${sha% *}" if [ "${prev_sha}" == "" ]; then prev_sha="${sha}" - elif [ "${sha}" != "${prev_sha}" ]; then + elif [ "${sha}" != "${prev_sha}" ] && { [ "${lib}" != "libcrypto.so" ] || [ "${module}" != "com.android.tethering" ]; }; then echo "Test failed, ${lib} has different hash value" exit 1 fi diff --git a/tests/lib.sh b/tests/lib.sh index 0973beb7f..2bcb63089 100644 --- a/tests/lib.sh +++ b/tests/lib.sh @@ -164,5 +164,6 @@ function scan_and_run_tests { fi for f in ${test_fns[*]}; do $f + info "Completed test case \e[96;1m$f\e[0m" done } diff --git a/tradefed/config.go b/tradefed/config.go index 999424cfb..326a00666 100644 --- a/tradefed/config.go +++ b/tradefed/config.go @@ -31,6 +31,7 @@ func init() { pctx.SourcePathVariable("NativeBenchmarkTestConfigTemplate", "build/make/core/native_benchmark_test_config_template.xml") pctx.SourcePathVariable("NativeHostTestConfigTemplate", "build/make/core/native_host_test_config_template.xml") pctx.SourcePathVariable("NativeTestConfigTemplate", "build/make/core/native_test_config_template.xml") + pctx.SourcePathVariable("PythonBinaryHostMoblyTestConfigTemplate", "build/make/core/python_binary_host_mobly_test_config_template.xml") pctx.SourcePathVariable("PythonBinaryHostTestConfigTemplate", "build/make/core/python_binary_host_test_config_template.xml") pctx.SourcePathVariable("RustDeviceTestConfigTemplate", "build/make/core/rust_device_test_config_template.xml") pctx.SourcePathVariable("RustHostTestConfigTemplate", "build/make/core/rust_host_test_config_template.xml") diff --git a/ui/build/soong.go b/ui/build/soong.go index 655ae35ec..871e63785 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -168,7 +168,7 @@ func (pb PrimaryBuilderFactory) primaryBuilderInvocation() bootstrap.PrimaryBuil commonArgs = append(commonArgs, "-t") } - if !pb.config.multitreeBuild { + if pb.config.multitreeBuild { commonArgs = append(commonArgs, "--multitree-build") } |