library.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  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 if ctx.BazelConversionMode() {
  206. // In Bazel conversion mode, we are currently ignoring the deptag, so we just need to supply a
  207. // compatible tag in order to add the dependency.
  208. return rlibAutoDep
  209. } else {
  210. panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName()))
  211. }
  212. }
  213. func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
  214. if ctx.RustModule().InVendor() {
  215. // Vendor modules should statically link libstd.
  216. return RlibLinkage
  217. } else if library.static() || library.MutatedProperties.VariantIsStaticStd {
  218. return RlibLinkage
  219. } else if library.baseCompiler.preferRlib() {
  220. return RlibLinkage
  221. }
  222. return DefaultLinkage
  223. }
  224. var _ compiler = (*libraryDecorator)(nil)
  225. var _ libraryInterface = (*libraryDecorator)(nil)
  226. var _ exportedFlagsProducer = (*libraryDecorator)(nil)
  227. // rust_library produces all rust variants.
  228. func RustLibraryFactory() android.Module {
  229. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  230. library.BuildOnlyRust()
  231. return module.Init()
  232. }
  233. // rust_ffi produces all ffi variants.
  234. func RustFFIFactory() android.Module {
  235. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  236. library.BuildOnlyFFI()
  237. return module.Init()
  238. }
  239. // rust_library_dylib produces a dylib.
  240. func RustLibraryDylibFactory() android.Module {
  241. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  242. library.BuildOnlyDylib()
  243. return module.Init()
  244. }
  245. // rust_library_rlib produces an rlib.
  246. func RustLibraryRlibFactory() android.Module {
  247. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  248. library.BuildOnlyRlib()
  249. return module.Init()
  250. }
  251. // rust_ffi_shared produces a shared library.
  252. func RustFFISharedFactory() android.Module {
  253. module, library := NewRustLibrary(android.HostAndDeviceSupported)
  254. library.BuildOnlyShared()
  255. return module.Init()
  256. }
  257. // rust_ffi_static produces a static library.
  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.
  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.
  270. func RustFFIHostFactory() android.Module {
  271. module, library := NewRustLibrary(android.HostSupported)
  272. library.BuildOnlyFFI()
  273. return module.Init()
  274. }
  275. // rust_library_dylib_host produces a dylib.
  276. func RustLibraryDylibHostFactory() android.Module {
  277. module, library := NewRustLibrary(android.HostSupported)
  278. library.BuildOnlyDylib()
  279. return module.Init()
  280. }
  281. // rust_library_rlib_host produces an rlib.
  282. func RustLibraryRlibHostFactory() android.Module {
  283. module, library := NewRustLibrary(android.HostSupported)
  284. library.BuildOnlyRlib()
  285. return module.Init()
  286. }
  287. // rust_ffi_static_host produces a static library.
  288. func RustFFIStaticHostFactory() android.Module {
  289. module, library := NewRustLibrary(android.HostSupported)
  290. library.BuildOnlyStatic()
  291. return module.Init()
  292. }
  293. // rust_ffi_shared_host produces an shared library.
  294. func RustFFISharedHostFactory() android.Module {
  295. module, library := NewRustLibrary(android.HostSupported)
  296. library.BuildOnlyShared()
  297. return module.Init()
  298. }
  299. func (library *libraryDecorator) BuildOnlyFFI() {
  300. library.MutatedProperties.BuildDylib = false
  301. library.MutatedProperties.BuildRlib = false
  302. library.MutatedProperties.BuildShared = true
  303. library.MutatedProperties.BuildStatic = true
  304. }
  305. func (library *libraryDecorator) BuildOnlyRust() {
  306. library.MutatedProperties.BuildDylib = true
  307. library.MutatedProperties.BuildRlib = true
  308. library.MutatedProperties.BuildShared = false
  309. library.MutatedProperties.BuildStatic = false
  310. }
  311. func (library *libraryDecorator) BuildOnlyDylib() {
  312. library.MutatedProperties.BuildDylib = true
  313. library.MutatedProperties.BuildRlib = false
  314. library.MutatedProperties.BuildShared = false
  315. library.MutatedProperties.BuildStatic = false
  316. }
  317. func (library *libraryDecorator) BuildOnlyRlib() {
  318. library.MutatedProperties.BuildDylib = false
  319. library.MutatedProperties.BuildRlib = true
  320. library.MutatedProperties.BuildShared = false
  321. library.MutatedProperties.BuildStatic = false
  322. }
  323. func (library *libraryDecorator) BuildOnlyStatic() {
  324. library.MutatedProperties.BuildRlib = false
  325. library.MutatedProperties.BuildDylib = false
  326. library.MutatedProperties.BuildShared = false
  327. library.MutatedProperties.BuildStatic = true
  328. }
  329. func (library *libraryDecorator) BuildOnlyShared() {
  330. library.MutatedProperties.BuildRlib = false
  331. library.MutatedProperties.BuildDylib = false
  332. library.MutatedProperties.BuildStatic = false
  333. library.MutatedProperties.BuildShared = true
  334. }
  335. func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
  336. module := newModule(hod, android.MultilibBoth)
  337. library := &libraryDecorator{
  338. MutatedProperties: LibraryMutatedProperties{
  339. BuildDylib: false,
  340. BuildRlib: false,
  341. BuildShared: false,
  342. BuildStatic: false,
  343. },
  344. baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
  345. flagExporter: NewFlagExporter(),
  346. }
  347. module.compiler = library
  348. return module, library
  349. }
  350. func (library *libraryDecorator) compilerProps() []interface{} {
  351. return append(library.baseCompiler.compilerProps(),
  352. &library.Properties,
  353. &library.MutatedProperties,
  354. &library.stripper.StripProperties)
  355. }
  356. func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
  357. deps = library.baseCompiler.compilerDeps(ctx, deps)
  358. if library.dylib() || library.shared() {
  359. if ctx.toolchain().Bionic() {
  360. deps = bionicDeps(ctx, deps, false)
  361. deps.CrtBegin = []string{"crtbegin_so"}
  362. deps.CrtEnd = []string{"crtend_so"}
  363. } else if ctx.Os() == android.LinuxMusl {
  364. deps = muslDeps(ctx, deps, false)
  365. deps.CrtBegin = []string{"libc_musl_crtbegin_so"}
  366. deps.CrtEnd = []string{"libc_musl_crtend_so"}
  367. }
  368. }
  369. return deps
  370. }
  371. func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
  372. return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
  373. }
  374. func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags {
  375. flags = library.baseCompiler.cfgFlags(ctx, flags)
  376. if library.dylib() {
  377. // We need to add a dependency on std in order to link crates as dylibs.
  378. // The hack to add this dependency is guarded by the following cfg so
  379. // that we don't force a dependency when it isn't needed.
  380. library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib")
  381. }
  382. flags.RustFlags = append(flags.RustFlags, library.baseCompiler.cfgsToFlags()...)
  383. flags.RustdocFlags = append(flags.RustdocFlags, library.baseCompiler.cfgsToFlags()...)
  384. return flags
  385. }
  386. func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
  387. flags = library.baseCompiler.compilerFlags(ctx, flags)
  388. flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
  389. if library.shared() || library.static() {
  390. library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
  391. }
  392. if library.shared() {
  393. flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx))
  394. }
  395. return flags
  396. }
  397. func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
  398. var outputFile android.ModuleOutPath
  399. var ret buildOutput
  400. var fileName string
  401. srcPath := library.srcPath(ctx, deps)
  402. if library.sourceProvider != nil {
  403. deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
  404. }
  405. // Calculate output filename
  406. if library.rlib() {
  407. fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
  408. outputFile = android.PathForModuleOut(ctx, fileName)
  409. ret.outputFile = outputFile
  410. } else if library.dylib() {
  411. fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
  412. outputFile = android.PathForModuleOut(ctx, fileName)
  413. ret.outputFile = outputFile
  414. } else if library.static() {
  415. fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
  416. outputFile = android.PathForModuleOut(ctx, fileName)
  417. ret.outputFile = outputFile
  418. } else if library.shared() {
  419. fileName = library.sharedLibFilename(ctx)
  420. outputFile = android.PathForModuleOut(ctx, fileName)
  421. ret.outputFile = outputFile
  422. }
  423. if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) {
  424. strippedOutputFile := outputFile
  425. outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
  426. library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
  427. library.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
  428. }
  429. library.baseCompiler.unstrippedOutputFile = outputFile
  430. flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
  431. flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
  432. flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
  433. if library.dylib() {
  434. // We need prefer-dynamic for now to avoid linking in the static stdlib. See:
  435. // https://github.com/rust-lang/rust/issues/19680
  436. // https://github.com/rust-lang/rust/issues/34909
  437. flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
  438. }
  439. // Call the appropriate builder for this library type
  440. if library.rlib() {
  441. ret.kytheFile = TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile).kytheFile
  442. } else if library.dylib() {
  443. ret.kytheFile = TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile).kytheFile
  444. } else if library.static() {
  445. ret.kytheFile = TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile).kytheFile
  446. } else if library.shared() {
  447. ret.kytheFile = TransformSrctoShared(ctx, srcPath, deps, flags, outputFile).kytheFile
  448. }
  449. if library.rlib() || library.dylib() {
  450. library.flagExporter.exportLinkDirs(deps.linkDirs...)
  451. library.flagExporter.exportLinkObjects(deps.linkObjects...)
  452. }
  453. if library.static() || library.shared() {
  454. ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
  455. IncludeDirs: library.includeDirs,
  456. })
  457. }
  458. if library.shared() {
  459. // Optimize out relinking against shared libraries whose interface hasn't changed by
  460. // depending on a table of contents file instead of the library itself.
  461. tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
  462. library.tocFile = android.OptionalPathForPath(tocFile)
  463. cc.TransformSharedObjectToToc(ctx, outputFile, tocFile)
  464. ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
  465. TableOfContents: android.OptionalPathForPath(tocFile),
  466. SharedLibrary: outputFile,
  467. Target: ctx.Target(),
  468. })
  469. }
  470. if library.static() {
  471. depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(outputFile).Build()
  472. ctx.SetProvider(cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{
  473. StaticLibrary: outputFile,
  474. TransitiveStaticLibrariesForOrdering: depSet,
  475. })
  476. }
  477. library.flagExporter.setProvider(ctx)
  478. return ret
  479. }
  480. func (library *libraryDecorator) srcPath(ctx ModuleContext, _ PathDeps) android.Path {
  481. if library.sourceProvider != nil {
  482. // Assume the first source from the source provider is the library entry point.
  483. return library.sourceProvider.Srcs()[0]
  484. } else {
  485. path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
  486. return path
  487. }
  488. }
  489. func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
  490. deps PathDeps) android.OptionalPath {
  491. // rustdoc has builtin support for documenting config specific information
  492. // regardless of the actual config it was given
  493. // (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information),
  494. // so we generate the rustdoc for only the primary module so that we have a
  495. // single set of docs to refer to.
  496. if ctx.Module() != ctx.PrimaryModule() {
  497. return android.OptionalPath{}
  498. }
  499. return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps),
  500. deps, flags))
  501. }
  502. func (library *libraryDecorator) getStem(ctx ModuleContext) string {
  503. stem := library.baseCompiler.getStemWithoutSuffix(ctx)
  504. validateLibraryStem(ctx, stem, library.crateName())
  505. return stem + String(library.baseCompiler.Properties.Suffix)
  506. }
  507. func (library *libraryDecorator) install(ctx ModuleContext) {
  508. // Only shared and dylib variants make sense to install.
  509. if library.shared() || library.dylib() {
  510. library.baseCompiler.install(ctx)
  511. }
  512. }
  513. func (library *libraryDecorator) Disabled() bool {
  514. return library.MutatedProperties.VariantIsDisabled
  515. }
  516. func (library *libraryDecorator) SetDisabled() {
  517. library.MutatedProperties.VariantIsDisabled = true
  518. }
  519. var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+")
  520. func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) {
  521. if crate_name == "" {
  522. ctx.PropertyErrorf("crate_name", "crate_name must be defined.")
  523. }
  524. // crate_names are used for the library output file, and rustc expects these
  525. // to be alphanumeric with underscores allowed.
  526. if validCrateName.MatchString(crate_name) {
  527. ctx.PropertyErrorf("crate_name",
  528. "library crate_names must be alphanumeric with underscores allowed")
  529. }
  530. // Libraries are expected to begin with "lib" followed by the crate_name
  531. if !strings.HasPrefix(filename, "lib"+crate_name) {
  532. ctx.ModuleErrorf("Invalid name or stem property; library filenames must start with lib<crate_name>")
  533. }
  534. }
  535. // LibraryMutator mutates the libraries into variants according to the
  536. // build{Rlib,Dylib} attributes.
  537. func LibraryMutator(mctx android.BottomUpMutatorContext) {
  538. // Only mutate on Rust libraries.
  539. m, ok := mctx.Module().(*Module)
  540. if !ok || m.compiler == nil {
  541. return
  542. }
  543. library, ok := m.compiler.(libraryInterface)
  544. if !ok {
  545. return
  546. }
  547. var variants []string
  548. // The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
  549. // depend on this variant. It must be the first variant to be declared.
  550. sourceVariant := false
  551. if m.sourceProvider != nil {
  552. variants = append(variants, "source")
  553. sourceVariant = true
  554. }
  555. if library.buildRlib() {
  556. variants = append(variants, rlibVariation)
  557. }
  558. if library.buildDylib() {
  559. variants = append(variants, dylibVariation)
  560. }
  561. if len(variants) == 0 {
  562. return
  563. }
  564. modules := mctx.CreateLocalVariations(variants...)
  565. // The order of the variations (modules) matches the variant names provided. Iterate
  566. // through the new variation modules and set their mutated properties.
  567. for i, v := range modules {
  568. switch variants[i] {
  569. case rlibVariation:
  570. v.(*Module).compiler.(libraryInterface).setRlib()
  571. case dylibVariation:
  572. v.(*Module).compiler.(libraryInterface).setDylib()
  573. if v.(*Module).ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
  574. // TODO(b/165791368)
  575. // Disable dylib Vendor Ramdisk variations until we support these.
  576. v.(*Module).Disable()
  577. }
  578. variation := v.(*Module).ModuleBase.ImageVariation().Variation
  579. if strings.HasPrefix(variation, cc.VendorVariationPrefix) {
  580. // TODO(b/204303985)
  581. // Disable vendor dylibs until they are supported
  582. v.(*Module).Disable()
  583. }
  584. if strings.HasPrefix(variation, cc.VendorVariationPrefix) &&
  585. m.HasVendorVariant() &&
  586. !snapshot.IsVendorProprietaryModule(mctx) &&
  587. strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() {
  588. // cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are
  589. // produced for Dylibs; however, dylibs should not be enabled for boardVndkVersion for
  590. // non-vendor proprietary modules.
  591. v.(*Module).Disable()
  592. }
  593. case "source":
  594. v.(*Module).compiler.(libraryInterface).setSource()
  595. // The source variant does not produce any library.
  596. // Disable the compilation steps.
  597. v.(*Module).compiler.SetDisabled()
  598. }
  599. }
  600. // If a source variant is created, add an inter-variant dependency
  601. // between the other variants and the source variant.
  602. if sourceVariant {
  603. sv := modules[0]
  604. for _, v := range modules[1:] {
  605. if !v.Enabled() {
  606. continue
  607. }
  608. mctx.AddInterVariantDependency(sourceDepTag, v, sv)
  609. }
  610. // Alias the source variation so it can be named directly in "srcs" properties.
  611. mctx.AliasVariation("source")
  612. }
  613. }
  614. func LibstdMutator(mctx android.BottomUpMutatorContext) {
  615. if m, ok := mctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
  616. switch library := m.compiler.(type) {
  617. case libraryInterface:
  618. // Only create a variant if a library is actually being built.
  619. if library.rlib() && !library.sysroot() {
  620. variants := []string{"rlib-std", "dylib-std"}
  621. modules := mctx.CreateLocalVariations(variants...)
  622. rlib := modules[0].(*Module)
  623. dylib := modules[1].(*Module)
  624. rlib.compiler.(libraryInterface).setRlibStd()
  625. dylib.compiler.(libraryInterface).setDylibStd()
  626. if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation ||
  627. strings.HasPrefix(dylib.ModuleBase.ImageVariation().Variation, cc.VendorVariationPrefix) {
  628. // TODO(b/165791368)
  629. // Disable rlibs that link against dylib-std on vendor and vendor ramdisk variations until those dylib
  630. // variants are properly supported.
  631. dylib.Disable()
  632. }
  633. rlib.Properties.RustSubName += RlibStdlibSuffix
  634. dylib.Properties.RustSubName += DylibStdlibSuffix
  635. }
  636. }
  637. }
  638. }
  639. func (l *libraryDecorator) snapshotHeaders() android.Paths {
  640. if l.collectedSnapshotHeaders == nil {
  641. panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
  642. }
  643. return l.collectedSnapshotHeaders
  644. }
  645. // collectHeadersForSnapshot collects all exported headers from library.
  646. // It globs header files in the source tree for exported include directories,
  647. // and tracks generated header files separately.
  648. //
  649. // This is to be called from GenerateAndroidBuildActions, and then collected
  650. // header files can be retrieved by snapshotHeaders().
  651. func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) {
  652. ret := android.Paths{}
  653. // Glob together the headers from the modules include_dirs property
  654. for _, path := range android.CopyOfPaths(l.includeDirs) {
  655. dir := path.String()
  656. globDir := dir + "/**/*"
  657. glob, err := ctx.GlobWithDeps(globDir, nil)
  658. if err != nil {
  659. ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
  660. return
  661. }
  662. for _, header := range glob {
  663. // Filter out only the files with extensions that are headers.
  664. found := false
  665. for _, ext := range cc.HeaderExts {
  666. if strings.HasSuffix(header, ext) {
  667. found = true
  668. break
  669. }
  670. }
  671. if !found {
  672. continue
  673. }
  674. ret = append(ret, android.PathForSource(ctx, header))
  675. }
  676. }
  677. // Glob together the headers from C dependencies as well, starting with non-generated headers.
  678. ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...)
  679. // Collect generated headers from C dependencies.
  680. ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...)
  681. // TODO(185577950): If support for generated headers is added, they need to be collected here as well.
  682. l.collectedSnapshotHeaders = ret
  683. }