blob: 49169ac08191a0e6470ae39a9a096a7d929155ce [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 {
205 return true
206}
207
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400208func (library *libraryDecorator) toc() android.OptionalPath {
209 return library.tocFile
210}
211
Ivan Lozanoffee3342019-08-27 12:03:00 -0700212func (library *libraryDecorator) rlib() bool {
213 return library.MutatedProperties.VariantIsRlib
214}
215
Ivan Lozano2b081132020-09-08 12:46:52 -0400216func (library *libraryDecorator) sysroot() bool {
217 return Bool(library.Properties.Sysroot)
218}
219
Ivan Lozanoffee3342019-08-27 12:03:00 -0700220func (library *libraryDecorator) dylib() bool {
221 return library.MutatedProperties.VariantIsDylib
222}
223
Ivan Lozano52767be2019-10-18 14:49:46 -0700224func (library *libraryDecorator) shared() bool {
225 return library.MutatedProperties.VariantIsShared
226}
227
228func (library *libraryDecorator) static() bool {
Colin Cross17f9dc52024-07-01 20:05:54 -0700229 return false
Ivan Lozano52767be2019-10-18 14:49:46 -0700230}
231
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200232func (library *libraryDecorator) source() bool {
233 return library.MutatedProperties.VariantIsSource
234}
235
Ashutosh Agarwal46e4fad2024-08-27 17:13:12 +0000236func (library *libraryDecorator) apexExclude() bool {
237 return Bool(library.Properties.Apex_exclude)
238}
239
Ivan Lozanoffee3342019-08-27 12:03:00 -0700240func (library *libraryDecorator) buildRlib() bool {
241 return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
242}
243
244func (library *libraryDecorator) buildDylib() bool {
245 return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true)
246}
247
Ivan Lozano52767be2019-10-18 14:49:46 -0700248func (library *libraryDecorator) buildShared() bool {
249 return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true)
250}
251
252func (library *libraryDecorator) buildStatic() bool {
253 return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true)
254}
255
Ivan Lozanoffee3342019-08-27 12:03:00 -0700256func (library *libraryDecorator) setRlib() {
257 library.MutatedProperties.VariantIsRlib = true
258 library.MutatedProperties.VariantIsDylib = false
Ivan Lozano52767be2019-10-18 14:49:46 -0700259 library.MutatedProperties.VariantIsShared = false
Ivan Lozanoffee3342019-08-27 12:03:00 -0700260}
261
262func (library *libraryDecorator) setDylib() {
263 library.MutatedProperties.VariantIsRlib = false
264 library.MutatedProperties.VariantIsDylib = true
Ivan Lozano52767be2019-10-18 14:49:46 -0700265 library.MutatedProperties.VariantIsShared = false
266}
267
Ivan Lozano3149e6e2021-06-01 15:09:53 -0400268func (library *libraryDecorator) rlibStd() bool {
269 return library.MutatedProperties.VariantIsStaticStd
270}
271
Ivan Lozano2b081132020-09-08 12:46:52 -0400272func (library *libraryDecorator) setRlibStd() {
273 library.MutatedProperties.VariantIsStaticStd = true
274}
275
276func (library *libraryDecorator) setDylibStd() {
277 library.MutatedProperties.VariantIsStaticStd = false
278}
279
Ivan Lozano52767be2019-10-18 14:49:46 -0700280func (library *libraryDecorator) setShared() {
Ivan Lozano52767be2019-10-18 14:49:46 -0700281 library.MutatedProperties.VariantIsShared = true
282 library.MutatedProperties.VariantIsRlib = false
283 library.MutatedProperties.VariantIsDylib = false
284}
285
286func (library *libraryDecorator) setStatic() {
Colin Cross17f9dc52024-07-01 20:05:54 -0700287 panic(fmt.Errorf("static variant is not supported for rust modules, use the rlib variant instead"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700288}
289
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200290func (library *libraryDecorator) setSource() {
291 library.MutatedProperties.VariantIsSource = true
292}
293
Liz Kammer356f7d42021-01-26 09:18:53 -0500294func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
Ivan Lozanoadd122a2023-07-13 11:01:41 -0400295 if library.preferRlib() {
Ivan Lozanoea086132020-12-08 14:43:00 -0500296 return rlibAutoDep
297 } else if library.rlib() || library.static() {
Matthew Maurer0f003b12020-06-29 14:34:06 -0700298 return rlibAutoDep
299 } else if library.dylib() || library.shared() {
300 return dylibAutoDep
301 } else {
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200302 panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName()))
Matthew Maurer0f003b12020-06-29 14:34:06 -0700303 }
304}
305
Ivan Lozano806efd32024-12-11 21:38:53 +0000306func (library *libraryDecorator) stdLinkage(device bool) RustLinkage {
307 if library.static() || library.MutatedProperties.VariantIsStaticStd {
Ivan Lozanoea086132020-12-08 14:43:00 -0500308 return RlibLinkage
309 } else if library.baseCompiler.preferRlib() {
310 return RlibLinkage
311 }
Ivan Lozano806efd32024-12-11 21:38:53 +0000312 return DylibLinkage
Ivan Lozanoea086132020-12-08 14:43:00 -0500313}
314
Ivan Lozanoffee3342019-08-27 12:03:00 -0700315var _ compiler = (*libraryDecorator)(nil)
Ivan Lozano52767be2019-10-18 14:49:46 -0700316var _ libraryInterface = (*libraryDecorator)(nil)
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000317var _ cc.VersionedInterface = (*libraryDecorator)(nil)
Matthew Maurerbb3add12020-06-25 09:34:12 -0700318var _ exportedFlagsProducer = (*libraryDecorator)(nil)
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000319var _ cc.VersionedInterface = (*libraryDecorator)(nil)
320
321func (library *libraryDecorator) HasLLNDKStubs() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000322 // Rust LLNDK is currently unsupported
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000323 return false
324}
325
326func (library *libraryDecorator) HasVendorPublicLibrary() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000327 // Rust does not support vendor_public_library yet.
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000328 return false
329}
330
331func (library *libraryDecorator) HasLLNDKHeaders() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000332 // Rust LLNDK is currently unsupported
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000333 return false
334}
335
336func (library *libraryDecorator) HasStubsVariants() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000337 // Just having stubs.symbol_file is enough to create a stub variant. In that case
338 // the stub for the future API level is created.
339 return library.Properties.Stubs.Symbol_file != nil ||
340 len(library.Properties.Stubs.Versions) > 0
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000341}
342
343func (library *libraryDecorator) IsStubsImplementationRequired() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000344 return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000345}
346
347func (library *libraryDecorator) GetAPIListCoverageXMLPath() android.ModuleOutPath {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000348 return library.apiListCoverageXmlPath
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000349}
350
351func (library *libraryDecorator) AllStubsVersions() []string {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000352 return library.MutatedProperties.AllStubsVersions
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000353}
354
355func (library *libraryDecorator) SetAllStubsVersions(versions []string) {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000356 library.MutatedProperties.AllStubsVersions = versions
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000357}
358
359func (library *libraryDecorator) SetStubsVersion(version string) {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000360 library.MutatedProperties.StubsVersion = version
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000361}
362
363func (library *libraryDecorator) SetBuildStubs(isLatest bool) {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000364 library.MutatedProperties.BuildStubs = true
365 library.MutatedProperties.IsLatestVersion = isLatest
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000366}
367
368func (library *libraryDecorator) BuildStubs() bool {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000369 return library.MutatedProperties.BuildStubs
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000370}
371
372func (library *libraryDecorator) ImplementationModuleName(name string) string {
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000373 return name
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000374}
375
376func (library *libraryDecorator) IsLLNDKMovedToApex() bool {
377 // Rust does not support LLNDK.
378 return false
379}
380
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000381func (library *libraryDecorator) StubsVersion() string {
382 return library.MutatedProperties.StubsVersion
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000383}
384
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000385// stubsVersions implements cc.VersionedInterface.
386func (library *libraryDecorator) StubsVersions(ctx android.BaseModuleContext) []string {
387 if !library.HasStubsVariants() {
388 return nil
389 }
390
391 // Future API level is implicitly added if there isn't
392 versions := cc.AddCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
393 cc.NormalizeVersions(ctx, versions)
394 return versions
Ivan Lozano9eaacc82024-10-30 14:28:17 +0000395}
Ivan Lozanoffee3342019-08-27 12:03:00 -0700396
Martin Geisler67ec0542022-11-18 12:08:55 +0100397// rust_library produces all Rust variants (rust_library_dylib and
398// rust_library_rlib).
Ivan Lozanoffee3342019-08-27 12:03:00 -0700399func RustLibraryFactory() android.Module {
Matthew Maurer2ae05132020-06-23 14:28:53 -0700400 module, library := NewRustLibrary(android.HostAndDeviceSupported)
401 library.BuildOnlyRust()
402 return module.Init()
403}
404
Ivan Lozano61848422024-12-13 19:45:00 +0000405// rust_ffi produces all FFI variants (rust_ffi_shared, rust_ffi_static).
Matthew Maurer2ae05132020-06-23 14:28:53 -0700406func RustFFIFactory() android.Module {
407 module, library := NewRustLibrary(android.HostAndDeviceSupported)
408 library.BuildOnlyFFI()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700409 return module.Init()
410}
411
Martin Geisler67ec0542022-11-18 12:08:55 +0100412// rust_library_dylib produces a Rust dylib (Rust crate type "dylib").
Ivan Lozanoffee3342019-08-27 12:03:00 -0700413func RustLibraryDylibFactory() android.Module {
414 module, library := NewRustLibrary(android.HostAndDeviceSupported)
415 library.BuildOnlyDylib()
416 return module.Init()
417}
418
Ivan Lozano806efd32024-12-11 21:38:53 +0000419// rust_library_rlib and rust_ffi_static produces an rlib (Rust crate type "rlib").
Ivan Lozanoffee3342019-08-27 12:03:00 -0700420func RustLibraryRlibFactory() android.Module {
421 module, library := NewRustLibrary(android.HostAndDeviceSupported)
422 library.BuildOnlyRlib()
423 return module.Init()
424}
425
Martin Geisler67ec0542022-11-18 12:08:55 +0100426// rust_ffi_shared produces a shared library (Rust crate type
427// "cdylib").
Matthew Maurer2ae05132020-06-23 14:28:53 -0700428func RustFFISharedFactory() android.Module {
Ivan Lozano52767be2019-10-18 14:49:46 -0700429 module, library := NewRustLibrary(android.HostAndDeviceSupported)
430 library.BuildOnlyShared()
431 return module.Init()
432}
433
Martin Geisler67ec0542022-11-18 12:08:55 +0100434// rust_library_host produces all Rust variants for the host
435// (rust_library_dylib_host and rust_library_rlib_host).
Ivan Lozanoffee3342019-08-27 12:03:00 -0700436func RustLibraryHostFactory() android.Module {
Matthew Maurer2ae05132020-06-23 14:28:53 -0700437 module, library := NewRustLibrary(android.HostSupported)
438 library.BuildOnlyRust()
439 return module.Init()
440}
441
Martin Geisler67ec0542022-11-18 12:08:55 +0100442// rust_ffi_host produces all FFI variants for the host
Ivan Lozano61848422024-12-13 19:45:00 +0000443// (rust_ffi_static_host and rust_ffi_shared_host).
Matthew Maurer2ae05132020-06-23 14:28:53 -0700444func RustFFIHostFactory() android.Module {
445 module, library := NewRustLibrary(android.HostSupported)
446 library.BuildOnlyFFI()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700447 return module.Init()
448}
449
Martin Geisler67ec0542022-11-18 12:08:55 +0100450// rust_library_dylib_host produces a dylib for the host (Rust crate
451// type "dylib").
Ivan Lozanoffee3342019-08-27 12:03:00 -0700452func RustLibraryDylibHostFactory() android.Module {
453 module, library := NewRustLibrary(android.HostSupported)
454 library.BuildOnlyDylib()
455 return module.Init()
456}
457
Ivan Lozano806efd32024-12-11 21:38:53 +0000458// rust_library_rlib_host and rust_ffi_static_host produces an rlib for the host
459// (Rust crate type "rlib").
Ivan Lozanoffee3342019-08-27 12:03:00 -0700460func RustLibraryRlibHostFactory() android.Module {
461 module, library := NewRustLibrary(android.HostSupported)
462 library.BuildOnlyRlib()
463 return module.Init()
464}
465
Martin Geisler67ec0542022-11-18 12:08:55 +0100466// rust_ffi_shared_host produces an shared library for the host (Rust
467// crate type "cdylib").
Matthew Maurer2ae05132020-06-23 14:28:53 -0700468func RustFFISharedHostFactory() android.Module {
Ivan Lozano52767be2019-10-18 14:49:46 -0700469 module, library := NewRustLibrary(android.HostSupported)
470 library.BuildOnlyShared()
471 return module.Init()
472}
473
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000474func CheckRustLibraryProperties(mctx android.DefaultableHookContext) {
475 lib := mctx.Module().(*Module).compiler.(libraryInterface)
476 if !lib.buildShared() {
477 if lib.libraryProperties().Stubs.Symbol_file != nil ||
478 lib.libraryProperties().Stubs.Implementation_installable != nil ||
479 len(lib.libraryProperties().Stubs.Versions) > 0 {
480
481 mctx.PropertyErrorf("stubs", "stubs properties can only be set for rust_ffi or rust_ffi_shared modules")
482 }
483 }
484}
485
Matthew Maurer2ae05132020-06-23 14:28:53 -0700486func (library *libraryDecorator) BuildOnlyFFI() {
487 library.MutatedProperties.BuildDylib = false
Ivan Lozano0a468a42024-05-13 21:03:34 -0400488 // we build rlibs for later static ffi linkage.
489 library.MutatedProperties.BuildRlib = true
Matthew Maurer2ae05132020-06-23 14:28:53 -0700490 library.MutatedProperties.BuildShared = true
Ivan Lozanofd47b1a2024-05-17 14:13:41 -0400491 library.MutatedProperties.BuildStatic = false
Matthew Maurer2ae05132020-06-23 14:28:53 -0700492}
493
494func (library *libraryDecorator) BuildOnlyRust() {
495 library.MutatedProperties.BuildDylib = true
496 library.MutatedProperties.BuildRlib = true
497 library.MutatedProperties.BuildShared = false
498 library.MutatedProperties.BuildStatic = false
499}
500
Ivan Lozanoffee3342019-08-27 12:03:00 -0700501func (library *libraryDecorator) BuildOnlyDylib() {
Matthew Maurer2ae05132020-06-23 14:28:53 -0700502 library.MutatedProperties.BuildDylib = true
Ivan Lozanoffee3342019-08-27 12:03:00 -0700503 library.MutatedProperties.BuildRlib = false
Ivan Lozano52767be2019-10-18 14:49:46 -0700504 library.MutatedProperties.BuildShared = false
505 library.MutatedProperties.BuildStatic = false
Ivan Lozanoffee3342019-08-27 12:03:00 -0700506}
507
508func (library *libraryDecorator) BuildOnlyRlib() {
509 library.MutatedProperties.BuildDylib = false
Matthew Maurer2ae05132020-06-23 14:28:53 -0700510 library.MutatedProperties.BuildRlib = true
Ivan Lozano52767be2019-10-18 14:49:46 -0700511 library.MutatedProperties.BuildShared = false
512 library.MutatedProperties.BuildStatic = false
513}
514
515func (library *libraryDecorator) BuildOnlyStatic() {
Ivan Lozano52767be2019-10-18 14:49:46 -0700516 library.MutatedProperties.BuildRlib = false
517 library.MutatedProperties.BuildDylib = false
Matthew Maurer2ae05132020-06-23 14:28:53 -0700518 library.MutatedProperties.BuildShared = false
519 library.MutatedProperties.BuildStatic = true
Ivan Lozano52767be2019-10-18 14:49:46 -0700520}
521
522func (library *libraryDecorator) BuildOnlyShared() {
Ivan Lozano52767be2019-10-18 14:49:46 -0700523 library.MutatedProperties.BuildRlib = false
524 library.MutatedProperties.BuildDylib = false
Matthew Maurer2ae05132020-06-23 14:28:53 -0700525 library.MutatedProperties.BuildStatic = false
526 library.MutatedProperties.BuildShared = true
Ivan Lozanoffee3342019-08-27 12:03:00 -0700527}
528
529func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
Ivan Lozano9d1df102020-04-28 10:10:23 -0400530 module := newModule(hod, android.MultilibBoth)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700531
532 library := &libraryDecorator{
533 MutatedProperties: LibraryMutatedProperties{
Matthew Maurer2ae05132020-06-23 14:28:53 -0700534 BuildDylib: false,
535 BuildRlib: false,
536 BuildShared: false,
537 BuildStatic: false,
Ivan Lozanoffee3342019-08-27 12:03:00 -0700538 },
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800539 baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
Matthew Maurerbb3add12020-06-25 09:34:12 -0700540 flagExporter: NewFlagExporter(),
Ivan Lozanoffee3342019-08-27 12:03:00 -0700541 }
542
543 module.compiler = library
544
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000545 module.SetDefaultableHook(CheckRustLibraryProperties)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700546 return module, library
547}
548
549func (library *libraryDecorator) compilerProps() []interface{} {
550 return append(library.baseCompiler.compilerProps(),
551 &library.Properties,
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200552 &library.MutatedProperties,
553 &library.stripper.StripProperties)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700554}
555
Ivan Lozanof1c84332019-09-20 11:00:37 -0700556func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
557 deps = library.baseCompiler.compilerDeps(ctx, deps)
558
Colin Crosse32f0932022-01-23 20:48:36 -0800559 if library.dylib() || library.shared() {
560 if ctx.toolchain().Bionic() {
561 deps = bionicDeps(ctx, deps, false)
562 deps.CrtBegin = []string{"crtbegin_so"}
563 deps.CrtEnd = []string{"crtend_so"}
564 } else if ctx.Os() == android.LinuxMusl {
565 deps = muslDeps(ctx, deps, false)
566 deps.CrtBegin = []string{"libc_musl_crtbegin_so"}
567 deps.CrtEnd = []string{"libc_musl_crtend_so"}
568 }
Ivan Lozanof1c84332019-09-20 11:00:37 -0700569 }
570
571 return deps
572}
Ivan Lozanobec05ea2020-06-09 08:27:49 -0400573
574func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
575 return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
576}
577
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400578// Library cfg flags common to all variants
579func CommonLibraryCfgFlags(ctx android.ModuleContext, flags Flags) Flags {
580 return flags
581}
582
Ivan Lozano67eada32021-09-23 11:50:33 -0400583func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags {
584 flags = library.baseCompiler.cfgFlags(ctx, flags)
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400585 flags = CommonLibraryCfgFlags(ctx, flags)
586
Cole Faustfdec8722024-05-22 11:38:29 -0700587 cfgs := library.baseCompiler.Properties.Cfgs.GetOrDefault(ctx, nil)
588
Cole Faustfdec8722024-05-22 11:38:29 -0700589 cfgFlags := cfgsToFlags(cfgs)
590
591 flags.RustFlags = append(flags.RustFlags, cfgFlags...)
592 flags.RustdocFlags = append(flags.RustdocFlags, cfgFlags...)
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400593
594 return flags
595}
596
597// Common flags applied to all libraries irrespective of properties or variant should be included here
598func CommonLibraryCompilerFlags(ctx android.ModuleContext, flags Flags) Flags {
599 flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
Ivan Lozano67eada32021-09-23 11:50:33 -0400600
601 return flags
602}
603
604func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
Ivan Lozanoe0833b12019-11-06 19:15:49 -0800605 flags = library.baseCompiler.compilerFlags(ctx, flags)
Ivan Lozano67eada32021-09-23 11:50:33 -0400606
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400607 flags = CommonLibraryCompilerFlags(ctx, flags)
608
Ivan Lozano806efd32024-12-11 21:38:53 +0000609 if library.rlib() || library.shared() {
610 // rlibs collect include dirs as well since they are used to
611 // produce staticlibs in the final C linkages
Ivan Lozanoe0833b12019-11-06 19:15:49 -0800612 library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
Ivan Lozanof033ca62024-03-21 13:43:14 -0400613 library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)...)
Ivan Lozanoe0833b12019-11-06 19:15:49 -0800614 }
Ivan Lozano0a468a42024-05-13 21:03:34 -0400615
Ivan Lozanobec05ea2020-06-09 08:27:49 -0400616 if library.shared() {
A. Cody Schuffelenc183e3a2023-08-14 21:09:47 -0700617 if ctx.Darwin() {
618 flags.LinkFlags = append(
619 flags.LinkFlags,
620 "-dynamic_lib",
621 "-install_name @rpath/"+library.sharedLibFilename(ctx),
622 )
623 } else {
624 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx))
625 }
Ivan Lozanobec05ea2020-06-09 08:27:49 -0400626 }
627
Ivan Lozanoe0833b12019-11-06 19:15:49 -0800628 return flags
629}
Ivan Lozanof1c84332019-09-20 11:00:37 -0700630
Sasha Smundaka76acba2022-04-18 20:12:56 -0700631func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
632 var outputFile android.ModuleOutPath
633 var ret buildOutput
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200634 var fileName string
Matthew Maurera28404a2023-11-20 23:33:28 +0000635 crateRootPath := crateRootPath(ctx, library)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700636
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400637 if library.sourceProvider != nil {
Ivan Lozano9d74a522020-12-01 09:25:22 -0500638 deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400639 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700640
Ivan Lozano0a468a42024-05-13 21:03:34 -0400641 // Ensure link dirs are not duplicated
642 deps.linkDirs = android.FirstUniqueStrings(deps.linkDirs)
643
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400644 // Calculate output filename
645 if library.rlib() {
646 fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
647 outputFile = android.PathForModuleOut(ctx, fileName)
Sasha Smundaka76acba2022-04-18 20:12:56 -0700648 ret.outputFile = outputFile
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400649 } else if library.dylib() {
650 fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
651 outputFile = android.PathForModuleOut(ctx, fileName)
Sasha Smundaka76acba2022-04-18 20:12:56 -0700652 ret.outputFile = outputFile
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400653 } else if library.static() {
654 fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
655 outputFile = android.PathForModuleOut(ctx, fileName)
Sasha Smundaka76acba2022-04-18 20:12:56 -0700656 ret.outputFile = outputFile
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400657 } else if library.shared() {
658 fileName = library.sharedLibFilename(ctx)
659 outputFile = android.PathForModuleOut(ctx, fileName)
Sasha Smundaka76acba2022-04-18 20:12:56 -0700660 ret.outputFile = outputFile
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400661 }
662
663 if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) {
664 strippedOutputFile := outputFile
665 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
666 library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
667
668 library.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
669 }
670 library.baseCompiler.unstrippedOutputFile = outputFile
671
Ivan Lozanoffee3342019-08-27 12:03:00 -0700672 flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
Ivan Lozano3dfa12d2021-02-04 11:29:41 -0500673 flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
Colin Cross004bd3f2023-10-02 11:39:17 -0700674 flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700675
Ivan Lozanof4589012024-11-20 22:18:11 +0000676 if String(library.Properties.Version_script) != "" {
677 if String(library.Properties.Extra_exported_symbols) != "" {
678 ctx.ModuleErrorf("version_script and extra_exported_symbols cannot both be set.")
679 }
680
681 if library.shared() {
682 // "-Wl,--android-version-script" signals to the rustcLinker script
683 // that the default version script should be removed.
684 flags.LinkFlags = append(flags.LinkFlags, "-Wl,--android-version-script="+android.PathForModuleSrc(ctx, String(library.Properties.Version_script)).String())
685 deps.LinkerDeps = append(deps.LinkerDeps, android.PathForModuleSrc(ctx, String(library.Properties.Version_script)))
686 } else if !library.static() && !library.rlib() {
687 // We include rlibs here because rust_ffi produces rlib variants
688 ctx.PropertyErrorf("version_script", "can only be set for rust_ffi modules")
689 }
690 }
691
692 if String(library.Properties.Extra_exported_symbols) != "" {
693 // Passing a second version script (rustc calculates and emits a
694 // default version script) will concatenate the first version script.
695 flags.LinkFlags = append(flags.LinkFlags, "-Wl,--version-script="+android.PathForModuleSrc(ctx, String(library.Properties.Extra_exported_symbols)).String())
696 deps.LinkerDeps = append(deps.LinkerDeps, android.PathForModuleSrc(ctx, String(library.Properties.Extra_exported_symbols)))
697 }
698
Matthew Maurer46c46cc2020-01-13 16:34:34 -0800699 if library.dylib() {
Ivan Lozanof4589012024-11-20 22:18:11 +0000700
Ivan Lozano52767be2019-10-18 14:49:46 -0700701 // We need prefer-dynamic for now to avoid linking in the static stdlib. See:
702 // https://github.com/rust-lang/rust/issues/19680
703 // https://github.com/rust-lang/rust/issues/34909
704 flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
705 }
706
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400707 // Call the appropriate builder for this library type
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000708 if library.stubs() {
709 ccFlags := library.getApiStubsCcFlags(ctx)
710 stubObjs := library.compileModuleLibApiStubs(ctx, ccFlags)
711 cc.BuildRustStubs(ctx, outputFile, deps.CrtBegin, deps.CrtEnd, stubObjs, ccFlags)
712 } else if library.rlib() {
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000713 ret.kytheFile = TransformSrctoRlib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
Ivan Lozanoffee3342019-08-27 12:03:00 -0700714 } else if library.dylib() {
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000715 ret.kytheFile = TransformSrctoDylib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
Ivan Lozano52767be2019-10-18 14:49:46 -0700716 } else if library.static() {
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000717 ret.kytheFile = TransformSrctoStatic(ctx, crateRootPath, deps, flags, outputFile).kytheFile
Ivan Lozano52767be2019-10-18 14:49:46 -0700718 } else if library.shared() {
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000719 ret.kytheFile = TransformSrctoShared(ctx, crateRootPath, deps, flags, outputFile).kytheFile
Ivan Lozanoffee3342019-08-27 12:03:00 -0700720 }
721
Ivan Lozano52767be2019-10-18 14:49:46 -0700722 if library.rlib() || library.dylib() {
Colin Cross0de8a1e2020-09-18 14:15:30 -0700723 library.flagExporter.exportLinkDirs(deps.linkDirs...)
Colin Cross0de8a1e2020-09-18 14:15:30 -0700724 library.flagExporter.exportLinkObjects(deps.linkObjects...)
Ivan Lozano52767be2019-10-18 14:49:46 -0700725 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700726
Ivan Lozano0a468a42024-05-13 21:03:34 -0400727 // Since we have FFI rlibs, we need to collect their includes as well
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000728 if library.static() || library.shared() || library.rlib() || library.stubs() {
Colin Cross40213022023-12-13 15:19:49 -0800729 android.SetProvider(ctx, cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
Ivan Lozano0a468a42024-05-13 21:03:34 -0400730 IncludeDirs: android.FirstUniquePaths(library.includeDirs),
Colin Cross0de8a1e2020-09-18 14:15:30 -0700731 })
732 }
733
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000734 if library.shared() || library.stubs() {
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400735 // Optimize out relinking against shared libraries whose interface hasn't changed by
736 // depending on a table of contents file instead of the library itself.
737 tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
738 library.tocFile = android.OptionalPathForPath(tocFile)
739 cc.TransformSharedObjectToToc(ctx, outputFile, tocFile)
740
Colin Cross40213022023-12-13 15:19:49 -0800741 android.SetProvider(ctx, cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400742 TableOfContents: android.OptionalPathForPath(tocFile),
743 SharedLibrary: outputFile,
744 Target: ctx.Target(),
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000745 IsStubs: library.BuildStubs(),
Colin Cross0de8a1e2020-09-18 14:15:30 -0700746 })
747 }
748
749 if library.static() {
Colin Crossa14fb6a2024-10-23 16:57:06 -0700750 depSet := depset.NewBuilder[android.Path](depset.TOPOLOGICAL).Direct(outputFile).Build()
Colin Cross40213022023-12-13 15:19:49 -0800751 android.SetProvider(ctx, cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{
Colin Cross0de8a1e2020-09-18 14:15:30 -0700752 StaticLibrary: outputFile,
753
754 TransitiveStaticLibrariesForOrdering: depSet,
755 })
756 }
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000757 cc.AddStubDependencyProviders(ctx)
Colin Cross0de8a1e2020-09-18 14:15:30 -0700758
759 library.flagExporter.setProvider(ctx)
760
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400761 return ret
Ivan Lozanoffee3342019-08-27 12:03:00 -0700762}
763
Matthew Maurera28404a2023-11-20 23:33:28 +0000764func (library *libraryDecorator) checkedCrateRootPath() (android.Path, error) {
Dan Albert06feee92021-03-19 15:06:02 -0700765 if library.sourceProvider != nil {
Matthew Maurera28404a2023-11-20 23:33:28 +0000766 srcs := library.sourceProvider.Srcs()
767 if len(srcs) == 0 {
768 return nil, errors.New("Source provider generated 0 sources")
769 }
Dan Albert06feee92021-03-19 15:06:02 -0700770 // Assume the first source from the source provider is the library entry point.
Matthew Maurera28404a2023-11-20 23:33:28 +0000771 return srcs[0], nil
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000772 } else {
Matthew Maurera28404a2023-11-20 23:33:28 +0000773 return library.baseCompiler.checkedCrateRootPath()
Dan Albert06feee92021-03-19 15:06:02 -0700774 }
775}
776
Ivan Lozanoa8a1fa12024-10-30 18:15:59 +0000777func (library *libraryDecorator) getApiStubsCcFlags(ctx ModuleContext) cc.Flags {
778 ccFlags := cc.Flags{}
779 toolchain := cc_config.FindToolchain(ctx.Os(), ctx.Arch())
780
781 platformSdkVersion := ""
782 if ctx.Device() {
783 platformSdkVersion = ctx.Config().PlatformSdkVersion().String()
784 }
785 minSdkVersion := cc.MinSdkVersion(ctx.RustModule(), cc.CtxIsForPlatform(ctx), ctx.Device(), platformSdkVersion)
786
787 // Collect common CC compilation flags
788 ccFlags = cc.CommonLinkerFlags(ctx, ccFlags, true, toolchain, false)
789 ccFlags = cc.CommonLibraryLinkerFlags(ctx, ccFlags, toolchain, library.getStem(ctx))
790 ccFlags = cc.AddStubLibraryCompilerFlags(ccFlags)
791 ccFlags = cc.AddTargetFlags(ctx, ccFlags, toolchain, minSdkVersion, false)
792
793 return ccFlags
794}
795
796func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, ccFlags cc.Flags) cc.Objects {
797 mod := ctx.RustModule()
798
799 symbolFile := String(library.Properties.Stubs.Symbol_file)
800 library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
801
802 apiParams := cc.ApiStubsParams{
803 NotInPlatform: mod.NotInPlatform(),
804 IsNdk: mod.IsNdk(ctx.Config()),
805 BaseModuleName: mod.BaseModuleName(),
806 ModuleName: ctx.ModuleName(),
807 }
808 flag := cc.GetApiStubsFlags(apiParams)
809
810 nativeAbiResult := cc.ParseNativeAbiDefinition(ctx, symbolFile,
811 android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
812 objs := cc.CompileStubLibrary(ctx, ccFlags, nativeAbiResult.StubSrc, mod.getSharedFlags())
813
814 library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.VersionScript)
815
816 // Parse symbol file to get API list for coverage
817 if library.StubsVersion() == "current" && ctx.PrimaryArch() && !mod.InRecovery() && !mod.InProduct() && !mod.InVendor() {
818 library.apiListCoverageXmlPath = cc.ParseSymbolFileForAPICoverage(ctx, symbolFile)
819 }
820
821 return objs
822}
823
Dan Albert06feee92021-03-19 15:06:02 -0700824func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
825 deps PathDeps) android.OptionalPath {
826 // rustdoc has builtin support for documenting config specific information
827 // regardless of the actual config it was given
828 // (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information),
829 // so we generate the rustdoc for only the primary module so that we have a
830 // single set of docs to refer to.
831 if ctx.Module() != ctx.PrimaryModule() {
832 return android.OptionalPath{}
833 }
834
Matthew Maurera28404a2023-11-20 23:33:28 +0000835 return android.OptionalPathForPath(Rustdoc(ctx, crateRootPath(ctx, library),
Dan Albert06feee92021-03-19 15:06:02 -0700836 deps, flags))
837}
838
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700839func (library *libraryDecorator) getStem(ctx ModuleContext) string {
840 stem := library.baseCompiler.getStemWithoutSuffix(ctx)
841 validateLibraryStem(ctx, stem, library.crateName())
842
843 return stem + String(library.baseCompiler.Properties.Suffix)
844}
845
Ivan Lozano2b081132020-09-08 12:46:52 -0400846func (library *libraryDecorator) install(ctx ModuleContext) {
847 // Only shared and dylib variants make sense to install.
848 if library.shared() || library.dylib() {
849 library.baseCompiler.install(ctx)
850 }
851}
852
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400853func (library *libraryDecorator) Disabled() bool {
854 return library.MutatedProperties.VariantIsDisabled
855}
856
857func (library *libraryDecorator) SetDisabled() {
858 library.MutatedProperties.VariantIsDisabled = true
859}
860
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700861var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+")
862
863func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) {
864 if crate_name == "" {
865 ctx.PropertyErrorf("crate_name", "crate_name must be defined.")
866 }
867
868 // crate_names are used for the library output file, and rustc expects these
869 // to be alphanumeric with underscores allowed.
870 if validCrateName.MatchString(crate_name) {
871 ctx.PropertyErrorf("crate_name",
872 "library crate_names must be alphanumeric with underscores allowed")
873 }
874
875 // Libraries are expected to begin with "lib" followed by the crate_name
876 if !strings.HasPrefix(filename, "lib"+crate_name) {
877 ctx.ModuleErrorf("Invalid name or stem property; library filenames must start with lib<crate_name>")
878 }
879}
880
Colin Cross8a49a3d2024-05-20 12:22:27 -0700881type libraryTransitionMutator struct{}
882
883func (libraryTransitionMutator) Split(ctx android.BaseModuleContext) []string {
884 m, ok := ctx.Module().(*Module)
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200885 if !ok || m.compiler == nil {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700886 return []string{""}
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200887 }
888 library, ok := m.compiler.(libraryInterface)
889 if !ok {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700890 return []string{""}
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200891 }
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400892
Ivan Lozano0a468a42024-05-13 21:03:34 -0400893 // Don't produce rlib/dylib/source variants for shared or static variants
894 if library.shared() || library.static() {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700895 return []string{""}
Ivan Lozano0a468a42024-05-13 21:03:34 -0400896 }
897
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200898 var variants []string
899 // The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
900 // depend on this variant. It must be the first variant to be declared.
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200901 if m.sourceProvider != nil {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700902 variants = append(variants, sourceVariation)
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200903 }
904 if library.buildRlib() {
905 variants = append(variants, rlibVariation)
906 }
907 if library.buildDylib() {
908 variants = append(variants, dylibVariation)
909 }
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400910
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200911 if len(variants) == 0 {
Colin Cross8a49a3d2024-05-20 12:22:27 -0700912 return []string{""}
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200913 }
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200914
Colin Cross8a49a3d2024-05-20 12:22:27 -0700915 return variants
916}
Ivan Lozano1921e802021-05-20 13:39:16 -0400917
Colin Cross8a49a3d2024-05-20 12:22:27 -0700918func (libraryTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
919 return ""
920}
921
922func (libraryTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
923 m, ok := ctx.Module().(*Module)
924 if !ok || m.compiler == nil {
925 return ""
926 }
927 library, ok := m.compiler.(libraryInterface)
928 if !ok {
929 return ""
930 }
931
932 if incomingVariation == "" {
933 if m.sourceProvider != nil {
934 return sourceVariation
935 }
936 if library.shared() {
937 return ""
938 }
939 if library.buildRlib() {
940 return rlibVariation
941 }
942 if library.buildDylib() {
943 return dylibVariation
Ivan Lozanoffee3342019-08-27 12:03:00 -0700944 }
945 }
Colin Cross8a49a3d2024-05-20 12:22:27 -0700946 return incomingVariation
947}
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200948
Colin Cross8a49a3d2024-05-20 12:22:27 -0700949func (libraryTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
950 m, ok := ctx.Module().(*Module)
951 if !ok || m.compiler == nil {
952 return
953 }
954 library, ok := m.compiler.(libraryInterface)
955 if !ok {
956 return
957 }
958
959 switch variation {
960 case rlibVariation:
961 library.setRlib()
962 case dylibVariation:
963 library.setDylib()
964 if m.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
965 // TODO(b/165791368)
966 // Disable dylib Vendor Ramdisk variations until we support these.
967 m.Disable()
968 }
969
970 case sourceVariation:
971 library.setSource()
972 // The source variant does not produce any library.
973 // Disable the compilation steps.
974 m.compiler.SetDisabled()
Ivan Lozanofd47b1a2024-05-17 14:13:41 -0400975 }
976
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200977 // If a source variant is created, add an inter-variant dependency
978 // between the other variants and the source variant.
Colin Cross8a49a3d2024-05-20 12:22:27 -0700979 if m.sourceProvider != nil && variation != sourceVariation {
980 ctx.AddVariationDependencies(
981 []blueprint.Variation{
982 {"rust_libraries", sourceVariation},
983 },
984 sourceDepTag, ctx.ModuleName())
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200985 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700986}
Ivan Lozano2b081132020-09-08 12:46:52 -0400987
Colin Cross8a49a3d2024-05-20 12:22:27 -0700988type libstdTransitionMutator struct{}
Ivan Lozano2b081132020-09-08 12:46:52 -0400989
Colin Cross8a49a3d2024-05-20 12:22:27 -0700990func (libstdTransitionMutator) Split(ctx android.BaseModuleContext) []string {
991 if m, ok := ctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
992 // Only create a variant if a library is actually being built.
993 if library, ok := m.compiler.(libraryInterface); ok {
994 if library.rlib() && !library.sysroot() {
Ivan Lozano806efd32024-12-11 21:38:53 +0000995 return []string{"rlib-std", "dylib-std"}
Ivan Lozano2b081132020-09-08 12:46:52 -0400996 }
997 }
998 }
Colin Cross8a49a3d2024-05-20 12:22:27 -0700999 return []string{""}
1000}
1001
1002func (libstdTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
1003 return ""
1004}
1005
1006func (libstdTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
1007 if m, ok := ctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
1008 if library, ok := m.compiler.(libraryInterface); ok {
1009 if library.shared() {
1010 return ""
1011 }
1012 if library.rlib() && !library.sysroot() {
1013 if incomingVariation != "" {
1014 return incomingVariation
1015 }
1016 return "rlib-std"
1017 }
1018 }
1019 }
1020 return ""
1021}
1022
1023func (libstdTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
1024 if variation == "rlib-std" {
1025 rlib := ctx.Module().(*Module)
1026 rlib.compiler.(libraryInterface).setRlibStd()
1027 rlib.Properties.RustSubName += RlibStdlibSuffix
1028 } else if variation == "dylib-std" {
1029 dylib := ctx.Module().(*Module)
1030 dylib.compiler.(libraryInterface).setDylibStd()
1031 if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
1032 // TODO(b/165791368)
1033 // Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
1034 // variants are properly supported.
1035 dylib.Disable()
1036 }
1037 }
Ivan Lozano2b081132020-09-08 12:46:52 -04001038}