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