ndk_sysroot.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // Copyright 2016 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 cc
  15. // The platform needs to provide the following artifacts for the NDK:
  16. // 1. Bionic headers.
  17. // 2. Platform API headers.
  18. // 3. NDK stub shared libraries.
  19. // 4. Bionic static libraries.
  20. //
  21. // TODO(danalbert): All of the above need to include NOTICE files.
  22. //
  23. // Components 1 and 2: Headers
  24. // The bionic and platform API headers are generalized into a single
  25. // `ndk_headers` rule. This rule has a `from` property that indicates a base
  26. // directory from which headers are to be taken, and a `to` property that
  27. // indicates where in the sysroot they should reside relative to usr/include.
  28. // There is also a `srcs` property that is glob compatible for specifying which
  29. // headers to include.
  30. //
  31. // Component 3: Stub Libraries
  32. // The shared libraries in the NDK are not the actual shared libraries they
  33. // refer to (to prevent people from accidentally loading them), but stub
  34. // libraries with placeholder implementations of everything for use at build time
  35. // only.
  36. //
  37. // Since we don't actually need to know anything about the stub libraries aside
  38. // from a list of functions and globals to be exposed, we can create these for
  39. // every platform level in the current tree. This is handled by the
  40. // ndk_library rule.
  41. //
  42. // Component 4: Static Libraries
  43. // The NDK only provides static libraries for bionic, not the platform APIs.
  44. // Since these need to be the actual implementation, we can't build old versions
  45. // in the current platform tree. As such, legacy versions are checked in
  46. // prebuilt to development/ndk, and a current version is built and archived as
  47. // part of the platform build. The platfrom already builds these libraries, our
  48. // NDK build rules only need to archive them for retrieval so they can be added
  49. // to the prebuilts.
  50. //
  51. // TODO(danalbert): Write `ndk_static_library` rule.
  52. import (
  53. "android/soong/android"
  54. )
  55. func init() {
  56. RegisterNdkModuleTypes(android.InitRegistrationContext)
  57. pctx.Import("android/soong/android")
  58. }
  59. func RegisterNdkModuleTypes(ctx android.RegistrationContext) {
  60. ctx.RegisterModuleType("ndk_headers", ndkHeadersFactory)
  61. ctx.RegisterModuleType("ndk_library", NdkLibraryFactory)
  62. ctx.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory)
  63. ctx.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory)
  64. ctx.RegisterParallelSingletonType("ndk", NdkSingleton)
  65. }
  66. func getNdkInstallBase(ctx android.PathContext) android.InstallPath {
  67. return android.PathForNdkInstall(ctx)
  68. }
  69. // Returns the main install directory for the NDK sysroot. Usable with --sysroot.
  70. func getNdkSysrootBase(ctx android.PathContext) android.InstallPath {
  71. return getNdkInstallBase(ctx).Join(ctx, "sysroot")
  72. }
  73. // The base timestamp file depends on the NDK headers and stub shared libraries,
  74. // but not the static libraries. This distinction is needed because the static
  75. // libraries themselves might need to depend on the base sysroot.
  76. func getNdkBaseTimestampFile(ctx android.PathContext) android.WritablePath {
  77. return android.PathForOutput(ctx, "ndk_base.timestamp")
  78. }
  79. // The headers timestamp file depends only on the NDK headers.
  80. // This is used mainly for .tidy files that do not need any stub libraries.
  81. func getNdkHeadersTimestampFile(ctx android.PathContext) android.WritablePath {
  82. return android.PathForOutput(ctx, "ndk_headers.timestamp")
  83. }
  84. // The full timestamp file depends on the base timestamp *and* the static
  85. // libraries.
  86. func getNdkFullTimestampFile(ctx android.PathContext) android.WritablePath {
  87. return android.PathForOutput(ctx, "ndk.timestamp")
  88. }
  89. func NdkSingleton() android.Singleton {
  90. return &ndkSingleton{}
  91. }
  92. type ndkSingleton struct{}
  93. func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  94. var staticLibInstallPaths android.Paths
  95. var headerPaths android.Paths
  96. var installPaths android.Paths
  97. var licensePaths android.Paths
  98. ctx.VisitAllModules(func(module android.Module) {
  99. if m, ok := module.(android.Module); ok && !m.Enabled() {
  100. return
  101. }
  102. if m, ok := module.(*headerModule); ok {
  103. headerPaths = append(headerPaths, m.installPaths...)
  104. installPaths = append(installPaths, m.installPaths...)
  105. licensePaths = append(licensePaths, m.licensePath)
  106. }
  107. if m, ok := module.(*versionedHeaderModule); ok {
  108. headerPaths = append(headerPaths, m.installPaths...)
  109. installPaths = append(installPaths, m.installPaths...)
  110. licensePaths = append(licensePaths, m.licensePath)
  111. }
  112. if m, ok := module.(*preprocessedHeadersModule); ok {
  113. headerPaths = append(headerPaths, m.installPaths...)
  114. installPaths = append(installPaths, m.installPaths...)
  115. licensePaths = append(licensePaths, m.licensePath)
  116. }
  117. if m, ok := module.(*Module); ok {
  118. if installer, ok := m.installer.(*stubDecorator); ok && m.library.buildStubs() {
  119. installPaths = append(installPaths, installer.installPath)
  120. }
  121. if library, ok := m.linker.(*libraryDecorator); ok {
  122. if library.ndkSysrootPath != nil {
  123. staticLibInstallPaths = append(
  124. staticLibInstallPaths, library.ndkSysrootPath)
  125. }
  126. }
  127. if object, ok := m.linker.(*objectLinker); ok {
  128. if object.ndkSysrootPath != nil {
  129. staticLibInstallPaths = append(
  130. staticLibInstallPaths, object.ndkSysrootPath)
  131. }
  132. }
  133. }
  134. })
  135. // Include only a single copy of each license file. The Bionic NOTICE is
  136. // long and is referenced by multiple Bionic modules.
  137. licensePaths = android.FirstUniquePaths(licensePaths)
  138. combinedLicense := getNdkInstallBase(ctx).Join(ctx, "NOTICE")
  139. ctx.Build(pctx, android.BuildParams{
  140. Rule: android.Cat,
  141. Description: "combine licenses",
  142. Output: combinedLicense,
  143. Inputs: licensePaths,
  144. })
  145. baseDepPaths := append(installPaths, combinedLicense)
  146. ctx.Build(pctx, android.BuildParams{
  147. Rule: android.Touch,
  148. Output: getNdkBaseTimestampFile(ctx),
  149. Implicits: baseDepPaths,
  150. Validation: getNdkAbiDiffTimestampFile(ctx),
  151. })
  152. ctx.Build(pctx, android.BuildParams{
  153. Rule: android.Touch,
  154. Output: getNdkHeadersTimestampFile(ctx),
  155. Implicits: headerPaths,
  156. })
  157. fullDepPaths := append(staticLibInstallPaths, getNdkBaseTimestampFile(ctx))
  158. // There's a phony "ndk" rule defined in core/main.mk that depends on this.
  159. // `m ndk` will build the sysroots for the architectures in the current
  160. // lunch target. `build/soong/scripts/build-ndk-prebuilts.sh` will build the
  161. // sysroots for all the NDK architectures and package them so they can be
  162. // imported into the NDK's build.
  163. ctx.Build(pctx, android.BuildParams{
  164. Rule: android.Touch,
  165. Output: getNdkFullTimestampFile(ctx),
  166. Implicits: fullDepPaths,
  167. })
  168. }