Loading android/api_levels.go +11 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android import ( "encoding/json" "fmt" "strconv" ) Loading Loading @@ -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) { Loading apex/apex.go +4 −8 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import ( "path/filepath" "regexp" "sort" "strconv" "strings" "sync" Loading Loading @@ -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 Loading apex/apex_test.go +56 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 { Loading cc/library.go +8 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 } Loading cc/library_test.go +54 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package cc import ( "reflect" "testing" "android/soong/android" ) func TestLibraryReuse(t *testing.T) { Loading Loading @@ -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
android/api_levels.go +11 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android import ( "encoding/json" "fmt" "strconv" ) Loading Loading @@ -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) { Loading
apex/apex.go +4 −8 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import ( "path/filepath" "regexp" "sort" "strconv" "strings" "sync" Loading Loading @@ -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 Loading
apex/apex_test.go +56 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 { Loading
cc/library.go +8 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 } Loading
cc/library_test.go +54 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package cc import ( "reflect" "testing" "android/soong/android" ) func TestLibraryReuse(t *testing.T) { Loading Loading @@ -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) }