diff --git a/java/java.go b/java/java.go index 9955be9c6..fa4aee43d 100644 --- a/java/java.go +++ b/java/java.go @@ -777,7 +777,18 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) string { var ret string - sdk, err := sdkVersionToNumber(ctx, sdkContext.sdkVersion()) + v := sdkContext.sdkVersion() + // For PDK builds, use the latest SDK version instead of "current" + if ctx.Config().IsPdkBuild() && (v == "" || v == "current") { + sdkVersions := ctx.Config().Get(sdkSingletonKey).([]int) + latestSdkVersion := 0 + if len(sdkVersions) > 0 { + latestSdkVersion = sdkVersions[len(sdkVersions)-1] + } + v = strconv.Itoa(latestSdkVersion) + } + + sdk, err := sdkVersionToNumber(ctx, v) if err != nil { ctx.PropertyErrorf("sdk_version", "%s", err) } diff --git a/java/java_test.go b/java/java_test.go index 889cae762..570efb70c 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -98,6 +98,7 @@ func testContext(config android.Config, bp string, ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel() }) ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory)) + ctx.RegisterPreSingletonType("sdk", android.SingletonFactoryAdaptor(sdkSingletonFactory)) // Register module types and mutators from cc needed for JNI testing ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory)) @@ -181,6 +182,9 @@ func testContext(config android.Config, bp string, "prebuilts/sdk/14/public/android.jar": nil, "prebuilts/sdk/14/public/framework.aidl": nil, "prebuilts/sdk/14/system/android.jar": nil, + "prebuilts/sdk/17/public/android.jar": nil, + "prebuilts/sdk/17/public/framework.aidl": nil, + "prebuilts/sdk/17/system/android.jar": nil, "prebuilts/sdk/current/core/android.jar": nil, "prebuilts/sdk/current/public/android.jar": nil, "prebuilts/sdk/current/public/framework.aidl": nil, diff --git a/java/sdk.go b/java/sdk.go index cd128d13e..988610f5b 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -19,10 +19,17 @@ import ( "android/soong/java/config" "fmt" "path/filepath" + "sort" "strconv" "strings" ) +func init() { + android.RegisterPreSingletonType("sdk", sdkSingletonFactory) +} + +const sdkSingletonKey = "sdkSingletonKey" + type sdkContext interface { // sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set. sdkVersion() string @@ -67,28 +74,22 @@ func sdkVersionToNumberAsString(ctx android.BaseContext, v string) (string, erro func decodeSdkDep(ctx android.BaseContext, sdkContext sdkContext) sdkDep { v := sdkContext.sdkVersion() + // For PDK builds, use the latest SDK version instead of "current" + if ctx.Config().IsPdkBuild() && (v == "" || v == "current") { + sdkVersions := ctx.Config().Get(sdkSingletonKey).([]int) + latestSdkVersion := 0 + if len(sdkVersions) > 0 { + latestSdkVersion = sdkVersions[len(sdkVersions)-1] + } + v = strconv.Itoa(latestSdkVersion) + } + i, err := sdkVersionToNumber(ctx, v) if err != nil { ctx.PropertyErrorf("sdk_version", "%s", err) return sdkDep{} } - // Ensures that the specificed system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor apks) - // or PRODUCT_SYSTEMSDK_VERSIONS (for other apks or when BOARD_SYSTEMSDK_VERSIONS is not set) - if strings.HasPrefix(v, "system_") && i != android.FutureApiLevel { - allowed_versions := ctx.DeviceConfig().PlatformSystemSdkVersions() - if ctx.DeviceSpecific() || ctx.SocSpecific() { - if len(ctx.DeviceConfig().SystemSdkVersions()) > 0 { - allowed_versions = ctx.DeviceConfig().SystemSdkVersions() - } - } - version := strings.TrimPrefix(v, "system_") - if len(allowed_versions) > 0 && !android.InList(version, allowed_versions) { - ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q", - v, allowed_versions) - } - } - toPrebuilt := func(sdk string) sdkDep { var api, v string if strings.Contains(sdk, "_") { @@ -148,6 +149,22 @@ func decodeSdkDep(ctx android.BaseContext, sdkContext sdkContext) sdkDep { return ret } + // Ensures that the specificed system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor apks) + // or PRODUCT_SYSTEMSDK_VERSIONS (for other apks or when BOARD_SYSTEMSDK_VERSIONS is not set) + if strings.HasPrefix(v, "system_") && i != android.FutureApiLevel { + allowed_versions := ctx.DeviceConfig().PlatformSystemSdkVersions() + if ctx.DeviceSpecific() || ctx.SocSpecific() { + if len(ctx.DeviceConfig().SystemSdkVersions()) > 0 { + allowed_versions = ctx.DeviceConfig().SystemSdkVersions() + } + } + version := strings.TrimPrefix(v, "system_") + if len(allowed_versions) > 0 && !android.InList(version, allowed_versions) { + ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q", + v, allowed_versions) + } + } + if ctx.Config().UnbundledBuildPrebuiltSdks() && v != "" { return toPrebuilt(v) } @@ -170,3 +187,32 @@ func decodeSdkDep(ctx android.BaseContext, sdkContext sdkContext) sdkDep { return toPrebuilt(v) } } + +func sdkSingletonFactory() android.Singleton { + return sdkSingleton{} +} + +type sdkSingleton struct{} + +func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) { + sdkJars, err := ctx.GlobWithDeps("prebuilts/sdk/*/public/android.jar", nil) + if err != nil { + ctx.Errorf("failed to glob prebuilts/sdk/*/public/android.jar: %s", err.Error()) + } + + var sdkVersions []int + for _, sdkJar := range sdkJars { + dir := filepath.Base(filepath.Dir(filepath.Dir(sdkJar))) + v, err := strconv.Atoi(dir) + if scerr, ok := err.(*strconv.NumError); ok && scerr.Err == strconv.ErrSyntax { + continue + } else if err != nil { + ctx.Errorf("invalid sdk jar %q, %s, %v", sdkJar, err.Error()) + } + sdkVersions = append(sdkVersions, v) + } + + sort.Ints(sdkVersions) + + ctx.Config().Once(sdkSingletonKey, func() interface{} { return sdkVersions }) +} diff --git a/java/sdk_test.go b/java/sdk_test.go index ced772908..6924e2654 100644 --- a/java/sdk_test.go +++ b/java/sdk_test.go @@ -27,6 +27,7 @@ import ( var classpathTestcases = []struct { name string unbundled bool + pdk bool moduleType string host android.OsClass properties string @@ -155,6 +156,30 @@ var classpathTestcases = []struct { system: "bootclasspath", // special value to tell 1.9 test to expect bootclasspath classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, }, + + { + name: "pdk default", + pdk: true, + bootclasspath: []string{`""`}, + system: "bootclasspath", // special value to tell 1.9 test to expect bootclasspath + classpath: []string{"prebuilts/sdk/17/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + }, + { + name: "pdk current", + pdk: true, + properties: `sdk_version: "current",`, + bootclasspath: []string{`""`}, + system: "bootclasspath", // special value to tell 1.9 test to expect bootclasspath + classpath: []string{"prebuilts/sdk/17/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + }, + { + name: "pdk 14", + pdk: true, + properties: `sdk_version: "14",`, + bootclasspath: []string{`""`}, + system: "bootclasspath", // special value to tell 1.9 test to expect bootclasspath + classpath: []string{"prebuilts/sdk/14/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + }, } func TestClasspath(t *testing.T) { @@ -209,6 +234,9 @@ func TestClasspath(t *testing.T) { if testcase.unbundled { config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) } + if testcase.pdk { + config.TestProductVariables.Pdk = proptools.BoolPtr(true) + } ctx := testContext(config, bp, nil) run(t, ctx, config) @@ -241,6 +269,9 @@ func TestClasspath(t *testing.T) { if testcase.unbundled { config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) } + if testcase.pdk { + config.TestProductVariables.Pdk = proptools.BoolPtr(true) + } ctx := testContext(config, bp, nil) run(t, ctx, config)