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.RegisterSingletonType("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 {
  51. return JAVA_VERSION_9
  52. }
  53. }
  54. // systemModuleKind returns the kind of system modules to use for the supplied combination of sdk
  55. // kind and API level.
  56. func systemModuleKind(sdkKind android.SdkKind, apiLevel android.ApiLevel) android.SdkKind {
  57. systemModuleKind := sdkKind
  58. if apiLevel.LessThanOrEqualTo(android.LastWithoutModuleLibCoreSystemModules) {
  59. // API levels less than or equal to 31 did not provide a core-for-system-modules.jar
  60. // specifically for the module-lib API. So, always use the public system modules for them.
  61. systemModuleKind = android.SdkPublic
  62. } else if systemModuleKind == android.SdkCore {
  63. // Core is by definition what is included in the system module for the public API so should
  64. // just use its system modules.
  65. systemModuleKind = android.SdkPublic
  66. } else if systemModuleKind == android.SdkSystem || systemModuleKind == android.SdkTest {
  67. // The core system and test APIs are currently the same as the public API so they should use
  68. // its system modules.
  69. systemModuleKind = android.SdkPublic
  70. } else if systemModuleKind == android.SdkSystemServer {
  71. // The core system server API is the same as the core module-lib API.
  72. systemModuleKind = android.SdkModule
  73. }
  74. return systemModuleKind
  75. }
  76. func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) sdkDep {
  77. sdkVersion := sdkContext.SdkVersion(ctx)
  78. if !sdkVersion.Valid() {
  79. ctx.PropertyErrorf("sdk_version", "invalid version %q", sdkVersion.Raw)
  80. return sdkDep{}
  81. }
  82. if ctx.DeviceSpecific() || ctx.SocSpecific() {
  83. sdkVersion = sdkVersion.ForVendorPartition(ctx)
  84. }
  85. if !sdkVersion.ValidateSystemSdk(ctx) {
  86. return sdkDep{}
  87. }
  88. if sdkVersion.UsePrebuilt(ctx) {
  89. dir := filepath.Join("prebuilts", "sdk", sdkVersion.ApiLevel.String(), sdkVersion.Kind.String())
  90. jar := filepath.Join(dir, "android.jar")
  91. // There's no aidl for other SDKs yet.
  92. // TODO(77525052): Add aidl files for other SDKs too.
  93. publicDir := filepath.Join("prebuilts", "sdk", sdkVersion.ApiLevel.String(), "public")
  94. aidl := filepath.Join(publicDir, "framework.aidl")
  95. jarPath := android.ExistentPathForSource(ctx, jar)
  96. aidlPath := android.ExistentPathForSource(ctx, aidl)
  97. lambdaStubsPath := android.PathForSource(ctx, config.SdkLambdaStubsPath)
  98. if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
  99. return sdkDep{
  100. invalidVersion: true,
  101. bootclasspath: []string{fmt.Sprintf("sdk_%s_%s_android", sdkVersion.Kind, sdkVersion.ApiLevel.String())},
  102. }
  103. }
  104. if !jarPath.Valid() {
  105. ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdkVersion.Raw, jar)
  106. return sdkDep{}
  107. }
  108. if !aidlPath.Valid() {
  109. ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdkVersion.Raw, aidl)
  110. return sdkDep{}
  111. }
  112. var systemModules string
  113. if defaultJavaLanguageVersion(ctx, sdkVersion).usesJavaModules() {
  114. systemModuleKind := systemModuleKind(sdkVersion.Kind, sdkVersion.ApiLevel)
  115. systemModules = fmt.Sprintf("sdk_%s_%s_system_modules", systemModuleKind, sdkVersion.ApiLevel)
  116. }
  117. return sdkDep{
  118. useFiles: true,
  119. jars: android.Paths{jarPath.Path(), lambdaStubsPath},
  120. aidl: android.OptionalPathForPath(aidlPath.Path()),
  121. systemModules: systemModules,
  122. }
  123. }
  124. toModule := func(systemModules string, module string, aidl android.Path) sdkDep {
  125. return sdkDep{
  126. useModule: true,
  127. bootclasspath: []string{module, config.DefaultLambdaStubsLibrary},
  128. systemModules: systemModules,
  129. java9Classpath: []string{module},
  130. frameworkResModule: "framework-res",
  131. aidl: android.OptionalPathForPath(aidl),
  132. }
  133. }
  134. switch sdkVersion.Kind {
  135. case android.SdkPrivate:
  136. return sdkDep{
  137. useModule: true,
  138. systemModules: corePlatformSystemModules(ctx),
  139. bootclasspath: corePlatformBootclasspathLibraries(ctx),
  140. classpath: config.FrameworkLibraries,
  141. frameworkResModule: "framework-res",
  142. }
  143. case android.SdkNone:
  144. systemModules := sdkContext.SystemModules()
  145. if systemModules == "" {
  146. ctx.PropertyErrorf("sdk_version",
  147. `system_modules is required to be set to a non-empty value when sdk_version is "none", did you mean sdk_version: "core_platform"?`)
  148. } else if systemModules == "none" {
  149. return sdkDep{
  150. noStandardLibs: true,
  151. }
  152. }
  153. return sdkDep{
  154. useModule: true,
  155. noStandardLibs: true,
  156. systemModules: systemModules,
  157. bootclasspath: []string{systemModules},
  158. }
  159. case android.SdkCorePlatform:
  160. return sdkDep{
  161. useModule: true,
  162. systemModules: corePlatformSystemModules(ctx),
  163. bootclasspath: corePlatformBootclasspathLibraries(ctx),
  164. noFrameworksLibs: true,
  165. }
  166. case android.SdkPublic:
  167. return toModule("core-public-stubs-system-modules", "android_stubs_current", sdkFrameworkAidlPath(ctx))
  168. case android.SdkSystem:
  169. return toModule("core-public-stubs-system-modules", "android_system_stubs_current", sdkFrameworkAidlPath(ctx))
  170. case android.SdkTest:
  171. return toModule("core-public-stubs-system-modules", "android_test_stubs_current", sdkFrameworkAidlPath(ctx))
  172. case android.SdkCore:
  173. return sdkDep{
  174. useModule: true,
  175. bootclasspath: []string{"core.current.stubs", config.DefaultLambdaStubsLibrary},
  176. systemModules: "core-public-stubs-system-modules",
  177. noFrameworksLibs: true,
  178. }
  179. case android.SdkModule:
  180. // TODO(146757305): provide .apk and .aidl that have more APIs for modules
  181. return toModule("core-module-lib-stubs-system-modules", "android_module_lib_stubs_current", nonUpdatableFrameworkAidlPath(ctx))
  182. case android.SdkSystemServer:
  183. // TODO(146757305): provide .apk and .aidl that have more APIs for modules
  184. return toModule("core-module-lib-stubs-system-modules", "android_system_server_stubs_current", sdkFrameworkAidlPath(ctx))
  185. default:
  186. panic(fmt.Errorf("invalid sdk %q", sdkVersion.Raw))
  187. }
  188. }
  189. func sdkPreSingletonFactory() android.Singleton {
  190. return sdkPreSingleton{}
  191. }
  192. type sdkPreSingleton struct{}
  193. func (sdkPreSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  194. sdkJars, err := ctx.GlobWithDeps("prebuilts/sdk/*/public/android.jar", nil)
  195. if err != nil {
  196. ctx.Errorf("failed to glob prebuilts/sdk/*/public/android.jar: %s", err.Error())
  197. }
  198. var sdkVersions []int
  199. for _, sdkJar := range sdkJars {
  200. dir := filepath.Base(filepath.Dir(filepath.Dir(sdkJar)))
  201. v, err := strconv.Atoi(dir)
  202. if scerr, ok := err.(*strconv.NumError); ok && scerr.Err == strconv.ErrSyntax {
  203. continue
  204. } else if err != nil {
  205. ctx.Errorf("invalid sdk jar %q, %s, %v", sdkJar, err.Error())
  206. }
  207. sdkVersions = append(sdkVersions, v)
  208. }
  209. sort.Ints(sdkVersions)
  210. ctx.Config().Once(sdkVersionsKey, func() interface{} { return sdkVersions })
  211. }
  212. func LatestSdkVersionInt(ctx android.EarlyModuleContext) int {
  213. sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
  214. latestSdkVersion := 0
  215. if len(sdkVersions) > 0 {
  216. latestSdkVersion = sdkVersions[len(sdkVersions)-1]
  217. }
  218. return latestSdkVersion
  219. }
  220. func sdkSingletonFactory() android.Singleton {
  221. return sdkSingleton{}
  222. }
  223. type sdkSingleton struct{}
  224. func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  225. if ctx.Config().AlwaysUsePrebuiltSdks() {
  226. return
  227. }
  228. createSdkFrameworkAidl(ctx)
  229. createNonUpdatableFrameworkAidl(ctx)
  230. createAPIFingerprint(ctx)
  231. }
  232. // Create framework.aidl by extracting anything that implements android.os.Parcelable from the SDK stubs modules.
  233. func createSdkFrameworkAidl(ctx android.SingletonContext) {
  234. stubsModules := []string{
  235. "android_stubs_current",
  236. "android_test_stubs_current",
  237. "android_system_stubs_current",
  238. }
  239. combinedAidl := sdkFrameworkAidlPath(ctx)
  240. tempPath := tempPathForRestat(ctx, combinedAidl)
  241. rule := createFrameworkAidl(stubsModules, tempPath, ctx)
  242. commitChangeForRestat(rule, tempPath, combinedAidl)
  243. rule.Build("framework_aidl", "generate framework.aidl")
  244. }
  245. // Creates a version of framework.aidl for the non-updatable part of the platform.
  246. func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) {
  247. stubsModules := []string{"android_module_lib_stubs_current"}
  248. combinedAidl := nonUpdatableFrameworkAidlPath(ctx)
  249. tempPath := tempPathForRestat(ctx, combinedAidl)
  250. rule := createFrameworkAidl(stubsModules, tempPath, ctx)
  251. commitChangeForRestat(rule, tempPath, combinedAidl)
  252. rule.Build("framework_non_updatable_aidl", "generate framework_non_updatable.aidl")
  253. }
  254. func createFrameworkAidl(stubsModules []string, path android.WritablePath, ctx android.SingletonContext) *android.RuleBuilder {
  255. stubsJars := make([]android.Paths, len(stubsModules))
  256. ctx.VisitAllModules(func(module android.Module) {
  257. // Collect dex jar paths for the modules listed above.
  258. if ctx.ModuleHasProvider(module, JavaInfoProvider) {
  259. j := ctx.ModuleProvider(module, JavaInfoProvider).(JavaInfo)
  260. name := ctx.ModuleName(module)
  261. if i := android.IndexList(name, stubsModules); i != -1 {
  262. stubsJars[i] = j.HeaderJars
  263. }
  264. }
  265. })
  266. var missingDeps []string
  267. for i := range stubsJars {
  268. if stubsJars[i] == nil {
  269. if ctx.Config().AllowMissingDependencies() {
  270. missingDeps = append(missingDeps, stubsModules[i])
  271. } else {
  272. ctx.Errorf("failed to find dex jar path for module %q", stubsModules[i])
  273. }
  274. }
  275. }
  276. rule := android.NewRuleBuilder(pctx, ctx)
  277. rule.MissingDeps(missingDeps)
  278. var aidls android.Paths
  279. for _, jars := range stubsJars {
  280. for _, jar := range jars {
  281. aidl := android.PathForOutput(ctx, "aidl", pathtools.ReplaceExtension(jar.Base(), "aidl"))
  282. rule.Command().
  283. Text("rm -f").Output(aidl)
  284. rule.Command().
  285. BuiltTool("sdkparcelables").
  286. Input(jar).
  287. Output(aidl)
  288. aidls = append(aidls, aidl)
  289. }
  290. }
  291. rule.Command().
  292. Text("rm -f").Output(path)
  293. rule.Command().
  294. Text("cat").
  295. Inputs(aidls).
  296. Text("| sort -u >").
  297. Output(path)
  298. return rule
  299. }
  300. func sdkFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
  301. return ctx.Config().Once(sdkFrameworkAidlPathKey, func() interface{} {
  302. return android.PathForOutput(ctx, "framework.aidl")
  303. }).(android.OutputPath)
  304. }
  305. func nonUpdatableFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
  306. return ctx.Config().Once(nonUpdatableFrameworkAidlPathKey, func() interface{} {
  307. return android.PathForOutput(ctx, "framework_non_updatable.aidl")
  308. }).(android.OutputPath)
  309. }
  310. // Create api_fingerprint.txt
  311. func createAPIFingerprint(ctx android.SingletonContext) {
  312. out := ApiFingerprintPath(ctx)
  313. rule := android.NewRuleBuilder(pctx, ctx)
  314. rule.Command().
  315. Text("rm -f").Output(out)
  316. cmd := rule.Command()
  317. if ctx.Config().PlatformSdkCodename() == "REL" {
  318. cmd.Text("echo REL >").Output(out)
  319. } else if ctx.Config().FrameworksBaseDirExists(ctx) && !ctx.Config().AlwaysUsePrebuiltSdks() {
  320. cmd.Text("cat")
  321. apiTxtFileModules := []string{
  322. "frameworks-base-api-current.txt",
  323. "frameworks-base-api-system-current.txt",
  324. "frameworks-base-api-module-lib-current.txt",
  325. "frameworks-base-api-system-server-current.txt",
  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 all the expected API modules %v, found %d\n", apiTxtFileModules, count)
  337. return
  338. }
  339. cmd.Text("| md5sum | cut -d' ' -f1 >").
  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. }