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/cc"
26	"android/soong/rust/config"
27)
28
29var pctx = android.NewPackageContext("android/soong/rust")
30
31func init() {
32	// Only allow rust modules to be defined for certain projects
33
34	android.AddNeverAllowRules(
35		android.NeverAllow().
36			NotIn(config.RustAllowedPaths...).
37			ModuleType(config.RustModuleTypes...))
38
39	android.RegisterModuleType("rust_defaults", defaultsFactory)
40	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
41		ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
42		ctx.BottomUp("rust_begin", BeginMutator).Parallel()
43	})
44	pctx.Import("android/soong/rust/config")
45	pctx.ImportAs("ccConfig", "android/soong/cc/config")
46}
47
48type Flags struct {
49	GlobalRustFlags []string // Flags that apply globally to rust
50	GlobalLinkFlags []string // Flags that apply globally to linker
51	RustFlags       []string // Flags that apply to rust
52	LinkFlags       []string // Flags that apply to linker
53	ClippyFlags     []string // Flags that apply to clippy-driver, during the linting
54	Toolchain       config.Toolchain
55	Coverage        bool
56	Clippy          bool
57}
58
59type BaseProperties struct {
60	AndroidMkRlibs         []string
61	AndroidMkDylibs        []string
62	AndroidMkProcMacroLibs []string
63	AndroidMkSharedLibs    []string
64	AndroidMkStaticLibs    []string
65
66	SubName        string `blueprint:"mutated"`
67	PreventInstall bool
68	HideFromMake   bool
69}
70
71type Module struct {
72	android.ModuleBase
73	android.DefaultableModuleBase
74
75	Properties BaseProperties
76
77	hod      android.HostOrDeviceSupported
78	multilib android.Multilib
79
80	compiler         compiler
81	coverage         *coverage
82	clippy           *clippy
83	cachedToolchain  config.Toolchain
84	sourceProvider   SourceProvider
85	subAndroidMkOnce map[subAndroidMkProvider]bool
86	outputFile       android.OptionalPath
87
88	subName string
89}
90
91func (mod *Module) OutputFiles(tag string) (android.Paths, error) {
92	switch tag {
93	case "":
94		if mod.sourceProvider != nil {
95			return mod.sourceProvider.Srcs(), nil
96		} else {
97			if mod.outputFile.Valid() {
98				return android.Paths{mod.outputFile.Path()}, nil
99			}
100			return android.Paths{}, nil
101		}
102	default:
103		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
104	}
105}
106
107var _ android.ImageInterface = (*Module)(nil)
108
109func (mod *Module) ImageMutatorBegin(ctx android.BaseModuleContext) {}
110
111func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
112	return true
113}
114
115func (mod *Module) RamdiskVariantNeeded(android.BaseModuleContext) bool {
116	return mod.InRamdisk()
117}
118
119func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool {
120	return mod.InRecovery()
121}
122
123func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string {
124	return nil
125}
126
127func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
128}
129
130func (mod *Module) BuildStubs() bool {
131	return false
132}
133
134func (mod *Module) HasStubsVariants() bool {
135	return false
136}
137
138func (mod *Module) SelectedStl() string {
139	return ""
140}
141
142func (mod *Module) NonCcVariants() bool {
143	if mod.compiler != nil {
144		if _, ok := mod.compiler.(libraryInterface); ok {
145			return false
146		}
147	}
148	panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName()))
149}
150
151func (mod *Module) ApiLevel() string {
152	panic(fmt.Errorf("Called ApiLevel on Rust module %q; stubs libraries are not yet supported.", mod.BaseModuleName()))
153}
154
155func (mod *Module) Static() bool {
156	if mod.compiler != nil {
157		if library, ok := mod.compiler.(libraryInterface); ok {
158			return library.static()
159		}
160	}
161	return false
162}
163
164func (mod *Module) Shared() bool {
165	if mod.compiler != nil {
166		if library, ok := mod.compiler.(libraryInterface); ok {
167			return library.shared()
168		}
169	}
170	return false
171}
172
173func (mod *Module) Toc() android.OptionalPath {
174	if mod.compiler != nil {
175		if _, ok := mod.compiler.(libraryInterface); ok {
176			return android.OptionalPath{}
177		}
178	}
179	panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName()))
180}
181
182func (mod *Module) OnlyInRamdisk() bool {
183	return false
184}
185
186func (mod *Module) OnlyInRecovery() bool {
187	return false
188}
189
190func (mod *Module) UseSdk() bool {
191	return false
192}
193
194func (mod *Module) UseVndk() bool {
195	return false
196}
197
198func (mod *Module) MustUseVendorVariant() bool {
199	return false
200}
201
202func (mod *Module) IsVndk() bool {
203	return false
204}
205
206func (mod *Module) HasVendorVariant() bool {
207	return false
208}
209
210func (mod *Module) SdkVersion() string {
211	return ""
212}
213
214func (mod *Module) AlwaysSdk() bool {
215	return false
216}
217
218func (mod *Module) IsSdkVariant() bool {
219	return false
220}
221
222func (mod *Module) ToolchainLibrary() bool {
223	return false
224}
225
226func (mod *Module) NdkPrebuiltStl() bool {
227	return false
228}
229
230func (mod *Module) StubDecorator() bool {
231	return false
232}
233
234type Deps struct {
235	Dylibs     []string
236	Rlibs      []string
237	Rustlibs   []string
238	ProcMacros []string
239	SharedLibs []string
240	StaticLibs []string
241
242	CrtBegin, CrtEnd string
243}
244
245type PathDeps struct {
246	DyLibs     RustLibraries
247	RLibs      RustLibraries
248	SharedLibs android.Paths
249	StaticLibs android.Paths
250	ProcMacros RustLibraries
251	linkDirs   []string
252	depFlags   []string
253	//ReexportedDeps android.Paths
254
255	// Used by bindgen modules which call clang
256	depClangFlags         []string
257	depIncludePaths       android.Paths
258	depSystemIncludePaths android.Paths
259
260	coverageFiles android.Paths
261
262	CrtBegin android.OptionalPath
263	CrtEnd   android.OptionalPath
264
265	// Paths to generated source files
266	SrcDeps android.Paths
267}
268
269type RustLibraries []RustLibrary
270
271type RustLibrary struct {
272	Path      android.Path
273	CrateName string
274}
275
276type compiler interface {
277	compilerFlags(ctx ModuleContext, flags Flags) Flags
278	compilerProps() []interface{}
279	compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path
280	compilerDeps(ctx DepsContext, deps Deps) Deps
281	crateName() string
282
283	inData() bool
284	install(ctx ModuleContext, path android.Path)
285	relativeInstallPath() string
286
287	nativeCoverage() bool
288}
289
290type exportedFlagsProducer interface {
291	exportedLinkDirs() []string
292	exportedDepFlags() []string
293	exportLinkDirs(...string)
294	exportDepFlags(...string)
295}
296
297type flagExporter struct {
298	depFlags []string
299	linkDirs []string
300}
301
302func (flagExporter *flagExporter) exportedLinkDirs() []string {
303	return flagExporter.linkDirs
304}
305
306func (flagExporter *flagExporter) exportedDepFlags() []string {
307	return flagExporter.depFlags
308}
309
310func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
311	flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
312}
313
314func (flagExporter *flagExporter) exportDepFlags(flags ...string) {
315	flagExporter.depFlags = android.FirstUniqueStrings(append(flagExporter.depFlags, flags...))
316}
317
318var _ exportedFlagsProducer = (*flagExporter)(nil)
319
320func NewFlagExporter() *flagExporter {
321	return &flagExporter{
322		depFlags: []string{},
323		linkDirs: []string{},
324	}
325}
326
327func (mod *Module) isCoverageVariant() bool {
328	return mod.coverage.Properties.IsCoverageVariant
329}
330
331var _ cc.Coverage = (*Module)(nil)
332
333func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
334	return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant
335}
336
337func (mod *Module) PreventInstall() {
338	mod.Properties.PreventInstall = true
339}
340
341func (mod *Module) HideFromMake() {
342	mod.Properties.HideFromMake = true
343}
344
345func (mod *Module) MarkAsCoverageVariant(coverage bool) {
346	mod.coverage.Properties.IsCoverageVariant = coverage
347}
348
349func (mod *Module) EnableCoverageIfNeeded() {
350	mod.coverage.Properties.CoverageEnabled = mod.coverage.Properties.NeedCoverageBuild
351}
352
353func defaultsFactory() android.Module {
354	return DefaultsFactory()
355}
356
357type Defaults struct {
358	android.ModuleBase
359	android.DefaultsModuleBase
360}
361
362func DefaultsFactory(props ...interface{}) android.Module {
363	module := &Defaults{}
364
365	module.AddProperties(props...)
366	module.AddProperties(
367		&BaseProperties{},
368		&BaseCompilerProperties{},
369		&BinaryCompilerProperties{},
370		&LibraryCompilerProperties{},
371		&ProcMacroCompilerProperties{},
372		&PrebuiltProperties{},
373		&SourceProviderProperties{},
374		&TestProperties{},
375		&cc.CoverageProperties{},
376		&ClippyProperties{},
377	)
378
379	android.InitDefaultsModule(module)
380	return module
381}
382
383func (mod *Module) CrateName() string {
384	return mod.compiler.crateName()
385}
386
387func (mod *Module) CcLibrary() bool {
388	if mod.compiler != nil {
389		if _, ok := mod.compiler.(*libraryDecorator); ok {
390			return true
391		}
392	}
393	return false
394}
395
396func (mod *Module) CcLibraryInterface() bool {
397	if mod.compiler != nil {
398		// use build{Static,Shared}() instead of {static,shared}() here because this might be called before
399		// VariantIs{Static,Shared} is set.
400		if lib, ok := mod.compiler.(libraryInterface); ok && (lib.buildShared() || lib.buildStatic()) {
401			return true
402		}
403	}
404	return false
405}
406
407func (mod *Module) IncludeDirs() android.Paths {
408	if mod.compiler != nil {
409		if library, ok := mod.compiler.(*libraryDecorator); ok {
410			return library.includeDirs
411		}
412	}
413	panic(fmt.Errorf("IncludeDirs called on non-library module: %q", mod.BaseModuleName()))
414}
415
416func (mod *Module) SetStatic() {
417	if mod.compiler != nil {
418		if library, ok := mod.compiler.(libraryInterface); ok {
419			library.setStatic()
420			return
421		}
422	}
423	panic(fmt.Errorf("SetStatic called on non-library module: %q", mod.BaseModuleName()))
424}
425
426func (mod *Module) SetShared() {
427	if mod.compiler != nil {
428		if library, ok := mod.compiler.(libraryInterface); ok {
429			library.setShared()
430			return
431		}
432	}
433	panic(fmt.Errorf("SetShared called on non-library module: %q", mod.BaseModuleName()))
434}
435
436func (mod *Module) SetBuildStubs() {
437	panic("SetBuildStubs not yet implemented for rust modules")
438}
439
440func (mod *Module) SetStubsVersions(string) {
441	panic("SetStubsVersions not yet implemented for rust modules")
442}
443
444func (mod *Module) StubsVersion() string {
445	panic("SetStubsVersions not yet implemented for rust modules")
446}
447
448func (mod *Module) BuildStaticVariant() bool {
449	if mod.compiler != nil {
450		if library, ok := mod.compiler.(libraryInterface); ok {
451			return library.buildStatic()
452		}
453	}
454	panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName()))
455}
456
457func (mod *Module) BuildSharedVariant() bool {
458	if mod.compiler != nil {
459		if library, ok := mod.compiler.(libraryInterface); ok {
460			return library.buildShared()
461		}
462	}
463	panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName()))
464}
465
466// Rust module deps don't have a link order (?)
467func (mod *Module) SetDepsInLinkOrder([]android.Path) {}
468
469func (mod *Module) GetDepsInLinkOrder() []android.Path {
470	return []android.Path{}
471}
472
473func (mod *Module) GetStaticVariant() cc.LinkableInterface {
474	return nil
475}
476
477func (mod *Module) Module() android.Module {
478	return mod
479}
480
481func (mod *Module) StubsVersions() []string {
482	// For now, Rust has no stubs versions.
483	if mod.compiler != nil {
484		if _, ok := mod.compiler.(libraryInterface); ok {
485			return []string{}
486		}
487	}
488	panic(fmt.Errorf("StubsVersions called on non-library module: %q", mod.BaseModuleName()))
489}
490
491func (mod *Module) OutputFile() android.OptionalPath {
492	return mod.outputFile
493}
494
495func (mod *Module) InRecovery() bool {
496	// For now, Rust has no notion of the recovery image
497	return false
498}
499func (mod *Module) HasStaticVariant() bool {
500	if mod.GetStaticVariant() != nil {
501		return true
502	}
503	return false
504}
505
506func (mod *Module) CoverageFiles() android.Paths {
507	if mod.compiler != nil {
508		if !mod.compiler.nativeCoverage() {
509			return android.Paths{}
510		}
511		if library, ok := mod.compiler.(*libraryDecorator); ok {
512			if library.coverageFile != nil {
513				return android.Paths{library.coverageFile}
514			}
515			return android.Paths{}
516		}
517	}
518	panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName()))
519}
520
521var _ cc.LinkableInterface = (*Module)(nil)
522
523func (mod *Module) Init() android.Module {
524	mod.AddProperties(&mod.Properties)
525
526	if mod.compiler != nil {
527		mod.AddProperties(mod.compiler.compilerProps()...)
528	}
529	if mod.coverage != nil {
530		mod.AddProperties(mod.coverage.props()...)
531	}
532	if mod.clippy != nil {
533		mod.AddProperties(mod.clippy.props()...)
534	}
535	if mod.sourceProvider != nil {
536		mod.AddProperties(mod.sourceProvider.sourceProviderProps()...)
537	}
538
539	android.InitAndroidArchModule(mod, mod.hod, mod.multilib)
540
541	android.InitDefaultableModule(mod)
542
543	// Explicitly disable unsupported targets.
544	android.AddLoadHook(mod, func(ctx android.LoadHookContext) {
545		disableTargets := struct {
546			Target struct {
547				Linux_bionic struct {
548					Enabled *bool
549				}
550			}
551		}{}
552		disableTargets.Target.Linux_bionic.Enabled = proptools.BoolPtr(false)
553
554		ctx.AppendProperties(&disableTargets)
555	})
556
557	return mod
558}
559
560func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
561	return &Module{
562		hod:      hod,
563		multilib: multilib,
564	}
565}
566func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
567	module := newBaseModule(hod, multilib)
568	module.coverage = &coverage{}
569	module.clippy = &clippy{}
570	return module
571}
572
573type ModuleContext interface {
574	android.ModuleContext
575	ModuleContextIntf
576}
577
578type BaseModuleContext interface {
579	android.BaseModuleContext
580	ModuleContextIntf
581}
582
583type DepsContext interface {
584	android.BottomUpMutatorContext
585	ModuleContextIntf
586}
587
588type ModuleContextIntf interface {
589	RustModule() *Module
590	toolchain() config.Toolchain
591}
592
593type depsContext struct {
594	android.BottomUpMutatorContext
595}
596
597type moduleContext struct {
598	android.ModuleContext
599}
600
601type baseModuleContext struct {
602	android.BaseModuleContext
603}
604
605func (ctx *moduleContext) RustModule() *Module {
606	return ctx.Module().(*Module)
607}
608
609func (ctx *moduleContext) toolchain() config.Toolchain {
610	return ctx.RustModule().toolchain(ctx)
611}
612
613func (ctx *depsContext) RustModule() *Module {
614	return ctx.Module().(*Module)
615}
616
617func (ctx *depsContext) toolchain() config.Toolchain {
618	return ctx.RustModule().toolchain(ctx)
619}
620
621func (ctx *baseModuleContext) RustModule() *Module {
622	return ctx.Module().(*Module)
623}
624
625func (ctx *baseModuleContext) toolchain() config.Toolchain {
626	return ctx.RustModule().toolchain(ctx)
627}
628
629func (mod *Module) nativeCoverage() bool {
630	return mod.compiler != nil && mod.compiler.nativeCoverage()
631}
632
633func (mod *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain {
634	if mod.cachedToolchain == nil {
635		mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch())
636	}
637	return mod.cachedToolchain
638}
639
640func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
641}
642
643func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
644	ctx := &moduleContext{
645		ModuleContext: actx,
646	}
647
648	toolchain := mod.toolchain(ctx)
649
650	if !toolchain.Supported() {
651		// This toolchain's unsupported, there's nothing to do for this mod.
652		return
653	}
654
655	deps := mod.depsToPaths(ctx)
656	flags := Flags{
657		Toolchain: toolchain,
658	}
659
660	if mod.compiler != nil {
661		flags = mod.compiler.compilerFlags(ctx, flags)
662	}
663	if mod.coverage != nil {
664		flags, deps = mod.coverage.flags(ctx, flags, deps)
665	}
666	if mod.clippy != nil {
667		flags, deps = mod.clippy.flags(ctx, flags, deps)
668	}
669
670	if mod.compiler != nil {
671		outputFile := mod.compiler.compile(ctx, flags, deps)
672		mod.outputFile = android.OptionalPathForPath(outputFile)
673		if !mod.Properties.PreventInstall {
674			mod.compiler.install(ctx, mod.outputFile.Path())
675		}
676	} else if mod.sourceProvider != nil {
677		outputFile := mod.sourceProvider.generateSource(ctx, deps)
678		mod.outputFile = android.OptionalPathForPath(outputFile)
679		mod.subName = ctx.ModuleSubDir()
680	}
681}
682
683func (mod *Module) deps(ctx DepsContext) Deps {
684	deps := Deps{}
685
686	if mod.compiler != nil {
687		deps = mod.compiler.compilerDeps(ctx, deps)
688	} else if mod.sourceProvider != nil {
689		deps = mod.sourceProvider.sourceProviderDeps(ctx, deps)
690	}
691
692	if mod.coverage != nil {
693		deps = mod.coverage.deps(ctx, deps)
694	}
695
696	deps.Rlibs = android.LastUniqueStrings(deps.Rlibs)
697	deps.Dylibs = android.LastUniqueStrings(deps.Dylibs)
698	deps.Rustlibs = android.LastUniqueStrings(deps.Rustlibs)
699	deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros)
700	deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
701	deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
702
703	return deps
704
705}
706
707type dependencyTag struct {
708	blueprint.BaseDependencyTag
709	name       string
710	library    bool
711	proc_macro bool
712}
713
714var (
715	rlibDepTag       = dependencyTag{name: "rlibTag", library: true}
716	dylibDepTag      = dependencyTag{name: "dylib", library: true}
717	procMacroDepTag  = dependencyTag{name: "procMacro", proc_macro: true}
718	testPerSrcDepTag = dependencyTag{name: "rust_unit_tests"}
719)
720
721type autoDep struct {
722	variation string
723	depTag    dependencyTag
724}
725
726var (
727	rlibAutoDep  = autoDep{variation: "rlib", depTag: rlibDepTag}
728	dylibAutoDep = autoDep{variation: "dylib", depTag: dylibDepTag}
729)
730
731type autoDeppable interface {
732	autoDep() autoDep
733}
734
735func (mod *Module) begin(ctx BaseModuleContext) {
736	if mod.coverage != nil {
737		mod.coverage.begin(ctx)
738	}
739}
740
741func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
742	var depPaths PathDeps
743
744	directRlibDeps := []*Module{}
745	directDylibDeps := []*Module{}
746	directProcMacroDeps := []*Module{}
747	directSharedLibDeps := [](cc.LinkableInterface){}
748	directStaticLibDeps := [](cc.LinkableInterface){}
749	directSrcProvidersDeps := []*Module{}
750	directSrcDeps := [](android.SourceFileProducer){}
751
752	ctx.VisitDirectDeps(func(dep android.Module) {
753		depName := ctx.OtherModuleName(dep)
754		depTag := ctx.OtherModuleDependencyTag(dep)
755		if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() {
756			//Handle Rust Modules
757
758			linkFile := rustDep.outputFile
759			if !linkFile.Valid() {
760				ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
761			}
762
763			switch depTag {
764			case dylibDepTag:
765				dylib, ok := rustDep.compiler.(libraryInterface)
766				if !ok || !dylib.dylib() {
767					ctx.ModuleErrorf("mod %q not an dylib library", depName)
768					return
769				}
770				directDylibDeps = append(directDylibDeps, rustDep)
771				mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, depName)
772			case rlibDepTag:
773				rlib, ok := rustDep.compiler.(libraryInterface)
774				if !ok || !rlib.rlib() {
775					ctx.ModuleErrorf("mod %q not an rlib library", depName)
776					return
777				}
778				depPaths.coverageFiles = append(depPaths.coverageFiles, rustDep.CoverageFiles()...)
779				directRlibDeps = append(directRlibDeps, rustDep)
780				mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, depName)
781			case procMacroDepTag:
782				directProcMacroDeps = append(directProcMacroDeps, rustDep)
783				mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, depName)
784			case android.SourceDepTag:
785				// Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
786				// OS/Arch variant is used.
787				var helper string
788				if ctx.Host() {
789					helper = "missing 'host_supported'?"
790				} else {
791					helper = "device module defined?"
792				}
793
794				if dep.Target().Os != ctx.Os() {
795					ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper)
796					return
797				} else if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
798					ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper)
799					return
800				}
801				directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
802			}
803
804			//Append the dependencies exportedDirs
805			if lib, ok := rustDep.compiler.(exportedFlagsProducer); ok {
806				depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedLinkDirs()...)
807				depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...)
808			}
809
810			if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
811				linkDir := linkPathFromFilePath(linkFile.Path())
812				if lib, ok := mod.compiler.(exportedFlagsProducer); ok {
813					lib.exportLinkDirs(linkDir)
814				}
815			}
816
817		} else if ccDep, ok := dep.(cc.LinkableInterface); ok {
818			//Handle C dependencies
819			if _, ok := ccDep.(*Module); !ok {
820				if ccDep.Module().Target().Os != ctx.Os() {
821					ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
822					return
823				}
824				if ccDep.Module().Target().Arch.ArchType != ctx.Arch().ArchType {
825					ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
826					return
827				}
828			}
829
830			linkFile := ccDep.OutputFile()
831			linkPath := linkPathFromFilePath(linkFile.Path())
832			libName := libNameFromFilePath(linkFile.Path())
833			depFlag := "-l" + libName
834
835			if !linkFile.Valid() {
836				ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
837			}
838
839			exportDep := false
840			switch depTag {
841			case cc.StaticDepTag:
842				depFlag = "-lstatic=" + libName
843				depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
844				depPaths.depFlags = append(depPaths.depFlags, depFlag)
845				depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
846				if mod, ok := ccDep.(*cc.Module); ok {
847					depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
848					depPaths.depClangFlags = append(depPaths.depClangFlags, mod.ExportedFlags()...)
849				}
850				depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...)
851				directStaticLibDeps = append(directStaticLibDeps, ccDep)
852				mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
853			case cc.SharedDepTag:
854				depFlag = "-ldylib=" + libName
855				depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
856				depPaths.depFlags = append(depPaths.depFlags, depFlag)
857				depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
858				if mod, ok := ccDep.(*cc.Module); ok {
859					depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
860					depPaths.depClangFlags = append(depPaths.depClangFlags, mod.ExportedFlags()...)
861				}
862				directSharedLibDeps = append(directSharedLibDeps, ccDep)
863				mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
864				exportDep = true
865			case cc.CrtBeginDepTag:
866				depPaths.CrtBegin = linkFile
867			case cc.CrtEndDepTag:
868				depPaths.CrtEnd = linkFile
869			}
870
871			// Make sure these dependencies are propagated
872			if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep {
873				lib.exportLinkDirs(linkPath)
874				lib.exportDepFlags(depFlag)
875			}
876		}
877
878		if srcDep, ok := dep.(android.SourceFileProducer); ok {
879			switch depTag {
880			case android.SourceDepTag:
881				// These are usually genrules which don't have per-target variants.
882				directSrcDeps = append(directSrcDeps, srcDep)
883			}
884		}
885	})
886
887	var rlibDepFiles RustLibraries
888	for _, dep := range directRlibDeps {
889		rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()})
890	}
891	var dylibDepFiles RustLibraries
892	for _, dep := range directDylibDeps {
893		dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()})
894	}
895	var procMacroDepFiles RustLibraries
896	for _, dep := range directProcMacroDeps {
897		procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()})
898	}
899
900	var staticLibDepFiles android.Paths
901	for _, dep := range directStaticLibDeps {
902		staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path())
903	}
904
905	var sharedLibDepFiles android.Paths
906	for _, dep := range directSharedLibDeps {
907		sharedLibDepFiles = append(sharedLibDepFiles, dep.OutputFile().Path())
908	}
909
910	var srcProviderDepFiles android.Paths
911	for _, dep := range directSrcProvidersDeps {
912		srcs, _ := dep.OutputFiles("")
913		srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
914	}
915	for _, dep := range directSrcDeps {
916		srcs := dep.Srcs()
917		srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
918	}
919
920	depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
921	depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
922	depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibDepFiles...)
923	depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...)
924	depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
925	depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
926
927	// Dedup exported flags from dependencies
928	depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
929	depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
930	depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
931	depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
932	depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths)
933
934	return depPaths
935}
936
937func (mod *Module) InstallInData() bool {
938	if mod.compiler == nil {
939		return false
940	}
941	return mod.compiler.inData()
942}
943
944func linkPathFromFilePath(filepath android.Path) string {
945	return strings.Split(filepath.String(), filepath.Base())[0]
946}
947
948func libNameFromFilePath(filepath android.Path) string {
949	libName := strings.TrimSuffix(filepath.Base(), filepath.Ext())
950	if strings.HasPrefix(libName, "lib") {
951		libName = libName[3:]
952	}
953	return libName
954}
955
956func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
957	ctx := &depsContext{
958		BottomUpMutatorContext: actx,
959	}
960
961	deps := mod.deps(ctx)
962	commonDepVariations := []blueprint.Variation{}
963	if cc.VersionVariantAvailable(mod) {
964		commonDepVariations = append(commonDepVariations,
965			blueprint.Variation{Mutator: "version", Variation: ""})
966	}
967	if !mod.Host() {
968		commonDepVariations = append(commonDepVariations,
969			blueprint.Variation{Mutator: "image", Variation: android.CoreVariation})
970	}
971	actx.AddVariationDependencies(
972		append(commonDepVariations, []blueprint.Variation{
973			{Mutator: "rust_libraries", Variation: "rlib"}}...),
974		rlibDepTag, deps.Rlibs...)
975	actx.AddVariationDependencies(
976		append(commonDepVariations, []blueprint.Variation{
977			{Mutator: "rust_libraries", Variation: "dylib"}}...),
978		dylibDepTag, deps.Dylibs...)
979
980	if deps.Rustlibs != nil {
981		autoDep := mod.compiler.(autoDeppable).autoDep()
982		actx.AddVariationDependencies(
983			append(commonDepVariations, []blueprint.Variation{
984				{Mutator: "rust_libraries", Variation: autoDep.variation}}...),
985			autoDep.depTag, deps.Rustlibs...)
986	}
987
988	actx.AddVariationDependencies(append(commonDepVariations,
989		blueprint.Variation{Mutator: "link", Variation: "shared"}),
990		cc.SharedDepTag, deps.SharedLibs...)
991	actx.AddVariationDependencies(append(commonDepVariations,
992		blueprint.Variation{Mutator: "link", Variation: "static"}),
993		cc.StaticDepTag, deps.StaticLibs...)
994
995	if deps.CrtBegin != "" {
996		actx.AddVariationDependencies(commonDepVariations, cc.CrtBeginDepTag, deps.CrtBegin)
997	}
998	if deps.CrtEnd != "" {
999		actx.AddVariationDependencies(commonDepVariations, cc.CrtEndDepTag, deps.CrtEnd)
1000	}
1001
1002	// proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy.
1003	actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...)
1004}
1005
1006func BeginMutator(ctx android.BottomUpMutatorContext) {
1007	if mod, ok := ctx.Module().(*Module); ok && mod.Enabled() {
1008		mod.beginMutator(ctx)
1009	}
1010}
1011
1012func (mod *Module) beginMutator(actx android.BottomUpMutatorContext) {
1013	ctx := &baseModuleContext{
1014		BaseModuleContext: actx,
1015	}
1016
1017	mod.begin(ctx)
1018}
1019
1020func (mod *Module) Name() string {
1021	name := mod.ModuleBase.Name()
1022	if p, ok := mod.compiler.(interface {
1023		Name(string) string
1024	}); ok {
1025		name = p.Name(name)
1026	}
1027	return name
1028}
1029
1030var _ android.HostToolProvider = (*Module)(nil)
1031
1032func (mod *Module) HostToolPath() android.OptionalPath {
1033	if !mod.Host() {
1034		return android.OptionalPath{}
1035	}
1036	if _, ok := mod.compiler.(*binaryDecorator); ok {
1037		return mod.outputFile
1038	}
1039	return android.OptionalPath{}
1040}
1041
1042var Bool = proptools.Bool
1043var BoolDefault = proptools.BoolDefault
1044var String = proptools.String
1045var StringPtr = proptools.StringPtr
1046
1047var _ android.OutputFileProducer = (*Module)(nil)
1048