sdk.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. // Copyright 2019 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package java
  15. import (
  16. "fmt"
  17. "path/filepath"
  18. "sort"
  19. "strconv"
  20. "android/soong/android"
  21. "android/soong/java/config"
  22. "github.com/google/blueprint/pathtools"
  23. )
  24. func init() {
  25. android.RegisterPreSingletonType("sdk_versions", sdkPreSingletonFactory)
  26. android.RegisterParallelSingletonType("sdk", sdkSingletonFactory)
  27. android.RegisterMakeVarsProvider(pctx, sdkMakeVars)
  28. }
  29. var sdkVersionsKey = android.NewOnceKey("sdkVersionsKey")
  30. var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
  31. var nonUpdatableFrameworkAidlPathKey = android.NewOnceKey("nonUpdatableFrameworkAidlPathKey")
  32. var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")
  33. func UseApiFingerprint(ctx android.BaseModuleContext) bool {
  34. if ctx.Config().UnbundledBuild() &&
  35. !ctx.Config().AlwaysUsePrebuiltSdks() &&
  36. ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
  37. return true
  38. }
  39. return false
  40. }
  41. func defaultJavaLanguageVersion(ctx android.EarlyModuleContext, s android.SdkSpec) javaVersion {
  42. sdk, err := s.EffectiveVersion(ctx)
  43. if err != nil {
  44. ctx.PropertyErrorf("sdk_version", "%s", err)
  45. }
  46. if sdk.FinalOrFutureInt() <= 23 {
  47. return JAVA_VERSION_7
  48. } else if sdk.FinalOrFutureInt() <= 29 {
  49. return JAVA_VERSION_8
  50. } else if sdk.FinalOrFutureInt() <= 31 {
  51. return JAVA_VERSION_9
  52. } else if sdk.FinalOrFutureInt() <= 33 {
  53. return JAVA_VERSION_11
  54. } else {
  55. return JAVA_VERSION_17
  56. }
  57. }
  58. // systemModuleKind returns the kind of system modules to use for the supplied combination of sdk
  59. // kind and API level.
  60. func systemModuleKind(sdkKind android.SdkKind, apiLevel android.ApiLevel) android.SdkKind {
  61. systemModuleKind := sdkKind
  62. if apiLevel.LessThanOrEqualTo(android.LastWithoutModuleLibCoreSystemModules) {
  63. // API levels less than or equal to 31 did not provide a core-for-system-modules.jar
  64. // specifically for the module-lib API. So, always use the public system modules for them.
  65. systemModuleKind = android.SdkPublic
  66. } else if systemModuleKind == android.SdkCore {
  67. // Core is by definition what is included in the system module for the public API so should
  68. // just use its system modules.
  69. systemModuleKind = android.SdkPublic
  70. } else if systemModuleKind == android.SdkSystem || systemModuleKind == android.SdkTest {
  71. // The core system and test APIs are currently the same as the public API so they should use
  72. // its system modules.
  73. systemModuleKind = android.SdkPublic
  74. } else if systemModuleKind == android.SdkSystemServer {
  75. // The core system server API is the same as the core module-lib API.
  76. systemModuleKind = android.SdkModule
  77. }
  78. return systemModuleKind
  79. }
  80. func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) sdkDep {
  81. sdkVersion := sdkContext.SdkVersion(ctx)
  82. if !sdkVersion.Valid() {
  83. ctx.PropertyErrorf("sdk_version", "invalid version %q", sdkVersion.Raw)
  84. return sdkDep{}
  85. }
  86. if ctx.DeviceSpecific() || ctx.SocSpecific() {
  87. sdkVersion = sdkVersion.ForVendorPartition(ctx)
  88. }
  89. if !sdkVersion.ValidateSystemSdk(ctx) {
  90. return sdkDep{}
  91. }
  92. if sdkVersion.UsePrebuilt(ctx) {
  93. dir := filepath.Join("prebuilts", "sdk", sdkVersion.ApiLevel.String(), sdkVersion.Kind.String())
  94. jar := filepath.Join(dir, "android.jar")
  95. // There's no aidl for other SDKs yet.
  96. // TODO(77525052): Add aidl files for other SDKs too.
  97. publicDir := filepath.Join("prebuilts", "sdk", sdkVersion.ApiLevel.String(), "public")
  98. aidl := filepath.Join(publicDir, "framework.aidl")
  99. jarPath := android.ExistentPathForSource(ctx, jar)
  100. aidlPath := android.ExistentPathForSource(ctx, aidl)
  101. lambdaStubsPath := android.PathForSource(ctx, config.SdkLambdaStubsPath)
  102. if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
  103. return sdkDep{
  104. invalidVersion: true,
  105. bootclasspath: []string{fmt.Sprintf("sdk_%s_%s_android", sdkVersion.Kind, sdkVersion.ApiLevel.String())},
  106. }
  107. }
  108. if !jarPath.Valid() {
  109. ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdkVersion.Raw, jar)
  110. return sdkDep{}
  111. }
  112. if !aidlPath.Valid() {
  113. ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdkVersion.Raw, aidl)
  114. return sdkDep{}
  115. }
  116. var systemModules string
  117. if defaultJavaLanguageVersion(ctx, sdkVersion).usesJavaModules() {
  118. systemModuleKind := systemModuleKind(sdkVersion.Kind, sdkVersion.ApiLevel)
  119. systemModules = fmt.Sprintf("sdk_%s_%s_system_modules", systemModuleKind, sdkVersion.ApiLevel)
  120. }
  121. return sdkDep{
  122. useFiles: true,
  123. jars: android.Paths{jarPath.Path(), lambdaStubsPath},
  124. aidl: android.OptionalPathForPath(aidlPath.Path()),
  125. systemModules: systemModules,
  126. }
  127. }
  128. toModule := func(module string, aidl android.Path) sdkDep {
  129. // Select the kind of system modules needed for the sdk version.
  130. systemModulesKind := systemModuleKind(sdkVersion.Kind, android.FutureApiLevel)
  131. systemModules := fmt.Sprintf("core-%s-stubs-system-modules", systemModulesKind)
  132. return sdkDep{
  133. useModule: true,
  134. bootclasspath: []string{module, config.DefaultLambdaStubsLibrary},
  135. systemModules: systemModules,
  136. java9Classpath: []string{module},
  137. frameworkResModule: "framework-res",
  138. aidl: android.OptionalPathForPath(aidl),
  139. }
  140. }
  141. switch sdkVersion.Kind {
  142. case android.SdkPrivate:
  143. return sdkDep{
  144. useModule: true,
  145. systemModules: corePlatformSystemModules(ctx),
  146. bootclasspath: corePlatformBootclasspathLibraries(ctx),
  147. classpath: config.FrameworkLibraries,
  148. frameworkResModule: "framework-res",
  149. }
  150. case android.SdkNone:
  151. systemModules := sdkContext.SystemModules()
  152. if systemModules == "" {
  153. ctx.PropertyErrorf("sdk_version",
  154. `system_modules is required to be set to a non-empty value when sdk_version is "none", did you mean sdk_version: "core_platform"?`)
  155. } else if systemModules == "none" {
  156. return sdkDep{
  157. noStandardLibs: true,
  158. }
  159. }
  160. return sdkDep{
  161. useModule: true,
  162. noStandardLibs: true,
  163. systemModules: systemModules,
  164. bootclasspath: []string{systemModules},
  165. }
  166. case android.SdkCorePlatform:
  167. return sdkDep{
  168. useModule: true,
  169. systemModules: corePlatformSystemModules(ctx),
  170. bootclasspath: corePlatformBootclasspathLibraries(ctx),
  171. noFrameworksLibs: true,
  172. }
  173. case android.SdkPublic, android.SdkSystem, android.SdkTest:
  174. return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), sdkFrameworkAidlPath(ctx))
  175. case android.SdkCore:
  176. return sdkDep{
  177. useModule: true,
  178. bootclasspath: []string{android.SdkCore.DefaultJavaLibraryName(), config.DefaultLambdaStubsLibrary},
  179. systemModules: "core-public-stubs-system-modules",
  180. noFrameworksLibs: true,
  181. }
  182. case android.SdkModule:
  183. // TODO(146757305): provide .apk and .aidl that have more APIs for modules
  184. return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), nonUpdatableFrameworkAidlPath(ctx))
  185. case android.SdkSystemServer:
  186. // TODO(146757305): provide .apk and .aidl that have more APIs for modules
  187. return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), sdkFrameworkAidlPath(ctx))
  188. default:
  189. panic(fmt.Errorf("invalid sdk %q", sdkVersion.Raw))
  190. }
  191. }
  192. func sdkPreSingletonFactory() android.Singleton {
  193. return sdkPreSingleton{}
  194. }
  195. type sdkPreSingleton struct{}
  196. func (sdkPreSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  197. sdkJars, err := ctx.GlobWithDeps("prebuilts/sdk/*/public/android.jar", nil)
  198. if err != nil {
  199. ctx.Errorf("failed to glob prebuilts/sdk/*/public/android.jar: %s", err.Error())
  200. }
  201. var sdkVersions []int
  202. for _, sdkJar := range sdkJars {
  203. dir := filepath.Base(filepath.Dir(filepath.Dir(sdkJar)))
  204. v, err := strconv.Atoi(dir)
  205. if scerr, ok := err.(*strconv.NumError); ok && scerr.Err == strconv.ErrSyntax {
  206. continue
  207. } else if err != nil {
  208. ctx.Errorf("invalid sdk jar %q, %s, %v", sdkJar, err.Error())
  209. }
  210. sdkVersions = append(sdkVersions, v)
  211. }
  212. sort.Ints(sdkVersions)
  213. ctx.Config().Once(sdkVersionsKey, func() interface{} { return sdkVersions })
  214. }
  215. func LatestSdkVersionInt(ctx android.EarlyModuleContext) int {
  216. sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
  217. latestSdkVersion := 0
  218. if len(sdkVersions) > 0 {
  219. latestSdkVersion = sdkVersions[len(sdkVersions)-1]
  220. }
  221. return latestSdkVersion
  222. }
  223. func sdkSingletonFactory() android.Singleton {
  224. return sdkSingleton{}
  225. }
  226. type sdkSingleton struct{}
  227. func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  228. if ctx.Config().AlwaysUsePrebuiltSdks() {
  229. return
  230. }
  231. createSdkFrameworkAidl(ctx)
  232. createNonUpdatableFrameworkAidl(ctx)
  233. createAPIFingerprint(ctx)
  234. }
  235. // Create framework.aidl by extracting anything that implements android.os.Parcelable from the SDK stubs modules.
  236. func createSdkFrameworkAidl(ctx android.SingletonContext) {
  237. stubsModules := []string{
  238. android.SdkPublic.DefaultJavaLibraryName(),
  239. android.SdkTest.DefaultJavaLibraryName(),
  240. android.SdkSystem.DefaultJavaLibraryName(),
  241. }
  242. combinedAidl := sdkFrameworkAidlPath(ctx)
  243. tempPath := tempPathForRestat(ctx, combinedAidl)
  244. rule := createFrameworkAidl(stubsModules, tempPath, ctx)
  245. commitChangeForRestat(rule, tempPath, combinedAidl)
  246. rule.Build("framework_aidl", "generate framework.aidl")
  247. }
  248. // Creates a version of framework.aidl for the non-updatable part of the platform.
  249. func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) {
  250. stubsModules := []string{android.SdkModule.DefaultJavaLibraryName()}
  251. combinedAidl := nonUpdatableFrameworkAidlPath(ctx)
  252. tempPath := tempPathForRestat(ctx, combinedAidl)
  253. rule := createFrameworkAidl(stubsModules, tempPath, ctx)
  254. commitChangeForRestat(rule, tempPath, combinedAidl)
  255. rule.Build("framework_non_updatable_aidl", "generate framework_non_updatable.aidl")
  256. }
  257. func createFrameworkAidl(stubsModules []string, path android.WritablePath, ctx android.SingletonContext) *android.RuleBuilder {
  258. stubsJars := make([]android.Paths, len(stubsModules))
  259. ctx.VisitAllModules(func(module android.Module) {
  260. // Collect dex jar paths for the modules listed above.
  261. if ctx.ModuleHasProvider(module, JavaInfoProvider) {
  262. j := ctx.ModuleProvider(module, JavaInfoProvider).(JavaInfo)
  263. name := ctx.ModuleName(module)
  264. if i := android.IndexList(name, stubsModules); i != -1 {
  265. stubsJars[i] = j.HeaderJars
  266. }
  267. }
  268. })
  269. var missingDeps []string
  270. for i := range stubsJars {
  271. if stubsJars[i] == nil {
  272. if ctx.Config().AllowMissingDependencies() {
  273. missingDeps = append(missingDeps, stubsModules[i])
  274. } else {
  275. ctx.Errorf("failed to find dex jar path for module %q", stubsModules[i])
  276. }
  277. }
  278. }
  279. rule := android.NewRuleBuilder(pctx, ctx)
  280. rule.MissingDeps(missingDeps)
  281. var aidls android.Paths
  282. for _, jars := range stubsJars {
  283. for _, jar := range jars {
  284. aidl := android.PathForOutput(ctx, "aidl", pathtools.ReplaceExtension(jar.Base(), "aidl"))
  285. rule.Command().
  286. Text("rm -f").Output(aidl)
  287. rule.Command().
  288. BuiltTool("sdkparcelables").
  289. Input(jar).
  290. Output(aidl)
  291. aidls = append(aidls, aidl)
  292. }
  293. }
  294. rule.Command().
  295. Text("rm -f").Output(path)
  296. rule.Command().
  297. Text("cat").
  298. Inputs(aidls).
  299. Text("| sort -u >").
  300. Output(path)
  301. return rule
  302. }
  303. func sdkFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
  304. return ctx.Config().Once(sdkFrameworkAidlPathKey, func() interface{} {
  305. return android.PathForOutput(ctx, "framework.aidl")
  306. }).(android.OutputPath)
  307. }
  308. func nonUpdatableFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
  309. return ctx.Config().Once(nonUpdatableFrameworkAidlPathKey, func() interface{} {
  310. return android.PathForOutput(ctx, "framework_non_updatable.aidl")
  311. }).(android.OutputPath)
  312. }
  313. // Create api_fingerprint.txt
  314. func createAPIFingerprint(ctx android.SingletonContext) {
  315. out := ApiFingerprintPath(ctx)
  316. rule := android.NewRuleBuilder(pctx, ctx)
  317. rule.Command().
  318. Text("rm -f").Output(out)
  319. cmd := rule.Command()
  320. if ctx.Config().PlatformSdkCodename() == "REL" {
  321. cmd.Text("echo REL >").Output(out)
  322. } else if ctx.Config().FrameworksBaseDirExists(ctx) && !ctx.Config().AlwaysUsePrebuiltSdks() {
  323. cmd.Text("cat")
  324. apiTxtFileModules := []string{
  325. "api_fingerprint",
  326. }
  327. count := 0
  328. ctx.VisitAllModules(func(module android.Module) {
  329. name := ctx.ModuleName(module)
  330. if android.InList(name, apiTxtFileModules) {
  331. cmd.Inputs(android.OutputFilesForModule(ctx, module, ""))
  332. count++
  333. }
  334. })
  335. if count != len(apiTxtFileModules) {
  336. ctx.Errorf("Could not find expected API module %v, found %d\n", apiTxtFileModules, count)
  337. return
  338. }
  339. cmd.Text(">").
  340. Output(out)
  341. } else {
  342. // Unbundled build
  343. // TODO: use a prebuilt api_fingerprint.txt from prebuilts/sdk/current.txt once we have one
  344. cmd.Text("echo").
  345. Flag(ctx.Config().PlatformPreviewSdkVersion()).
  346. Text(">").
  347. Output(out)
  348. }
  349. rule.Build("api_fingerprint", "generate api_fingerprint.txt")
  350. }
  351. func ApiFingerprintPath(ctx android.PathContext) android.OutputPath {
  352. return ctx.Config().Once(apiFingerprintPathKey, func() interface{} {
  353. return android.PathForOutput(ctx, "api_fingerprint.txt")
  354. }).(android.OutputPath)
  355. }
  356. func sdkMakeVars(ctx android.MakeVarsContext) {
  357. if ctx.Config().AlwaysUsePrebuiltSdks() {
  358. return
  359. }
  360. ctx.Strict("FRAMEWORK_AIDL", sdkFrameworkAidlPath(ctx).String())
  361. ctx.Strict("API_FINGERPRINT", ApiFingerprintPath(ctx).String())
  362. }