xref: /aosp_15_r20/build/soong/rust/rust.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1// Copyright 2019 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package rust
16
17import (
18	"fmt"
19	"strconv"
20	"strings"
21
22	"android/soong/bloaty"
23
24	"github.com/google/blueprint"
25	"github.com/google/blueprint/depset"
26	"github.com/google/blueprint/proptools"
27
28	"android/soong/android"
29	"android/soong/cc"
30	cc_config "android/soong/cc/config"
31	"android/soong/fuzz"
32	"android/soong/rust/config"
33)
34
35var pctx = android.NewPackageContext("android/soong/rust")
36
37func init() {
38	android.RegisterModuleType("rust_defaults", defaultsFactory)
39	android.PreDepsMutators(registerPreDepsMutators)
40	android.PostDepsMutators(registerPostDepsMutators)
41	pctx.Import("android/soong/android")
42	pctx.Import("android/soong/rust/config")
43	pctx.ImportAs("cc_config", "android/soong/cc/config")
44	android.InitRegistrationContext.RegisterParallelSingletonType("kythe_rust_extract", kytheExtractRustFactory)
45}
46
47func registerPreDepsMutators(ctx android.RegisterMutatorsContext) {
48	ctx.Transition("rust_libraries", &libraryTransitionMutator{})
49	ctx.Transition("rust_stdlinkage", &libstdTransitionMutator{})
50	ctx.BottomUp("rust_begin", BeginMutator)
51}
52
53func registerPostDepsMutators(ctx android.RegisterMutatorsContext) {
54	ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator)
55}
56
57type Flags struct {
58	GlobalRustFlags []string // Flags that apply globally to rust
59	GlobalLinkFlags []string // Flags that apply globally to linker
60	RustFlags       []string // Flags that apply to rust
61	LinkFlags       []string // Flags that apply to linker
62	ClippyFlags     []string // Flags that apply to clippy-driver, during the linting
63	RustdocFlags    []string // Flags that apply to rustdoc
64	Toolchain       config.Toolchain
65	Coverage        bool
66	Clippy          bool
67	EmitXrefs       bool // If true, emit rules to aid cross-referencing
68}
69
70type BaseProperties struct {
71	AndroidMkRlibs         []string `blueprint:"mutated"`
72	AndroidMkDylibs        []string `blueprint:"mutated"`
73	AndroidMkProcMacroLibs []string `blueprint:"mutated"`
74	AndroidMkStaticLibs    []string `blueprint:"mutated"`
75	AndroidMkHeaderLibs    []string `blueprint:"mutated"`
76
77	ImageVariation string `blueprint:"mutated"`
78	VndkVersion    string `blueprint:"mutated"`
79	SubName        string `blueprint:"mutated"`
80
81	// SubName is used by CC for tracking image variants / SDK versions. RustSubName is used for Rust-specific
82	// subnaming which shouldn't be visible to CC modules (such as the rlib stdlinkage subname). This should be
83	// appended before SubName.
84	RustSubName string `blueprint:"mutated"`
85
86	// Set by imageMutator
87	ProductVariantNeeded       bool     `blueprint:"mutated"`
88	VendorVariantNeeded        bool     `blueprint:"mutated"`
89	CoreVariantNeeded          bool     `blueprint:"mutated"`
90	VendorRamdiskVariantNeeded bool     `blueprint:"mutated"`
91	RamdiskVariantNeeded       bool     `blueprint:"mutated"`
92	RecoveryVariantNeeded      bool     `blueprint:"mutated"`
93	ExtraVariants              []string `blueprint:"mutated"`
94
95	// Allows this module to use non-APEX version of libraries. Useful
96	// for building binaries that are started before APEXes are activated.
97	Bootstrap *bool
98
99	// Used by vendor snapshot to record dependencies from snapshot modules.
100	SnapshotSharedLibs []string `blueprint:"mutated"`
101	SnapshotStaticLibs []string `blueprint:"mutated"`
102	SnapshotRlibs      []string `blueprint:"mutated"`
103	SnapshotDylibs     []string `blueprint:"mutated"`
104
105	// Make this module available when building for ramdisk.
106	// On device without a dedicated recovery partition, the module is only
107	// available after switching root into
108	// /first_stage_ramdisk. To expose the module before switching root, install
109	// the recovery variant instead.
110	Ramdisk_available *bool
111
112	// Make this module available when building for vendor ramdisk.
113	// On device without a dedicated recovery partition, the module is only
114	// available after switching root into
115	// /first_stage_ramdisk. To expose the module before switching root, install
116	// the recovery variant instead
117	Vendor_ramdisk_available *bool
118
119	// Normally Soong uses the directory structure to decide which modules
120	// should be included (framework) or excluded (non-framework) from the
121	// different snapshots (vendor, recovery, etc.), but this property
122	// allows a partner to exclude a module normally thought of as a
123	// framework module from the vendor snapshot.
124	Exclude_from_vendor_snapshot *bool
125
126	// Normally Soong uses the directory structure to decide which modules
127	// should be included (framework) or excluded (non-framework) from the
128	// different snapshots (vendor, recovery, etc.), but this property
129	// allows a partner to exclude a module normally thought of as a
130	// framework module from the recovery snapshot.
131	Exclude_from_recovery_snapshot *bool
132
133	// Make this module available when building for recovery
134	Recovery_available *bool
135
136	// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
137	Min_sdk_version *string
138
139	HideFromMake   bool `blueprint:"mutated"`
140	PreventInstall bool `blueprint:"mutated"`
141
142	Installable *bool
143}
144
145type Module struct {
146	fuzz.FuzzModule
147
148	VendorProperties cc.VendorProperties
149
150	Properties BaseProperties
151
152	hod        android.HostOrDeviceSupported
153	multilib   android.Multilib
154	testModule bool
155
156	makeLinkType string
157
158	afdo             *afdo
159	compiler         compiler
160	coverage         *coverage
161	clippy           *clippy
162	sanitize         *sanitize
163	cachedToolchain  config.Toolchain
164	sourceProvider   SourceProvider
165	subAndroidMkOnce map[SubAndroidMkProvider]bool
166
167	exportedLinkDirs []string
168
169	// Output file to be installed, may be stripped or unstripped.
170	outputFile android.OptionalPath
171
172	// Cross-reference input file
173	kytheFiles android.Paths
174
175	docTimestampFile android.OptionalPath
176
177	hideApexVariantFromMake bool
178
179	// For apex variants, this is set as apex.min_sdk_version
180	apexSdkVersion android.ApiLevel
181
182	transitiveAndroidMkSharedLibs depset.DepSet[string]
183}
184
185func (mod *Module) Header() bool {
186	//TODO: If Rust libraries provide header variants, this needs to be updated.
187	return false
188}
189
190func (mod *Module) SetPreventInstall() {
191	mod.Properties.PreventInstall = true
192}
193
194func (mod *Module) SetHideFromMake() {
195	mod.Properties.HideFromMake = true
196}
197
198func (mod *Module) HiddenFromMake() bool {
199	return mod.Properties.HideFromMake
200}
201
202func (mod *Module) SanitizePropDefined() bool {
203	// Because compiler is not set for some Rust modules where sanitize might be set, check that compiler is also not
204	// nil since we need compiler to actually sanitize.
205	return mod.sanitize != nil && mod.compiler != nil
206}
207
208func (mod *Module) IsPrebuilt() bool {
209	if _, ok := mod.compiler.(*prebuiltLibraryDecorator); ok {
210		return true
211	}
212	return false
213}
214
215func (mod *Module) SelectedStl() string {
216	return ""
217}
218
219func (mod *Module) NonCcVariants() bool {
220	if mod.compiler != nil {
221		if library, ok := mod.compiler.(libraryInterface); ok {
222			return library.buildRlib() || library.buildDylib()
223		}
224	}
225	panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName()))
226}
227
228func (mod *Module) Static() bool {
229	if mod.compiler != nil {
230		if library, ok := mod.compiler.(libraryInterface); ok {
231			return library.static()
232		}
233	}
234	return false
235}
236
237func (mod *Module) Shared() bool {
238	if mod.compiler != nil {
239		if library, ok := mod.compiler.(libraryInterface); ok {
240			return library.shared()
241		}
242	}
243	return false
244}
245
246func (mod *Module) Dylib() bool {
247	if mod.compiler != nil {
248		if library, ok := mod.compiler.(libraryInterface); ok {
249			return library.dylib()
250		}
251	}
252	return false
253}
254
255func (mod *Module) Source() bool {
256	if mod.compiler != nil {
257		if library, ok := mod.compiler.(libraryInterface); ok && mod.sourceProvider != nil {
258			return library.source()
259		}
260	}
261	return false
262}
263
264func (mod *Module) RlibStd() bool {
265	if mod.compiler != nil {
266		if library, ok := mod.compiler.(libraryInterface); ok && library.rlib() {
267			return library.rlibStd()
268		}
269	}
270	panic(fmt.Errorf("RlibStd() called on non-rlib module: %q", mod.BaseModuleName()))
271}
272
273func (mod *Module) Rlib() bool {
274	if mod.compiler != nil {
275		if library, ok := mod.compiler.(libraryInterface); ok {
276			return library.rlib()
277		}
278	}
279	return false
280}
281
282func (mod *Module) Binary() bool {
283	if binary, ok := mod.compiler.(binaryInterface); ok {
284		return binary.binary()
285	}
286	return false
287}
288
289func (mod *Module) StaticExecutable() bool {
290	if !mod.Binary() {
291		return false
292	}
293	return mod.StaticallyLinked()
294}
295
296func (mod *Module) ApexExclude() bool {
297	if mod.compiler != nil {
298		if library, ok := mod.compiler.(libraryInterface); ok {
299			return library.apexExclude()
300		}
301	}
302	return false
303}
304
305func (mod *Module) Object() bool {
306	// Rust has no modules which produce only object files.
307	return false
308}
309
310func (mod *Module) Toc() android.OptionalPath {
311	if mod.compiler != nil {
312		if lib, ok := mod.compiler.(libraryInterface); ok {
313			return lib.toc()
314		}
315	}
316	panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName()))
317}
318
319func (mod *Module) UseSdk() bool {
320	return false
321}
322
323func (mod *Module) RelativeInstallPath() string {
324	if mod.compiler != nil {
325		return mod.compiler.relativeInstallPath()
326	}
327	return ""
328}
329
330func (mod *Module) UseVndk() bool {
331	return mod.Properties.VndkVersion != ""
332}
333
334func (mod *Module) Bootstrap() bool {
335	return Bool(mod.Properties.Bootstrap)
336}
337
338func (mod *Module) SubName() string {
339	return mod.Properties.SubName
340}
341
342func (mod *Module) IsVndkPrebuiltLibrary() bool {
343	// Rust modules do not provide VNDK prebuilts
344	return false
345}
346
347func (mod *Module) IsVendorPublicLibrary() bool {
348	return mod.VendorProperties.IsVendorPublicLibrary
349}
350
351func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool {
352	// Rust modules to not provide Sdk variants
353	return false
354}
355
356func (c *Module) IsVndkPrivate() bool {
357	return false
358}
359
360func (c *Module) IsLlndk() bool {
361	return false
362}
363
364func (mod *Module) KernelHeadersDecorator() bool {
365	return false
366}
367
368func (m *Module) NeedsLlndkVariants() bool {
369	return false
370}
371
372func (m *Module) NeedsVendorPublicLibraryVariants() bool {
373	return false
374}
375
376func (mod *Module) HasLlndkStubs() bool {
377	return false
378}
379
380func (mod *Module) StubsVersion() string {
381	panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", mod.BaseModuleName()))
382}
383
384func (mod *Module) SdkVersion() string {
385	return ""
386}
387
388func (mod *Module) AlwaysSdk() bool {
389	return false
390}
391
392func (mod *Module) IsSdkVariant() bool {
393	return false
394}
395
396func (mod *Module) SplitPerApiLevel() bool {
397	return false
398}
399
400func (mod *Module) XrefRustFiles() android.Paths {
401	return mod.kytheFiles
402}
403
404type Deps struct {
405	Dylibs          []string
406	Rlibs           []string
407	Rustlibs        []string
408	Stdlibs         []string
409	ProcMacros      []string
410	SharedLibs      []string
411	StaticLibs      []string
412	WholeStaticLibs []string
413	HeaderLibs      []string
414
415	// Used for data dependencies adjacent to tests
416	DataLibs []string
417	DataBins []string
418
419	CrtBegin, CrtEnd []string
420}
421
422type PathDeps struct {
423	DyLibs        RustLibraries
424	RLibs         RustLibraries
425	SharedLibs    android.Paths
426	SharedLibDeps android.Paths
427	StaticLibs    android.Paths
428	ProcMacros    RustLibraries
429	AfdoProfiles  android.Paths
430
431	// depFlags and depLinkFlags are rustc and linker (clang) flags.
432	depFlags     []string
433	depLinkFlags []string
434
435	// linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker
436	// Both of these are exported and propagate to dependencies.
437	linkDirs    []string
438	linkObjects []string
439
440	// exportedLinkDirs are exported linkDirs for direct rlib dependencies to
441	// cc_library_static dependants of rlibs.
442	// Track them separately from linkDirs so superfluous -L flags don't get emitted.
443	exportedLinkDirs []string
444
445	// Used by bindgen modules which call clang
446	depClangFlags         []string
447	depIncludePaths       android.Paths
448	depGeneratedHeaders   android.Paths
449	depSystemIncludePaths android.Paths
450
451	CrtBegin android.Paths
452	CrtEnd   android.Paths
453
454	// Paths to generated source files
455	SrcDeps          android.Paths
456	srcProviderFiles android.Paths
457
458	directImplementationDeps     android.Paths
459	transitiveImplementationDeps []depset.DepSet[android.Path]
460}
461
462type RustLibraries []RustLibrary
463
464type RustLibrary struct {
465	Path      android.Path
466	CrateName string
467}
468
469type exportedFlagsProducer interface {
470	exportLinkDirs(...string)
471	exportLinkObjects(...string)
472}
473
474type xref interface {
475	XrefRustFiles() android.Paths
476}
477
478type flagExporter struct {
479	linkDirs    []string
480	ccLinkDirs  []string
481	linkObjects []string
482}
483
484func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
485	flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
486}
487
488func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
489	flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
490}
491
492func (flagExporter *flagExporter) setProvider(ctx ModuleContext) {
493	android.SetProvider(ctx, FlagExporterInfoProvider, FlagExporterInfo{
494		LinkDirs:    flagExporter.linkDirs,
495		LinkObjects: flagExporter.linkObjects,
496	})
497}
498
499var _ exportedFlagsProducer = (*flagExporter)(nil)
500
501func NewFlagExporter() *flagExporter {
502	return &flagExporter{}
503}
504
505type FlagExporterInfo struct {
506	Flags       []string
507	LinkDirs    []string // TODO: this should be android.Paths
508	LinkObjects []string // TODO: this should be android.Paths
509}
510
511var FlagExporterInfoProvider = blueprint.NewProvider[FlagExporterInfo]()
512
513func (mod *Module) isCoverageVariant() bool {
514	return mod.coverage.Properties.IsCoverageVariant
515}
516
517var _ cc.Coverage = (*Module)(nil)
518
519func (mod *Module) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool {
520	return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant
521}
522
523func (mod *Module) VndkVersion() string {
524	return mod.Properties.VndkVersion
525}
526
527func (mod *Module) ExportedCrateLinkDirs() []string {
528	return mod.exportedLinkDirs
529}
530
531func (mod *Module) PreventInstall() bool {
532	return mod.Properties.PreventInstall
533}
534
535func (mod *Module) MarkAsCoverageVariant(coverage bool) {
536	mod.coverage.Properties.IsCoverageVariant = coverage
537}
538
539func (mod *Module) EnableCoverageIfNeeded() {
540	mod.coverage.Properties.CoverageEnabled = mod.coverage.Properties.NeedCoverageBuild
541}
542
543func defaultsFactory() android.Module {
544	return DefaultsFactory()
545}
546
547type Defaults struct {
548	android.ModuleBase
549	android.DefaultsModuleBase
550}
551
552func DefaultsFactory(props ...interface{}) android.Module {
553	module := &Defaults{}
554
555	module.AddProperties(props...)
556	module.AddProperties(
557		&BaseProperties{},
558		&cc.AfdoProperties{},
559		&cc.VendorProperties{},
560		&BenchmarkProperties{},
561		&BindgenProperties{},
562		&BaseCompilerProperties{},
563		&BinaryCompilerProperties{},
564		&LibraryCompilerProperties{},
565		&ProcMacroCompilerProperties{},
566		&PrebuiltProperties{},
567		&SourceProviderProperties{},
568		&TestProperties{},
569		&cc.CoverageProperties{},
570		&cc.RustBindgenClangProperties{},
571		&ClippyProperties{},
572		&SanitizeProperties{},
573		&fuzz.FuzzProperties{},
574	)
575
576	android.InitDefaultsModule(module)
577	return module
578}
579
580func (mod *Module) CrateName() string {
581	return mod.compiler.crateName()
582}
583
584func (mod *Module) CcLibrary() bool {
585	if mod.compiler != nil {
586		if _, ok := mod.compiler.(libraryInterface); ok {
587			return true
588		}
589	}
590	return false
591}
592
593func (mod *Module) CcLibraryInterface() bool {
594	if mod.compiler != nil {
595		// use build{Static,Shared}() instead of {static,shared}() here because this might be called before
596		// VariantIs{Static,Shared} is set.
597		if lib, ok := mod.compiler.(libraryInterface); ok && (lib.buildShared() || lib.buildStatic()) {
598			return true
599		}
600	}
601	return false
602}
603
604func (mod *Module) RustLibraryInterface() bool {
605	if mod.compiler != nil {
606		if _, ok := mod.compiler.(libraryInterface); ok {
607			return true
608		}
609	}
610	return false
611}
612
613func (mod *Module) IsFuzzModule() bool {
614	if _, ok := mod.compiler.(*fuzzDecorator); ok {
615		return true
616	}
617	return false
618}
619
620func (mod *Module) FuzzModuleStruct() fuzz.FuzzModule {
621	return mod.FuzzModule
622}
623
624func (mod *Module) FuzzPackagedModule() fuzz.FuzzPackagedModule {
625	if fuzzer, ok := mod.compiler.(*fuzzDecorator); ok {
626		return fuzzer.fuzzPackagedModule
627	}
628	panic(fmt.Errorf("FuzzPackagedModule called on non-fuzz module: %q", mod.BaseModuleName()))
629}
630
631func (mod *Module) FuzzSharedLibraries() android.RuleBuilderInstalls {
632	if fuzzer, ok := mod.compiler.(*fuzzDecorator); ok {
633		return fuzzer.sharedLibraries
634	}
635	panic(fmt.Errorf("FuzzSharedLibraries called on non-fuzz module: %q", mod.BaseModuleName()))
636}
637
638func (mod *Module) UnstrippedOutputFile() android.Path {
639	if mod.compiler != nil {
640		return mod.compiler.unstrippedOutputFilePath()
641	}
642	return nil
643}
644
645func (mod *Module) SetStatic() {
646	if mod.compiler != nil {
647		if library, ok := mod.compiler.(libraryInterface); ok {
648			library.setStatic()
649			return
650		}
651	}
652	panic(fmt.Errorf("SetStatic called on non-library module: %q", mod.BaseModuleName()))
653}
654
655func (mod *Module) SetShared() {
656	if mod.compiler != nil {
657		if library, ok := mod.compiler.(libraryInterface); ok {
658			library.setShared()
659			return
660		}
661	}
662	panic(fmt.Errorf("SetShared called on non-library module: %q", mod.BaseModuleName()))
663}
664
665func (mod *Module) BuildStaticVariant() bool {
666	if mod.compiler != nil {
667		if library, ok := mod.compiler.(libraryInterface); ok {
668			return library.buildStatic()
669		}
670	}
671	panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName()))
672}
673
674func (mod *Module) BuildRlibVariant() bool {
675	if mod.compiler != nil {
676		if library, ok := mod.compiler.(libraryInterface); ok {
677			return library.buildRlib()
678		}
679	}
680	panic(fmt.Errorf("BuildRlibVariant called on non-library module: %q", mod.BaseModuleName()))
681}
682
683func (mod *Module) IsRustFFI() bool {
684	if mod.compiler != nil {
685		if library, ok := mod.compiler.(libraryInterface); ok {
686			return library.isFFILibrary()
687		}
688	}
689	return false
690}
691
692func (mod *Module) BuildSharedVariant() bool {
693	if mod.compiler != nil {
694		if library, ok := mod.compiler.(libraryInterface); ok {
695			return library.buildShared()
696		}
697	}
698	panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName()))
699}
700
701func (mod *Module) Module() android.Module {
702	return mod
703}
704
705func (mod *Module) OutputFile() android.OptionalPath {
706	return mod.outputFile
707}
708
709func (mod *Module) CoverageFiles() android.Paths {
710	if mod.compiler != nil {
711		return android.Paths{}
712	}
713	panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName()))
714}
715
716// Rust does not produce gcno files, and therefore does not produce a coverage archive.
717func (mod *Module) CoverageOutputFile() android.OptionalPath {
718	return android.OptionalPath{}
719}
720
721func (mod *Module) IsNdk(config android.Config) bool {
722	return false
723}
724
725func (mod *Module) HasStubsVariants() bool {
726	return false
727}
728
729func (mod *Module) IsStubs() bool {
730	return false
731}
732
733func (mod *Module) installable(apexInfo android.ApexInfo) bool {
734	if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) {
735		return false
736	}
737
738	// The apex variant is not installable because it is included in the APEX and won't appear
739	// in the system partition as a standalone file.
740	if !apexInfo.IsForPlatform() {
741		return false
742	}
743
744	return mod.OutputFile().Valid() && !mod.Properties.PreventInstall
745}
746
747func (ctx moduleContext) apexVariationName() string {
748	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
749	return apexInfo.ApexVariationName
750}
751
752var _ cc.LinkableInterface = (*Module)(nil)
753
754func (mod *Module) Init() android.Module {
755	mod.AddProperties(&mod.Properties)
756	mod.AddProperties(&mod.VendorProperties)
757
758	if mod.afdo != nil {
759		mod.AddProperties(mod.afdo.props()...)
760	}
761	if mod.compiler != nil {
762		mod.AddProperties(mod.compiler.compilerProps()...)
763	}
764	if mod.coverage != nil {
765		mod.AddProperties(mod.coverage.props()...)
766	}
767	if mod.clippy != nil {
768		mod.AddProperties(mod.clippy.props()...)
769	}
770	if mod.sourceProvider != nil {
771		mod.AddProperties(mod.sourceProvider.SourceProviderProps()...)
772	}
773	if mod.sanitize != nil {
774		mod.AddProperties(mod.sanitize.props()...)
775	}
776
777	android.InitAndroidArchModule(mod, mod.hod, mod.multilib)
778	android.InitApexModule(mod)
779
780	android.InitDefaultableModule(mod)
781	return mod
782}
783
784func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
785	return &Module{
786		hod:      hod,
787		multilib: multilib,
788	}
789}
790func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
791	module := newBaseModule(hod, multilib)
792	module.afdo = &afdo{}
793	module.coverage = &coverage{}
794	module.clippy = &clippy{}
795	module.sanitize = &sanitize{}
796	return module
797}
798
799type ModuleContext interface {
800	android.ModuleContext
801	ModuleContextIntf
802}
803
804type BaseModuleContext interface {
805	android.BaseModuleContext
806	ModuleContextIntf
807}
808
809type DepsContext interface {
810	android.BottomUpMutatorContext
811	ModuleContextIntf
812}
813
814type ModuleContextIntf interface {
815	RustModule() *Module
816	toolchain() config.Toolchain
817}
818
819type depsContext struct {
820	android.BottomUpMutatorContext
821}
822
823type moduleContext struct {
824	android.ModuleContext
825}
826
827type baseModuleContext struct {
828	android.BaseModuleContext
829}
830
831func (ctx *moduleContext) RustModule() *Module {
832	return ctx.Module().(*Module)
833}
834
835func (ctx *moduleContext) toolchain() config.Toolchain {
836	return ctx.RustModule().toolchain(ctx)
837}
838
839func (ctx *depsContext) RustModule() *Module {
840	return ctx.Module().(*Module)
841}
842
843func (ctx *depsContext) toolchain() config.Toolchain {
844	return ctx.RustModule().toolchain(ctx)
845}
846
847func (ctx *baseModuleContext) RustModule() *Module {
848	return ctx.Module().(*Module)
849}
850
851func (ctx *baseModuleContext) toolchain() config.Toolchain {
852	return ctx.RustModule().toolchain(ctx)
853}
854
855func (mod *Module) nativeCoverage() bool {
856	// Bug: http://b/137883967 - native-bridge modules do not currently work with coverage
857	if mod.Target().NativeBridge == android.NativeBridgeEnabled {
858		return false
859	}
860	return mod.compiler != nil && mod.compiler.nativeCoverage()
861}
862
863func (mod *Module) EverInstallable() bool {
864	return mod.compiler != nil &&
865		// Check to see whether the module is actually ever installable.
866		mod.compiler.everInstallable()
867}
868
869func (mod *Module) Installable() *bool {
870	return mod.Properties.Installable
871}
872
873func (mod *Module) ProcMacro() bool {
874	if pm, ok := mod.compiler.(procMacroInterface); ok {
875		return pm.ProcMacro()
876	}
877	return false
878}
879
880func (mod *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain {
881	if mod.cachedToolchain == nil {
882		mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
883	}
884	return mod.cachedToolchain
885}
886
887func (mod *Module) ccToolchain(ctx android.BaseModuleContext) cc_config.Toolchain {
888	return cc_config.FindToolchain(ctx.Os(), ctx.Arch())
889}
890
891func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
892}
893
894func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
895	ctx := &moduleContext{
896		ModuleContext: actx,
897	}
898
899	apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider)
900	if !apexInfo.IsForPlatform() {
901		mod.hideApexVariantFromMake = true
902	}
903
904	toolchain := mod.toolchain(ctx)
905	mod.makeLinkType = cc.GetMakeLinkType(actx, mod)
906
907	mod.Properties.SubName = cc.GetSubnameProperty(actx, mod)
908
909	if !toolchain.Supported() {
910		// This toolchain's unsupported, there's nothing to do for this mod.
911		return
912	}
913
914	deps := mod.depsToPaths(ctx)
915	// Export linkDirs for CC rust generatedlibs
916	mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.exportedLinkDirs...)
917	mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.linkDirs...)
918
919	flags := Flags{
920		Toolchain: toolchain,
921	}
922
923	// Calculate rustc flags
924	if mod.afdo != nil {
925		flags, deps = mod.afdo.flags(actx, flags, deps)
926	}
927	if mod.compiler != nil {
928		flags = mod.compiler.compilerFlags(ctx, flags)
929		flags = mod.compiler.cfgFlags(ctx, flags)
930		flags = mod.compiler.featureFlags(ctx, mod, flags)
931	}
932	if mod.coverage != nil {
933		flags, deps = mod.coverage.flags(ctx, flags, deps)
934	}
935	if mod.clippy != nil {
936		flags, deps = mod.clippy.flags(ctx, flags, deps)
937	}
938	if mod.sanitize != nil {
939		flags, deps = mod.sanitize.flags(ctx, flags, deps)
940	}
941
942	// SourceProvider needs to call GenerateSource() before compiler calls
943	// compile() so it can provide the source. A SourceProvider has
944	// multiple variants (e.g. source, rlib, dylib). Only the "source"
945	// variant is responsible for effectively generating the source. The
946	// remaining variants relies on the "source" variant output.
947	if mod.sourceProvider != nil {
948		if mod.compiler.(libraryInterface).source() {
949			mod.sourceProvider.GenerateSource(ctx, deps)
950			mod.sourceProvider.setSubName(ctx.ModuleSubDir())
951		} else {
952			sourceMod := actx.GetDirectDepWithTag(mod.Name(), sourceDepTag)
953			sourceLib := sourceMod.(*Module).compiler.(*libraryDecorator)
954			mod.sourceProvider.setOutputFiles(sourceLib.sourceProvider.Srcs())
955		}
956		ctx.CheckbuildFile(mod.sourceProvider.Srcs()...)
957		android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: mod.sourceProvider.Srcs().Strings()})
958	}
959
960	if mod.compiler != nil && !mod.compiler.Disabled() {
961		mod.compiler.initialize(ctx)
962		buildOutput := mod.compiler.compile(ctx, flags, deps)
963		if ctx.Failed() {
964			return
965		}
966		mod.outputFile = android.OptionalPathForPath(buildOutput.outputFile)
967		ctx.CheckbuildFile(buildOutput.outputFile)
968		if buildOutput.kytheFile != nil {
969			mod.kytheFiles = append(mod.kytheFiles, buildOutput.kytheFile)
970		}
971		bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), android.OptionalPathForPath(mod.compiler.unstrippedOutputFilePath()))
972
973		mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps)
974
975		apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider)
976		if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) && !mod.ProcMacro() {
977			// If the module has been specifically configure to not be installed then
978			// hide from make as otherwise it will break when running inside make as the
979			// output path to install will not be specified. Not all uninstallable
980			// modules can be hidden from make as some are needed for resolving make
981			// side dependencies. In particular, proc-macros need to be captured in the
982			// host snapshot.
983			mod.HideFromMake()
984			mod.SkipInstall()
985		} else if !mod.installable(apexInfo) {
986			mod.SkipInstall()
987		}
988
989		// Still call install though, the installs will be stored as PackageSpecs to allow
990		// using the outputs in a genrule.
991		if mod.OutputFile().Valid() {
992			mod.compiler.install(ctx)
993			if ctx.Failed() {
994				return
995			}
996			// Export your own directory as a linkDir
997			mod.exportedLinkDirs = append(mod.exportedLinkDirs, linkPathFromFilePath(mod.OutputFile().Path()))
998
999		}
1000
1001		android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{
1002			ImplementationDeps: depset.New(depset.PREORDER, deps.directImplementationDeps, deps.transitiveImplementationDeps),
1003		})
1004
1005		ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
1006	}
1007
1008	android.SetProvider(ctx, cc.LinkableInfoKey, cc.LinkableInfo{
1009		StaticExecutable: mod.StaticExecutable(),
1010	})
1011
1012	mod.setOutputFiles(ctx)
1013
1014	buildComplianceMetadataInfo(ctx, mod, deps)
1015}
1016
1017func (mod *Module) setOutputFiles(ctx ModuleContext) {
1018	if mod.sourceProvider != nil && (mod.compiler == nil || mod.compiler.Disabled()) {
1019		ctx.SetOutputFiles(mod.sourceProvider.Srcs(), "")
1020	} else if mod.OutputFile().Valid() {
1021		ctx.SetOutputFiles(android.Paths{mod.OutputFile().Path()}, "")
1022	} else {
1023		ctx.SetOutputFiles(android.Paths{}, "")
1024	}
1025	if mod.compiler != nil {
1026		ctx.SetOutputFiles(android.PathsIfNonNil(mod.compiler.unstrippedOutputFilePath()), "unstripped")
1027	}
1028}
1029
1030func buildComplianceMetadataInfo(ctx *moduleContext, mod *Module, deps PathDeps) {
1031	// Dump metadata that can not be done in android/compliance-metadata.go
1032	metadataInfo := ctx.ComplianceMetadataInfo()
1033	metadataInfo.SetStringValue(android.ComplianceMetadataProp.IS_STATIC_LIB, strconv.FormatBool(mod.Static()))
1034	metadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, mod.outputFile.String())
1035
1036	// Static libs
1037	staticDeps := ctx.GetDirectDepsWithTag(rlibDepTag)
1038	staticDepNames := make([]string, 0, len(staticDeps))
1039	for _, dep := range staticDeps {
1040		staticDepNames = append(staticDepNames, dep.Name())
1041	}
1042	ccStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(false))
1043	for _, dep := range ccStaticDeps {
1044		staticDepNames = append(staticDepNames, dep.Name())
1045	}
1046
1047	staticDepPaths := make([]string, 0, len(deps.StaticLibs)+len(deps.RLibs))
1048	// C static libraries
1049	for _, dep := range deps.StaticLibs {
1050		staticDepPaths = append(staticDepPaths, dep.String())
1051	}
1052	// Rust static libraries
1053	for _, dep := range deps.RLibs {
1054		staticDepPaths = append(staticDepPaths, dep.Path.String())
1055	}
1056	metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames))
1057	metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths))
1058
1059	// C Whole static libs
1060	ccWholeStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(true))
1061	wholeStaticDepNames := make([]string, 0, len(ccWholeStaticDeps))
1062	for _, dep := range ccStaticDeps {
1063		wholeStaticDepNames = append(wholeStaticDepNames, dep.Name())
1064	}
1065	metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames))
1066}
1067
1068func (mod *Module) deps(ctx DepsContext) Deps {
1069	deps := Deps{}
1070
1071	if mod.compiler != nil {
1072		deps = mod.compiler.compilerDeps(ctx, deps)
1073	}
1074	if mod.sourceProvider != nil {
1075		deps = mod.sourceProvider.SourceProviderDeps(ctx, deps)
1076	}
1077
1078	if mod.coverage != nil {
1079		deps = mod.coverage.deps(ctx, deps)
1080	}
1081
1082	if mod.sanitize != nil {
1083		deps = mod.sanitize.deps(ctx, deps)
1084	}
1085
1086	deps.Rlibs = android.LastUniqueStrings(deps.Rlibs)
1087	deps.Dylibs = android.LastUniqueStrings(deps.Dylibs)
1088	deps.Rustlibs = android.LastUniqueStrings(deps.Rustlibs)
1089	deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros)
1090	deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
1091	deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
1092	deps.Stdlibs = android.LastUniqueStrings(deps.Stdlibs)
1093	deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs)
1094	return deps
1095
1096}
1097
1098type dependencyTag struct {
1099	blueprint.BaseDependencyTag
1100	name      string
1101	library   bool
1102	procMacro bool
1103	dynamic   bool
1104}
1105
1106// InstallDepNeeded returns true for rlibs, dylibs, and proc macros so that they or their transitive
1107// dependencies (especially C/C++ shared libs) are installed as dependencies of a rust binary.
1108func (d dependencyTag) InstallDepNeeded() bool {
1109	return d.library || d.procMacro
1110}
1111
1112var _ android.InstallNeededDependencyTag = dependencyTag{}
1113
1114func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
1115	if d.library && d.dynamic {
1116		return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
1117	}
1118	return nil
1119}
1120
1121func (d dependencyTag) PropagateAconfigValidation() bool {
1122	return d == rlibDepTag || d == sourceDepTag
1123}
1124
1125var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{}
1126
1127var _ android.LicenseAnnotationsDependencyTag = dependencyTag{}
1128
1129var (
1130	customBindgenDepTag = dependencyTag{name: "customBindgenTag"}
1131	rlibDepTag          = dependencyTag{name: "rlibTag", library: true}
1132	dylibDepTag         = dependencyTag{name: "dylib", library: true, dynamic: true}
1133	procMacroDepTag     = dependencyTag{name: "procMacro", procMacro: true}
1134	sourceDepTag        = dependencyTag{name: "source"}
1135	dataLibDepTag       = dependencyTag{name: "data lib"}
1136	dataBinDepTag       = dependencyTag{name: "data bin"}
1137)
1138
1139func IsDylibDepTag(depTag blueprint.DependencyTag) bool {
1140	tag, ok := depTag.(dependencyTag)
1141	return ok && tag == dylibDepTag
1142}
1143
1144func IsRlibDepTag(depTag blueprint.DependencyTag) bool {
1145	tag, ok := depTag.(dependencyTag)
1146	return ok && tag == rlibDepTag
1147}
1148
1149type autoDep struct {
1150	variation string
1151	depTag    dependencyTag
1152}
1153
1154var (
1155	sourceVariation = "source"
1156	rlibVariation   = "rlib"
1157	dylibVariation  = "dylib"
1158	rlibAutoDep     = autoDep{variation: rlibVariation, depTag: rlibDepTag}
1159	dylibAutoDep    = autoDep{variation: dylibVariation, depTag: dylibDepTag}
1160)
1161
1162type autoDeppable interface {
1163	autoDep(ctx android.BottomUpMutatorContext) autoDep
1164}
1165
1166func (mod *Module) begin(ctx BaseModuleContext) {
1167	if mod.coverage != nil {
1168		mod.coverage.begin(ctx)
1169	}
1170	if mod.sanitize != nil {
1171		mod.sanitize.begin(ctx)
1172	}
1173}
1174
1175func (mod *Module) Prebuilt() *android.Prebuilt {
1176	if p, ok := mod.compiler.(rustPrebuilt); ok {
1177		return p.prebuilt()
1178	}
1179	return nil
1180}
1181
1182func (mod *Module) Symlinks() []string {
1183	// TODO update this to return the list of symlinks when Rust supports defining symlinks
1184	return nil
1185}
1186
1187func rustMakeLibName(ctx android.ModuleContext, c cc.LinkableInterface, dep cc.LinkableInterface, depName string) string {
1188	if rustDep, ok := dep.(*Module); ok {
1189		// Use base module name for snapshots when exporting to Makefile.
1190		if snapshotPrebuilt, ok := rustDep.compiler.(cc.SnapshotInterface); ok {
1191			baseName := rustDep.BaseModuleName()
1192			return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix() + rustDep.AndroidMkSuffix()
1193		}
1194	}
1195	return cc.MakeLibName(ctx, c, dep, depName)
1196}
1197
1198func collectIncludedProtos(mod *Module, dep *Module) {
1199	if protoMod, ok := mod.sourceProvider.(*protobufDecorator); ok {
1200		if _, ok := dep.sourceProvider.(*protobufDecorator); ok {
1201			protoMod.additionalCrates = append(protoMod.additionalCrates, dep.CrateName())
1202		}
1203	}
1204}
1205
1206func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
1207	var depPaths PathDeps
1208
1209	directRlibDeps := []*Module{}
1210	directDylibDeps := []*Module{}
1211	directProcMacroDeps := []*Module{}
1212	directSharedLibDeps := []cc.SharedLibraryInfo{}
1213	directStaticLibDeps := [](cc.LinkableInterface){}
1214	directSrcProvidersDeps := []*Module{}
1215	directSrcDeps := [](android.SourceFileProducer){}
1216
1217	// For the dependency from platform to apex, use the latest stubs
1218	mod.apexSdkVersion = android.FutureApiLevel
1219	apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
1220	if !apexInfo.IsForPlatform() {
1221		mod.apexSdkVersion = apexInfo.MinSdkVersion
1222	}
1223
1224	if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
1225		// In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
1226		// so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
1227		// (b/144430859)
1228		mod.apexSdkVersion = android.FutureApiLevel
1229	}
1230
1231	skipModuleList := map[string]bool{}
1232
1233	var transitiveAndroidMkSharedLibs []depset.DepSet[string]
1234	var directAndroidMkSharedLibs []string
1235
1236	ctx.VisitDirectDeps(func(dep android.Module) {
1237		depName := ctx.OtherModuleName(dep)
1238		depTag := ctx.OtherModuleDependencyTag(dep)
1239		if _, exists := skipModuleList[depName]; exists {
1240			return
1241		}
1242
1243		if depTag == android.DarwinUniversalVariantTag {
1244			return
1245		}
1246
1247		if rustDep, ok := dep.(*Module); ok && !rustDep.Static() && !rustDep.Shared() {
1248			//Handle Rust Modules
1249			makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
1250
1251			switch {
1252			case depTag == dylibDepTag:
1253				dylib, ok := rustDep.compiler.(libraryInterface)
1254				if !ok || !dylib.dylib() {
1255					ctx.ModuleErrorf("mod %q not an dylib library", depName)
1256					return
1257				}
1258				directDylibDeps = append(directDylibDeps, rustDep)
1259				mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName)
1260				mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName))
1261
1262				depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
1263				if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
1264					depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
1265				}
1266
1267			case depTag == rlibDepTag:
1268				rlib, ok := rustDep.compiler.(libraryInterface)
1269				if !ok || !rlib.rlib() {
1270					ctx.ModuleErrorf("mod %q not an rlib library", makeLibName)
1271					return
1272				}
1273				directRlibDeps = append(directRlibDeps, rustDep)
1274				mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
1275				mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName))
1276
1277				// rust_ffi rlibs may export include dirs, so collect those here.
1278				exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
1279				depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
1280				depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path()))
1281
1282				// rlibs are not installed, so don't add the output file to directImplementationDeps
1283				if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
1284					depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
1285				}
1286
1287			case depTag == procMacroDepTag:
1288				directProcMacroDeps = append(directProcMacroDeps, rustDep)
1289				mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
1290				// proc_macro link dirs need to be exported, so collect those here.
1291				depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path()))
1292
1293			case depTag == sourceDepTag:
1294				if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
1295					collectIncludedProtos(mod, rustDep)
1296				}
1297			case cc.IsStaticDepTag(depTag):
1298				// Rust FFI rlibs should not be declared in a Rust modules
1299				// "static_libs" list as we can't handle them properly at the
1300				// moment (for example, they only produce an rlib-std variant).
1301				// Instead, a normal rust_library variant should be used.
1302				ctx.PropertyErrorf("static_libs",
1303					"found '%s' in static_libs; use a rust_library module in rustlibs instead of a rust_ffi module in static_libs",
1304					depName)
1305
1306			}
1307
1308			transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs)
1309
1310			if android.IsSourceDepTagWithOutputTag(depTag, "") {
1311				// Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
1312				// OS/Arch variant is used.
1313				var helper string
1314				if ctx.Host() {
1315					helper = "missing 'host_supported'?"
1316				} else {
1317					helper = "device module defined?"
1318				}
1319
1320				if dep.Target().Os != ctx.Os() {
1321					ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper)
1322					return
1323				} else if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
1324					ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper)
1325					return
1326				}
1327				directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
1328			}
1329
1330			exportedInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider)
1331			//Append the dependencies exportedDirs, except for proc-macros which target a different arch/OS
1332			if depTag != procMacroDepTag {
1333				depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
1334				depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
1335				depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
1336			}
1337
1338			if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
1339				linkFile := rustDep.UnstrippedOutputFile()
1340				linkDir := linkPathFromFilePath(linkFile)
1341				if lib, ok := mod.compiler.(exportedFlagsProducer); ok {
1342					lib.exportLinkDirs(linkDir)
1343				}
1344			}
1345
1346			if depTag == sourceDepTag {
1347				if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() {
1348					if _, ok := rustDep.sourceProvider.(*protobufDecorator); ok {
1349						exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
1350						depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
1351					}
1352				}
1353			}
1354		} else if ccDep, ok := dep.(cc.LinkableInterface); ok {
1355			//Handle C dependencies
1356			makeLibName := cc.MakeLibName(ctx, mod, ccDep, depName)
1357			if _, ok := ccDep.(*Module); !ok {
1358				if ccDep.Module().Target().Os != ctx.Os() {
1359					ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
1360					return
1361				}
1362				if ccDep.Module().Target().Arch.ArchType != ctx.Arch().ArchType {
1363					ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
1364					return
1365				}
1366			}
1367			linkObject := ccDep.OutputFile()
1368			if !linkObject.Valid() {
1369				if !ctx.Config().AllowMissingDependencies() {
1370					ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
1371				} else {
1372					ctx.AddMissingDependencies([]string{depName})
1373				}
1374				return
1375			}
1376
1377			linkPath := linkPathFromFilePath(linkObject.Path())
1378
1379			exportDep := false
1380			switch {
1381			case cc.IsStaticDepTag(depTag):
1382				if cc.IsWholeStaticLib(depTag) {
1383					// rustc will bundle static libraries when they're passed with "-lstatic=<lib>". This will fail
1384					// if the library is not prefixed by "lib".
1385					if mod.Binary() {
1386						// Binaries may sometimes need to link whole static libraries that don't start with 'lib'.
1387						// Since binaries don't need to 'rebundle' these like libraries and only use these for the
1388						// final linkage, pass the args directly to the linker to handle these cases.
1389						depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", linkObject.Path().String(), "-Wl,--no-whole-archive"}...)
1390					} else if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
1391						depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
1392					} else {
1393						ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName())
1394					}
1395				}
1396
1397				// Add this to linkObjects to pass the library directly to the linker as well. This propagates
1398				// to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant.
1399				depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
1400				depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
1401
1402				exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
1403				depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
1404				depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
1405				depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
1406				depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
1407				directStaticLibDeps = append(directStaticLibDeps, ccDep)
1408
1409				// Record baseLibName for snapshots.
1410				mod.Properties.SnapshotStaticLibs = append(mod.Properties.SnapshotStaticLibs, cc.BaseLibName(depName))
1411
1412				mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, makeLibName)
1413			case cc.IsSharedDepTag(depTag):
1414				// For the shared lib dependencies, we may link to the stub variant
1415				// of the dependency depending on the context (e.g. if this
1416				// dependency crosses the APEX boundaries).
1417				sharedLibraryInfo, exportedInfo := cc.ChooseStubOrImpl(ctx, dep)
1418
1419				if !sharedLibraryInfo.IsStubs {
1420					depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
1421					if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
1422						depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
1423					}
1424				}
1425
1426				// Re-get linkObject as ChooseStubOrImpl actually tells us which
1427				// object (either from stub or non-stub) to use.
1428				linkObject = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary)
1429				if !linkObject.Valid() {
1430					if !ctx.Config().AllowMissingDependencies() {
1431						ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
1432					} else {
1433						ctx.AddMissingDependencies([]string{depName})
1434					}
1435					return
1436				}
1437				linkPath = linkPathFromFilePath(linkObject.Path())
1438
1439				depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
1440				depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
1441				depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
1442				depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
1443				depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
1444				depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
1445				directSharedLibDeps = append(directSharedLibDeps, sharedLibraryInfo)
1446
1447				// Record baseLibName for snapshots.
1448				mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName))
1449
1450				directAndroidMkSharedLibs = append(directAndroidMkSharedLibs, makeLibName)
1451				exportDep = true
1452			case cc.IsHeaderDepTag(depTag):
1453				exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
1454				depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
1455				depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
1456				depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
1457				mod.Properties.AndroidMkHeaderLibs = append(mod.Properties.AndroidMkHeaderLibs, makeLibName)
1458			case depTag == cc.CrtBeginDepTag:
1459				depPaths.CrtBegin = append(depPaths.CrtBegin, linkObject.Path())
1460			case depTag == cc.CrtEndDepTag:
1461				depPaths.CrtEnd = append(depPaths.CrtEnd, linkObject.Path())
1462			}
1463
1464			// Make sure these dependencies are propagated
1465			if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep {
1466				lib.exportLinkDirs(linkPath)
1467				lib.exportLinkObjects(linkObject.String())
1468			}
1469		} else {
1470			switch {
1471			case depTag == cc.CrtBeginDepTag:
1472				depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, ""))
1473			case depTag == cc.CrtEndDepTag:
1474				depPaths.CrtEnd = append(depPaths.CrtEnd, android.OutputFileForModule(ctx, dep, ""))
1475			}
1476		}
1477
1478		if srcDep, ok := dep.(android.SourceFileProducer); ok {
1479			if android.IsSourceDepTagWithOutputTag(depTag, "") {
1480				// These are usually genrules which don't have per-target variants.
1481				directSrcDeps = append(directSrcDeps, srcDep)
1482			}
1483		}
1484	})
1485
1486	mod.transitiveAndroidMkSharedLibs = depset.New[string](depset.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
1487
1488	var rlibDepFiles RustLibraries
1489	aliases := mod.compiler.Aliases()
1490	for _, dep := range directRlibDeps {
1491		crateName := dep.CrateName()
1492		if alias, aliased := aliases[crateName]; aliased {
1493			crateName = alias
1494		}
1495		rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
1496	}
1497	var dylibDepFiles RustLibraries
1498	for _, dep := range directDylibDeps {
1499		crateName := dep.CrateName()
1500		if alias, aliased := aliases[crateName]; aliased {
1501			crateName = alias
1502		}
1503		dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
1504	}
1505	var procMacroDepFiles RustLibraries
1506	for _, dep := range directProcMacroDeps {
1507		crateName := dep.CrateName()
1508		if alias, aliased := aliases[crateName]; aliased {
1509			crateName = alias
1510		}
1511		procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
1512	}
1513
1514	var staticLibDepFiles android.Paths
1515	for _, dep := range directStaticLibDeps {
1516		staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path())
1517	}
1518
1519	var sharedLibFiles android.Paths
1520	var sharedLibDepFiles android.Paths
1521	for _, dep := range directSharedLibDeps {
1522		sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary)
1523		if dep.TableOfContents.Valid() {
1524			sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path())
1525		} else {
1526			sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary)
1527		}
1528	}
1529
1530	var srcProviderDepFiles android.Paths
1531	for _, dep := range directSrcProvidersDeps {
1532		srcs := android.OutputFilesForModule(ctx, dep, "")
1533		srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
1534	}
1535	for _, dep := range directSrcDeps {
1536		srcs := dep.Srcs()
1537		srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
1538	}
1539
1540	depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
1541	depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
1542	depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibFiles...)
1543	depPaths.SharedLibDeps = append(depPaths.SharedLibDeps, sharedLibDepFiles...)
1544	depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...)
1545	depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
1546	depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
1547
1548	// Dedup exported flags from dependencies
1549	depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
1550	depPaths.linkObjects = android.FirstUniqueStrings(depPaths.linkObjects)
1551	depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
1552	depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
1553	depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
1554	depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths)
1555
1556	return depPaths
1557}
1558
1559func (mod *Module) InstallInData() bool {
1560	if mod.compiler == nil {
1561		return false
1562	}
1563	return mod.compiler.inData()
1564}
1565
1566func (mod *Module) InstallInRamdisk() bool {
1567	return mod.InRamdisk()
1568}
1569
1570func (mod *Module) InstallInVendorRamdisk() bool {
1571	return mod.InVendorRamdisk()
1572}
1573
1574func (mod *Module) InstallInRecovery() bool {
1575	return mod.InRecovery()
1576}
1577
1578func linkPathFromFilePath(filepath android.Path) string {
1579	return strings.Split(filepath.String(), filepath.Base())[0]
1580}
1581
1582// usePublicApi returns true if the rust variant should link against NDK (publicapi)
1583func (r *Module) usePublicApi() bool {
1584	return r.Device() && r.UseSdk()
1585}
1586
1587// useVendorApi returns true if the rust variant should link against LLNDK (vendorapi)
1588func (r *Module) useVendorApi() bool {
1589	return r.Device() && (r.InVendor() || r.InProduct())
1590}
1591
1592func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
1593	ctx := &depsContext{
1594		BottomUpMutatorContext: actx,
1595	}
1596
1597	deps := mod.deps(ctx)
1598	var commonDepVariations []blueprint.Variation
1599
1600	if ctx.Os() == android.Android {
1601		deps.SharedLibs, _ = cc.FilterNdkLibs(mod, ctx.Config(), deps.SharedLibs)
1602	}
1603
1604	stdLinkage := "dylib-std"
1605	if mod.compiler.stdLinkage(ctx) == RlibLinkage {
1606		stdLinkage = "rlib-std"
1607	}
1608
1609	rlibDepVariations := commonDepVariations
1610
1611	if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
1612		rlibDepVariations = append(rlibDepVariations,
1613			blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
1614	}
1615
1616	// rlibs
1617	rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation})
1618	for _, lib := range deps.Rlibs {
1619		depTag := rlibDepTag
1620		actx.AddVariationDependencies(rlibDepVariations, depTag, lib)
1621	}
1622
1623	// dylibs
1624	dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation})
1625
1626	for _, lib := range deps.Dylibs {
1627		actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib)
1628	}
1629
1630	// rustlibs
1631	if deps.Rustlibs != nil {
1632		if !mod.compiler.Disabled() {
1633			for _, lib := range deps.Rustlibs {
1634				autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
1635				if autoDep.depTag == rlibDepTag {
1636					// Handle the rlib deptag case
1637					actx.AddVariationDependencies(rlibDepVariations, rlibDepTag, lib)
1638
1639				} else {
1640					// autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however.
1641					// Check for the existence of the dylib deptag variant. Select it if available,
1642					// otherwise select the rlib variant.
1643					autoDepVariations := append(commonDepVariations,
1644						blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
1645					if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) {
1646						actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib)
1647
1648					} else {
1649						// If there's no dylib dependency available, try to add the rlib dependency instead.
1650						actx.AddVariationDependencies(rlibDepVariations, rlibDepTag, lib)
1651
1652					}
1653				}
1654			}
1655		} else if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
1656			for _, lib := range deps.Rustlibs {
1657				srcProviderVariations := append(commonDepVariations,
1658					blueprint.Variation{Mutator: "rust_libraries", Variation: sourceVariation})
1659
1660				// Only add rustlib dependencies if they're source providers themselves.
1661				// This is used to track which crate names need to be added to the source generated
1662				// in the rust_protobuf mod.rs.
1663				if actx.OtherModuleDependencyVariantExists(srcProviderVariations, lib) {
1664					actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib)
1665				}
1666			}
1667		}
1668	}
1669
1670	// stdlibs
1671	if deps.Stdlibs != nil {
1672		if mod.compiler.stdLinkage(ctx) == RlibLinkage {
1673			for _, lib := range deps.Stdlibs {
1674				actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
1675					rlibDepTag, lib)
1676			}
1677		} else {
1678			for _, lib := range deps.Stdlibs {
1679				actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib)
1680
1681			}
1682		}
1683	}
1684
1685	for _, lib := range deps.SharedLibs {
1686		depTag := cc.SharedDepTag()
1687		name, version := cc.StubsLibNameAndVersion(lib)
1688
1689		variations := []blueprint.Variation{
1690			{Mutator: "link", Variation: "shared"},
1691		}
1692		cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
1693	}
1694
1695	for _, lib := range deps.WholeStaticLibs {
1696		depTag := cc.StaticDepTag(true)
1697
1698		actx.AddVariationDependencies([]blueprint.Variation{
1699			{Mutator: "link", Variation: "static"},
1700		}, depTag, lib)
1701	}
1702
1703	for _, lib := range deps.StaticLibs {
1704		depTag := cc.StaticDepTag(false)
1705
1706		actx.AddVariationDependencies([]blueprint.Variation{
1707			{Mutator: "link", Variation: "static"},
1708		}, depTag, lib)
1709	}
1710
1711	actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...)
1712
1713	crtVariations := cc.GetCrtVariations(ctx, mod)
1714	for _, crt := range deps.CrtBegin {
1715		actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, crt)
1716	}
1717	for _, crt := range deps.CrtEnd {
1718		actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, crt)
1719	}
1720
1721	if mod.sourceProvider != nil {
1722		if bindgen, ok := mod.sourceProvider.(*bindgenDecorator); ok &&
1723			bindgen.Properties.Custom_bindgen != "" {
1724			actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), customBindgenDepTag,
1725				bindgen.Properties.Custom_bindgen)
1726		}
1727	}
1728
1729	actx.AddVariationDependencies([]blueprint.Variation{
1730		{Mutator: "link", Variation: "shared"},
1731	}, dataLibDepTag, deps.DataLibs...)
1732
1733	actx.AddVariationDependencies(nil, dataBinDepTag, deps.DataBins...)
1734
1735	// proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy.
1736	actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...)
1737
1738	mod.afdo.addDep(ctx, actx)
1739}
1740
1741func BeginMutator(ctx android.BottomUpMutatorContext) {
1742	if mod, ok := ctx.Module().(*Module); ok && mod.Enabled(ctx) {
1743		mod.beginMutator(ctx)
1744	}
1745}
1746
1747func (mod *Module) beginMutator(actx android.BottomUpMutatorContext) {
1748	ctx := &baseModuleContext{
1749		BaseModuleContext: actx,
1750	}
1751
1752	mod.begin(ctx)
1753}
1754
1755func (mod *Module) Name() string {
1756	name := mod.ModuleBase.Name()
1757	if p, ok := mod.compiler.(interface {
1758		Name(string) string
1759	}); ok {
1760		name = p.Name(name)
1761	}
1762	return name
1763}
1764
1765func (mod *Module) disableClippy() {
1766	if mod.clippy != nil {
1767		mod.clippy.Properties.Clippy_lints = proptools.StringPtr("none")
1768	}
1769}
1770
1771var _ android.HostToolProvider = (*Module)(nil)
1772
1773func (mod *Module) HostToolPath() android.OptionalPath {
1774	if !mod.Host() {
1775		return android.OptionalPath{}
1776	}
1777	if binary, ok := mod.compiler.(*binaryDecorator); ok {
1778		return android.OptionalPathForPath(binary.baseCompiler.path)
1779	} else if pm, ok := mod.compiler.(*procMacroDecorator); ok {
1780		// Even though proc-macros aren't strictly "tools", since they target the compiler
1781		// and act as compiler plugins, we treat them similarly.
1782		return android.OptionalPathForPath(pm.baseCompiler.path)
1783	}
1784	return android.OptionalPath{}
1785}
1786
1787var _ android.ApexModule = (*Module)(nil)
1788
1789// If a module is marked for exclusion from apexes, don't provide apex variants.
1790// TODO(b/362509506): remove this once stubs are properly supported by rust_ffi targets.
1791func (m *Module) CanHaveApexVariants() bool {
1792	if m.ApexExclude() {
1793		return false
1794	} else {
1795		return m.ApexModuleBase.CanHaveApexVariants()
1796	}
1797}
1798
1799func (mod *Module) MinSdkVersion() string {
1800	return String(mod.Properties.Min_sdk_version)
1801}
1802
1803// Implements android.ApexModule
1804func (mod *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
1805	minSdkVersion := mod.MinSdkVersion()
1806	if minSdkVersion == "apex_inherit" {
1807		return nil
1808	}
1809	if minSdkVersion == "" {
1810		return fmt.Errorf("min_sdk_version is not specificed")
1811	}
1812
1813	// Not using nativeApiLevelFromUser because the context here is not
1814	// necessarily a native context.
1815	ver, err := android.ApiLevelFromUser(ctx, minSdkVersion)
1816	if err != nil {
1817		return err
1818	}
1819
1820	if ver.GreaterThan(sdkVersion) {
1821		return fmt.Errorf("newer SDK(%v)", ver)
1822	}
1823	return nil
1824}
1825
1826// Implements android.ApexModule
1827func (mod *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
1828	depTag := ctx.OtherModuleDependencyTag(dep)
1829
1830	if ccm, ok := dep.(*cc.Module); ok {
1831		if ccm.HasStubsVariants() {
1832			if cc.IsSharedDepTag(depTag) {
1833				// dynamic dep to a stubs lib crosses APEX boundary
1834				return false
1835			}
1836			if cc.IsRuntimeDepTag(depTag) {
1837				// runtime dep to a stubs lib also crosses APEX boundary
1838				return false
1839			}
1840
1841			if cc.IsHeaderDepTag(depTag) {
1842				return false
1843			}
1844		}
1845		if mod.Static() && cc.IsSharedDepTag(depTag) {
1846			// shared_lib dependency from a static lib is considered as crossing
1847			// the APEX boundary because the dependency doesn't actually is
1848			// linked; the dependency is used only during the compilation phase.
1849			return false
1850		}
1851	}
1852
1853	if depTag == procMacroDepTag || depTag == customBindgenDepTag {
1854		return false
1855	}
1856
1857	if rustDep, ok := dep.(*Module); ok && rustDep.ApexExclude() {
1858		return false
1859	}
1860
1861	return true
1862}
1863
1864// Overrides ApexModule.IsInstallabeToApex()
1865func (mod *Module) IsInstallableToApex() bool {
1866	if mod.compiler != nil {
1867		if lib, ok := mod.compiler.(libraryInterface); ok && (lib.shared() || lib.dylib()) {
1868			return true
1869		}
1870		if _, ok := mod.compiler.(*binaryDecorator); ok {
1871			return true
1872		}
1873	}
1874	return false
1875}
1876
1877// If a library file has a "lib" prefix, extract the library name without the prefix.
1878func libNameFromFilePath(filepath android.Path) (string, bool) {
1879	libName := strings.TrimSuffix(filepath.Base(), filepath.Ext())
1880	if strings.HasPrefix(libName, "lib") {
1881		libName = libName[3:]
1882		return libName, true
1883	}
1884	return "", false
1885}
1886
1887func kytheExtractRustFactory() android.Singleton {
1888	return &kytheExtractRustSingleton{}
1889}
1890
1891type kytheExtractRustSingleton struct {
1892}
1893
1894func (k kytheExtractRustSingleton) GenerateBuildActions(ctx android.SingletonContext) {
1895	var xrefTargets android.Paths
1896	ctx.VisitAllModules(func(module android.Module) {
1897		if rustModule, ok := module.(xref); ok {
1898			xrefTargets = append(xrefTargets, rustModule.XrefRustFiles()...)
1899		}
1900	})
1901	if len(xrefTargets) > 0 {
1902		ctx.Phony("xref_rust", xrefTargets...)
1903	}
1904}
1905
1906func (c *Module) Partition() string {
1907	return ""
1908}
1909
1910var Bool = proptools.Bool
1911var BoolDefault = proptools.BoolDefault
1912var String = proptools.String
1913var StringPtr = proptools.StringPtr
1914