vndk.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. // Copyright 2017 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. import (
  16. "encoding/json"
  17. "errors"
  18. "fmt"
  19. "path/filepath"
  20. "sort"
  21. "strings"
  22. "android/soong/android"
  23. "android/soong/cc/config"
  24. "android/soong/etc"
  25. "android/soong/snapshot"
  26. "github.com/google/blueprint"
  27. )
  28. const (
  29. llndkLibrariesTxt = "llndk.libraries.txt"
  30. vndkCoreLibrariesTxt = "vndkcore.libraries.txt"
  31. vndkSpLibrariesTxt = "vndksp.libraries.txt"
  32. vndkPrivateLibrariesTxt = "vndkprivate.libraries.txt"
  33. vndkProductLibrariesTxt = "vndkproduct.libraries.txt"
  34. vndkUsingCoreVariantLibrariesTxt = "vndkcorevariant.libraries.txt"
  35. )
  36. func VndkLibrariesTxtModules(vndkVersion string) []string {
  37. if vndkVersion == "current" {
  38. return []string{
  39. llndkLibrariesTxt,
  40. vndkCoreLibrariesTxt,
  41. vndkSpLibrariesTxt,
  42. vndkPrivateLibrariesTxt,
  43. vndkProductLibrariesTxt,
  44. }
  45. }
  46. // Snapshot vndks have their own *.libraries.VER.txt files.
  47. // Note that snapshots don't have "vndkcorevariant.libraries.VER.txt"
  48. return []string{
  49. insertVndkVersion(llndkLibrariesTxt, vndkVersion),
  50. insertVndkVersion(vndkCoreLibrariesTxt, vndkVersion),
  51. insertVndkVersion(vndkSpLibrariesTxt, vndkVersion),
  52. insertVndkVersion(vndkPrivateLibrariesTxt, vndkVersion),
  53. insertVndkVersion(vndkProductLibrariesTxt, vndkVersion),
  54. }
  55. }
  56. type VndkProperties struct {
  57. Vndk struct {
  58. // declared as a VNDK or VNDK-SP module. The vendor variant
  59. // will be installed in /system instead of /vendor partition.
  60. //
  61. // `vendor_available` and `product_available` must be explicitly
  62. // set to either true or false together with `vndk: {enabled: true}`.
  63. Enabled *bool
  64. // declared as a VNDK-SP module, which is a subset of VNDK.
  65. //
  66. // `vndk: { enabled: true }` must set together.
  67. //
  68. // All these modules are allowed to link to VNDK-SP or LL-NDK
  69. // modules only. Other dependency will cause link-type errors.
  70. //
  71. // If `support_system_process` is not set or set to false,
  72. // the module is VNDK-core and can link to other VNDK-core,
  73. // VNDK-SP or LL-NDK modules only.
  74. Support_system_process *bool
  75. // declared as a VNDK-private module.
  76. // This module still creates the vendor and product variants refering
  77. // to the `vendor_available: true` and `product_available: true`
  78. // properties. However, it is only available to the other VNDK modules
  79. // but not to the non-VNDK vendor or product modules.
  80. Private *bool
  81. // Extending another module
  82. Extends *string
  83. }
  84. }
  85. type vndkdep struct {
  86. Properties VndkProperties
  87. }
  88. func (vndk *vndkdep) props() []interface{} {
  89. return []interface{}{&vndk.Properties}
  90. }
  91. func (vndk *vndkdep) isVndk() bool {
  92. return Bool(vndk.Properties.Vndk.Enabled)
  93. }
  94. func (vndk *vndkdep) isVndkSp() bool {
  95. return Bool(vndk.Properties.Vndk.Support_system_process)
  96. }
  97. func (vndk *vndkdep) isVndkExt() bool {
  98. return vndk.Properties.Vndk.Extends != nil
  99. }
  100. func (vndk *vndkdep) getVndkExtendsModuleName() string {
  101. return String(vndk.Properties.Vndk.Extends)
  102. }
  103. func (vndk *vndkdep) typeName() string {
  104. if !vndk.isVndk() {
  105. return "native:vendor"
  106. }
  107. if !vndk.isVndkExt() {
  108. if !vndk.isVndkSp() {
  109. return "native:vendor:vndk"
  110. }
  111. return "native:vendor:vndksp"
  112. }
  113. if !vndk.isVndkSp() {
  114. return "native:vendor:vndkext"
  115. }
  116. return "native:vendor:vndkspext"
  117. }
  118. // VNDK link type check from a module with UseVndk() == true.
  119. func (vndk *vndkdep) vndkCheckLinkType(ctx android.BaseModuleContext, to *Module, tag blueprint.DependencyTag) {
  120. if to.linker == nil {
  121. return
  122. }
  123. if !vndk.isVndk() {
  124. // Non-VNDK modules those installed to /vendor, /system/vendor,
  125. // /product or /system/product cannot depend on VNDK-private modules
  126. // that include VNDK-core-private, VNDK-SP-private and LLNDK-private.
  127. if to.IsVndkPrivate() {
  128. ctx.ModuleErrorf("non-VNDK module should not link to %q which has `private: true`", to.Name())
  129. }
  130. }
  131. if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
  132. // Check only shared libraries.
  133. // Other (static) libraries are allowed to link.
  134. return
  135. }
  136. if to.IsLlndk() {
  137. // LL-NDK libraries are allowed to link
  138. return
  139. }
  140. if !to.UseVndk() {
  141. ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
  142. vndk.typeName(), to.Name())
  143. return
  144. }
  145. if tag == vndkExtDepTag {
  146. // Ensure `extends: "name"` property refers a vndk module that has vendor_available
  147. // and has identical vndk properties.
  148. if to.vndkdep == nil || !to.vndkdep.isVndk() {
  149. ctx.ModuleErrorf("`extends` refers a non-vndk module %q", to.Name())
  150. return
  151. }
  152. if vndk.isVndkSp() != to.vndkdep.isVndkSp() {
  153. ctx.ModuleErrorf(
  154. "`extends` refers a module %q with mismatched support_system_process",
  155. to.Name())
  156. return
  157. }
  158. if to.IsVndkPrivate() {
  159. ctx.ModuleErrorf(
  160. "`extends` refers module %q which has `private: true`",
  161. to.Name())
  162. return
  163. }
  164. }
  165. if to.vndkdep == nil {
  166. return
  167. }
  168. // Check the dependencies of VNDK shared libraries.
  169. if err := vndkIsVndkDepAllowed(vndk, to.vndkdep); err != nil {
  170. ctx.ModuleErrorf("(%s) should not link to %q (%s): %v",
  171. vndk.typeName(), to.Name(), to.vndkdep.typeName(), err)
  172. return
  173. }
  174. }
  175. func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) error {
  176. // Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules.
  177. if from.isVndkExt() {
  178. if from.isVndkSp() {
  179. if to.isVndk() && !to.isVndkSp() {
  180. return errors.New("VNDK-SP extensions must not depend on VNDK or VNDK extensions")
  181. }
  182. return nil
  183. }
  184. // VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
  185. return nil
  186. }
  187. if from.isVndk() {
  188. if to.isVndkExt() {
  189. return errors.New("VNDK-core and VNDK-SP must not depend on VNDK extensions")
  190. }
  191. if from.isVndkSp() {
  192. if !to.isVndkSp() {
  193. return errors.New("VNDK-SP must only depend on VNDK-SP")
  194. }
  195. return nil
  196. }
  197. if !to.isVndk() {
  198. return errors.New("VNDK-core must only depend on VNDK-core or VNDK-SP")
  199. }
  200. return nil
  201. }
  202. // Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
  203. return nil
  204. }
  205. type moduleListerFunc func(ctx android.SingletonContext) (moduleNames, fileNames []string)
  206. var (
  207. llndkLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsLLNDK && !m.Header() })
  208. vndkSPLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKSP })
  209. vndkCoreLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKCore })
  210. vndkPrivateLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKPrivate })
  211. vndkProductLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKProduct })
  212. vndkUsingCoreVariantLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKUsingCoreVariant })
  213. )
  214. // vndkModuleLister takes a predicate that operates on a Module and returns a moduleListerFunc
  215. // that produces a list of module names and output file names for which the predicate returns true.
  216. func vndkModuleLister(predicate func(*Module) bool) moduleListerFunc {
  217. return func(ctx android.SingletonContext) (moduleNames, fileNames []string) {
  218. ctx.VisitAllModules(func(m android.Module) {
  219. if c, ok := m.(*Module); ok && predicate(c) && !c.IsVndkPrebuiltLibrary() {
  220. filename, err := getVndkFileName(c)
  221. if err != nil {
  222. ctx.ModuleErrorf(m, "%s", err)
  223. }
  224. moduleNames = append(moduleNames, ctx.ModuleName(m))
  225. fileNames = append(fileNames, filename)
  226. }
  227. })
  228. moduleNames = android.SortedUniqueStrings(moduleNames)
  229. fileNames = android.SortedUniqueStrings(fileNames)
  230. return
  231. }
  232. }
  233. // vndkModuleListRemover takes a moduleListerFunc and a prefix and returns a moduleListerFunc
  234. // that returns the same lists as the input moduleListerFunc, but with modules with the
  235. // given prefix removed.
  236. func vndkModuleListRemover(lister moduleListerFunc, prefix string) moduleListerFunc {
  237. return func(ctx android.SingletonContext) (moduleNames, fileNames []string) {
  238. moduleNames, fileNames = lister(ctx)
  239. filter := func(in []string) []string {
  240. out := make([]string, 0, len(in))
  241. for _, lib := range in {
  242. if strings.HasPrefix(lib, prefix) {
  243. continue
  244. }
  245. out = append(out, lib)
  246. }
  247. return out
  248. }
  249. return filter(moduleNames), filter(fileNames)
  250. }
  251. }
  252. var vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey")
  253. func vndkMustUseVendorVariantList(cfg android.Config) []string {
  254. return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} {
  255. return config.VndkMustUseVendorVariantList
  256. }).([]string)
  257. }
  258. // test may call this to override global configuration(config.VndkMustUseVendorVariantList)
  259. // when it is called, it must be before the first call to vndkMustUseVendorVariantList()
  260. func setVndkMustUseVendorVariantListForTest(config android.Config, mustUseVendorVariantList []string) {
  261. config.Once(vndkMustUseVendorVariantListKey, func() interface{} {
  262. return mustUseVendorVariantList
  263. })
  264. }
  265. func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
  266. if m.InProduct() {
  267. // We may skip the steps for the product variants because they
  268. // are already covered by the vendor variants.
  269. return
  270. }
  271. name := m.BaseModuleName()
  272. if lib := m.library; lib != nil && lib.hasStubsVariants() && name != "libz" {
  273. // b/155456180 libz is the ONLY exception here. We don't want to make
  274. // libz an LLNDK library because we in general can't guarantee that
  275. // libz will behave consistently especially about the compression.
  276. // i.e. the compressed output might be different across releases.
  277. // As the library is an external one, it's risky to keep the compatibility
  278. // promise if it becomes an LLNDK.
  279. mctx.PropertyErrorf("vndk.enabled", "This library provides stubs. Shouldn't be VNDK. Consider making it as LLNDK")
  280. }
  281. if inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
  282. m.Properties.MustUseVendorVariant = true
  283. }
  284. if mctx.DeviceConfig().VndkUseCoreVariant() && !m.Properties.MustUseVendorVariant {
  285. m.VendorProperties.IsVNDKUsingCoreVariant = true
  286. }
  287. if m.vndkdep.isVndkSp() {
  288. m.VendorProperties.IsVNDKSP = true
  289. } else {
  290. m.VendorProperties.IsVNDKCore = true
  291. }
  292. if m.IsVndkPrivate() {
  293. m.VendorProperties.IsVNDKPrivate = true
  294. }
  295. if Bool(m.VendorProperties.Product_available) {
  296. m.VendorProperties.IsVNDKProduct = true
  297. }
  298. }
  299. // Check for modules that mustn't be VNDK
  300. func shouldSkipVndkMutator(m *Module) bool {
  301. if !m.Enabled() {
  302. return true
  303. }
  304. if !m.Device() {
  305. // Skip non-device modules
  306. return true
  307. }
  308. if m.Target().NativeBridge == android.NativeBridgeEnabled {
  309. // Skip native_bridge modules
  310. return true
  311. }
  312. return false
  313. }
  314. func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
  315. if shouldSkipVndkMutator(m) {
  316. return false
  317. }
  318. // prebuilt vndk modules should match with device
  319. // TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
  320. // When b/142675459 is landed, remove following check
  321. if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.MatchesWithDevice(mctx.DeviceConfig()) {
  322. return false
  323. }
  324. if lib, ok := m.linker.(libraryInterface); ok {
  325. // VNDK APEX for VNDK-Lite devices will have VNDK-SP libraries from core variants
  326. if mctx.DeviceConfig().VndkVersion() == "" {
  327. // b/73296261: filter out libz.so because it is considered as LLNDK for VNDK-lite devices
  328. if mctx.ModuleName() == "libz" {
  329. return false
  330. }
  331. return m.ImageVariation().Variation == android.CoreVariation && lib.shared() && m.IsVndkSp() && !m.IsVndkExt()
  332. }
  333. // VNDK APEX doesn't need stub variants
  334. if lib.buildStubs() {
  335. return false
  336. }
  337. useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
  338. mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
  339. return lib.shared() && m.InVendor() && m.IsVndk() && !m.IsVndkExt() && !useCoreVariant
  340. }
  341. return false
  342. }
  343. // gather list of vndk-core, vndk-sp, and ll-ndk libs
  344. func VndkMutator(mctx android.BottomUpMutatorContext) {
  345. m, ok := mctx.Module().(*Module)
  346. if !ok {
  347. return
  348. }
  349. if shouldSkipVndkMutator(m) {
  350. return
  351. }
  352. lib, isLib := m.linker.(*libraryDecorator)
  353. prebuiltLib, isPrebuiltLib := m.linker.(*prebuiltLibraryLinker)
  354. if m.UseVndk() && isLib && lib.hasLLNDKStubs() {
  355. m.VendorProperties.IsLLNDK = true
  356. m.VendorProperties.IsVNDKPrivate = Bool(lib.Properties.Llndk.Private)
  357. }
  358. if m.UseVndk() && isPrebuiltLib && prebuiltLib.hasLLNDKStubs() {
  359. m.VendorProperties.IsLLNDK = true
  360. m.VendorProperties.IsVNDKPrivate = Bool(prebuiltLib.Properties.Llndk.Private)
  361. }
  362. if m.IsVndkPrebuiltLibrary() && !m.IsVndk() {
  363. m.VendorProperties.IsLLNDK = true
  364. // TODO(b/280697209): copy "llndk.private" flag to vndk_prebuilt_shared
  365. }
  366. if (isLib && lib.buildShared()) || (isPrebuiltLib && prebuiltLib.buildShared()) {
  367. if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
  368. processVndkLibrary(mctx, m)
  369. return
  370. }
  371. }
  372. }
  373. func init() {
  374. RegisterVndkLibraryTxtTypes(android.InitRegistrationContext)
  375. android.RegisterParallelSingletonType("vndk-snapshot", VndkSnapshotSingleton)
  376. }
  377. func RegisterVndkLibraryTxtTypes(ctx android.RegistrationContext) {
  378. ctx.RegisterParallelSingletonModuleType("llndk_libraries_txt", llndkLibrariesTxtFactory)
  379. ctx.RegisterParallelSingletonModuleType("vndksp_libraries_txt", vndkSPLibrariesTxtFactory)
  380. ctx.RegisterParallelSingletonModuleType("vndkcore_libraries_txt", vndkCoreLibrariesTxtFactory)
  381. ctx.RegisterParallelSingletonModuleType("vndkprivate_libraries_txt", vndkPrivateLibrariesTxtFactory)
  382. ctx.RegisterParallelSingletonModuleType("vndkproduct_libraries_txt", vndkProductLibrariesTxtFactory)
  383. ctx.RegisterParallelSingletonModuleType("vndkcorevariant_libraries_txt", vndkUsingCoreVariantLibrariesTxtFactory)
  384. }
  385. type vndkLibrariesTxt struct {
  386. android.SingletonModuleBase
  387. lister moduleListerFunc
  388. makeVarName string
  389. filterOutFromMakeVar string
  390. properties VndkLibrariesTxtProperties
  391. outputFile android.OutputPath
  392. moduleNames []string
  393. fileNames []string
  394. }
  395. type VndkLibrariesTxtProperties struct {
  396. Insert_vndk_version *bool
  397. }
  398. var _ etc.PrebuiltEtcModule = &vndkLibrariesTxt{}
  399. var _ android.OutputFileProducer = &vndkLibrariesTxt{}
  400. // llndk_libraries_txt is a singleton module whose content is a list of LLNDK libraries
  401. // generated by Soong but can be referenced by other modules.
  402. // For example, apex_vndk can depend on these files as prebuilt.
  403. // Make uses LLNDK_LIBRARIES to determine which libraries to install.
  404. // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
  405. // Therefore, by removing the library here, we cause it to only be installed if libc
  406. // depends on it.
  407. func llndkLibrariesTxtFactory() android.SingletonModule {
  408. return newVndkLibrariesWithMakeVarFilter(llndkLibraries, "LLNDK_LIBRARIES", "libclang_rt.hwasan")
  409. }
  410. // vndksp_libraries_txt is a singleton module whose content is a list of VNDKSP libraries
  411. // generated by Soong but can be referenced by other modules.
  412. // For example, apex_vndk can depend on these files as prebuilt.
  413. func vndkSPLibrariesTxtFactory() android.SingletonModule {
  414. return newVndkLibrariesTxt(vndkSPLibraries, "VNDK_SAMEPROCESS_LIBRARIES")
  415. }
  416. // vndkcore_libraries_txt is a singleton module whose content is a list of VNDK core libraries
  417. // generated by Soong but can be referenced by other modules.
  418. // For example, apex_vndk can depend on these files as prebuilt.
  419. func vndkCoreLibrariesTxtFactory() android.SingletonModule {
  420. return newVndkLibrariesTxt(vndkCoreLibraries, "VNDK_CORE_LIBRARIES")
  421. }
  422. // vndkprivate_libraries_txt is a singleton module whose content is a list of VNDK private libraries
  423. // generated by Soong but can be referenced by other modules.
  424. // For example, apex_vndk can depend on these files as prebuilt.
  425. func vndkPrivateLibrariesTxtFactory() android.SingletonModule {
  426. return newVndkLibrariesTxt(vndkPrivateLibraries, "VNDK_PRIVATE_LIBRARIES")
  427. }
  428. // vndkproduct_libraries_txt is a singleton module whose content is a list of VNDK product libraries
  429. // generated by Soong but can be referenced by other modules.
  430. // For example, apex_vndk can depend on these files as prebuilt.
  431. func vndkProductLibrariesTxtFactory() android.SingletonModule {
  432. return newVndkLibrariesTxt(vndkProductLibraries, "VNDK_PRODUCT_LIBRARIES")
  433. }
  434. // vndkcorevariant_libraries_txt is a singleton module whose content is a list of VNDK libraries
  435. // that are using the core variant, generated by Soong but can be referenced by other modules.
  436. // For example, apex_vndk can depend on these files as prebuilt.
  437. func vndkUsingCoreVariantLibrariesTxtFactory() android.SingletonModule {
  438. return newVndkLibrariesTxt(vndkUsingCoreVariantLibraries, "VNDK_USING_CORE_VARIANT_LIBRARIES")
  439. }
  440. func newVndkLibrariesWithMakeVarFilter(lister moduleListerFunc, makeVarName string, filter string) android.SingletonModule {
  441. m := &vndkLibrariesTxt{
  442. lister: lister,
  443. makeVarName: makeVarName,
  444. filterOutFromMakeVar: filter,
  445. }
  446. m.AddProperties(&m.properties)
  447. android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
  448. return m
  449. }
  450. func newVndkLibrariesTxt(lister moduleListerFunc, makeVarName string) android.SingletonModule {
  451. return newVndkLibrariesWithMakeVarFilter(lister, makeVarName, "")
  452. }
  453. func insertVndkVersion(filename string, vndkVersion string) string {
  454. if index := strings.LastIndex(filename, "."); index != -1 {
  455. return filename[:index] + "." + vndkVersion + filename[index:]
  456. }
  457. return filename
  458. }
  459. func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  460. var filename string
  461. if BoolDefault(txt.properties.Insert_vndk_version, true) {
  462. filename = insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion())
  463. } else {
  464. filename = txt.Name()
  465. }
  466. txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
  467. installPath := android.PathForModuleInstall(ctx, "etc")
  468. ctx.InstallFile(installPath, filename, txt.outputFile)
  469. }
  470. func (txt *vndkLibrariesTxt) GenerateSingletonBuildActions(ctx android.SingletonContext) {
  471. txt.moduleNames, txt.fileNames = txt.lister(ctx)
  472. android.WriteFileRule(ctx, txt.outputFile, strings.Join(txt.fileNames, "\n"))
  473. }
  474. func (txt *vndkLibrariesTxt) AndroidMkEntries() []android.AndroidMkEntries {
  475. return []android.AndroidMkEntries{android.AndroidMkEntries{
  476. Class: "ETC",
  477. OutputFile: android.OptionalPathForPath(txt.outputFile),
  478. ExtraEntries: []android.AndroidMkExtraEntriesFunc{
  479. func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
  480. entries.SetString("LOCAL_MODULE_STEM", txt.outputFile.Base())
  481. },
  482. },
  483. }}
  484. }
  485. func (txt *vndkLibrariesTxt) MakeVars(ctx android.MakeVarsContext) {
  486. filter := func(modules []string, prefix string) []string {
  487. if prefix == "" {
  488. return modules
  489. }
  490. var result []string
  491. for _, module := range modules {
  492. if strings.HasPrefix(module, prefix) {
  493. continue
  494. } else {
  495. result = append(result, module)
  496. }
  497. }
  498. return result
  499. }
  500. ctx.Strict(txt.makeVarName, strings.Join(filter(txt.moduleNames, txt.filterOutFromMakeVar), " "))
  501. }
  502. // PrebuiltEtcModule interface
  503. func (txt *vndkLibrariesTxt) OutputFile() android.OutputPath {
  504. return txt.outputFile
  505. }
  506. // PrebuiltEtcModule interface
  507. func (txt *vndkLibrariesTxt) BaseDir() string {
  508. return "etc"
  509. }
  510. // PrebuiltEtcModule interface
  511. func (txt *vndkLibrariesTxt) SubDir() string {
  512. return ""
  513. }
  514. func (txt *vndkLibrariesTxt) OutputFiles(tag string) (android.Paths, error) {
  515. return android.Paths{txt.outputFile}, nil
  516. }
  517. func VndkSnapshotSingleton() android.Singleton {
  518. return &vndkSnapshotSingleton{}
  519. }
  520. type vndkSnapshotSingleton struct {
  521. vndkLibrariesFile android.OutputPath
  522. vndkSnapshotZipFile android.OptionalPath
  523. }
  524. func isVndkSnapshotAware(config android.DeviceConfig, m LinkableInterface,
  525. apexInfo android.ApexInfo) (vndkType string, isVndkSnapshotLib bool) {
  526. if m.Target().NativeBridge == android.NativeBridgeEnabled {
  527. return "", false
  528. }
  529. // !inVendor: There's product/vendor variants for VNDK libs. We only care about vendor variants.
  530. // !installable: Snapshot only cares about "installable" modules.
  531. // !m.IsLlndk: llndk stubs are required for building against snapshots.
  532. // IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
  533. // !outputFile.Valid: Snapshot requires valid output file.
  534. if !m.InVendor() || (!installable(m, apexInfo) && !m.IsLlndk()) || m.IsSnapshotPrebuilt() || !m.OutputFile().Valid() {
  535. return "", false
  536. }
  537. if !m.IsSnapshotLibrary() || !m.Shared() {
  538. return "", false
  539. }
  540. if m.VndkVersion() == config.PlatformVndkVersion() {
  541. if m.IsVndk() && !m.IsVndkExt() {
  542. if m.IsVndkSp() {
  543. return "vndk-sp", true
  544. } else {
  545. return "vndk-core", true
  546. }
  547. } else if m.HasLlndkStubs() && m.StubsVersion() == "" {
  548. // Use default version for the snapshot.
  549. return "llndk-stub", true
  550. }
  551. }
  552. return "", false
  553. }
  554. func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  555. // build these files even if PlatformVndkVersion or BoardVndkVersion is not set
  556. c.buildVndkLibrariesTxtFiles(ctx)
  557. // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
  558. if ctx.DeviceConfig().VndkVersion() != "current" {
  559. return
  560. }
  561. if ctx.DeviceConfig().PlatformVndkVersion() == "" {
  562. return
  563. }
  564. var snapshotOutputs android.Paths
  565. /*
  566. VNDK snapshot zipped artifacts directory structure:
  567. {SNAPSHOT_ARCH}/
  568. arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
  569. shared/
  570. vndk-core/
  571. (VNDK-core libraries, e.g. libbinder.so)
  572. vndk-sp/
  573. (VNDK-SP libraries, e.g. libc++.so)
  574. llndk-stub/
  575. (LLNDK stub libraries)
  576. arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
  577. shared/
  578. vndk-core/
  579. (VNDK-core libraries, e.g. libbinder.so)
  580. vndk-sp/
  581. (VNDK-SP libraries, e.g. libc++.so)
  582. llndk-stub/
  583. (LLNDK stub libraries)
  584. binder32/
  585. (This directory is newly introduced in v28 (Android P) to hold
  586. prebuilts built for 32-bit binder interface.)
  587. arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/
  588. ...
  589. configs/
  590. (various *.txt configuration files)
  591. include/
  592. (header files of same directory structure with source tree)
  593. NOTICE_FILES/
  594. (notice files of libraries, e.g. libcutils.so.txt)
  595. */
  596. snapshotDir := "vndk-snapshot"
  597. snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
  598. configsDir := filepath.Join(snapshotArchDir, "configs")
  599. noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
  600. includeDir := filepath.Join(snapshotArchDir, "include")
  601. // set of notice files copied.
  602. noticeBuilt := make(map[string]bool)
  603. // paths of VNDK modules for GPL license checking
  604. modulePaths := make(map[string]string)
  605. // actual module names of .so files
  606. // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full"
  607. moduleNames := make(map[string]string)
  608. var headers android.Paths
  609. // installVndkSnapshotLib copies built .so file from the module.
  610. // Also, if the build artifacts is on, write a json file which contains all exported flags
  611. // with FlagExporterInfo.
  612. installVndkSnapshotLib := func(m *Module, vndkType string) (android.Paths, bool) {
  613. var ret android.Paths
  614. targetArch := "arch-" + m.Target().Arch.ArchType.String()
  615. if m.Target().Arch.ArchVariant != "" {
  616. targetArch += "-" + m.Target().Arch.ArchVariant
  617. }
  618. libPath := m.outputFile.Path()
  619. snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base())
  620. ret = append(ret, snapshot.CopyFileRule(pctx, ctx, libPath, snapshotLibOut))
  621. // json struct to export snapshot information
  622. prop := struct {
  623. MinSdkVersion string `json:",omitempty"`
  624. LicenseKinds []string `json:",omitempty"`
  625. LicenseTexts []string `json:",omitempty"`
  626. ExportedDirs []string `json:",omitempty"`
  627. ExportedSystemDirs []string `json:",omitempty"`
  628. ExportedFlags []string `json:",omitempty"`
  629. RelativeInstallPath string `json:",omitempty"`
  630. }{}
  631. prop.LicenseKinds = m.EffectiveLicenseKinds()
  632. prop.LicenseTexts = m.EffectiveLicenseFiles().Strings()
  633. prop.MinSdkVersion = m.MinSdkVersion()
  634. if ctx.Config().VndkSnapshotBuildArtifacts() {
  635. exportedInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
  636. prop.ExportedFlags = exportedInfo.Flags
  637. prop.ExportedDirs = exportedInfo.IncludeDirs.Strings()
  638. prop.ExportedSystemDirs = exportedInfo.SystemIncludeDirs.Strings()
  639. prop.RelativeInstallPath = m.RelativeInstallPath()
  640. }
  641. propOut := snapshotLibOut + ".json"
  642. j, err := json.Marshal(prop)
  643. if err != nil {
  644. ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
  645. return nil, false
  646. }
  647. ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
  648. return ret, true
  649. }
  650. ctx.VisitAllModules(func(module android.Module) {
  651. m, ok := module.(*Module)
  652. if !ok || !m.Enabled() {
  653. return
  654. }
  655. apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
  656. vndkType, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo)
  657. if !ok {
  658. return
  659. }
  660. // For all snapshot candidates, the followings are captured.
  661. // - .so files
  662. // - notice files
  663. //
  664. // The followings are also captured if VNDK_SNAPSHOT_BUILD_ARTIFACTS.
  665. // - .json files containing exported flags
  666. // - exported headers from collectHeadersForSnapshot()
  667. //
  668. // Headers are deduplicated after visiting all modules.
  669. // install .so files for appropriate modules.
  670. // Also install .json files if VNDK_SNAPSHOT_BUILD_ARTIFACTS
  671. libs, ok := installVndkSnapshotLib(m, vndkType)
  672. if !ok {
  673. return
  674. }
  675. snapshotOutputs = append(snapshotOutputs, libs...)
  676. // These are for generating module_names.txt and module_paths.txt
  677. stem := m.outputFile.Path().Base()
  678. moduleNames[stem] = ctx.ModuleName(m)
  679. modulePaths[stem] = ctx.ModuleDir(m)
  680. for _, notice := range m.EffectiveLicenseFiles() {
  681. if _, ok := noticeBuilt[notice.String()]; !ok {
  682. noticeBuilt[notice.String()] = true
  683. snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
  684. pctx, ctx, notice, filepath.Join(noticeDir, notice.String())))
  685. }
  686. }
  687. if ctx.Config().VndkSnapshotBuildArtifacts() {
  688. headers = append(headers, m.SnapshotHeaders()...)
  689. }
  690. })
  691. // install all headers after removing duplicates
  692. for _, header := range android.FirstUniquePaths(headers) {
  693. snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
  694. pctx, ctx, header, filepath.Join(includeDir, header.String())))
  695. }
  696. // install *.libraries.txt except vndkcorevariant.libraries.txt
  697. ctx.VisitAllModules(func(module android.Module) {
  698. m, ok := module.(*vndkLibrariesTxt)
  699. if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt {
  700. return
  701. }
  702. snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
  703. pctx, ctx, m.OutputFile(), filepath.Join(configsDir, m.Name())))
  704. })
  705. /*
  706. module_paths.txt contains paths on which VNDK modules are defined.
  707. e.g.,
  708. libbase.so system/libbase
  709. libc.so bionic/libc
  710. ...
  711. */
  712. snapshotOutputs = append(snapshotOutputs, installMapListFileRule(ctx, modulePaths, filepath.Join(configsDir, "module_paths.txt")))
  713. /*
  714. module_names.txt contains names as which VNDK modules are defined,
  715. because output filename and module name can be different with stem and suffix properties.
  716. e.g.,
  717. libcutils.so libcutils
  718. libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full
  719. ...
  720. */
  721. snapshotOutputs = append(snapshotOutputs, installMapListFileRule(ctx, moduleNames, filepath.Join(configsDir, "module_names.txt")))
  722. // All artifacts are ready. Sort them to normalize ninja and then zip.
  723. sort.Slice(snapshotOutputs, func(i, j int) bool {
  724. return snapshotOutputs[i].String() < snapshotOutputs[j].String()
  725. })
  726. zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip")
  727. zipRule := android.NewRuleBuilder(pctx, ctx)
  728. // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
  729. snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list")
  730. rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
  731. zipRule.Command().
  732. Text("tr").
  733. FlagWithArg("-d ", "\\'").
  734. FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
  735. FlagWithOutput("> ", snapshotOutputList)
  736. zipRule.Temporary(snapshotOutputList)
  737. zipRule.Command().
  738. BuiltTool("soong_zip").
  739. FlagWithOutput("-o ", zipPath).
  740. FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
  741. FlagWithInput("-l ", snapshotOutputList)
  742. zipRule.Build(zipPath.String(), "vndk snapshot "+zipPath.String())
  743. zipRule.DeleteTemporaryFiles()
  744. c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath)
  745. }
  746. func getVndkFileName(m *Module) (string, error) {
  747. if library, ok := m.linker.(*libraryDecorator); ok {
  748. return library.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
  749. }
  750. if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok {
  751. return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
  752. }
  753. return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
  754. }
  755. func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) {
  756. // Build list of vndk libs as merged & tagged & filter-out(libclang_rt):
  757. // Since each target have different set of libclang_rt.* files,
  758. // keep the common set of files in vndk.libraries.txt
  759. _, llndk := vndkModuleListRemover(llndkLibraries, "libclang_rt.")(ctx)
  760. _, vndkcore := vndkModuleListRemover(vndkCoreLibraries, "libclang_rt.")(ctx)
  761. _, vndksp := vndkSPLibraries(ctx)
  762. _, vndkprivate := vndkPrivateLibraries(ctx)
  763. _, vndkproduct := vndkModuleListRemover(vndkProductLibraries, "libclang_rt.")(ctx)
  764. var merged []string
  765. merged = append(merged, addPrefix(llndk, "LLNDK: ")...)
  766. merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...)
  767. merged = append(merged, addPrefix(vndkcore, "VNDK-core: ")...)
  768. merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...)
  769. merged = append(merged, addPrefix(vndkproduct, "VNDK-product: ")...)
  770. c.vndkLibrariesFile = android.PathForOutput(ctx, "vndk", "vndk.libraries.txt")
  771. android.WriteFileRule(ctx, c.vndkLibrariesFile, strings.Join(merged, "\n"))
  772. }
  773. func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
  774. // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if
  775. // they been moved to an apex.
  776. movedToApexLlndkLibraries := make(map[string]bool)
  777. ctx.VisitAllModules(func(module android.Module) {
  778. if library := moduleLibraryInterface(module); library != nil && library.hasLLNDKStubs() {
  779. // Skip bionic libs, they are handled in different manner
  780. name := library.implementationModuleName(module.(*Module).BaseModuleName())
  781. if module.(android.ApexModule).DirectlyInAnyApex() && !isBionic(name) {
  782. movedToApexLlndkLibraries[name] = true
  783. }
  784. }
  785. })
  786. ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES",
  787. strings.Join(android.SortedKeys(movedToApexLlndkLibraries), " "))
  788. ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String())
  789. ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String())
  790. }