ndk_library.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  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. import (
  16. "fmt"
  17. "path/filepath"
  18. "runtime"
  19. "strings"
  20. "sync"
  21. "github.com/google/blueprint"
  22. "github.com/google/blueprint/proptools"
  23. "android/soong/android"
  24. "android/soong/bazel"
  25. "android/soong/cc/config"
  26. )
  27. func init() {
  28. pctx.HostBinToolVariable("ndkStubGenerator", "ndkstubgen")
  29. pctx.HostBinToolVariable("abidiff", "abidiff")
  30. pctx.HostBinToolVariable("abitidy", "abitidy")
  31. pctx.HostBinToolVariable("abidw", "abidw")
  32. }
  33. var (
  34. genStubSrc = pctx.AndroidStaticRule("genStubSrc",
  35. blueprint.RuleParams{
  36. Command: "$ndkStubGenerator --arch $arch --api $apiLevel " +
  37. "--api-map $apiMap $flags $in $out",
  38. CommandDeps: []string{"$ndkStubGenerator"},
  39. }, "arch", "apiLevel", "apiMap", "flags")
  40. abidw = pctx.AndroidStaticRule("abidw",
  41. blueprint.RuleParams{
  42. Command: "$abidw --type-id-style hash --no-corpus-path " +
  43. "--no-show-locs --no-comp-dir-path -w $symbolList " +
  44. "$in --out-file $out",
  45. CommandDeps: []string{"$abidw"},
  46. }, "symbolList")
  47. abitidy = pctx.AndroidStaticRule("abitidy",
  48. blueprint.RuleParams{
  49. Command: "$abitidy --all $flags -i $in -o $out",
  50. CommandDeps: []string{"$abitidy"},
  51. }, "flags")
  52. abidiff = pctx.AndroidStaticRule("abidiff",
  53. blueprint.RuleParams{
  54. // Need to create *some* output for ninja. We don't want to use tee
  55. // because we don't want to spam the build output with "nothing
  56. // changed" messages, so redirect output message to $out, and if
  57. // changes were detected print the output and fail.
  58. Command: "$abidiff $args $in > $out || (cat $out && false)",
  59. CommandDeps: []string{"$abidiff"},
  60. }, "args")
  61. ndkLibrarySuffix = ".ndk"
  62. ndkKnownLibsKey = android.NewOnceKey("ndkKnownLibsKey")
  63. // protects ndkKnownLibs writes during parallel BeginMutator.
  64. ndkKnownLibsLock sync.Mutex
  65. stubImplementation = dependencyTag{name: "stubImplementation"}
  66. )
  67. // The First_version and Unversioned_until properties of this struct should not
  68. // be used directly, but rather through the ApiLevel returning methods
  69. // firstVersion() and unversionedUntil().
  70. // Creates a stub shared library based on the provided version file.
  71. //
  72. // Example:
  73. //
  74. // ndk_library {
  75. //
  76. // name: "libfoo",
  77. // symbol_file: "libfoo.map.txt",
  78. // first_version: "9",
  79. //
  80. // }
  81. type libraryProperties struct {
  82. // Relative path to the symbol map.
  83. // An example file can be seen here: TODO(danalbert): Make an example.
  84. Symbol_file *string `android:"path"`
  85. // The first API level a library was available. A library will be generated
  86. // for every API level beginning with this one.
  87. First_version *string
  88. // The first API level that library should have the version script applied.
  89. // This defaults to the value of first_version, and should almost never be
  90. // used. This is only needed to work around platform bugs like
  91. // https://github.com/android-ndk/ndk/issues/265.
  92. Unversioned_until *string
  93. // If true, does not emit errors when APIs lacking type information are
  94. // found. This is false by default and should not be enabled outside bionic,
  95. // where it is enabled pending a fix for http://b/190554910 (no debug info
  96. // for asm implemented symbols).
  97. Allow_untyped_symbols *bool
  98. // Headers presented by this library to the Public API Surface
  99. Export_header_libs []string
  100. }
  101. type stubDecorator struct {
  102. *libraryDecorator
  103. properties libraryProperties
  104. versionScriptPath android.ModuleGenPath
  105. parsedCoverageXmlPath android.ModuleOutPath
  106. installPath android.Path
  107. abiDumpPath android.OutputPath
  108. abiDiffPaths android.Paths
  109. apiLevel android.ApiLevel
  110. firstVersion android.ApiLevel
  111. unversionedUntil android.ApiLevel
  112. }
  113. var _ versionedInterface = (*stubDecorator)(nil)
  114. func shouldUseVersionScript(ctx BaseModuleContext, stub *stubDecorator) bool {
  115. return stub.apiLevel.GreaterThanOrEqualTo(stub.unversionedUntil)
  116. }
  117. func (stub *stubDecorator) implementationModuleName(name string) string {
  118. return strings.TrimSuffix(name, ndkLibrarySuffix)
  119. }
  120. func ndkLibraryVersions(ctx android.BaseMutatorContext, from android.ApiLevel) []string {
  121. var versions []android.ApiLevel
  122. versionStrs := []string{}
  123. for _, version := range ctx.Config().AllSupportedApiLevels() {
  124. if version.GreaterThanOrEqualTo(from) {
  125. versions = append(versions, version)
  126. versionStrs = append(versionStrs, version.String())
  127. }
  128. }
  129. versionStrs = append(versionStrs, android.FutureApiLevel.String())
  130. return versionStrs
  131. }
  132. func (this *stubDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
  133. if !ctx.Module().Enabled() {
  134. return nil
  135. }
  136. if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
  137. ctx.Module().Disable()
  138. return nil
  139. }
  140. firstVersion, err := nativeApiLevelFromUser(ctx,
  141. String(this.properties.First_version))
  142. if err != nil {
  143. ctx.PropertyErrorf("first_version", err.Error())
  144. return nil
  145. }
  146. return ndkLibraryVersions(ctx, firstVersion)
  147. }
  148. func (this *stubDecorator) initializeProperties(ctx BaseModuleContext) bool {
  149. this.apiLevel = nativeApiLevelOrPanic(ctx, this.stubsVersion())
  150. var err error
  151. this.firstVersion, err = nativeApiLevelFromUser(ctx,
  152. String(this.properties.First_version))
  153. if err != nil {
  154. ctx.PropertyErrorf("first_version", err.Error())
  155. return false
  156. }
  157. str := proptools.StringDefault(this.properties.Unversioned_until, "minimum")
  158. this.unversionedUntil, err = nativeApiLevelFromUser(ctx, str)
  159. if err != nil {
  160. ctx.PropertyErrorf("unversioned_until", err.Error())
  161. return false
  162. }
  163. return true
  164. }
  165. func getNDKKnownLibs(config android.Config) *[]string {
  166. return config.Once(ndkKnownLibsKey, func() interface{} {
  167. return &[]string{}
  168. }).(*[]string)
  169. }
  170. func (c *stubDecorator) compilerInit(ctx BaseModuleContext) {
  171. c.baseCompiler.compilerInit(ctx)
  172. name := ctx.baseModuleName()
  173. if strings.HasSuffix(name, ndkLibrarySuffix) {
  174. ctx.PropertyErrorf("name", "Do not append %q manually, just use the base name", ndkLibrarySuffix)
  175. }
  176. ndkKnownLibsLock.Lock()
  177. defer ndkKnownLibsLock.Unlock()
  178. ndkKnownLibs := getNDKKnownLibs(ctx.Config())
  179. for _, lib := range *ndkKnownLibs {
  180. if lib == name {
  181. return
  182. }
  183. }
  184. *ndkKnownLibs = append(*ndkKnownLibs, name)
  185. }
  186. var stubLibraryCompilerFlags = []string{
  187. // We're knowingly doing some otherwise unsightly things with builtin
  188. // functions here. We're just generating stub libraries, so ignore it.
  189. "-Wno-incompatible-library-redeclaration",
  190. "-Wno-incomplete-setjmp-declaration",
  191. "-Wno-builtin-requires-header",
  192. "-Wno-invalid-noreturn",
  193. "-Wall",
  194. "-Werror",
  195. // These libraries aren't actually used. Don't worry about unwinding
  196. // (avoids the need to link an unwinder into a fake library).
  197. "-fno-unwind-tables",
  198. }
  199. func init() {
  200. config.ExportStringList("StubLibraryCompilerFlags", stubLibraryCompilerFlags)
  201. }
  202. func addStubLibraryCompilerFlags(flags Flags) Flags {
  203. flags.Global.CFlags = append(flags.Global.CFlags, stubLibraryCompilerFlags...)
  204. // All symbols in the stubs library should be visible.
  205. if inList("-fvisibility=hidden", flags.Local.CFlags) {
  206. flags.Local.CFlags = append(flags.Local.CFlags, "-fvisibility=default")
  207. }
  208. return flags
  209. }
  210. func (stub *stubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
  211. flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
  212. return addStubLibraryCompilerFlags(flags)
  213. }
  214. type ndkApiOutputs struct {
  215. stubSrc android.ModuleGenPath
  216. versionScript android.ModuleGenPath
  217. symbolList android.ModuleGenPath
  218. }
  219. func parseNativeAbiDefinition(ctx ModuleContext, symbolFile string,
  220. apiLevel android.ApiLevel, genstubFlags string) ndkApiOutputs {
  221. stubSrcPath := android.PathForModuleGen(ctx, "stub.c")
  222. versionScriptPath := android.PathForModuleGen(ctx, "stub.map")
  223. symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
  224. symbolListPath := android.PathForModuleGen(ctx, "abi_symbol_list.txt")
  225. apiLevelsJson := android.GetApiLevelsJson(ctx)
  226. ctx.Build(pctx, android.BuildParams{
  227. Rule: genStubSrc,
  228. Description: "generate stubs " + symbolFilePath.Rel(),
  229. Outputs: []android.WritablePath{stubSrcPath, versionScriptPath,
  230. symbolListPath},
  231. Input: symbolFilePath,
  232. Implicits: []android.Path{apiLevelsJson},
  233. Args: map[string]string{
  234. "arch": ctx.Arch().ArchType.String(),
  235. "apiLevel": apiLevel.String(),
  236. "apiMap": apiLevelsJson.String(),
  237. "flags": genstubFlags,
  238. },
  239. })
  240. return ndkApiOutputs{
  241. stubSrc: stubSrcPath,
  242. versionScript: versionScriptPath,
  243. symbolList: symbolListPath,
  244. }
  245. }
  246. func compileStubLibrary(ctx ModuleContext, flags Flags, src android.Path) Objects {
  247. // libc/libm stubs libraries end up mismatching with clang's internal definition of these
  248. // functions (which have noreturn attributes and other things). Because we just want to create a
  249. // stub with symbol definitions, and types aren't important in C, ignore the mismatch.
  250. flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, "-fno-builtin")
  251. return compileObjs(ctx, flagsToBuilderFlags(flags), "",
  252. android.Paths{src}, nil, nil, nil, nil)
  253. }
  254. func (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path {
  255. dep := ctx.GetDirectDepWithTag(strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix),
  256. stubImplementation)
  257. if dep == nil {
  258. ctx.ModuleErrorf("Could not find implementation for stub")
  259. return nil
  260. }
  261. impl, ok := dep.(*Module)
  262. if !ok {
  263. ctx.ModuleErrorf("Implementation for stub is not correct module type")
  264. return nil
  265. }
  266. output := impl.UnstrippedOutputFile()
  267. if output == nil {
  268. ctx.ModuleErrorf("implementation module (%s) has no output", impl)
  269. return nil
  270. }
  271. return output
  272. }
  273. func (this *stubDecorator) libraryName(ctx ModuleContext) string {
  274. return strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix)
  275. }
  276. func (this *stubDecorator) findPrebuiltAbiDump(ctx ModuleContext,
  277. apiLevel android.ApiLevel) android.OptionalPath {
  278. subpath := filepath.Join("prebuilts/abi-dumps/ndk", apiLevel.String(),
  279. ctx.Arch().ArchType.String(), this.libraryName(ctx), "abi.xml")
  280. return android.ExistentPathForSource(ctx, subpath)
  281. }
  282. // Feature flag.
  283. func canDumpAbi(config android.Config) bool {
  284. if runtime.GOOS == "darwin" {
  285. return false
  286. }
  287. // abidw doesn't currently handle top-byte-ignore correctly. Disable ABI
  288. // dumping for those configs while we wait for a fix. We'll still have ABI
  289. // checking coverage from non-hwasan builds.
  290. // http://b/190554910
  291. if android.InList("hwaddress", config.SanitizeDevice()) {
  292. return false
  293. }
  294. // http://b/156513478
  295. // http://b/277624006
  296. // This step is expensive. We're not able to do anything with the outputs of
  297. // this step yet (canDiffAbi is flagged off because libabigail isn't able to
  298. // handle all our libraries), disable it. There's no sense in protecting
  299. // against checking in code that breaks abidw since by the time any of this
  300. // can be turned on we'll need to migrate to STG anyway.
  301. return false
  302. }
  303. // Feature flag to disable diffing against prebuilts.
  304. func canDiffAbi() bool {
  305. return false
  306. }
  307. func (this *stubDecorator) dumpAbi(ctx ModuleContext, symbolList android.Path) {
  308. implementationLibrary := this.findImplementationLibrary(ctx)
  309. abiRawPath := getNdkAbiDumpInstallBase(ctx).Join(ctx,
  310. this.apiLevel.String(), ctx.Arch().ArchType.String(),
  311. this.libraryName(ctx), "abi.raw.xml")
  312. ctx.Build(pctx, android.BuildParams{
  313. Rule: abidw,
  314. Description: fmt.Sprintf("abidw %s", implementationLibrary),
  315. Input: implementationLibrary,
  316. Output: abiRawPath,
  317. Implicit: symbolList,
  318. Args: map[string]string{
  319. "symbolList": symbolList.String(),
  320. },
  321. })
  322. this.abiDumpPath = getNdkAbiDumpInstallBase(ctx).Join(ctx,
  323. this.apiLevel.String(), ctx.Arch().ArchType.String(),
  324. this.libraryName(ctx), "abi.xml")
  325. untypedFlag := "--abort-on-untyped-symbols"
  326. if proptools.BoolDefault(this.properties.Allow_untyped_symbols, false) {
  327. untypedFlag = ""
  328. }
  329. ctx.Build(pctx, android.BuildParams{
  330. Rule: abitidy,
  331. Description: fmt.Sprintf("abitidy %s", implementationLibrary),
  332. Input: abiRawPath,
  333. Output: this.abiDumpPath,
  334. Args: map[string]string{
  335. "flags": untypedFlag,
  336. },
  337. })
  338. }
  339. func findNextApiLevel(ctx ModuleContext, apiLevel android.ApiLevel) *android.ApiLevel {
  340. apiLevels := append(ctx.Config().AllSupportedApiLevels(),
  341. android.FutureApiLevel)
  342. for _, api := range apiLevels {
  343. if api.GreaterThan(apiLevel) {
  344. return &api
  345. }
  346. }
  347. return nil
  348. }
  349. func (this *stubDecorator) diffAbi(ctx ModuleContext) {
  350. // Catch any ABI changes compared to the checked-in definition of this API
  351. // level.
  352. abiDiffPath := android.PathForModuleOut(ctx, "abidiff.timestamp")
  353. prebuiltAbiDump := this.findPrebuiltAbiDump(ctx, this.apiLevel)
  354. missingPrebuiltError := fmt.Sprintf(
  355. "Did not find prebuilt ABI dump for %q (%q). Generate with "+
  356. "//development/tools/ndk/update_ndk_abi.sh.", this.libraryName(ctx),
  357. prebuiltAbiDump.InvalidReason())
  358. if !prebuiltAbiDump.Valid() {
  359. ctx.Build(pctx, android.BuildParams{
  360. Rule: android.ErrorRule,
  361. Output: abiDiffPath,
  362. Args: map[string]string{
  363. "error": missingPrebuiltError,
  364. },
  365. })
  366. } else {
  367. ctx.Build(pctx, android.BuildParams{
  368. Rule: abidiff,
  369. Description: fmt.Sprintf("abidiff %s %s", prebuiltAbiDump,
  370. this.abiDumpPath),
  371. Output: abiDiffPath,
  372. Inputs: android.Paths{prebuiltAbiDump.Path(), this.abiDumpPath},
  373. })
  374. }
  375. this.abiDiffPaths = append(this.abiDiffPaths, abiDiffPath)
  376. // Also ensure that the ABI of the next API level (if there is one) matches
  377. // this API level. *New* ABI is allowed, but any changes to APIs that exist
  378. // in this API level are disallowed.
  379. if !this.apiLevel.IsCurrent() {
  380. nextApiLevel := findNextApiLevel(ctx, this.apiLevel)
  381. if nextApiLevel == nil {
  382. panic(fmt.Errorf("could not determine which API level follows "+
  383. "non-current API level %s", this.apiLevel))
  384. }
  385. nextAbiDiffPath := android.PathForModuleOut(ctx,
  386. "abidiff_next.timestamp")
  387. nextAbiDump := this.findPrebuiltAbiDump(ctx, *nextApiLevel)
  388. if !nextAbiDump.Valid() {
  389. ctx.Build(pctx, android.BuildParams{
  390. Rule: android.ErrorRule,
  391. Output: nextAbiDiffPath,
  392. Args: map[string]string{
  393. "error": missingPrebuiltError,
  394. },
  395. })
  396. } else {
  397. ctx.Build(pctx, android.BuildParams{
  398. Rule: abidiff,
  399. Description: fmt.Sprintf("abidiff %s %s", this.abiDumpPath,
  400. nextAbiDump),
  401. Output: nextAbiDiffPath,
  402. Inputs: android.Paths{this.abiDumpPath, nextAbiDump.Path()},
  403. Args: map[string]string{
  404. "args": "--no-added-syms",
  405. },
  406. })
  407. }
  408. this.abiDiffPaths = append(this.abiDiffPaths, nextAbiDiffPath)
  409. }
  410. }
  411. func (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
  412. if !strings.HasSuffix(String(c.properties.Symbol_file), ".map.txt") {
  413. ctx.PropertyErrorf("symbol_file", "must end with .map.txt")
  414. }
  415. if !c.buildStubs() {
  416. // NDK libraries have no implementation variant, nothing to do
  417. return Objects{}
  418. }
  419. if !c.initializeProperties(ctx) {
  420. // Emits its own errors, so we don't need to.
  421. return Objects{}
  422. }
  423. symbolFile := String(c.properties.Symbol_file)
  424. nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "")
  425. objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
  426. c.versionScriptPath = nativeAbiResult.versionScript
  427. if canDumpAbi(ctx.Config()) {
  428. c.dumpAbi(ctx, nativeAbiResult.symbolList)
  429. if canDiffAbi() {
  430. c.diffAbi(ctx)
  431. }
  432. }
  433. if c.apiLevel.IsCurrent() && ctx.PrimaryArch() {
  434. c.parsedCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
  435. }
  436. return objs
  437. }
  438. // Add a dependency on the header modules of this ndk_library
  439. func (linker *stubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
  440. return Deps{
  441. HeaderLibs: linker.properties.Export_header_libs,
  442. }
  443. }
  444. func (linker *stubDecorator) Name(name string) string {
  445. return name + ndkLibrarySuffix
  446. }
  447. func (stub *stubDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
  448. stub.libraryDecorator.libName = ctx.baseModuleName()
  449. return stub.libraryDecorator.linkerFlags(ctx, flags)
  450. }
  451. func (stub *stubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
  452. objs Objects) android.Path {
  453. if !stub.buildStubs() {
  454. // NDK libraries have no implementation variant, nothing to do
  455. return nil
  456. }
  457. if shouldUseVersionScript(ctx, stub) {
  458. linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String()
  459. flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag)
  460. flags.LdFlagsDeps = append(flags.LdFlagsDeps, stub.versionScriptPath)
  461. }
  462. stub.libraryDecorator.skipAPIDefine = true
  463. return stub.libraryDecorator.link(ctx, flags, deps, objs)
  464. }
  465. func (stub *stubDecorator) nativeCoverage() bool {
  466. return false
  467. }
  468. // Returns the install path for unversioned NDK libraries (currently only static
  469. // libraries).
  470. func getUnversionedLibraryInstallPath(ctx ModuleContext) android.InstallPath {
  471. return getNdkSysrootBase(ctx).Join(ctx, "usr/lib", config.NDKTriple(ctx.toolchain()))
  472. }
  473. // Returns the install path for versioned NDK libraries. These are most often
  474. // stubs, but the same paths are used for CRT objects.
  475. func getVersionedLibraryInstallPath(ctx ModuleContext, apiLevel android.ApiLevel) android.InstallPath {
  476. return getUnversionedLibraryInstallPath(ctx).Join(ctx, apiLevel.String())
  477. }
  478. func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) {
  479. installDir := getVersionedLibraryInstallPath(ctx, stub.apiLevel)
  480. stub.installPath = ctx.InstallFile(installDir, path.Base(), path)
  481. }
  482. func newStubLibrary() *Module {
  483. module, library := NewLibrary(android.DeviceSupported)
  484. library.BuildOnlyShared()
  485. module.stl = nil
  486. module.sanitize = nil
  487. library.disableStripping()
  488. stub := &stubDecorator{
  489. libraryDecorator: library,
  490. }
  491. module.compiler = stub
  492. module.linker = stub
  493. module.installer = stub
  494. module.library = stub
  495. module.Properties.AlwaysSdk = true
  496. module.Properties.Sdk_version = StringPtr("current")
  497. module.AddProperties(&stub.properties, &library.MutatedProperties)
  498. return module
  499. }
  500. // ndk_library creates a library that exposes a stub implementation of functions
  501. // and variables for use at build time only.
  502. func NdkLibraryFactory() android.Module {
  503. module := newStubLibrary()
  504. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
  505. android.InitBazelModule(module)
  506. return module
  507. }
  508. type bazelCcApiContributionAttributes struct {
  509. Api bazel.LabelAttribute
  510. Api_surfaces bazel.StringListAttribute
  511. Hdrs bazel.LabelListAttribute
  512. Library_name string
  513. }
  514. // Names of the cc_api_header targets in the bp2build workspace
  515. func apiHeaderLabels(ctx android.TopDownMutatorContext, hdrLibs []string) bazel.LabelList {
  516. addSuffix := func(ctx android.BazelConversionPathContext, module blueprint.Module) string {
  517. label := android.BazelModuleLabel(ctx, module)
  518. return android.ApiContributionTargetName(label)
  519. }
  520. return android.BazelLabelForModuleDepsWithFn(ctx, hdrLibs, addSuffix)
  521. }