vndk.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  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) {
  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. useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
  334. mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
  335. return lib.shared() && m.InVendor() && m.IsVndk() && !m.IsVndkExt() && !useCoreVariant
  336. }
  337. return false
  338. }
  339. // gather list of vndk-core, vndk-sp, and ll-ndk libs
  340. func VndkMutator(mctx android.BottomUpMutatorContext) {
  341. m, ok := mctx.Module().(*Module)
  342. if !ok {
  343. return
  344. }
  345. if shouldSkipVndkMutator(m) {
  346. return
  347. }
  348. lib, isLib := m.linker.(*libraryDecorator)
  349. prebuiltLib, isPrebuiltLib := m.linker.(*prebuiltLibraryLinker)
  350. if m.UseVndk() && isLib && lib.hasLLNDKStubs() {
  351. m.VendorProperties.IsLLNDK = true
  352. m.VendorProperties.IsVNDKPrivate = Bool(lib.Properties.Llndk.Private)
  353. }
  354. if m.UseVndk() && isPrebuiltLib && prebuiltLib.hasLLNDKStubs() {
  355. m.VendorProperties.IsLLNDK = true
  356. m.VendorProperties.IsVNDKPrivate = Bool(prebuiltLib.Properties.Llndk.Private)
  357. }
  358. if (isLib && lib.buildShared()) || (isPrebuiltLib && prebuiltLib.buildShared()) {
  359. if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
  360. processVndkLibrary(mctx, m)
  361. return
  362. }
  363. }
  364. }
  365. func init() {
  366. RegisterVndkLibraryTxtTypes(android.InitRegistrationContext)
  367. android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
  368. }
  369. func RegisterVndkLibraryTxtTypes(ctx android.RegistrationContext) {
  370. ctx.RegisterSingletonModuleType("llndk_libraries_txt", llndkLibrariesTxtFactory)
  371. ctx.RegisterSingletonModuleType("vndksp_libraries_txt", vndkSPLibrariesTxtFactory)
  372. ctx.RegisterSingletonModuleType("vndkcore_libraries_txt", vndkCoreLibrariesTxtFactory)
  373. ctx.RegisterSingletonModuleType("vndkprivate_libraries_txt", vndkPrivateLibrariesTxtFactory)
  374. ctx.RegisterSingletonModuleType("vndkproduct_libraries_txt", vndkProductLibrariesTxtFactory)
  375. ctx.RegisterSingletonModuleType("vndkcorevariant_libraries_txt", vndkUsingCoreVariantLibrariesTxtFactory)
  376. }
  377. type vndkLibrariesTxt struct {
  378. android.SingletonModuleBase
  379. lister moduleListerFunc
  380. makeVarName string
  381. filterOutFromMakeVar string
  382. properties VndkLibrariesTxtProperties
  383. outputFile android.OutputPath
  384. moduleNames []string
  385. fileNames []string
  386. }
  387. type VndkLibrariesTxtProperties struct {
  388. Insert_vndk_version *bool
  389. }
  390. var _ etc.PrebuiltEtcModule = &vndkLibrariesTxt{}
  391. var _ android.OutputFileProducer = &vndkLibrariesTxt{}
  392. // llndk_libraries_txt is a singleton module whose content is a list of LLNDK libraries
  393. // generated by Soong but can be referenced by other modules.
  394. // For example, apex_vndk can depend on these files as prebuilt.
  395. // Make uses LLNDK_LIBRARIES to determine which libraries to install.
  396. // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
  397. // Therefore, by removing the library here, we cause it to only be installed if libc
  398. // depends on it.
  399. func llndkLibrariesTxtFactory() android.SingletonModule {
  400. return newVndkLibrariesWithMakeVarFilter(llndkLibraries, "LLNDK_LIBRARIES", "libclang_rt.hwasan")
  401. }
  402. // vndksp_libraries_txt is a singleton module whose content is a list of VNDKSP libraries
  403. // generated by Soong but can be referenced by other modules.
  404. // For example, apex_vndk can depend on these files as prebuilt.
  405. func vndkSPLibrariesTxtFactory() android.SingletonModule {
  406. return newVndkLibrariesTxt(vndkSPLibraries, "VNDK_SAMEPROCESS_LIBRARIES")
  407. }
  408. // vndkcore_libraries_txt is a singleton module whose content is a list of VNDK core libraries
  409. // generated by Soong but can be referenced by other modules.
  410. // For example, apex_vndk can depend on these files as prebuilt.
  411. func vndkCoreLibrariesTxtFactory() android.SingletonModule {
  412. return newVndkLibrariesTxt(vndkCoreLibraries, "VNDK_CORE_LIBRARIES")
  413. }
  414. // vndkprivate_libraries_txt is a singleton module whose content is a list of VNDK private libraries
  415. // generated by Soong but can be referenced by other modules.
  416. // For example, apex_vndk can depend on these files as prebuilt.
  417. func vndkPrivateLibrariesTxtFactory() android.SingletonModule {
  418. return newVndkLibrariesTxt(vndkPrivateLibraries, "VNDK_PRIVATE_LIBRARIES")
  419. }
  420. // vndkproduct_libraries_txt is a singleton module whose content is a list of VNDK product libraries
  421. // generated by Soong but can be referenced by other modules.
  422. // For example, apex_vndk can depend on these files as prebuilt.
  423. func vndkProductLibrariesTxtFactory() android.SingletonModule {
  424. return newVndkLibrariesTxt(vndkProductLibraries, "VNDK_PRODUCT_LIBRARIES")
  425. }
  426. // vndkcorevariant_libraries_txt is a singleton module whose content is a list of VNDK libraries
  427. // that are using the core variant, generated by Soong but can be referenced by other modules.
  428. // For example, apex_vndk can depend on these files as prebuilt.
  429. func vndkUsingCoreVariantLibrariesTxtFactory() android.SingletonModule {
  430. return newVndkLibrariesTxt(vndkUsingCoreVariantLibraries, "VNDK_USING_CORE_VARIANT_LIBRARIES")
  431. }
  432. func newVndkLibrariesWithMakeVarFilter(lister moduleListerFunc, makeVarName string, filter string) android.SingletonModule {
  433. m := &vndkLibrariesTxt{
  434. lister: lister,
  435. makeVarName: makeVarName,
  436. filterOutFromMakeVar: filter,
  437. }
  438. m.AddProperties(&m.properties)
  439. android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
  440. return m
  441. }
  442. func newVndkLibrariesTxt(lister moduleListerFunc, makeVarName string) android.SingletonModule {
  443. return newVndkLibrariesWithMakeVarFilter(lister, makeVarName, "")
  444. }
  445. func insertVndkVersion(filename string, vndkVersion string) string {
  446. if index := strings.LastIndex(filename, "."); index != -1 {
  447. return filename[:index] + "." + vndkVersion + filename[index:]
  448. }
  449. return filename
  450. }
  451. func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  452. var filename string
  453. if BoolDefault(txt.properties.Insert_vndk_version, true) {
  454. filename = insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion())
  455. } else {
  456. filename = txt.Name()
  457. }
  458. txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
  459. installPath := android.PathForModuleInstall(ctx, "etc")
  460. ctx.InstallFile(installPath, filename, txt.outputFile)
  461. }
  462. func (txt *vndkLibrariesTxt) GenerateSingletonBuildActions(ctx android.SingletonContext) {
  463. txt.moduleNames, txt.fileNames = txt.lister(ctx)
  464. android.WriteFileRule(ctx, txt.outputFile, strings.Join(txt.fileNames, "\n"))
  465. }
  466. func (txt *vndkLibrariesTxt) AndroidMkEntries() []android.AndroidMkEntries {
  467. return []android.AndroidMkEntries{android.AndroidMkEntries{
  468. Class: "ETC",
  469. OutputFile: android.OptionalPathForPath(txt.outputFile),
  470. ExtraEntries: []android.AndroidMkExtraEntriesFunc{
  471. func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
  472. entries.SetString("LOCAL_MODULE_STEM", txt.outputFile.Base())
  473. },
  474. },
  475. }}
  476. }
  477. func (txt *vndkLibrariesTxt) MakeVars(ctx android.MakeVarsContext) {
  478. filter := func(modules []string, prefix string) []string {
  479. if prefix == "" {
  480. return modules
  481. }
  482. var result []string
  483. for _, module := range modules {
  484. if strings.HasPrefix(module, prefix) {
  485. continue
  486. } else {
  487. result = append(result, module)
  488. }
  489. }
  490. return result
  491. }
  492. ctx.Strict(txt.makeVarName, strings.Join(filter(txt.moduleNames, txt.filterOutFromMakeVar), " "))
  493. }
  494. // PrebuiltEtcModule interface
  495. func (txt *vndkLibrariesTxt) OutputFile() android.OutputPath {
  496. return txt.outputFile
  497. }
  498. // PrebuiltEtcModule interface
  499. func (txt *vndkLibrariesTxt) BaseDir() string {
  500. return "etc"
  501. }
  502. // PrebuiltEtcModule interface
  503. func (txt *vndkLibrariesTxt) SubDir() string {
  504. return ""
  505. }
  506. func (txt *vndkLibrariesTxt) OutputFiles(tag string) (android.Paths, error) {
  507. return android.Paths{txt.outputFile}, nil
  508. }
  509. func VndkSnapshotSingleton() android.Singleton {
  510. return &vndkSnapshotSingleton{}
  511. }
  512. type vndkSnapshotSingleton struct {
  513. vndkLibrariesFile android.OutputPath
  514. vndkSnapshotZipFile android.OptionalPath
  515. }
  516. func isVndkSnapshotAware(config android.DeviceConfig, m LinkableInterface,
  517. apexInfo android.ApexInfo) (vndkType string, isVndkSnapshotLib bool) {
  518. if m.Target().NativeBridge == android.NativeBridgeEnabled {
  519. return "", false
  520. }
  521. // !inVendor: There's product/vendor variants for VNDK libs. We only care about vendor variants.
  522. // !installable: Snapshot only cares about "installable" modules.
  523. // !m.IsLlndk: llndk stubs are required for building against snapshots.
  524. // IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
  525. // !outputFile.Valid: Snapshot requires valid output file.
  526. if !m.InVendor() || (!installable(m, apexInfo) && !m.IsLlndk()) || m.IsSnapshotPrebuilt() || !m.OutputFile().Valid() {
  527. return "", false
  528. }
  529. if !m.IsSnapshotLibrary() || !m.Shared() {
  530. return "", false
  531. }
  532. if m.VndkVersion() == config.PlatformVndkVersion() {
  533. if m.IsVndk() && !m.IsVndkExt() {
  534. if m.IsVndkSp() {
  535. return "vndk-sp", true
  536. } else {
  537. return "vndk-core", true
  538. }
  539. } else if m.HasLlndkStubs() && m.StubsVersion() == "" {
  540. // Use default version for the snapshot.
  541. return "llndk-stub", true
  542. }
  543. }
  544. return "", false
  545. }
  546. func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  547. // build these files even if PlatformVndkVersion or BoardVndkVersion is not set
  548. c.buildVndkLibrariesTxtFiles(ctx)
  549. // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
  550. if ctx.DeviceConfig().VndkVersion() != "current" {
  551. return
  552. }
  553. if ctx.DeviceConfig().PlatformVndkVersion() == "" {
  554. return
  555. }
  556. var snapshotOutputs android.Paths
  557. /*
  558. VNDK snapshot zipped artifacts directory structure:
  559. {SNAPSHOT_ARCH}/
  560. arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
  561. shared/
  562. vndk-core/
  563. (VNDK-core libraries, e.g. libbinder.so)
  564. vndk-sp/
  565. (VNDK-SP libraries, e.g. libc++.so)
  566. llndk-stub/
  567. (LLNDK stub libraries)
  568. arch-{TARGET_2ND_ARCH}-{TARGET_2ND_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. binder32/
  577. (This directory is newly introduced in v28 (Android P) to hold
  578. prebuilts built for 32-bit binder interface.)
  579. arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/
  580. ...
  581. configs/
  582. (various *.txt configuration files)
  583. include/
  584. (header files of same directory structure with source tree)
  585. NOTICE_FILES/
  586. (notice files of libraries, e.g. libcutils.so.txt)
  587. */
  588. snapshotDir := "vndk-snapshot"
  589. snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
  590. configsDir := filepath.Join(snapshotArchDir, "configs")
  591. includeDir := filepath.Join(snapshotArchDir, "include")
  592. // paths of VNDK modules for GPL license checking
  593. modulePaths := make(map[string]string)
  594. // actual module names of .so files
  595. // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full"
  596. moduleNames := make(map[string]string)
  597. var headers android.Paths
  598. // installVndkSnapshotLib copies built .so file from the module.
  599. // Also, if the build artifacts is on, write a json file which contains all exported flags
  600. // with FlagExporterInfo.
  601. installVndkSnapshotLib := func(m *Module, vndkType string) (android.Paths, bool) {
  602. var ret android.Paths
  603. targetArch := "arch-" + m.Target().Arch.ArchType.String()
  604. if m.Target().Arch.ArchVariant != "" {
  605. targetArch += "-" + m.Target().Arch.ArchVariant
  606. }
  607. libPath := m.outputFile.Path()
  608. snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base())
  609. ret = append(ret, snapshot.CopyFileRule(pctx, ctx, libPath, snapshotLibOut))
  610. if ctx.Config().VndkSnapshotBuildArtifacts() {
  611. prop := struct {
  612. ExportedDirs []string `json:",omitempty"`
  613. ExportedSystemDirs []string `json:",omitempty"`
  614. ExportedFlags []string `json:",omitempty"`
  615. RelativeInstallPath string `json:",omitempty"`
  616. }{}
  617. exportedInfo := ctx.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
  618. prop.ExportedFlags = exportedInfo.Flags
  619. prop.ExportedDirs = exportedInfo.IncludeDirs.Strings()
  620. prop.ExportedSystemDirs = exportedInfo.SystemIncludeDirs.Strings()
  621. prop.RelativeInstallPath = m.RelativeInstallPath()
  622. propOut := snapshotLibOut + ".json"
  623. j, err := json.Marshal(prop)
  624. if err != nil {
  625. ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
  626. return nil, false
  627. }
  628. ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
  629. }
  630. return ret, true
  631. }
  632. ctx.VisitAllModules(func(module android.Module) {
  633. m, ok := module.(*Module)
  634. if !ok || !m.Enabled() {
  635. return
  636. }
  637. apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
  638. vndkType, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo)
  639. if !ok {
  640. return
  641. }
  642. // For all snapshot candidates, the followings are captured.
  643. // - .so files
  644. // - notice files
  645. //
  646. // The followings are also captured if VNDK_SNAPSHOT_BUILD_ARTIFACTS.
  647. // - .json files containing exported flags
  648. // - exported headers from collectHeadersForSnapshot()
  649. //
  650. // Headers are deduplicated after visiting all modules.
  651. // install .so files for appropriate modules.
  652. // Also install .json files if VNDK_SNAPSHOT_BUILD_ARTIFACTS
  653. libs, ok := installVndkSnapshotLib(m, vndkType)
  654. if !ok {
  655. return
  656. }
  657. snapshotOutputs = append(snapshotOutputs, libs...)
  658. // These are for generating module_names.txt and module_paths.txt
  659. stem := m.outputFile.Path().Base()
  660. moduleNames[stem] = ctx.ModuleName(m)
  661. modulePaths[stem] = ctx.ModuleDir(m)
  662. if ctx.Config().VndkSnapshotBuildArtifacts() {
  663. headers = append(headers, m.SnapshotHeaders()...)
  664. }
  665. })
  666. // install all headers after removing duplicates
  667. for _, header := range android.FirstUniquePaths(headers) {
  668. snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
  669. pctx, ctx, header, filepath.Join(includeDir, header.String())))
  670. }
  671. // install *.libraries.txt except vndkcorevariant.libraries.txt
  672. ctx.VisitAllModules(func(module android.Module) {
  673. m, ok := module.(*vndkLibrariesTxt)
  674. if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt {
  675. return
  676. }
  677. snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
  678. pctx, ctx, m.OutputFile(), filepath.Join(configsDir, m.Name())))
  679. })
  680. /*
  681. module_paths.txt contains paths on which VNDK modules are defined.
  682. e.g.,
  683. libbase.so system/libbase
  684. libc.so bionic/libc
  685. ...
  686. */
  687. snapshotOutputs = append(snapshotOutputs, installMapListFileRule(ctx, modulePaths, filepath.Join(configsDir, "module_paths.txt")))
  688. /*
  689. module_names.txt contains names as which VNDK modules are defined,
  690. because output filename and module name can be different with stem and suffix properties.
  691. e.g.,
  692. libcutils.so libcutils
  693. libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full
  694. ...
  695. */
  696. snapshotOutputs = append(snapshotOutputs, installMapListFileRule(ctx, moduleNames, filepath.Join(configsDir, "module_names.txt")))
  697. // All artifacts are ready. Sort them to normalize ninja and then zip.
  698. sort.Slice(snapshotOutputs, func(i, j int) bool {
  699. return snapshotOutputs[i].String() < snapshotOutputs[j].String()
  700. })
  701. zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip")
  702. zipRule := android.NewRuleBuilder(pctx, ctx)
  703. // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
  704. snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list")
  705. rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
  706. zipRule.Command().
  707. Text("tr").
  708. FlagWithArg("-d ", "\\'").
  709. FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
  710. FlagWithOutput("> ", snapshotOutputList)
  711. zipRule.Temporary(snapshotOutputList)
  712. zipRule.Command().
  713. BuiltTool("soong_zip").
  714. FlagWithOutput("-o ", zipPath).
  715. FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
  716. FlagWithInput("-l ", snapshotOutputList)
  717. zipRule.Build(zipPath.String(), "vndk snapshot "+zipPath.String())
  718. zipRule.DeleteTemporaryFiles()
  719. c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath)
  720. }
  721. func getVndkFileName(m *Module) (string, error) {
  722. if library, ok := m.linker.(*libraryDecorator); ok {
  723. return library.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
  724. }
  725. if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok {
  726. return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
  727. }
  728. return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
  729. }
  730. func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) {
  731. // Build list of vndk libs as merged & tagged & filter-out(libclang_rt):
  732. // Since each target have different set of libclang_rt.* files,
  733. // keep the common set of files in vndk.libraries.txt
  734. _, llndk := vndkModuleListRemover(llndkLibraries, "libclang_rt.")(ctx)
  735. _, vndkcore := vndkModuleListRemover(vndkCoreLibraries, "libclang_rt.")(ctx)
  736. _, vndksp := vndkSPLibraries(ctx)
  737. _, vndkprivate := vndkPrivateLibraries(ctx)
  738. _, vndkproduct := vndkModuleListRemover(vndkProductLibraries, "libclang_rt.")(ctx)
  739. var merged []string
  740. merged = append(merged, addPrefix(llndk, "LLNDK: ")...)
  741. merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...)
  742. merged = append(merged, addPrefix(vndkcore, "VNDK-core: ")...)
  743. merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...)
  744. merged = append(merged, addPrefix(vndkproduct, "VNDK-product: ")...)
  745. c.vndkLibrariesFile = android.PathForOutput(ctx, "vndk", "vndk.libraries.txt")
  746. android.WriteFileRule(ctx, c.vndkLibrariesFile, strings.Join(merged, "\n"))
  747. }
  748. func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
  749. // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if
  750. // they been moved to an apex.
  751. movedToApexLlndkLibraries := make(map[string]bool)
  752. ctx.VisitAllModules(func(module android.Module) {
  753. if library := moduleLibraryInterface(module); library != nil && library.hasLLNDKStubs() {
  754. // Skip bionic libs, they are handled in different manner
  755. name := library.implementationModuleName(module.(*Module).BaseModuleName())
  756. if module.(android.ApexModule).DirectlyInAnyApex() && !isBionic(name) {
  757. movedToApexLlndkLibraries[name] = true
  758. }
  759. }
  760. })
  761. ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES",
  762. strings.Join(android.SortedStringKeys(movedToApexLlndkLibraries), " "))
  763. ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String())
  764. ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String())
  765. }