library.go 27 KB

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