Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28a49820 authored by Jooyung Han's avatar Jooyung Han Committed by Gerrit Code Review
Browse files

Merge "Apex: support codenames for min_sdk_version"

parents 52c0b7b3 aed150d6
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ package android

import (
	"encoding/json"
	"fmt"
	"strconv"
)

@@ -84,14 +85,19 @@ func getApiLevelsMap(config Config) map[string]int {
// Converts an API level string into its numeric form.
// * Codenames are decoded.
// * Numeric API levels are simply converted.
// * "minimum" and "current" are not currently handled since the former is
//   NDK specific and the latter has inconsistent meaning.
// * "current" is mapped to FutureApiLevel(10000)
// * "minimum" is NDK specific and not handled with this. (refer normalizeNdkApiLevel in cc.go)
func ApiStrToNum(ctx BaseModuleContext, apiLevel string) (int, error) {
	num, ok := getApiLevelsMap(ctx.Config())[apiLevel]
	if ok {
	if apiLevel == "current" {
		return FutureApiLevel, nil
	}
	if num, ok := getApiLevelsMap(ctx.Config())[apiLevel]; ok {
		return num, nil
	}
	if num, err := strconv.Atoi(apiLevel); err == nil {
		return num, nil
	}
	return strconv.Atoi(apiLevel)
	return 0, fmt.Errorf("SDK version should be one of \"current\", <number> or <codename>: %q", apiLevel)
}

func (a *apiLevelsSingleton) GenerateBuildActions(ctx SingletonContext) {
+4 −8
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import (
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"sync"

@@ -1806,14 +1805,11 @@ func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext, do payloadDepsCa

func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) int {
	ver := proptools.StringDefault(a.properties.Min_sdk_version, "current")
	if ver != "current" {
		minSdkVersion, err := strconv.Atoi(ver)
	intVer, err := android.ApiStrToNum(ctx, ver)
	if err != nil {
			ctx.PropertyErrorf("min_sdk_version", "should be \"current\" or <number>, but %q", ver)
		ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
	}
		return minSdkVersion
	}
	return android.FutureApiLevel
	return intVer
}

// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
+56 −2
Original line number Diff line number Diff line
@@ -1144,6 +1144,60 @@ func TestApexUseStubsAccordingToMinSdkVersionInUnbundledBuild(t *testing.T) {
	expectNoLink("liba", "shared_otherapex", "libz", "shared")
}

func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
			name: "myapex",
			key: "myapex.key",
			native_shared_libs: ["libx"],
			min_sdk_version: "R",
		}

		apex_key {
			name: "myapex.key",
			public_key: "testkey.avbpubkey",
			private_key: "testkey.pem",
		}

		cc_library {
			name: "libx",
			shared_libs: ["libz"],
			system_shared_libs: [],
			stl: "none",
			apex_available: [ "myapex" ],
		}

		cc_library {
			name: "libz",
			system_shared_libs: [],
			stl: "none",
			stubs: {
				versions: ["29", "R"],
			},
		}
	`, func(fs map[string][]byte, config android.Config) {
		config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
	})

	expectLink := func(from, from_variant, to, to_variant string) {
		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
		ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
	}
	expectNoLink := func(from, from_variant, to, to_variant string) {
		ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
		ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
	}
	// 9000 is quite a magic number.
	// Finalized SDK codenames are mapped as P(28), Q(29), ...
	// And, codenames which are not finalized yet(active_codenames + future_codenames) are numbered from 9000, 9001, ...
	// to distinguish them from finalized and future_api(10000)
	// In this test, "R" is assumed not finalized yet( listed in Platform_version_active_codenames) and translated into 9000
	// (refer android/api_levels.go)
	expectLink("libx", "shared_myapex", "libz", "shared_9000")
	expectNoLink("libx", "shared_myapex", "libz", "shared_29")
	expectNoLink("libx", "shared_myapex", "libz", "shared")
}

func TestApexMinSdkVersionDefaultsToLatest(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
@@ -1334,11 +1388,11 @@ func TestInvalidMinSdkVersion(t *testing.T) {
		}
	`)

	testApexError(t, `"myapex" .*: min_sdk_version: should be "current" or <number>`, `
	testApexError(t, `"myapex" .*: min_sdk_version: SDK version should be .*`, `
		apex {
			name: "myapex",
			key: "myapex.key",
			min_sdk_version: "R",
			min_sdk_version: "abc",
		}

		apex_key {
+8 −4
Original line number Diff line number Diff line
@@ -1501,18 +1501,22 @@ func LatestStubsVersionFor(config android.Config, name string) string {
	return ""
}

func checkVersions(ctx android.BaseModuleContext, versions []string) {
func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
	numVersions := make([]int, len(versions))
	for i, v := range versions {
		numVer, err := strconv.Atoi(v)
		numVer, err := android.ApiStrToNum(ctx, v)
		if err != nil {
			ctx.PropertyErrorf("versions", "%q is not a number", v)
			ctx.PropertyErrorf("versions", "%s", err.Error())
			return
		}
		numVersions[i] = numVer
	}
	if !sort.IsSorted(sort.IntSlice(numVersions)) {
		ctx.PropertyErrorf("versions", "not sorted: %v", versions)
	}
	for i, v := range numVersions {
		versions[i] = strconv.Itoa(v)
	}
}

func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) {
@@ -1542,7 +1546,7 @@ func VersionMutator(mctx android.BottomUpMutatorContext) {
	if library, ok := mctx.Module().(LinkableInterface); ok && VersionVariantAvailable(library) {
		if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 {
			versions := library.StubsVersions()
			checkVersions(mctx, versions)
			normalizeVersions(mctx, versions)
			if mctx.Failed() {
				return
			}
+54 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ package cc
import (
	"reflect"
	"testing"

	"android/soong/android"
)

func TestLibraryReuse(t *testing.T) {
@@ -186,3 +188,55 @@ func TestLibraryReuse(t *testing.T) {
		}
	})
}

func TestStubsVersions(t *testing.T) {
	bp := `
		cc_library {
			name: "libfoo",
			srcs: ["foo.c"],
			stubs: {
				versions: ["29", "R", "10000"],
			},
		}
	`
	config := TestConfig(buildDir, android.Android, nil, bp, nil)
	config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
	ctx := testCcWithConfig(t, config)

	variants := ctx.ModuleVariantsForTests("libfoo")
	for _, expectedVer := range []string{"29", "9000", "10000"} {
		expectedVariant := "android_arm_armv7-a-neon_shared_" + expectedVer
		if !inList(expectedVariant, variants) {
			t.Errorf("missing expected variant: %q", expectedVariant)
		}
	}
}

func TestStubsVersions_NotSorted(t *testing.T) {
	bp := `
		cc_library {
			name: "libfoo",
			srcs: ["foo.c"],
			stubs: {
				versions: ["29", "10000", "R"],
			},
		}
	`
	config := TestConfig(buildDir, android.Android, nil, bp, nil)
	config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
	testCcErrorWithConfig(t, `"libfoo" .*: versions: not sorted`, config)
}

func TestStubsVersions_ParseError(t *testing.T) {
	bp := `
		cc_library {
			name: "libfoo",
			srcs: ["foo.c"],
			stubs: {
				versions: ["29", "10000", "X"],
			},
		}
	`

	testCcError(t, `"libfoo" .*: versions: SDK version should be`, bp)
}
Loading