library.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. // Copyright 2019 The Android Open Source Project
  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 rust
  15. import (
  16. "fmt"
  17. "regexp"
  18. "strings"
  19. "android/soong/android"
  20. "android/soong/cc"
  21. "android/soong/snapshot"
  22. )
  23. var (
  24. RlibStdlibSuffix = ".rlib-std"
  25. )
  26. func init() {
  27. android.RegisterModuleType("rust_library", RustLibraryFactory)
  28. android.RegisterModuleType("rust_library_dylib", RustLibraryDylibFactory)
  29. android.RegisterModuleType("rust_library_rlib", RustLibraryRlibFactory)
  30. android.RegisterModuleType("rust_library_host", RustLibraryHostFactory)
  31. android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory)
  32. android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
  33. android.RegisterModuleType("rust_ffi", RustFFIFactory)
  34. android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
  35. android.RegisterModuleType("rust_ffi_static", RustFFIStaticFactory)
  36. android.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
  37. android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
  38. android.RegisterModuleType("rust_ffi_host_static", RustFFIStaticHostFactory)
  39. }
  40. type VariantLibraryProperties struct {
  41. Enabled *bool `android:"arch_variant"`
  42. Srcs []string `android:"path,arch_variant"`
  43. }
  44. type LibraryCompilerProperties struct {
  45. Rlib VariantLibraryProperties `android:"arch_variant"`
  46. Dylib VariantLibraryProperties `android:"arch_variant"`
  47. Shared VariantLibraryProperties `android:"arch_variant"`
  48. Static VariantLibraryProperties `android:"arch_variant"`
  49. // path to include directories to pass to cc_* modules, only relevant for static/shared variants.
  50. Include_dirs []string `android:"path,arch_variant"`
  51. // Whether this library is part of the Rust toolchain sysroot.
  52. Sysroot *bool
  53. }
  54. type LibraryMutatedProperties struct {
  55. // Build a dylib variant
  56. BuildDylib bool `blueprint:"mutated"`
  57. // Build an rlib variant
  58. BuildRlib bool `blueprint:"mutated"`
  59. // Build a shared library variant
  60. BuildShared bool `blueprint:"mutated"`
  61. // Build a static library variant
  62. BuildStatic bool `blueprint:"mutated"`
  63. // This variant is a dylib
  64. VariantIsDylib bool `blueprint:"mutated"`
  65. // This variant is an rlib
  66. VariantIsRlib bool `blueprint:"mutated"`
  67. // This variant is a shared library
  68. VariantIsShared bool `blueprint:"mutated"`
  69. // This variant is a static library
  70. VariantIsStatic bool `blueprint:"mutated"`
  71. // This variant is a source provider
  72. VariantIsSource bool `blueprint:"mutated"`
  73. // This variant is disabled and should not be compiled
  74. // (used for SourceProvider variants that produce only source)
  75. VariantIsDisabled bool `blueprint:"mutated"`
  76. // Whether this library variant should be link libstd via rlibs
  77. VariantIsStaticStd bool `blueprint:"mutated"`
  78. }
  79. type libraryDecorator struct {
  80. *baseCompiler
  81. *flagExporter
  82. stripper Stripper
  83. Properties LibraryCompilerProperties
  84. MutatedProperties LibraryMutatedProperties
  85. includeDirs android.Paths
  86. sourceProvider SourceProvider
  87. collectedSnapshotHeaders android.Paths
  88. // table-of-contents file for cdylib crates to optimize out relinking when possible
  89. tocFile android.OptionalPath
  90. }
  91. type libraryInterface interface {
  92. rlib() bool
  93. dylib() bool
  94. static() bool
  95. shared() bool
  96. sysroot() bool
  97. source() bool
  98. // Returns true if the build options for the module have selected a particular build type
  99. buildRlib() bool
  100. buildDylib() bool
  101. buildShared() bool
  102. buildStatic() bool
  103. // Sets a particular variant type
  104. setRlib()
  105. setDylib()
  106. setShared()
  107. setStatic()
  108. setSource()
  109. // libstd linkage functions
  110. rlibStd() bool
  111. setRlibStd()
  112. setDylibStd()
  113. // Build a specific library variant
  114. BuildOnlyFFI()
  115. BuildOnlyRust()
  116. BuildOnlyRlib()
  117. BuildOnlyDylib()
  118. BuildOnlyStatic()
  119. BuildOnlyShared()
  120. toc() android.OptionalPath
  121. }
  122. func (library *libraryDecorator) nativeCoverage() bool {
  123. return true
  124. }
  125. func (library *libraryDecorator) toc() android.OptionalPath {
  126. return library.tocFile
  127. }
  128. func (library *libraryDecorator) rlib() bool {
  129. return library.MutatedProperties.VariantIsRlib
  130. }
  131. func (library *libraryDecorator) sysroot() bool {
  132. return Bool(library.Properties.Sysroot)
  133. }
  134. func (library *libraryDecorator) dylib() bool {
  135. return library.MutatedProperties.VariantIsDylib
  136. }
  137. func (library *libraryDecorator) shared() bool {
  138. return library.MutatedProperties.VariantIsShared
  139. }
  140. func (library *libraryDecorator) static() bool {
  141. return library.MutatedProperties.VariantIsStatic
  142. }
  143. func (library *libraryDecorator) source() bool {
  144. return library.MutatedProperties.VariantIsSource
  145. }
  146. func (library *libraryDecorator) buildRlib() bool {
  147. return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
  148. }
  149. func (library *libraryDecorator) buildDylib() bool {
  150. return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true)
  151. }
  152. func (library *libraryDecorator) buildShared() bool {
  153. return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true)
  154. }
  155. func (library *libraryDecorator) buildStatic() bool {
  156. return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true)
  157. }
  158. func (library *libraryDecorator) setRlib() {
  159. library.MutatedProperties.VariantIsRlib = true
  160. library.MutatedProperties.VariantIsDylib = false
  161. library.MutatedProperties.VariantIsStatic = false
  162. library.MutatedProperties.VariantIsShared = false
  163. }
  164. func (library *libraryDecorator) setDylib() {
  165. library.MutatedProperties.VariantIsRlib = false
  166. library.MutatedProperties.VariantIsDylib = true
  167. library.MutatedProperties.VariantIsStatic = false
  168. library.MutatedProperties.VariantIsShared = false
  169. }
  170. func (library *libraryDecorator) rlibStd() bool {
  171. return library.MutatedProperties.VariantIsStaticStd
  172. }
  173. func (library *libraryDecorator) setRlibStd() {
  174. library.MutatedProperties.VariantIsStaticStd = true
  175. }
  176. func (library *libraryDecorator) setDylibStd() {
  177. library.MutatedProperties.VariantIsStaticStd = false
  178. }
  179. func (library *libraryDecorator) setShared() {
  180. library.MutatedProperties.VariantIsStatic = false
  181. library.MutatedProperties.VariantIsShared = true
  182. library.MutatedProperties.VariantIsRlib = false
  183. library.MutatedProperties.VariantIsDylib = false
  184. }
  185. func (library *libraryDecorator) setStatic() {
  186. library.MutatedProperties.VariantIsStatic = true
  187. library.MutatedProperties.VariantIsShared = false
  188. library.MutatedProperties.VariantIsRlib = false
  189. library.MutatedProperties.VariantIsDylib = false
  190. }
  191. func (library *libraryDecorator) setSource() {
  192. library.MutatedProperties.VariantIsSource = true
  193. }
  194. func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
  195. if ctx.Module().(*Module).InVendor() {
  196. // Vendor modules should statically link libstd.
  197. return rlibAutoDep
  198. } else if library.preferRlib() {
  199. return rlibAutoDep
  200. } else if library.rlib() || library.static() {
  201. return rlibAutoDep
  202. } else if library.dylib() || library.shared() {
  203. return dylibAutoDep
  204. } else {
  205. panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName()))
  206. }
  207. }
  208. func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
  209. if ctx.RustModule().InVendor() {
  210. // Vendor modules should statically link libstd.
  211. return RlibLinkage
  212. } else if library.static() || library.MutatedProperties.VariantIsStaticStd {
  213. return RlibLinkage
  214. } else if library.baseCompiler.preferRlib() {
  215. return RlibLinkage
  216. }
  217. return DefaultLinkage
  218. }
  219. var _ compiler = (*libraryDecorator)(nil)
  220. var _ libraryInterface = (*libraryDecorator)(nil)
  221. var _ exportedFlagsProducer = (*libraryDecorator)(nil)
  222. // rust_library produces all Rust variants (rust_library_dylib and
  223. // rust_library_rlib).
  224. func RustLibraryFactory() android.Module {
  225. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  226. library.BuildOnlyRust()
  227. return module.Init()
  228. }
  229. // rust_ffi produces all FFI variants (rust_ffi_shared and
  230. // rust_ffi_static).
  231. func RustFFIFactory() android.Module {
  232. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  233. library.BuildOnlyFFI()
  234. return module.Init()
  235. }
  236. // rust_library_dylib produces a Rust dylib (Rust crate type "dylib").
  237. func RustLibraryDylibFactory() android.Module {
  238. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  239. library.BuildOnlyDylib()
  240. return module.Init()
  241. }
  242. // rust_library_rlib produces an rlib (Rust crate type "rlib").
  243. func RustLibraryRlibFactory() android.Module {
  244. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  245. library.BuildOnlyRlib()
  246. return module.Init()
  247. }
  248. // rust_ffi_shared produces a shared library (Rust crate type
  249. // "cdylib").
  250. func RustFFISharedFactory() android.Module {
  251. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  252. library.BuildOnlyShared()
  253. return module.Init()
  254. }
  255. // rust_ffi_static produces a static library (Rust crate type
  256. // "staticlib").
  257. func RustFFIStaticFactory() android.Module {
  258. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  259. library.BuildOnlyStatic()
  260. return module.Init()
  261. }
  262. // rust_library_host produces all Rust variants for the host
  263. // (rust_library_dylib_host and rust_library_rlib_host).
  264. func RustLibraryHostFactory() android.Module {
  265. module, library := NewRustLibrary(android.HostSupported)
  266. library.BuildOnlyRust()
  267. return module.Init()
  268. }
  269. // rust_ffi_host produces all FFI variants for the host
  270. // (rust_ffi_static_host and rust_ffi_shared_host).
  271. func RustFFIHostFactory() android.Module {
  272. module, library := NewRustLibrary(android.HostSupported)
  273. library.BuildOnlyFFI()
  274. return module.Init()
  275. }
  276. // rust_library_dylib_host produces a dylib for the host (Rust crate
  277. // type "dylib").
  278. func RustLibraryDylibHostFactory() android.Module {
  279. module, library := NewRustLibrary(android.HostSupported)
  280. library.BuildOnlyDylib()
  281. return module.Init()
  282. }
  283. // rust_library_rlib_host produces an rlib for the host (Rust crate
  284. // type "rlib").
  285. func RustLibraryRlibHostFactory() android.Module {
  286. module, library := NewRustLibrary(android.HostSupported)
  287. library.BuildOnlyRlib()
  288. return module.Init()
  289. }
  290. // rust_ffi_static_host produces a static library for the host (Rust
  291. // crate type "staticlib").
  292. func RustFFIStaticHostFactory() android.Module {
  293. module, library := NewRustLibrary(android.HostSupported)
  294. library.BuildOnlyStatic()
  295. return module.Init()
  296. }
  297. // rust_ffi_shared_host produces an shared library for the host (Rust
  298. // crate type "cdylib").
  299. func RustFFISharedHostFactory() android.Module {
  300. module, library := NewRustLibrary(android.HostSupported)
  301. library.BuildOnlyShared()
  302. return module.Init()
  303. }
  304. func (library *libraryDecorator) BuildOnlyFFI() {
  305. library.MutatedProperties.BuildDylib = false
  306. library.MutatedProperties.BuildRlib = false
  307. library.MutatedProperties.BuildShared = true
  308. library.MutatedProperties.BuildStatic = true
  309. }
  310. func (library *libraryDecorator) BuildOnlyRust() {
  311. library.MutatedProperties.BuildDylib = true
  312. library.MutatedProperties.BuildRlib = true
  313. library.MutatedProperties.BuildShared = false
  314. library.MutatedProperties.BuildStatic = false
  315. }
  316. func (library *libraryDecorator) BuildOnlyDylib() {
  317. library.MutatedProperties.BuildDylib = true
  318. library.MutatedProperties.BuildRlib = false
  319. library.MutatedProperties.BuildShared = false
  320. library.MutatedProperties.BuildStatic = false
  321. }
  322. func (library *libraryDecorator) BuildOnlyRlib() {
  323. library.MutatedProperties.BuildDylib = false
  324. library.MutatedProperties.BuildRlib = true
  325. library.MutatedProperties.BuildShared = false
  326. library.MutatedProperties.BuildStatic = false
  327. }
  328. func (library *libraryDecorator) BuildOnlyStatic() {
  329. library.MutatedProperties.BuildRlib = false
  330. library.MutatedProperties.BuildDylib = false
  331. library.MutatedProperties.BuildShared = false
  332. library.MutatedProperties.BuildStatic = true
  333. }
  334. func (library *libraryDecorator) BuildOnlyShared() {
  335. library.MutatedProperties.BuildRlib = false
  336. library.MutatedProperties.BuildDylib = false
  337. library.MutatedProperties.BuildStatic = false
  338. library.MutatedProperties.BuildShared = true
  339. }
  340. func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
  341. module := newModule(hod, android.MultilibBoth)
  342. library := &libraryDecorator{
  343. MutatedProperties: LibraryMutatedProperties{
  344. BuildDylib: false,
  345. BuildRlib: false,
  346. BuildShared: false,
  347. BuildStatic: false,
  348. },
  349. baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
  350. flagExporter: NewFlagExporter(),
  351. }
  352. module.compiler = library
  353. return module, library
  354. }
  355. func (library *libraryDecorator) compilerProps() []interface{} {
  356. return append(library.baseCompiler.compilerProps(),
  357. &library.Properties,
  358. &library.MutatedProperties,
  359. &library.stripper.StripProperties)
  360. }
  361. func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
  362. deps = library.baseCompiler.compilerDeps(ctx, deps)
  363. if library.dylib() || library.shared() {
  364. if ctx.toolchain().Bionic() {
  365. deps = bionicDeps(ctx, deps, false)
  366. deps.CrtBegin = []string{"crtbegin_so"}
  367. deps.CrtEnd = []string{"crtend_so"}
  368. } else if ctx.Os() == android.LinuxMusl {
  369. deps = muslDeps(ctx, deps, false)
  370. deps.CrtBegin = []string{"libc_musl_crtbegin_so"}
  371. deps.CrtEnd = []string{"libc_musl_crtend_so"}
  372. }
  373. }
  374. return deps
  375. }
  376. func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
  377. return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
  378. }
  379. func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags {
  380. flags = library.baseCompiler.cfgFlags(ctx, flags)
  381. if library.dylib() {
  382. // We need to add a dependency on std in order to link crates as dylibs.
  383. // The hack to add this dependency is guarded by the following cfg so
  384. // that we don't force a dependency when it isn't needed.
  385. library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib")
  386. }
  387. flags.RustFlags = append(flags.RustFlags, library.baseCompiler.cfgsToFlags()...)
  388. flags.RustdocFlags = append(flags.RustdocFlags, library.baseCompiler.cfgsToFlags()...)
  389. return flags
  390. }
  391. func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
  392. flags = library.baseCompiler.compilerFlags(ctx, flags)
  393. flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
  394. if library.shared() || library.static() {
  395. library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
  396. }
  397. if library.shared() {
  398. flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx))
  399. }
  400. return flags
  401. }
  402. func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
  403. var outputFile android.ModuleOutPath
  404. var ret buildOutput
  405. var fileName string
  406. srcPath := library.srcPath(ctx, deps)
  407. if library.sourceProvider != nil {
  408. deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
  409. }
  410. // Calculate output filename
  411. if library.rlib() {
  412. fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
  413. outputFile = android.PathForModuleOut(ctx, fileName)
  414. ret.outputFile = outputFile
  415. } else if library.dylib() {
  416. fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
  417. outputFile = android.PathForModuleOut(ctx, fileName)
  418. ret.outputFile = outputFile
  419. } else if library.static() {
  420. fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
  421. outputFile = android.PathForModuleOut(ctx, fileName)
  422. ret.outputFile = outputFile
  423. } else if library.shared() {
  424. fileName = library.sharedLibFilename(ctx)
  425. outputFile = android.PathForModuleOut(ctx, fileName)
  426. ret.outputFile = outputFile
  427. }
  428. if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) {
  429. strippedOutputFile := outputFile
  430. outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
  431. library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
  432. library.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
  433. }
  434. library.baseCompiler.unstrippedOutputFile = outputFile
  435. flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
  436. flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
  437. flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
  438. if library.dylib() {
  439. // We need prefer-dynamic for now to avoid linking in the static stdlib. See:
  440. // https://github.com/rust-lang/rust/issues/19680
  441. // https://github.com/rust-lang/rust/issues/34909
  442. flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
  443. }
  444. // Call the appropriate builder for this library type
  445. if library.rlib() {
  446. ret.kytheFile = TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile).kytheFile
  447. } else if library.dylib() {
  448. ret.kytheFile = TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile).kytheFile
  449. } else if library.static() {
  450. ret.kytheFile = TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile).kytheFile
  451. } else if library.shared() {
  452. ret.kytheFile = TransformSrctoShared(ctx, srcPath, deps, flags, outputFile).kytheFile
  453. }
  454. if library.rlib() || library.dylib() {
  455. library.flagExporter.exportLinkDirs(deps.linkDirs...)
  456. library.flagExporter.exportLinkObjects(deps.linkObjects...)
  457. library.flagExporter.exportLibDeps(deps.LibDeps...)
  458. }
  459. if library.static() || library.shared() {
  460. ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
  461. IncludeDirs: library.includeDirs,
  462. })
  463. }
  464. if library.shared() {
  465. // Optimize out relinking against shared libraries whose interface hasn't changed by
  466. // depending on a table of contents file instead of the library itself.
  467. tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
  468. library.tocFile = android.OptionalPathForPath(tocFile)
  469. cc.TransformSharedObjectToToc(ctx, outputFile, tocFile)
  470. ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
  471. TableOfContents: android.OptionalPathForPath(tocFile),
  472. SharedLibrary: outputFile,
  473. Target: ctx.Target(),
  474. })
  475. }
  476. if library.static() {
  477. depSet := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(outputFile).Build()
  478. ctx.SetProvider(cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{
  479. StaticLibrary: outputFile,
  480. TransitiveStaticLibrariesForOrdering: depSet,
  481. })
  482. }
  483. library.flagExporter.setProvider(ctx)
  484. return ret
  485. }
  486. func (library *libraryDecorator) srcPath(ctx ModuleContext, _ PathDeps) android.Path {
  487. if library.sourceProvider != nil {
  488. // Assume the first source from the source provider is the library entry point.
  489. return library.sourceProvider.Srcs()[0]
  490. } else {
  491. path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
  492. return path
  493. }
  494. }
  495. func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
  496. deps PathDeps) android.OptionalPath {
  497. // rustdoc has builtin support for documenting config specific information
  498. // regardless of the actual config it was given
  499. // (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information),
  500. // so we generate the rustdoc for only the primary module so that we have a
  501. // single set of docs to refer to.
  502. if ctx.Module() != ctx.PrimaryModule() {
  503. return android.OptionalPath{}
  504. }
  505. return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps),
  506. deps, flags))
  507. }
  508. func (library *libraryDecorator) getStem(ctx ModuleContext) string {
  509. stem := library.baseCompiler.getStemWithoutSuffix(ctx)
  510. validateLibraryStem(ctx, stem, library.crateName())
  511. return stem + String(library.baseCompiler.Properties.Suffix)
  512. }
  513. func (library *libraryDecorator) install(ctx ModuleContext) {
  514. // Only shared and dylib variants make sense to install.
  515. if library.shared() || library.dylib() {
  516. library.baseCompiler.install(ctx)
  517. }
  518. }
  519. func (library *libraryDecorator) Disabled() bool {
  520. return library.MutatedProperties.VariantIsDisabled
  521. }
  522. func (library *libraryDecorator) SetDisabled() {
  523. library.MutatedProperties.VariantIsDisabled = true
  524. }
  525. var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+")
  526. func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) {
  527. if crate_name == "" {
  528. ctx.PropertyErrorf("crate_name", "crate_name must be defined.")
  529. }
  530. // crate_names are used for the library output file, and rustc expects these
  531. // to be alphanumeric with underscores allowed.
  532. if validCrateName.MatchString(crate_name) {
  533. ctx.PropertyErrorf("crate_name",
  534. "library crate_names must be alphanumeric with underscores allowed")
  535. }
  536. // Libraries are expected to begin with "lib" followed by the crate_name
  537. if !strings.HasPrefix(filename, "lib"+crate_name) {
  538. ctx.ModuleErrorf("Invalid name or stem property; library filenames must start with lib<crate_name>")
  539. }
  540. }
  541. // LibraryMutator mutates the libraries into variants according to the
  542. // build{Rlib,Dylib} attributes.
  543. func LibraryMutator(mctx android.BottomUpMutatorContext) {
  544. // Only mutate on Rust libraries.
  545. m, ok := mctx.Module().(*Module)
  546. if !ok || m.compiler == nil {
  547. return
  548. }
  549. library, ok := m.compiler.(libraryInterface)
  550. if !ok {
  551. return
  552. }
  553. var variants []string
  554. // The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
  555. // depend on this variant. It must be the first variant to be declared.
  556. sourceVariant := false
  557. if m.sourceProvider != nil {
  558. variants = append(variants, "source")
  559. sourceVariant = true
  560. }
  561. if library.buildRlib() {
  562. variants = append(variants, rlibVariation)
  563. }
  564. if library.buildDylib() {
  565. variants = append(variants, dylibVariation)
  566. }
  567. if len(variants) == 0 {
  568. return
  569. }
  570. modules := mctx.CreateLocalVariations(variants...)
  571. // The order of the variations (modules) matches the variant names provided. Iterate
  572. // through the new variation modules and set their mutated properties.
  573. for i, v := range modules {
  574. switch variants[i] {
  575. case rlibVariation:
  576. v.(*Module).compiler.(libraryInterface).setRlib()
  577. case dylibVariation:
  578. v.(*Module).compiler.(libraryInterface).setDylib()
  579. if v.(*Module).ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
  580. // TODO(b/165791368)
  581. // Disable dylib Vendor Ramdisk variations until we support these.
  582. v.(*Module).Disable()
  583. }
  584. variation := v.(*Module).ModuleBase.ImageVariation().Variation
  585. if strings.HasPrefix(variation, cc.VendorVariationPrefix) {
  586. // TODO(b/204303985)
  587. // Disable vendor dylibs until they are supported
  588. v.(*Module).Disable()
  589. }
  590. if strings.HasPrefix(variation, cc.VendorVariationPrefix) &&
  591. m.HasVendorVariant() &&
  592. !snapshot.IsVendorProprietaryModule(mctx) &&
  593. strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() {
  594. // cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are
  595. // produced for Dylibs; however, dylibs should not be enabled for boardVndkVersion for
  596. // non-vendor proprietary modules.
  597. v.(*Module).Disable()
  598. }
  599. case "source":
  600. v.(*Module).compiler.(libraryInterface).setSource()
  601. // The source variant does not produce any library.
  602. // Disable the compilation steps.
  603. v.(*Module).compiler.SetDisabled()
  604. }
  605. }
  606. // If a source variant is created, add an inter-variant dependency
  607. // between the other variants and the source variant.
  608. if sourceVariant {
  609. sv := modules[0]
  610. for _, v := range modules[1:] {
  611. if !v.Enabled() {
  612. continue
  613. }
  614. mctx.AddInterVariantDependency(sourceDepTag, v, sv)
  615. }
  616. // Alias the source variation so it can be named directly in "srcs" properties.
  617. mctx.AliasVariation("source")
  618. }
  619. }
  620. func LibstdMutator(mctx android.BottomUpMutatorContext) {
  621. if m, ok := mctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
  622. switch library := m.compiler.(type) {
  623. case libraryInterface:
  624. // Only create a variant if a library is actually being built.
  625. if library.rlib() && !library.sysroot() {
  626. variants := []string{"rlib-std", "dylib-std"}
  627. modules := mctx.CreateLocalVariations(variants...)
  628. rlib := modules[0].(*Module)
  629. dylib := modules[1].(*Module)
  630. rlib.compiler.(libraryInterface).setRlibStd()
  631. dylib.compiler.(libraryInterface).setDylibStd()
  632. if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation ||
  633. strings.HasPrefix(dylib.ModuleBase.ImageVariation().Variation, cc.VendorVariationPrefix) {
  634. // TODO(b/165791368)
  635. // Disable rlibs that link against dylib-std on vendor and vendor ramdisk variations until those dylib
  636. // variants are properly supported.
  637. dylib.Disable()
  638. }
  639. rlib.Properties.RustSubName += RlibStdlibSuffix
  640. }
  641. }
  642. }
  643. }
  644. func (l *libraryDecorator) snapshotHeaders() android.Paths {
  645. if l.collectedSnapshotHeaders == nil {
  646. panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
  647. }
  648. return l.collectedSnapshotHeaders
  649. }
  650. // collectHeadersForSnapshot collects all exported headers from library.
  651. // It globs header files in the source tree for exported include directories,
  652. // and tracks generated header files separately.
  653. //
  654. // This is to be called from GenerateAndroidBuildActions, and then collected
  655. // header files can be retrieved by snapshotHeaders().
  656. func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) {
  657. ret := android.Paths{}
  658. // Glob together the headers from the modules include_dirs property
  659. for _, path := range android.CopyOfPaths(l.includeDirs) {
  660. dir := path.String()
  661. globDir := dir + "/**/*"
  662. glob, err := ctx.GlobWithDeps(globDir, nil)
  663. if err != nil {
  664. ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
  665. return
  666. }
  667. for _, header := range glob {
  668. // Filter out only the files with extensions that are headers.
  669. found := false
  670. for _, ext := range cc.HeaderExts {
  671. if strings.HasSuffix(header, ext) {
  672. found = true
  673. break
  674. }
  675. }
  676. if !found {
  677. continue
  678. }
  679. ret = append(ret, android.PathForSource(ctx, header))
  680. }
  681. }
  682. // Glob together the headers from C dependencies as well, starting with non-generated headers.
  683. ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...)
  684. // Collect generated headers from C dependencies.
  685. ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...)
  686. // TODO(185577950): If support for generated headers is added, they need to be collected here as well.
  687. l.collectedSnapshotHeaders = ret
  688. }