From 88960aa827de544a69cfb24609040e5efe006520 Mon Sep 17 00:00:00 2001 From: Yi-Yo Chiang Date: Fri, 19 Jan 2024 15:02:29 +0800 Subject: [PATCH] cc: Vendor modules should NOT derive its "SDK" level from VNDK Although vendor modules can be built bundled, they are technially not part of the "platform", as it cannot access platform libraries (system partition) directly. They can only link to a restricted set of platform libraries (LLNDK), and access restricted set of APIs. We used to derive the LLNDK API level from the VNDK version. However after VNDK deprecation, there is no "VNDK version" anymore. Instead we would just derive the value from platform SDK version: * If building an in-development build, build vendor modules against the in-development "current" API level. * If building a REL / Final build, vendor should target the latest stable API. Bug: 320423828 Test: go test Test: presubmit Test: build and boot Change-Id: I2c5ef6530e9046b2dcc282bc1f020d8a505eab15 --- android/config.go | 4 ++++ cc/cc.go | 16 ++++++++++++++-- cc/cc_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ cc/object_test.go | 12 +++++++++--- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/android/config.go b/android/config.go index eb1e647d4..f1c2918e8 100644 --- a/android/config.go +++ b/android/config.go @@ -1309,6 +1309,10 @@ func (c *config) VendorApiLevel() string { return String(c.productVariables.VendorApiLevel) } +func (c *config) VendorApiLevelFrozen() bool { + return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN") +} + func (c *deviceConfig) Arches() []Arch { var arches []Arch for _, target := range c.config.Targets[Android] { diff --git a/cc/cc.go b/cc/cc.go index c07e35850..5a901e530 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1608,9 +1608,10 @@ func (ctx *moduleContextImpl) useSdk() bool { func (ctx *moduleContextImpl) sdkVersion() string { if ctx.ctx.Device() { - if ctx.useVndk() { + config := ctx.ctx.Config() + if !config.IsVndkDeprecated() && ctx.useVndk() { vndkVer := ctx.mod.VndkVersion() - if inList(vndkVer, ctx.ctx.Config().PlatformVersionActiveCodenames()) { + if inList(vndkVer, config.PlatformVersionActiveCodenames()) { return "current" } return vndkVer @@ -1628,6 +1629,17 @@ func (ctx *moduleContextImpl) minSdkVersion() string { if ver == "apex_inherit" || ver == "" { ver = ctx.sdkVersion() } + + if ctx.ctx.Device() { + config := ctx.ctx.Config() + if config.IsVndkDeprecated() && ctx.inVendor() { + // If building for vendor with final API, then use the latest _stable_ API as "current". + if config.VendorApiLevelFrozen() && (ver == "" || ver == "current") { + ver = config.PlatformSdkVersion().String() + } + } + } + // For crt objects, the meaning of min_sdk_version is very different from other types of // module. For them, min_sdk_version defines the oldest version that the build system will // create versioned variants for. For example, if min_sdk_version is 16, then sdk variant of diff --git a/cc/cc_test.go b/cc/cc_test.go index 321bd380b..6cc500b5f 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -43,6 +43,7 @@ var prepareForCcTest = android.GroupFixturePreparers( android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.VendorApiLevel = StringPtr("202404") variables.DeviceVndkVersion = StringPtr("current") + variables.KeepVndk = BoolPtr(true) variables.Platform_vndk_version = StringPtr("29") }), ) @@ -4843,3 +4844,43 @@ func TestImageVariantsWithoutVndk(t *testing.T) { testDepWithVariant("vendor") testDepWithVariant("product") } + +func TestVendorSdkVersionWithoutVndk(t *testing.T) { + t.Parallel() + + bp := ` + cc_library { + name: "libfoo", + srcs: ["libfoo.cc"], + vendor_available: true, + } + + cc_library { + name: "libbar", + srcs: ["libbar.cc"], + vendor_available: true, + min_sdk_version: "29", + } + ` + + ctx := prepareForCcTestWithoutVndk.RunTestWithBp(t, bp) + testSdkVersionFlag := func(module, version string) { + flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"] + android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version) + } + + testSdkVersionFlag("libfoo", "10000") + testSdkVersionFlag("libbar", "29") + + ctx = android.GroupFixturePreparers( + prepareForCcTestWithoutVndk, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + if variables.BuildFlags == nil { + variables.BuildFlags = make(map[string]string) + } + variables.BuildFlags["RELEASE_BOARD_API_LEVEL_FROZEN"] = "true" + }), + ).RunTestWithBp(t, bp) + testSdkVersionFlag("libfoo", "30") + testSdkVersionFlag("libbar", "29") +} diff --git a/cc/object_test.go b/cc/object_test.go index e6a3fdd45..c0d133190 100644 --- a/cc/object_test.go +++ b/cc/object_test.go @@ -22,7 +22,7 @@ import ( ) func TestMinSdkVersionsOfCrtObjects(t *testing.T) { - ctx := testCc(t, ` + bp := ` cc_object { name: "crt_foo", srcs: ["foo.c"], @@ -30,8 +30,8 @@ func TestMinSdkVersionsOfCrtObjects(t *testing.T) { stl: "none", min_sdk_version: "28", vendor_available: true, - }`) - + } + ` variants := []struct { variant string num string @@ -43,11 +43,17 @@ func TestMinSdkVersionsOfCrtObjects(t *testing.T) { {"android_arm64_armv8-a_sdk_current", "10000"}, {"android_vendor.29_arm64_armv8-a", "29"}, } + + ctx := prepareForCcTest.RunTestWithBp(t, bp) for _, v := range variants { cflags := ctx.ModuleForTests("crt_foo", v.variant).Rule("cc").Args["cFlags"] expected := "-target aarch64-linux-android" + v.num + " " android.AssertStringDoesContain(t, "cflag", cflags, expected) } + ctx = prepareForCcTestWithoutVndk.RunTestWithBp(t, bp) + android.AssertStringDoesContain(t, "cflag", + ctx.ModuleForTests("crt_foo", "android_vendor_arm64_armv8-a").Rule("cc").Args["cFlags"], + "-target aarch64-linux-android10000 ") } func TestUseCrtObjectOfCorrectVersion(t *testing.T) {