blob: 0ebd7d3b174e55afbd9cfd15eb56dce7610a72e7 [file] [log] [blame]
Ivan Lozanoffee3342019-08-27 12:03:00 -07001// 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
15package rust
16
17import (
Matthew Maurera28404a2023-11-20 23:33:28 +000018 "errors"
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +020019 "fmt"
Ivan Lozanoad8b18b2019-10-31 19:38:29 -070020 "regexp"
21 "strings"
22
Colin Cross8a49a3d2024-05-20 12:22:27 -070023 "github.com/google/blueprint"
Colin Crossa14fb6a2024-10-23 16:57:06 -070024 "github.com/google/blueprint/depset"
Colin Cross8a49a3d2024-05-20 12:22:27 -070025
Ivan Lozanoffee3342019-08-27 12:03:00 -070026 "android/soong/android"
Colin Cross0de8a1e2020-09-18 14:15:30 -070027 "android/soong/cc"
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +000028 cc_config "android/soong/cc/config"
Ivan Lozanoffee3342019-08-27 12:03:00 -070029)
30
Ivan Lozano2b081132020-09-08 12:46:52 -040031var (
Ivan Lozano4df02572023-06-15 14:21:09 -040032 RlibStdlibSuffix = ".rlib-std"
Ivan Lozano2b081132020-09-08 12:46:52 -040033)
34
Ivan Lozanoffee3342019-08-27 12:03:00 -070035func init() {
36 android.RegisterModuleType("rust_library", RustLibraryFactory)
37 android.RegisterModuleType("rust_library_dylib", RustLibraryDylibFactory)
38 android.RegisterModuleType("rust_library_rlib", RustLibraryRlibFactory)
39 android.RegisterModuleType("rust_library_host", RustLibraryHostFactory)
40 android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory)
41 android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
Matthew Maurer2ae05132020-06-23 14:28:53 -070042 android.RegisterModuleType("rust_ffi", RustFFIFactory)
43 android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
Matthew Maurer2ae05132020-06-23 14:28:53 -070044 android.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
45 android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
Ivan Lozano806efd32024-12-11 21:38:53 +000046 android.RegisterModuleType("rust_ffi_static", RustLibraryRlibFactory)
47 android.RegisterModuleType("rust_ffi_host_static", RustLibraryRlibHostFactory)
Ivan Lozanoffee3342019-08-27 12:03:00 -070048}
49
50type VariantLibraryProperties struct {
Matthew Maurerc761eec2020-06-25 00:47:46 -070051 Enabled *bool `android:"arch_variant"`
52 Srcs []string `android:"path,arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070053}
54
55type LibraryCompilerProperties struct {
Ivan Lozano52767be2019-10-18 14:49:46 -070056 Rlib VariantLibraryProperties `android:"arch_variant"`
57 Dylib VariantLibraryProperties `android:"arch_variant"`
58 Shared VariantLibraryProperties `android:"arch_variant"`
59 Static VariantLibraryProperties `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070060
Ivan Lozanof033ca62024-03-21 13:43:14 -040061 // TODO: Remove this when all instances of Include_dirs have been removed from rust_ffi modules.
62 // path to include directories to pass to cc_* modules, only relevant for static/shared variants (deprecated, use export_include_dirs instead).
Ivan Lozano52767be2019-10-18 14:49:46 -070063 Include_dirs []string `android:"path,arch_variant"`
Ivan Lozano2b081132020-09-08 12:46:52 -040064
Ivan Lozanof033ca62024-03-21 13:43:14 -040065 // path to include directories to export to cc_* modules, only relevant for static/shared variants.
66 Export_include_dirs []string `android:"path,arch_variant"`
67
Ivan Lozanof4589012024-11-20 22:18:11 +000068 // Version script to pass to the linker. By default this will replace the
69 // implicit rustc emitted version script to mirror expected behavior in CC.
70 // This is only relevant for rust_ffi_shared modules which are exposing a
71 // versioned C API.
72 Version_script *string `android:"path,arch_variant"`
73
74 // A version_script formatted text file with additional symbols to export
75 // for rust shared or dylibs which the rustc compiler does not automatically
76 // export, e.g. additional symbols from whole_static_libs. Unlike
77 // Version_script, this is not meant to imply a stable API.
78 Extra_exported_symbols *string `android:"path,arch_variant"`
79
Ivan Lozano2b081132020-09-08 12:46:52 -040080 // Whether this library is part of the Rust toolchain sysroot.
81 Sysroot *bool
Ashutosh Agarwal46e4fad2024-08-27 17:13:12 +000082
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +000083 // Deprecated - exclude this rust_ffi target from being included in APEXes.
84 // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
Ashutosh Agarwal46e4fad2024-08-27 17:13:12 +000085 Apex_exclude *bool
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +000086
87 // Generate stubs to make this library accessible to APEXes.
88 // Can only be set for modules producing shared libraries.
89 Stubs cc.StubsProperties `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070090}
91
92type LibraryMutatedProperties struct {
Ivan Lozanoffee3342019-08-27 12:03:00 -070093 // Build a dylib variant
94 BuildDylib bool `blueprint:"mutated"`
95 // Build an rlib variant
96 BuildRlib bool `blueprint:"mutated"`
Ivan Lozano52767be2019-10-18 14:49:46 -070097 // Build a shared library variant
98 BuildShared bool `blueprint:"mutated"`
99 // Build a static library variant
100 BuildStatic bool `blueprint:"mutated"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700101
102 // This variant is a dylib
103 VariantIsDylib bool `blueprint:"mutated"`
104 // This variant is an rlib
105 VariantIsRlib bool `blueprint:"mutated"`
Ivan Lozano52767be2019-10-18 14:49:46 -0700106 // This variant is a shared library
107 VariantIsShared bool `blueprint:"mutated"`
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200108 // This variant is a source provider
109 VariantIsSource bool `blueprint:"mutated"`
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400110
111 // This variant is disabled and should not be compiled
112 // (used for SourceProvider variants that produce only source)
113 VariantIsDisabled bool `blueprint:"mutated"`
Ivan Lozano2b081132020-09-08 12:46:52 -0400114
115 // Whether this library variant should be link libstd via rlibs
116 VariantIsStaticStd bool `blueprint:"mutated"`
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000117
118 // This variant is a stubs lib
119 BuildStubs bool `blueprint:"mutated"`
120 // This variant is the latest version
121 IsLatestVersion bool `blueprint:"mutated"`
122 // Version of the stubs lib
123 StubsVersion string `blueprint:"mutated"`
124 // List of all stubs versions associated with an implementation lib
125 AllStubsVersions []string `blueprint:"mutated"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700126}
127
128type libraryDecorator struct {
129 *baseCompiler
Matthew Maurerbb3add12020-06-25 09:34:12 -0700130 *flagExporter
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200131 stripper Stripper
Ivan Lozanoffee3342019-08-27 12:03:00 -0700132
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400133 Properties LibraryCompilerProperties
134 MutatedProperties LibraryMutatedProperties
135 includeDirs android.Paths
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400136 sourceProvider SourceProvider
Ivan Lozano1921e802021-05-20 13:39:16 -0400137
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400138 // table-of-contents file for cdylib crates to optimize out relinking when possible
139 tocFile android.OptionalPath
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000140
141 // Path to the file containing the APIs exported by this library
142 stubsSymbolFilePath android.Path
143 apiListCoverageXmlPath android.ModuleOutPath
144 versionScriptPath android.OptionalPath
145}
146
147func (library *libraryDecorator) stubs() bool {
148 return library.MutatedProperties.BuildStubs
149}
150
151func (library *libraryDecorator) setAPIListCoverageXMLPath(xml android.ModuleOutPath) {
152 library.apiListCoverageXmlPath = xml
153}
154
155func (library *libraryDecorator) libraryProperties() LibraryCompilerProperties {
156 return library.Properties
Ivan Lozanoffee3342019-08-27 12:03:00 -0700157}
158
159type libraryInterface interface {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000160 cc.VersionedInterface
161
Ivan Lozanoffee3342019-08-27 12:03:00 -0700162 rlib() bool
163 dylib() bool
Ivan Lozano52767be2019-10-18 14:49:46 -0700164 static() bool
165 shared() bool
Ivan Lozano2b081132020-09-08 12:46:52 -0400166 sysroot() bool
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200167 source() bool
Ashutosh Agarwal46e4fad2024-08-27 17:13:12 +0000168 apexExclude() bool
Ivan Lozanoffee3342019-08-27 12:03:00 -0700169
170 // Returns true if the build options for the module have selected a particular build type
171 buildRlib() bool
172 buildDylib() bool
Ivan Lozano52767be2019-10-18 14:49:46 -0700173 buildShared() bool
174 buildStatic() bool
Ivan Lozanoffee3342019-08-27 12:03:00 -0700175
176 // Sets a particular variant type
177 setRlib()
178 setDylib()
Ivan Lozano52767be2019-10-18 14:49:46 -0700179 setShared()
180 setStatic()
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200181 setSource()
Ivan Lozano52767be2019-10-18 14:49:46 -0700182
Ivan Lozano3149e6e2021-06-01 15:09:53 -0400183 // libstd linkage functions
184 rlibStd() bool
Ivan Lozano2b081132020-09-08 12:46:52 -0400185 setRlibStd()
186 setDylibStd()
187
Ivan Lozano52767be2019-10-18 14:49:46 -0700188 // Build a specific library variant
Matthew Maurer2ae05132020-06-23 14:28:53 -0700189 BuildOnlyFFI()
190 BuildOnlyRust()
Ivan Lozano52767be2019-10-18 14:49:46 -0700191 BuildOnlyRlib()
192 BuildOnlyDylib()
193 BuildOnlyStatic()
194 BuildOnlyShared()
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400195
196 toc() android.OptionalPath
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000197
198 IsStubsImplementationRequired() bool
199 setAPIListCoverageXMLPath(out android.ModuleOutPath)
200
201 libraryProperties() LibraryCompilerProperties
Ivan Lozanoffee3342019-08-27 12:03:00 -0700202}
203
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400204func (library *libraryDecorator) nativeCoverage() bool {
Ivan Lozano3cc1daf2025-02-03 16:16:34 +0000205 if library.BuildStubs() {
206 return false
207 }
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400208 return true
209}
210
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400211func (library *libraryDecorator) toc() android.OptionalPath {
212 return library.tocFile
213}
214
Ivan Lozanoffee3342019-08-27 12:03:00 -0700215func (library *libraryDecorator) rlib() bool {
216 return library.MutatedProperties.VariantIsRlib
217}
218
Ivan Lozano2b081132020-09-08 12:46:52 -0400219func (library *libraryDecorator) sysroot() bool {
220 return Bool(library.Properties.Sysroot)
221}
222
Ivan Lozanoffee3342019-08-27 12:03:00 -0700223func (library *libraryDecorator) dylib() bool {
224 return library.MutatedProperties.VariantIsDylib
225}
226
Ivan Lozano52767be2019-10-18 14:49:46 -0700227func (library *libraryDecorator) shared() bool {
228 return library.MutatedProperties.VariantIsShared
229}
230
231func (library *libraryDecorator) static() bool {
Colin Cross17f9dc52024-07-01 20:05:54 -0700232 return false
Ivan Lozano52767be2019-10-18 14:49:46 -0700233}
234
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200235func (library *libraryDecorator) source() bool {
236 return library.MutatedProperties.VariantIsSource
237}
238
Ashutosh Agarwal46e4fad2024-08-27 17:13:12 +0000239func (library *libraryDecorator) apexExclude() bool {
240 return Bool(library.Properties.Apex_exclude)
241}
242
Ivan Lozanoffee3342019-08-27 12:03:00 -0700243func (library *libraryDecorator) buildRlib() bool {
244 return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
245}
246
247func (library *libraryDecorator) buildDylib() bool {
248 return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true)
249}
250
Ivan Lozano52767be2019-10-18 14:49:46 -0700251func (library *libraryDecorator) buildShared() bool {
252 return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true)
253}
254
255func (library *libraryDecorator) buildStatic() bool {
256 return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true)
257}
258
Ivan Lozanoffee3342019-08-27 12:03:00 -0700259func (library *libraryDecorator) setRlib() {
260 library.MutatedProperties.VariantIsRlib = true
261 library.MutatedProperties.VariantIsDylib = false
Ivan Lozano52767be2019-10-18 14:49:46 -0700262 library.MutatedProperties.VariantIsShared = false
Ivan Lozanoffee3342019-08-27 12:03:00 -0700263}
264
265func (library *libraryDecorator) setDylib() {
266 library.MutatedProperties.VariantIsRlib = false
267 library.MutatedProperties.VariantIsDylib = true
Ivan Lozano52767be2019-10-18 14:49:46 -0700268 library.MutatedProperties.VariantIsShared = false
269}
270
Ivan Lozano3149e6e2021-06-01 15:09:53 -0400271func (library *libraryDecorator) rlibStd() bool {
272 return library.MutatedProperties.VariantIsStaticStd
273}
274
Ivan Lozano2b081132020-09-08 12:46:52 -0400275func (library *libraryDecorator) setRlibStd() {
276 library.MutatedProperties.VariantIsStaticStd = true
277}
278
279func (library *libraryDecorator) setDylibStd() {
280 library.MutatedProperties.VariantIsStaticStd = false
281}
282
Ivan Lozano52767be2019-10-18 14:49:46 -0700283func (library *libraryDecorator) setShared() {
Ivan Lozano52767be2019-10-18 14:49:46 -0700284 library.MutatedProperties.VariantIsShared = true
285 library.MutatedProperties.VariantIsRlib = false
286 library.MutatedProperties.VariantIsDylib = false
287}
288
289func (library *libraryDecorator) setStatic() {
Colin Cross17f9dc52024-07-01 20:05:54 -0700290 panic(fmt.Errorf("static variant is not supported for rust modules, use the rlib variant instead"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700291}
292
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200293func (library *libraryDecorator) setSource() {
294 library.MutatedProperties.VariantIsSource = true
295}
296
Liz Kammer356f7d42021-01-26 09:18:53 -0500297func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
Ivan Lozanoadd122a2023-07-13 11:01:41 -0400298 if library.preferRlib() {
Ivan Lozanoea086132020-12-08 14:43:00 -0500299 return rlibAutoDep
300 } else if library.rlib() || library.static() {
Matthew Maurer0f003b12020-06-29 14:34:06 -0700301 return rlibAutoDep
302 } else if library.dylib() || library.shared() {
303 return dylibAutoDep
304 } else {
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200305 panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName()))
Matthew Maurer0f003b12020-06-29 14:34:06 -0700306 }
307}
308
Ivan Lozano806efd32024-12-11 21:38:53 +0000309func (library *libraryDecorator) stdLinkage(device bool) RustLinkage {
310 if library.static() || library.MutatedProperties.VariantIsStaticStd {
Ivan Lozanoea086132020-12-08 14:43:00 -0500311 return RlibLinkage
312 } else if library.baseCompiler.preferRlib() {
313 return RlibLinkage
314 }
Ivan Lozano806efd32024-12-11 21:38:53 +0000315 return DylibLinkage
Ivan Lozanoea086132020-12-08 14:43:00 -0500316}
317
Ivan Lozanoffee3342019-08-27 12:03:00 -0700318var _ compiler = (*libraryDecorator)(nil)
Ivan Lozano52767be2019-10-18 14:49:46 -0700319var _ libraryInterface = (*libraryDecorator)(nil)
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000320var _ cc.VersionedInterface = (*libraryDecorator)(nil)
Matthew Maurerbb3add12020-06-25 09:34:12 -0700321var _ exportedFlagsProducer = (*libraryDecorator)(nil)
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000322var _ cc.VersionedInterface = (*libraryDecorator)(nil)
323
324func (library *libraryDecorator) HasLLNDKStubs() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000325 // Rust LLNDK is currently unsupported
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000326 return false
327}
328
329func (library *libraryDecorator) HasVendorPublicLibrary() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000330 // Rust does not support vendor_public_library yet.
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000331 return false
332}
333
334func (library *libraryDecorator) HasLLNDKHeaders() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000335 // Rust LLNDK is currently unsupported
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000336 return false
337}
338
339func (library *libraryDecorator) HasStubsVariants() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000340 // Just having stubs.symbol_file is enough to create a stub variant. In that case
341 // the stub for the future API level is created.
342 return library.Properties.Stubs.Symbol_file != nil ||
343 len(library.Properties.Stubs.Versions) > 0
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000344}
345
346func (library *libraryDecorator) IsStubsImplementationRequired() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000347 return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000348}
349
350func (library *libraryDecorator) GetAPIListCoverageXMLPath() android.ModuleOutPath {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000351 return library.apiListCoverageXmlPath
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000352}
353
354func (library *libraryDecorator) AllStubsVersions() []string {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000355 return library.MutatedProperties.AllStubsVersions
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000356}
357
358func (library *libraryDecorator) SetAllStubsVersions(versions []string) {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000359 library.MutatedProperties.AllStubsVersions = versions
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000360}
361
362func (library *libraryDecorator) SetStubsVersion(version string) {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000363 library.MutatedProperties.StubsVersion = version
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000364}
365
366func (library *libraryDecorator) SetBuildStubs(isLatest bool) {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000367 library.MutatedProperties.BuildStubs = true
368 library.MutatedProperties.IsLatestVersion = isLatest
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000369}
370
371func (library *libraryDecorator) BuildStubs() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000372 return library.MutatedProperties.BuildStubs
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000373}
374
375func (library *libraryDecorator) ImplementationModuleName(name string) string {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000376 return name
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000377}
378
379func (library *libraryDecorator) IsLLNDKMovedToApex() bool {
380 // Rust does not support LLNDK.
381 return false
382}
383
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000384func (library *libraryDecorator) StubsVersion() string {
385 return library.MutatedProperties.StubsVersion
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000386}
387
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000388// stubsVersions implements cc.VersionedInterface.
389func (library *libraryDecorator) StubsVersions(ctx android.BaseModuleContext) []string {
390 if !library.HasStubsVariants() {
391 return nil
392 }
393
394 // Future API level is implicitly added if there isn't
395 versions := cc.AddCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
396 cc.NormalizeVersions(ctx, versions)
397 return versions
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000398}
Ivan Lozanoffee3342019-08-27 12:03:00 -0700399
Martin Geisler67ec0542022-11-18 12:08:55 +0100400// rust_library produces all Rust variants (rust_library_dylib and
401// rust_library_rlib).
Ivan Lozanoffee3342019-08-27 12:03:00 -0700402func RustLibraryFactory() android.Module {
Matthew Maurer2ae05132020-06-23 14:28:53 -0700403 module, library := NewRustLibrary(android.HostAndDeviceSupported)
404 library.BuildOnlyRust()
405 return module.Init()
406}
407
Ivan Lozano61848422024-12-13 19:45:00 +0000408// rust_ffi produces all FFI variants (rust_ffi_shared, rust_ffi_static).
Matthew Maurer2ae05132020-06-23 14:28:53 -0700409func RustFFIFactory() android.Module {
410 module, library := NewRustLibrary(android.HostAndDeviceSupported)
411 library.BuildOnlyFFI()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700412 return module.Init()
413}
414
Martin Geisler67ec0542022-11-18 12:08:55 +0100415// rust_library_dylib produces a Rust dylib (Rust crate type "dylib").
Ivan Lozanoffee3342019-08-27 12:03:00 -0700416func RustLibraryDylibFactory() android.Module {
417 module, library := NewRustLibrary(android.HostAndDeviceSupported)
418 library.BuildOnlyDylib()
419 return module.Init()
420}
421
Ivan Lozano806efd32024-12-11 21:38:53 +0000422// rust_library_rlib and rust_ffi_static produces an rlib (Rust crate type "rlib").
Ivan Lozanoffee3342019-08-27 12:03:00 -0700423func RustLibraryRlibFactory() android.Module {
424 module, library := NewRustLibrary(android.HostAndDeviceSupported)
425 library.BuildOnlyRlib()
426 return module.Init()
427}
428
Martin Geisler67ec0542022-11-18 12:08:55 +0100429// rust_ffi_shared produces a shared library (Rust crate type
430// "cdylib").
Matthew Maurer2ae05132020-06-23 14:28:53 -0700431func RustFFISharedFactory() android.Module {
Ivan Lozano52767be2019-10-18 14:49:46 -0700432 module, library := NewRustLibrary(android.HostAndDeviceSupported)
433 library.BuildOnlyShared()
434 return module.Init()
435}
436
Martin Geisler67ec0542022-11-18 12:08:55 +0100437// rust_library_host produces all Rust variants for the host
438// (rust_library_dylib_host and rust_library_rlib_host).
Ivan Lozanoffee3342019-08-27 12:03:00 -0700439func RustLibraryHostFactory() android.Module {
Matthew Maurer2ae05132020-06-23 14:28:53 -0700440 module, library := NewRustLibrary(android.HostSupported)
441 library.BuildOnlyRust()
442 return module.Init()
443}
444
Martin Geisler67ec0542022-11-18 12:08:55 +0100445// rust_ffi_host produces all FFI variants for the host
Ivan Lozano61848422024-12-13 19:45:00 +0000446// (rust_ffi_static_host and rust_ffi_shared_host).
Matthew Maurer2ae05132020-06-23 14:28:53 -0700447func RustFFIHostFactory() android.Module {
448 module, library := NewRustLibrary(android.HostSupported)
449 library.BuildOnlyFFI()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700450 return module.Init()
451}
452
Martin Geisler67ec0542022-11-18 12:08:55 +0100453// rust_library_dylib_host produces a dylib for the host (Rust crate
454// type "dylib").
Ivan Lozanoffee3342019-08-27 12:03:00 -0700455func RustLibraryDylibHostFactory() android.Module {
456 module, library := NewRustLibrary(android.HostSupported)
457 library.BuildOnlyDylib()
458 return module.Init()
459}
460
Ivan Lozano806efd32024-12-11 21:38:53 +0000461// rust_library_rlib_host and rust_ffi_static_host produces an rlib for the host
462// (Rust crate type "rlib").
Ivan Lozanoffee3342019-08-27 12:03:00 -0700463func RustLibraryRlibHostFactory() android.Module {
464 module, library := NewRustLibrary(android.HostSupported)
465 library.BuildOnlyRlib()
466 return module.Init()
467}
468
Martin Geisler67ec0542022-11-18 12:08:55 +0100469// rust_ffi_shared_host produces an shared library for the host (Rust
470// crate type "cdylib").
Matthew Maurer2ae05132020-06-23 14:28:53 -0700471func RustFFISharedHostFactory() android.Module {
Ivan Lozano52767be2019-10-18 14:49:46 -0700472 module, library := NewRustLibrary(android.HostSupported)
473 library.BuildOnlyShared()
474 return module.Init()
475}
476
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000477func CheckRustLibraryProperties(mctx android.DefaultableHookContext) {
478 lib := mctx.Module().(*Module).compiler.(libraryInterface)
479 if !lib.buildShared() {
480 if lib.libraryProperties().Stubs.Symbol_file != nil ||
481 lib.libraryProperties().Stubs.Implementation_installable != nil ||
482 len(lib.libraryProperties().Stubs.Versions) > 0 {
483
484 mctx.PropertyErrorf("stubs", "stubs properties can only be set for rust_ffi or rust_ffi_shared modules")
485 }
486 }
487}
488
Matthew Maurer2ae05132020-06-23 14:28:53 -0700489func (library *libraryDecorator) BuildOnlyFFI() {
490 library.MutatedProperties.BuildDylib = false
Ivan Lozano0a468a42024-05-13 21:03:34 -0400491 // we build rlibs for later static ffi linkage.
492 library.MutatedProperties.BuildRlib = true
Matthew Maurer2ae05132020-06-23 14:28:53 -0700493 library.MutatedProperties.BuildShared = true
Ivan Lozanofd47b1a2024-05-17 14:13:41 -0400494 library.MutatedProperties.BuildStatic = false
Matthew Maurer2ae05132020-06-23 14:28:53 -0700495}
496
497func (library *libraryDecorator) BuildOnlyRust() {
498 library.MutatedProperties.BuildDylib = true
499 library.MutatedProperties.BuildRlib = true
500 library.MutatedProperties.BuildShared = false
501 library.MutatedProperties.BuildStatic = false
502}
503
Ivan Lozanoffee3342019-08-27 12:03:00 -0700504func (library *libraryDecorator) BuildOnlyDylib() {
Matthew Maurer2ae05132020-06-23 14:28:53 -0700505 library.MutatedProperties.BuildDylib = true
Ivan Lozanoffee3342019-08-27 12:03:00 -0700506 library.MutatedProperties.BuildRlib = false
Ivan Lozano52767be2019-10-18 14:49:46 -0700507 library.MutatedProperties.BuildShared = false
508 library.MutatedProperties.BuildStatic = false
Ivan Lozanoffee3342019-08-27 12:03:00 -0700509}
510
511func (library *libraryDecorator) BuildOnlyRlib() {
512 library.MutatedProperties.BuildDylib = false
Matthew Maurer2ae05132020-06-23 14:28:53 -0700513 library.MutatedProperties.BuildRlib = true
Ivan Lozano52767be2019-10-18 14:49:46 -0700514 library.MutatedProperties.BuildShared = false
515 library.MutatedProperties.BuildStatic = false
516}
517
518func (library *libraryDecorator) BuildOnlyStatic() {
Ivan Lozano52767be2019-10-18 14:49:46 -0700519 library.MutatedProperties.BuildRlib = false
520 library.MutatedProperties.BuildDylib = false
Matthew Maurer2ae05132020-06-23 14:28:53 -0700521 library.MutatedProperties.BuildShared = false
522 library.MutatedProperties.BuildStatic = true
Ivan Lozano52767be2019-10-18 14:49:46 -0700523}
524
525func (library *libraryDecorator) BuildOnlyShared() {
Ivan Lozano52767be2019-10-18 14:49:46 -0700526 library.MutatedProperties.BuildRlib = false
527 library.MutatedProperties.BuildDylib = false
Matthew Maurer2ae05132020-06-23 14:28:53 -0700528 library.MutatedProperties.BuildStatic = false
529 library.MutatedProperties.BuildShared = true
Ivan Lozanoffee3342019-08-27 12:03:00 -0700530}
531
532func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
Ivan Lozano9d1df102020-04-28 10:10:23 -0400533 module := newModule(hod, android.MultilibBoth)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700534
535 library := &libraryDecorator{
536 MutatedProperties: LibraryMutatedProperties{
Matthew Maurer2ae05132020-06-23 14:28:53 -0700537 BuildDylib: false,
538 BuildRlib: false,
539 BuildShared: false,
540 BuildStatic: false,
Ivan Lozanoffee3342019-08-27 12:03:00 -0700541 },
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800542 baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
Matthew Maurerbb3add12020-06-25 09:34:12 -0700543 flagExporter: NewFlagExporter(),
Ivan Lozanoffee3342019-08-27 12:03:00 -0700544 }
545
546 module.compiler = library
547
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000548 module.SetDefaultableHook(CheckRustLibraryProperties)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700549 return module, library
550}
551
552func (library *libraryDecorator) compilerProps() []interface{} {
553 return append(library.baseCompiler.compilerProps(),
554 &library.Properties,
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200555 &library.MutatedProperties,
556 &library.stripper.StripProperties)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700557}
558
Ivan Lozanof1c84332019-09-20 11:00:37 -0700559func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
560 deps = library.baseCompiler.compilerDeps(ctx, deps)
561
Colin Crosse32f0932022-01-23 20:48:36 -0800562 if library.dylib() || library.shared() {
563 if ctx.toolchain().Bionic() {
564 deps = bionicDeps(ctx, deps, false)
565 deps.CrtBegin = []string{"crtbegin_so"}
566 deps.CrtEnd = []string{"crtend_so"}
567 } else if ctx.Os() == android.LinuxMusl {
568 deps = muslDeps(ctx, deps, false)
569 deps.CrtBegin = []string{"libc_musl_crtbegin_so"}
570 deps.CrtEnd = []string{"libc_musl_crtend_so"}
571 }
Ivan Lozanof1c84332019-09-20 11:00:37 -0700572 }
573
574 return deps
575}
Ivan Lozanobec05ea2020-06-09 08:27:49 -0400576
577func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
578 return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
579}
580
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400581// Library cfg flags common to all variants
582func CommonLibraryCfgFlags(ctx android.ModuleContext, flags Flags) Flags {
583 return flags
584}
585
Ivan Lozano67eada32021-09-23 11:50:33 -0400586func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags {
587 flags = library.baseCompiler.cfgFlags(ctx, flags)
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400588 flags = CommonLibraryCfgFlags(ctx, flags)
589
Cole Faustfdec8722024-05-22 11:38:29 -0700590 cfgs := library.baseCompiler.Properties.Cfgs.GetOrDefault(ctx, nil)
591
Cole Faustfdec8722024-05-22 11:38:29 -0700592 cfgFlags := cfgsToFlags(cfgs)
593
594 flags.RustFlags = append(flags.RustFlags, cfgFlags...)
595 flags.RustdocFlags = append(flags.RustdocFlags, cfgFlags...)
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400596
597 return flags
598}
599
600// Common flags applied to all libraries irrespective of properties or variant should be included here
601func CommonLibraryCompilerFlags(ctx android.ModuleContext, flags Flags) Flags {
602 flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
Ivan Lozano67eada32021-09-23 11:50:33 -0400603
604 return flags
605}
606
607func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
Ivan Lozanoe0833b12019-11-06 19:15:49 -0800608 flags = library.baseCompiler.compilerFlags(ctx, flags)
Ivan Lozano67eada32021-09-23 11:50:33 -0400609
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400610 flags = CommonLibraryCompilerFlags(ctx, flags)
611
Ivan Lozano806efd32024-12-11 21:38:53 +0000612 if library.rlib() || library.shared() {
613 // rlibs collect include dirs as well since they are used to
614 // produce staticlibs in the final C linkages
Ivan Lozanoe0833b12019-11-06 19:15:49 -0800615 library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
Ivan Lozanof033ca62024-03-21 13:43:14 -0400616 library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)...)
Ivan Lozanoe0833b12019-11-06 19:15:49 -0800617 }
Ivan Lozano0a468a42024-05-13 21:03:34 -0400618
Ivan Lozanobec05ea2020-06-09 08:27:49 -0400619 if library.shared() {
A. Cody Schuffelenc183e3a2023-08-14 21:09:47 -0700620 if ctx.Darwin() {
621 flags.LinkFlags = append(
622 flags.LinkFlags,
623 "-dynamic_lib",
624 "-install_name @rpath/"+library.sharedLibFilename(ctx),
625 )
626 } else {
627 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx))
628 }
Ivan Lozanobec05ea2020-06-09 08:27:49 -0400629 }
630
Ivan Lozanoe0833b12019-11-06 19:15:49 -0800631 return flags
632}
Ivan Lozanof1c84332019-09-20 11:00:37 -0700633
Sasha Smundaka76acba2022-04-18 20:12:56 -0700634func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
635 var outputFile android.ModuleOutPath
636 var ret buildOutput
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200637 var fileName string
Matthew Maurera28404a2023-11-20 23:33:28 +0000638 crateRootPath := crateRootPath(ctx, library)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700639
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400640 if library.sourceProvider != nil {
Ivan Lozano9d74a522020-12-01 09:25:22 -0500641 deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400642 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700643
Ivan Lozano0a468a42024-05-13 21:03:34 -0400644 // Ensure link dirs are not duplicated
645 deps.linkDirs = android.FirstUniqueStrings(deps.linkDirs)
646
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400647 // Calculate output filename
648 if library.rlib() {
649 fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
650 outputFile = android.PathForModuleOut(ctx, fileName)
Sasha Smundaka76acba2022-04-18 20:12:56 -0700651 ret.outputFile = outputFile
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400652 } else if library.dylib() {
653 fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
654 outputFile = android.PathForModuleOut(ctx, fileName)
Sasha Smundaka76acba2022-04-18 20:12:56 -0700655 ret.outputFile = outputFile
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400656 } else if library.static() {
657 fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
658 outputFile = android.PathForModuleOut(ctx, fileName)
Sasha Smundaka76acba2022-04-18 20:12:56 -0700659 ret.outputFile = outputFile
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400660 } else if library.shared() {
661 fileName = library.sharedLibFilename(ctx)
662 outputFile = android.PathForModuleOut(ctx, fileName)
Sasha Smundaka76acba2022-04-18 20:12:56 -0700663 ret.outputFile = outputFile
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400664 }
665
666 if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) {
667 strippedOutputFile := outputFile
668 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
669 library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
670
671 library.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
672 }
673 library.baseCompiler.unstrippedOutputFile = outputFile
674
Ivan Lozanoffee3342019-08-27 12:03:00 -0700675 flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
Ivan Lozano3dfa12d2021-02-04 11:29:41 -0500676 flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
Ivan Lozano1f10f682024-11-08 16:16:50 +0000677 flags.LinkFlags = append(flags.LinkFlags, deps.rustLibObjects...)
678 flags.LinkFlags = append(flags.LinkFlags, deps.sharedLibObjects...)
679 flags.LinkFlags = append(flags.LinkFlags, deps.staticLibObjects...)
680 flags.LinkFlags = append(flags.LinkFlags, deps.wholeStaticLibObjects...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700681
Ivan Lozanof4589012024-11-20 22:18:11 +0000682 if String(library.Properties.Version_script) != "" {
683 if String(library.Properties.Extra_exported_symbols) != "" {
684 ctx.ModuleErrorf("version_script and extra_exported_symbols cannot both be set.")
685 }
686
687 if library.shared() {
688 // "-Wl,--android-version-script" signals to the rustcLinker script
689 // that the default version script should be removed.
690 flags.LinkFlags = append(flags.LinkFlags, "-Wl,--android-version-script="+android.PathForModuleSrc(ctx, String(library.Properties.Version_script)).String())
691 deps.LinkerDeps = append(deps.LinkerDeps, android.PathForModuleSrc(ctx, String(library.Properties.Version_script)))
692 } else if !library.static() && !library.rlib() {
693 // We include rlibs here because rust_ffi produces rlib variants
694 ctx.PropertyErrorf("version_script", "can only be set for rust_ffi modules")
695 }
696 }
697
698 if String(library.Properties.Extra_exported_symbols) != "" {
699 // Passing a second version script (rustc calculates and emits a
700 // default version script) will concatenate the first version script.
701 flags.LinkFlags = append(flags.LinkFlags, "-Wl,--version-script="+android.PathForModuleSrc(ctx, String(library.Properties.Extra_exported_symbols)).String())
702 deps.LinkerDeps = append(deps.LinkerDeps, android.PathForModuleSrc(ctx, String(library.Properties.Extra_exported_symbols)))
703 }
704
Matthew Maurer46c46cc2020-01-13 16:34:34 -0800705 if library.dylib() {
Ivan Lozanof4589012024-11-20 22:18:11 +0000706
Ivan Lozano52767be2019-10-18 14:49:46 -0700707 // We need prefer-dynamic for now to avoid linking in the static stdlib. See:
708 // https://github.com/rust-lang/rust/issues/19680
709 // https://github.com/rust-lang/rust/issues/34909
710 flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
711 }
712
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400713 // Call the appropriate builder for this library type
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000714 if library.stubs() {
715 ccFlags := library.getApiStubsCcFlags(ctx)
716 stubObjs := library.compileModuleLibApiStubs(ctx, ccFlags)
Ivan Lozano47596d62025-01-28 13:50:55 +0000717 cc.BuildRustStubs(ctx, outputFile, stubObjs, ccFlags)
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000718 } else if library.rlib() {
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000719 ret.kytheFile = TransformSrctoRlib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
Ivan Lozanoffee3342019-08-27 12:03:00 -0700720 } else if library.dylib() {
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000721 ret.kytheFile = TransformSrctoDylib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
Ivan Lozano52767be2019-10-18 14:49:46 -0700722 } else if library.static() {
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000723 ret.kytheFile = TransformSrctoStatic(ctx, crateRootPath, deps, flags, outputFile).kytheFile
Ivan Lozano52767be2019-10-18 14:49:46 -0700724 } else if library.shared() {
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000725 ret.kytheFile = TransformSrctoShared(ctx, crateRootPath, deps, flags, outputFile).kytheFile
Ivan Lozanoffee3342019-08-27 12:03:00 -0700726 }
727
Ivan Lozano1f10f682024-11-08 16:16:50 +0000728 // rlibs and dylibs propagate their shared, whole static, and rustlib dependencies
Ivan Lozano52767be2019-10-18 14:49:46 -0700729 if library.rlib() || library.dylib() {
Colin Cross0de8a1e2020-09-18 14:15:30 -0700730 library.flagExporter.exportLinkDirs(deps.linkDirs...)
Ivan Lozano1f10f682024-11-08 16:16:50 +0000731 library.flagExporter.exportRustLibs(deps.rustLibObjects...)
732 library.flagExporter.exportSharedLibs(deps.sharedLibObjects...)
733 library.flagExporter.exportWholeStaticLibs(deps.wholeStaticLibObjects...)
734 }
735
736 // rlibs also propagate their staticlibs dependencies
737 if library.rlib() {
738 library.flagExporter.exportStaticLibs(deps.staticLibObjects...)
Ivan Lozano52767be2019-10-18 14:49:46 -0700739 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700740
Ivan Lozano0a468a42024-05-13 21:03:34 -0400741 // Since we have FFI rlibs, we need to collect their includes as well
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000742 if library.static() || library.shared() || library.rlib() || library.stubs() {
Colin Cross40213022023-12-13 15:19:49 -0800743 android.SetProvider(ctx, cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
Ivan Lozano0a468a42024-05-13 21:03:34 -0400744 IncludeDirs: android.FirstUniquePaths(library.includeDirs),
Colin Cross0de8a1e2020-09-18 14:15:30 -0700745 })
746 }
747
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000748 if library.shared() || library.stubs() {
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400749 // Optimize out relinking against shared libraries whose interface hasn't changed by
750 // depending on a table of contents file instead of the library itself.
751 tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
752 library.tocFile = android.OptionalPathForPath(tocFile)
753 cc.TransformSharedObjectToToc(ctx, outputFile, tocFile)
754
Colin Cross40213022023-12-13 15:19:49 -0800755 android.SetProvider(ctx, cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400756 TableOfContents: android.OptionalPathForPath(tocFile),
757 SharedLibrary: outputFile,
758 Target: ctx.Target(),
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000759 IsStubs: library.BuildStubs(),
Colin Cross0de8a1e2020-09-18 14:15:30 -0700760 })
761 }
762
763 if library.static() {
Colin Crossa14fb6a2024-10-23 16:57:06 -0700764 depSet := depset.NewBuilder[android.Path](depset.TOPOLOGICAL).Direct(outputFile).Build()
Colin Cross40213022023-12-13 15:19:49 -0800765 android.SetProvider(ctx, cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{
Colin Cross0de8a1e2020-09-18 14:15:30 -0700766 StaticLibrary: outputFile,
767
768 TransitiveStaticLibrariesForOrdering: depSet,
769 })
770 }
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000771 cc.AddStubDependencyProviders(ctx)
Colin Cross0de8a1e2020-09-18 14:15:30 -0700772
Ivan Lozano1f10f682024-11-08 16:16:50 +0000773 // Set our flagexporter provider to export relevant Rust flags
Colin Cross0de8a1e2020-09-18 14:15:30 -0700774 library.flagExporter.setProvider(ctx)
775
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400776 return ret
Ivan Lozanoffee3342019-08-27 12:03:00 -0700777}
778
Matthew Maurera28404a2023-11-20 23:33:28 +0000779func (library *libraryDecorator) checkedCrateRootPath() (android.Path, error) {
Dan Albert06feee92021-03-19 15:06:02 -0700780 if library.sourceProvider != nil {
Matthew Maurera28404a2023-11-20 23:33:28 +0000781 srcs := library.sourceProvider.Srcs()
782 if len(srcs) == 0 {
783 return nil, errors.New("Source provider generated 0 sources")
784 }
Dan Albert06feee92021-03-19 15:06:02 -0700785 // Assume the first source from the source provider is the library entry point.
Matthew Maurera28404a2023-11-20 23:33:28 +0000786 return srcs[0], nil
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000787 } else {
Matthew Maurera28404a2023-11-20 23:33:28 +0000788 return library.baseCompiler.checkedCrateRootPath()
Dan Albert06feee92021-03-19 15:06:02 -0700789 }
790}
791
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000792func (library *libraryDecorator) getApiStubsCcFlags(ctx ModuleContext) cc.Flags {
793 ccFlags := cc.Flags{}
794 toolchain := cc_config.FindToolchain(ctx.Os(), ctx.Arch())
795
796 platformSdkVersion := ""
797 if ctx.Device() {
798 platformSdkVersion = ctx.Config().PlatformSdkVersion().String()
799 }
800 minSdkVersion := cc.MinSdkVersion(ctx.RustModule(), cc.CtxIsForPlatform(ctx), ctx.Device(), platformSdkVersion)
801
802 // Collect common CC compilation flags
803 ccFlags = cc.CommonLinkerFlags(ctx, ccFlags, true, toolchain, false)
804 ccFlags = cc.CommonLibraryLinkerFlags(ctx, ccFlags, toolchain, library.getStem(ctx))
805 ccFlags = cc.AddStubLibraryCompilerFlags(ccFlags)
806 ccFlags = cc.AddTargetFlags(ctx, ccFlags, toolchain, minSdkVersion, false)
807
808 return ccFlags
809}
810
811func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, ccFlags cc.Flags) cc.Objects {
812 mod := ctx.RustModule()
813
814 symbolFile := String(library.Properties.Stubs.Symbol_file)
815 library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
816
817 apiParams := cc.ApiStubsParams{
818 NotInPlatform: mod.NotInPlatform(),
819 IsNdk: mod.IsNdk(ctx.Config()),
820 BaseModuleName: mod.BaseModuleName(),
821 ModuleName: ctx.ModuleName(),
822 }
823 flag := cc.GetApiStubsFlags(apiParams)
824
825 nativeAbiResult := cc.ParseNativeAbiDefinition(ctx, symbolFile,
826 android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
827 objs := cc.CompileStubLibrary(ctx, ccFlags, nativeAbiResult.StubSrc, mod.getSharedFlags())
828
829 library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.VersionScript)
830
831 // Parse symbol file to get API list for coverage
832 if library.StubsVersion() == "current" && ctx.PrimaryArch() && !mod.InRecovery() && !mod.InProduct() && !mod.InVendor() {
833 library.apiListCoverageXmlPath = cc.ParseSymbolFileForAPICoverage(ctx, symbolFile)
834 }
835
836 return objs
837}
838
Dan Albert06feee92021-03-19 15:06:02 -0700839func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
840 deps PathDeps) android.OptionalPath {
841 // rustdoc has builtin support for documenting config specific information
842 // regardless of the actual config it was given
843 // (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information),
844 // so we generate the rustdoc for only the primary module so that we have a
845 // single set of docs to refer to.
846 if ctx.Module() != ctx.PrimaryModule() {
847 return android.OptionalPath{}
848 }
849
Matthew Maurera28404a2023-11-20 23:33:28 +0000850 return android.OptionalPathForPath(Rustdoc(ctx, crateRootPath(ctx, library),
Dan Albert06feee92021-03-19 15:06:02 -0700851 deps, flags))
852}
853
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700854func (library *libraryDecorator) getStem(ctx ModuleContext) string {
855 stem := library.baseCompiler.getStemWithoutSuffix(ctx)
856 validateLibraryStem(ctx, stem, library.crateName())
857
858 return stem + String(library.baseCompiler.Properties.Suffix)
859}
860
Ivan Lozano2b081132020-09-08 12:46:52 -0400861func (library *libraryDecorator) install(ctx ModuleContext) {
862 // Only shared and dylib variants make sense to install.
863 if library.shared() || library.dylib() {
864 library.baseCompiler.install(ctx)
865 }
866}
867
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400868func (library *libraryDecorator) Disabled() bool {
869 return library.MutatedProperties.VariantIsDisabled
870}
871
872func (library *libraryDecorator) SetDisabled() {
873 library.MutatedProperties.VariantIsDisabled = true
874}
875
Cole Faust58eef4f2025-01-29 15:14:17 -0800876func (library *libraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
877 library.baseCompiler.moduleInfoJSON(ctx, moduleInfoJSON)
878
879 if library.rlib() {
880 moduleInfoJSON.Class = []string{"RLIB_LIBRARIES"}
881 } else if library.dylib() {
882 moduleInfoJSON.Class = []string{"DYLIB_LIBRARIES"}
883 } else if library.static() {
884 moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"}
885 } else if library.shared() {
886 moduleInfoJSON.Class = []string{"SHARED_LIBRARIES"}
887 }
888}
889
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700890var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+")
891
892func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) {
893 if crate_name == "" {
894 ctx.PropertyErrorf("crate_name", "crate_name must be defined.")
895 }
896
897 // crate_names are used for the library output file, and rustc expects these
898 // to be alphanumeric with underscores allowed.
899 if validCrateName.MatchString(crate_name) {
900 ctx.PropertyErrorf("crate_name",
901 "library crate_names must be alphanumeric with underscores allowed")
902 }
903
904 // Libraries are expected to begin with "lib" followed by the crate_name
905 if !strings.HasPrefix(filename, "lib"+crate_name) {
906 ctx.ModuleErrorf("Invalid name or stem property; library filenames must start with lib<crate_name>")
907 }
908}
909
Colin Cross8a49a3d2024-05-20 12:22:27 -0700910type libraryTransitionMutator struct{}
911
912func (libraryTransitionMutator) Split(ctx android.BaseModuleContext) []string {
913 m, ok := ctx.Module().(*Module)
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200914 if !ok || m.compiler == nil {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700915 return []string{""}
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200916 }
917 library, ok := m.compiler.(libraryInterface)
918 if !ok {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700919 return []string{""}
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200920 }
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400921
Ivan Lozano0a468a42024-05-13 21:03:34 -0400922 // Don't produce rlib/dylib/source variants for shared or static variants
923 if library.shared() || library.static() {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700924 return []string{""}
Ivan Lozano0a468a42024-05-13 21:03:34 -0400925 }
926
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200927 var variants []string
928 // The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
929 // depend on this variant. It must be the first variant to be declared.
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200930 if m.sourceProvider != nil {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700931 variants = append(variants, sourceVariation)
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200932 }
933 if library.buildRlib() {
934 variants = append(variants, rlibVariation)
935 }
936 if library.buildDylib() {
937 variants = append(variants, dylibVariation)
938 }
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400939
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200940 if len(variants) == 0 {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700941 return []string{""}
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200942 }
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200943
Colin Cross8a49a3d2024-05-20 12:22:27 -0700944 return variants
945}
Ivan Lozano1921e802021-05-20 13:39:16 -0400946
Colin Cross8a49a3d2024-05-20 12:22:27 -0700947func (libraryTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
Colin Crossd8d8b852024-12-20 16:32:37 -0800948 if ctx.DepTag() == android.PrebuiltDepTag {
949 return sourceVariation
950 }
Colin Cross8a49a3d2024-05-20 12:22:27 -0700951 return ""
952}
953
954func (libraryTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
955 m, ok := ctx.Module().(*Module)
956 if !ok || m.compiler == nil {
957 return ""
958 }
959 library, ok := m.compiler.(libraryInterface)
960 if !ok {
961 return ""
962 }
963
964 if incomingVariation == "" {
965 if m.sourceProvider != nil {
966 return sourceVariation
967 }
968 if library.shared() {
969 return ""
970 }
971 if library.buildRlib() {
972 return rlibVariation
973 }
974 if library.buildDylib() {
975 return dylibVariation
Ivan Lozanoffee3342019-08-27 12:03:00 -0700976 }
977 }
Colin Cross8a49a3d2024-05-20 12:22:27 -0700978 return incomingVariation
979}
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200980
Colin Cross8a49a3d2024-05-20 12:22:27 -0700981func (libraryTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
982 m, ok := ctx.Module().(*Module)
983 if !ok || m.compiler == nil {
984 return
985 }
986 library, ok := m.compiler.(libraryInterface)
987 if !ok {
988 return
989 }
990
991 switch variation {
992 case rlibVariation:
993 library.setRlib()
994 case dylibVariation:
995 library.setDylib()
996 if m.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
997 // TODO(b/165791368)
998 // Disable dylib Vendor Ramdisk variations until we support these.
999 m.Disable()
1000 }
1001
1002 case sourceVariation:
1003 library.setSource()
1004 // The source variant does not produce any library.
1005 // Disable the compilation steps.
1006 m.compiler.SetDisabled()
Ivan Lozanofd47b1a2024-05-17 14:13:41 -04001007 }
1008
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +02001009 // If a source variant is created, add an inter-variant dependency
1010 // between the other variants and the source variant.
Colin Cross8a49a3d2024-05-20 12:22:27 -07001011 if m.sourceProvider != nil && variation != sourceVariation {
1012 ctx.AddVariationDependencies(
1013 []blueprint.Variation{
1014 {"rust_libraries", sourceVariation},
1015 },
1016 sourceDepTag, ctx.ModuleName())
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +02001017 }
Colin Crossd8d8b852024-12-20 16:32:37 -08001018
1019 if prebuilt, ok := m.compiler.(*prebuiltLibraryDecorator); ok {
1020 if Bool(prebuilt.Properties.Force_use_prebuilt) && len(prebuilt.prebuiltSrcs()) > 0 {
1021 m.Prebuilt().SetUsePrebuilt(true)
1022 }
1023 }
Ivan Lozanoffee3342019-08-27 12:03:00 -07001024}
Ivan Lozano2b081132020-09-08 12:46:52 -04001025
Colin Cross8a49a3d2024-05-20 12:22:27 -07001026type libstdTransitionMutator struct{}
Ivan Lozano2b081132020-09-08 12:46:52 -04001027
Colin Cross8a49a3d2024-05-20 12:22:27 -07001028func (libstdTransitionMutator) Split(ctx android.BaseModuleContext) []string {
1029 if m, ok := ctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
1030 // Only create a variant if a library is actually being built.
1031 if library, ok := m.compiler.(libraryInterface); ok {
1032 if library.rlib() && !library.sysroot() {
Ivan Lozano806efd32024-12-11 21:38:53 +00001033 return []string{"rlib-std", "dylib-std"}
Ivan Lozano2b081132020-09-08 12:46:52 -04001034 }
1035 }
1036 }
Colin Cross8a49a3d2024-05-20 12:22:27 -07001037 return []string{""}
1038}
1039
1040func (libstdTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
Colin Crossd8d8b852024-12-20 16:32:37 -08001041 if ctx.DepTag() == android.PrebuiltDepTag {
1042 return sourceVariation
1043 }
Colin Cross8a49a3d2024-05-20 12:22:27 -07001044 return ""
1045}
1046
1047func (libstdTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
1048 if m, ok := ctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
1049 if library, ok := m.compiler.(libraryInterface); ok {
1050 if library.shared() {
1051 return ""
1052 }
1053 if library.rlib() && !library.sysroot() {
1054 if incomingVariation != "" {
1055 return incomingVariation
1056 }
1057 return "rlib-std"
1058 }
1059 }
1060 }
1061 return ""
1062}
1063
1064func (libstdTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
1065 if variation == "rlib-std" {
1066 rlib := ctx.Module().(*Module)
1067 rlib.compiler.(libraryInterface).setRlibStd()
1068 rlib.Properties.RustSubName += RlibStdlibSuffix
1069 } else if variation == "dylib-std" {
1070 dylib := ctx.Module().(*Module)
1071 dylib.compiler.(libraryInterface).setDylibStd()
1072 if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
1073 // TODO(b/165791368)
1074 // Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
1075 // variants are properly supported.
1076 dylib.Disable()
1077 }
1078 }
Ivan Lozano2b081132020-09-08 12:46:52 -04001079}