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