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