__ANDROID_API__ tracks min_sdk_version

Previously, for cc_* modules, __ANDROID_API__ tracked the sdk_version
property. This however has caused a few number of problems:

1. It's confusing. __ANDROID_API__ has meant minSdkVersion. Therefore
the sdk_version property should mean minSdkVersion (since the macro
tracks the property). However, the introduction of the new
min_sdk_version property (which is currently for APEX) made this very
confusing. Also, this is not consistent with the java_* modules where
sdk_version means compileSdkVersion.

2. This is preventing go/android-future-symbols. The plan is to make the
APIs that are above the minSdkVersion available as weak symbols.
Previously those APIs had to be accessed via dlsym because they are
hidden behind the __ANDROID_API__ macro at build-time. To use make the
APIs visible at build-time, the module authors had to __ANDROID_API__
beyond their minSdkVersion. This is against the definition of
__ANDROID_API__.

To solve above problems, __ANDROID_API__ now correctly tracks
min_sdk_version. In addition, min_sdk_version now defaults to
sdk_version. Therefore, most of the modules that don't set
min_sdk_version aren't affected by this change.

Bug: 163288375
Test: m
Change-Id: I645e6bb1234c27ae0a69b7b87a59206cfd350744
This commit is contained in:
Jiyong Park 2020-08-10 15:59:36 +09:00
parent fb49bd190a
commit b35a819834
2 changed files with 50 additions and 4 deletions

View file

@ -256,11 +256,27 @@ type BaseProperties struct {
// Deprecated. true is the default, false is invalid.
Clang *bool `android:"arch_variant"`
// Minimum sdk version supported when compiling against the ndk. Setting this property causes
// two variants to be built, one for the platform and one for apps.
// The API level that this module is built against. The APIs of this API level will be
// visible at build time, but use of any APIs newer than min_sdk_version will render the
// module unloadable on older devices. In the future it will be possible to weakly-link new
// APIs, making the behavior match Java: such modules will load on older devices, but
// calling new APIs on devices that do not support them will result in a crash.
//
// This property has the same behavior as sdk_version does for Java modules. For those
// familiar with Android Gradle, the property behaves similarly to how compileSdkVersion
// does for Java code.
//
// In addition, setting this property causes two variants to be built, one for the platform
// and one for apps.
Sdk_version *string
// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
// Minimum OS API level supported by this C or C++ module. This property becomes the value
// of the __ANDROID_API__ macro. When the C or C++ module is included in an APEX or an APK,
// this property is also used to ensure that the min_sdk_version of the containing module is
// not older (i.e. less) than this module's min_sdk_version. When not set, this property
// defaults to the value of sdk_version. When this is set to "apex_inherit", this tracks
// min_sdk_version of the containing APEX. When the module
// is not built for an APEX, "apex_inherit" defaults to sdk_version.
Min_sdk_version *string
// If true, always create an sdk variant and don't create a platform variant.
@ -428,6 +444,8 @@ type ModuleContextIntf interface {
canUseSdk() bool
useSdk() bool
sdkVersion() string
minSdkVersion() string
isSdkVariant() bool
useVndk() bool
isNdk(config android.Config) bool
IsLlndk() bool
@ -1300,6 +1318,29 @@ func (ctx *moduleContextImpl) sdkVersion() string {
return ""
}
func (ctx *moduleContextImpl) minSdkVersion() string {
ver := ctx.mod.MinSdkVersion()
if ver == "apex_inherit" && !ctx.isForPlatform() {
ver = ctx.apexSdkVersion().String()
}
if ver == "apex_inherit" || ver == "" {
ver = ctx.sdkVersion()
}
// Also make sure that minSdkVersion is not greater than sdkVersion, if they are both numbers
sdkVersionInt, err := strconv.Atoi(ctx.sdkVersion())
minSdkVersionInt, err2 := strconv.Atoi(ver)
if err == nil && err2 == nil {
if sdkVersionInt < minSdkVersionInt {
return strconv.Itoa(sdkVersionInt)
}
}
return ver
}
func (ctx *moduleContextImpl) isSdkVariant() bool {
return ctx.mod.IsSdkVariant()
}
func (ctx *moduleContextImpl) useVndk() bool {
return ctx.mod.UseVndk()
}

View file

@ -404,7 +404,12 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
target := "-target " + tc.ClangTriple()
if ctx.Os().Class == android.Device {
version := ctx.sdkVersion()
// When built for the non-updateble part of platform, minSdkVersion doesn't matter.
// It matters only when building we are building for modules that can be unbundled.
version := "current"
if !ctx.isForPlatform() || ctx.isSdkVariant() {
version = ctx.minSdkVersion()
}
if version == "" || version == "current" {
target += strconv.Itoa(android.FutureApiLevelInt)
} else {