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