| // Copyright 2019 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package rust |
| |
| import ( |
| "fmt" |
| "strings" |
| |
| "github.com/google/blueprint" |
| "github.com/google/blueprint/proptools" |
| |
| "android/soong/android" |
| "android/soong/cc" |
| "android/soong/rust/config" |
| ) |
| |
| var pctx = android.NewPackageContext("android/soong/rust") |
| |
| func init() { |
| // Only allow rust modules to be defined for certain projects |
| |
| android.AddNeverAllowRules( |
| android.NeverAllow(). |
| NotIn(config.RustAllowedPaths...). |
| ModuleType(config.RustModuleTypes...)) |
| |
| android.RegisterModuleType("rust_defaults", defaultsFactory) |
| android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { |
| ctx.BottomUp("rust_libraries", LibraryMutator).Parallel() |
| ctx.BottomUp("rust_begin", BeginMutator).Parallel() |
| }) |
| pctx.Import("android/soong/rust/config") |
| } |
| |
| type Flags struct { |
| GlobalRustFlags []string // Flags that apply globally to rust |
| GlobalLinkFlags []string // Flags that apply globally to linker |
| RustFlags []string // Flags that apply to rust |
| LinkFlags []string // Flags that apply to linker |
| RustFlagsDeps android.Paths // Files depended on by compiler flags |
| Toolchain config.Toolchain |
| Coverage bool |
| } |
| |
| type BaseProperties struct { |
| AndroidMkRlibs []string |
| AndroidMkDylibs []string |
| AndroidMkProcMacroLibs []string |
| AndroidMkSharedLibs []string |
| AndroidMkStaticLibs []string |
| SubName string `blueprint:"mutated"` |
| PreventInstall bool |
| HideFromMake bool |
| } |
| |
| type Module struct { |
| android.ModuleBase |
| android.DefaultableModuleBase |
| |
| Properties BaseProperties |
| |
| hod android.HostOrDeviceSupported |
| multilib android.Multilib |
| |
| compiler compiler |
| coverage *coverage |
| cachedToolchain config.Toolchain |
| subAndroidMkOnce map[subAndroidMkProvider]bool |
| outputFile android.OptionalPath |
| } |
| |
| var _ android.ImageInterface = (*Module)(nil) |
| |
| func (mod *Module) ImageMutatorBegin(ctx android.BaseModuleContext) {} |
| |
| func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool { |
| return true |
| } |
| |
| func (mod *Module) RamdiskVariantNeeded(android.BaseModuleContext) bool { |
| return mod.InRamdisk() |
| } |
| |
| func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool { |
| return mod.InRecovery() |
| } |
| |
| func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string { |
| return nil |
| } |
| |
| func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { |
| } |
| |
| func (mod *Module) BuildStubs() bool { |
| return false |
| } |
| |
| func (mod *Module) HasStubsVariants() bool { |
| return false |
| } |
| |
| func (mod *Module) SelectedStl() string { |
| return "" |
| } |
| |
| func (mod *Module) NonCcVariants() bool { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(libraryInterface); ok { |
| if library.buildRlib() || library.buildDylib() { |
| return true |
| } else { |
| return false |
| } |
| } |
| } |
| panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) ApiLevel() string { |
| panic(fmt.Errorf("Called ApiLevel on Rust module %q; stubs libraries are not yet supported.", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) Static() bool { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(libraryInterface); ok { |
| return library.static() |
| } |
| } |
| panic(fmt.Errorf("Static called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) Shared() bool { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(libraryInterface); ok { |
| return library.static() |
| } |
| } |
| panic(fmt.Errorf("Shared called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) Toc() android.OptionalPath { |
| if mod.compiler != nil { |
| if _, ok := mod.compiler.(libraryInterface); ok { |
| return android.OptionalPath{} |
| } |
| } |
| panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) OnlyInRamdisk() bool { |
| return false |
| } |
| |
| func (mod *Module) OnlyInRecovery() bool { |
| return false |
| } |
| |
| func (mod *Module) UseSdk() bool { |
| return false |
| } |
| |
| func (mod *Module) UseVndk() bool { |
| return false |
| } |
| |
| func (mod *Module) MustUseVendorVariant() bool { |
| return false |
| } |
| |
| func (mod *Module) IsVndk() bool { |
| return false |
| } |
| |
| func (mod *Module) HasVendorVariant() bool { |
| return false |
| } |
| |
| func (mod *Module) SdkVersion() string { |
| return "" |
| } |
| |
| func (mod *Module) AlwaysSdk() bool { |
| return false |
| } |
| |
| func (mod *Module) ToolchainLibrary() bool { |
| return false |
| } |
| |
| func (mod *Module) NdkPrebuiltStl() bool { |
| return false |
| } |
| |
| func (mod *Module) StubDecorator() bool { |
| return false |
| } |
| |
| type Deps struct { |
| Dylibs []string |
| Rlibs []string |
| ProcMacros []string |
| SharedLibs []string |
| StaticLibs []string |
| |
| CrtBegin, CrtEnd string |
| } |
| |
| type PathDeps struct { |
| DyLibs RustLibraries |
| RLibs RustLibraries |
| SharedLibs android.Paths |
| StaticLibs android.Paths |
| ProcMacros RustLibraries |
| linkDirs []string |
| depFlags []string |
| //ReexportedDeps android.Paths |
| |
| coverageFiles android.Paths |
| |
| CrtBegin android.OptionalPath |
| CrtEnd android.OptionalPath |
| } |
| |
| type RustLibraries []RustLibrary |
| |
| type RustLibrary struct { |
| Path android.Path |
| CrateName string |
| } |
| |
| type compiler interface { |
| compilerFlags(ctx ModuleContext, flags Flags) Flags |
| compilerProps() []interface{} |
| compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path |
| compilerDeps(ctx DepsContext, deps Deps) Deps |
| crateName() string |
| |
| inData() bool |
| install(ctx ModuleContext, path android.Path) |
| relativeInstallPath() string |
| |
| nativeCoverage() bool |
| } |
| |
| func (mod *Module) isCoverageVariant() bool { |
| return mod.coverage.Properties.IsCoverageVariant |
| } |
| |
| var _ cc.Coverage = (*Module)(nil) |
| |
| func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { |
| return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant |
| } |
| |
| func (mod *Module) PreventInstall() { |
| mod.Properties.PreventInstall = true |
| } |
| |
| func (mod *Module) HideFromMake() { |
| mod.Properties.HideFromMake = true |
| } |
| |
| func (mod *Module) MarkAsCoverageVariant(coverage bool) { |
| mod.coverage.Properties.IsCoverageVariant = coverage |
| } |
| |
| func (mod *Module) EnableCoverageIfNeeded() { |
| mod.coverage.Properties.CoverageEnabled = mod.coverage.Properties.NeedCoverageBuild |
| } |
| |
| func defaultsFactory() android.Module { |
| return DefaultsFactory() |
| } |
| |
| type Defaults struct { |
| android.ModuleBase |
| android.DefaultsModuleBase |
| } |
| |
| func DefaultsFactory(props ...interface{}) android.Module { |
| module := &Defaults{} |
| |
| module.AddProperties(props...) |
| module.AddProperties( |
| &BaseProperties{}, |
| &BaseCompilerProperties{}, |
| &BinaryCompilerProperties{}, |
| &LibraryCompilerProperties{}, |
| &ProcMacroCompilerProperties{}, |
| &PrebuiltProperties{}, |
| &TestProperties{}, |
| &cc.CoverageProperties{}, |
| ) |
| |
| android.InitDefaultsModule(module) |
| return module |
| } |
| |
| func (mod *Module) CrateName() string { |
| return mod.compiler.crateName() |
| } |
| |
| func (mod *Module) CcLibrary() bool { |
| if mod.compiler != nil { |
| if _, ok := mod.compiler.(*libraryDecorator); ok { |
| return true |
| } |
| } |
| return false |
| } |
| |
| func (mod *Module) CcLibraryInterface() bool { |
| if mod.compiler != nil { |
| if _, ok := mod.compiler.(libraryInterface); ok { |
| return true |
| } |
| } |
| return false |
| } |
| |
| func (mod *Module) IncludeDirs() android.Paths { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(*libraryDecorator); ok { |
| return library.includeDirs |
| } |
| } |
| panic(fmt.Errorf("IncludeDirs called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) SetStatic() { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(libraryInterface); ok { |
| library.setStatic() |
| return |
| } |
| } |
| panic(fmt.Errorf("SetStatic called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) SetShared() { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(libraryInterface); ok { |
| library.setShared() |
| return |
| } |
| } |
| panic(fmt.Errorf("SetShared called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) SetBuildStubs() { |
| panic("SetBuildStubs not yet implemented for rust modules") |
| } |
| |
| func (mod *Module) SetStubsVersions(string) { |
| panic("SetStubsVersions not yet implemented for rust modules") |
| } |
| |
| func (mod *Module) StubsVersion() string { |
| panic("SetStubsVersions not yet implemented for rust modules") |
| } |
| |
| func (mod *Module) BuildStaticVariant() bool { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(libraryInterface); ok { |
| return library.buildStatic() |
| } |
| } |
| panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) BuildSharedVariant() bool { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(libraryInterface); ok { |
| return library.buildShared() |
| } |
| } |
| panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| // Rust module deps don't have a link order (?) |
| func (mod *Module) SetDepsInLinkOrder([]android.Path) {} |
| |
| func (mod *Module) GetDepsInLinkOrder() []android.Path { |
| return []android.Path{} |
| } |
| |
| func (mod *Module) GetStaticVariant() cc.LinkableInterface { |
| return nil |
| } |
| |
| func (mod *Module) Module() android.Module { |
| return mod |
| } |
| |
| func (mod *Module) StubsVersions() []string { |
| // For now, Rust has no stubs versions. |
| if mod.compiler != nil { |
| if _, ok := mod.compiler.(*libraryDecorator); ok { |
| return []string{} |
| } |
| } |
| panic(fmt.Errorf("StubsVersions called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| func (mod *Module) OutputFile() android.OptionalPath { |
| return mod.outputFile |
| } |
| |
| func (mod *Module) InRecovery() bool { |
| // For now, Rust has no notion of the recovery image |
| return false |
| } |
| func (mod *Module) HasStaticVariant() bool { |
| if mod.GetStaticVariant() != nil { |
| return true |
| } |
| return false |
| } |
| |
| func (mod *Module) CoverageFiles() android.Paths { |
| if mod.compiler != nil { |
| if library, ok := mod.compiler.(*libraryDecorator); ok { |
| if library.coverageFile != nil { |
| return android.Paths{library.coverageFile} |
| } |
| return android.Paths{} |
| } |
| } |
| panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName())) |
| } |
| |
| var _ cc.LinkableInterface = (*Module)(nil) |
| |
| func (mod *Module) Init() android.Module { |
| mod.AddProperties(&mod.Properties) |
| |
| if mod.compiler != nil { |
| mod.AddProperties(mod.compiler.compilerProps()...) |
| } |
| if mod.coverage != nil { |
| mod.AddProperties(mod.coverage.props()...) |
| } |
| |
| android.InitAndroidArchModule(mod, mod.hod, mod.multilib) |
| |
| android.InitDefaultableModule(mod) |
| |
| // Explicitly disable unsupported targets. |
| android.AddLoadHook(mod, func(ctx android.LoadHookContext) { |
| disableTargets := struct { |
| Target struct { |
| Linux_bionic struct { |
| Enabled *bool |
| } |
| } |
| }{} |
| disableTargets.Target.Linux_bionic.Enabled = proptools.BoolPtr(false) |
| |
| ctx.AppendProperties(&disableTargets) |
| }) |
| |
| return mod |
| } |
| |
| func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { |
| return &Module{ |
| hod: hod, |
| multilib: multilib, |
| } |
| } |
| func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { |
| module := newBaseModule(hod, multilib) |
| module.coverage = &coverage{} |
| return module |
| } |
| |
| type ModuleContext interface { |
| android.ModuleContext |
| ModuleContextIntf |
| } |
| |
| type BaseModuleContext interface { |
| android.BaseModuleContext |
| ModuleContextIntf |
| } |
| |
| type DepsContext interface { |
| android.BottomUpMutatorContext |
| ModuleContextIntf |
| } |
| |
| type ModuleContextIntf interface { |
| toolchain() config.Toolchain |
| baseModuleName() string |
| CrateName() string |
| nativeCoverage() bool |
| } |
| |
| type depsContext struct { |
| android.BottomUpMutatorContext |
| moduleContextImpl |
| } |
| |
| type moduleContext struct { |
| android.ModuleContext |
| moduleContextImpl |
| } |
| |
| func (ctx *moduleContextImpl) nativeCoverage() bool { |
| return ctx.mod.nativeCoverage() |
| } |
| |
| func (mod *Module) nativeCoverage() bool { |
| return mod.compiler != nil && mod.compiler.nativeCoverage() |
| } |
| |
| type moduleContextImpl struct { |
| mod *Module |
| ctx BaseModuleContext |
| } |
| |
| func (ctx *moduleContextImpl) toolchain() config.Toolchain { |
| return ctx.mod.toolchain(ctx.ctx) |
| } |
| |
| func (mod *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain { |
| if mod.cachedToolchain == nil { |
| mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch()) |
| } |
| return mod.cachedToolchain |
| } |
| |
| func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) { |
| } |
| |
| func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { |
| ctx := &moduleContext{ |
| ModuleContext: actx, |
| moduleContextImpl: moduleContextImpl{ |
| mod: mod, |
| }, |
| } |
| ctx.ctx = ctx |
| |
| toolchain := mod.toolchain(ctx) |
| |
| if !toolchain.Supported() { |
| // This toolchain's unsupported, there's nothing to do for this mod. |
| return |
| } |
| |
| deps := mod.depsToPaths(ctx) |
| flags := Flags{ |
| Toolchain: toolchain, |
| } |
| |
| if mod.compiler != nil { |
| flags = mod.compiler.compilerFlags(ctx, flags) |
| } |
| if mod.coverage != nil { |
| flags, deps = mod.coverage.flags(ctx, flags, deps) |
| } |
| |
| if mod.compiler != nil { |
| outputFile := mod.compiler.compile(ctx, flags, deps) |
| mod.outputFile = android.OptionalPathForPath(outputFile) |
| if !mod.Properties.PreventInstall { |
| mod.compiler.install(ctx, mod.outputFile.Path()) |
| } |
| } |
| } |
| |
| func (mod *Module) deps(ctx DepsContext) Deps { |
| deps := Deps{} |
| |
| if mod.compiler != nil { |
| deps = mod.compiler.compilerDeps(ctx, deps) |
| } |
| |
| if mod.coverage != nil { |
| deps = mod.coverage.deps(ctx, deps) |
| } |
| |
| deps.Rlibs = android.LastUniqueStrings(deps.Rlibs) |
| deps.Dylibs = android.LastUniqueStrings(deps.Dylibs) |
| deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros) |
| deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs) |
| deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs) |
| |
| return deps |
| |
| } |
| |
| func (ctx *moduleContextImpl) baseModuleName() string { |
| return ctx.mod.ModuleBase.BaseModuleName() |
| } |
| |
| func (ctx *moduleContextImpl) CrateName() string { |
| return ctx.mod.CrateName() |
| } |
| |
| type dependencyTag struct { |
| blueprint.BaseDependencyTag |
| name string |
| library bool |
| proc_macro bool |
| } |
| |
| var ( |
| rlibDepTag = dependencyTag{name: "rlibTag", library: true} |
| dylibDepTag = dependencyTag{name: "dylib", library: true} |
| procMacroDepTag = dependencyTag{name: "procMacro", proc_macro: true} |
| testPerSrcDepTag = dependencyTag{name: "rust_unit_tests"} |
| ) |
| |
| func (mod *Module) begin(ctx BaseModuleContext) { |
| if mod.coverage != nil { |
| mod.coverage.begin(ctx) |
| } |
| } |
| |
| func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { |
| var depPaths PathDeps |
| |
| directRlibDeps := []*Module{} |
| directDylibDeps := []*Module{} |
| directProcMacroDeps := []*Module{} |
| directSharedLibDeps := [](cc.LinkableInterface){} |
| directStaticLibDeps := [](cc.LinkableInterface){} |
| |
| ctx.VisitDirectDeps(func(dep android.Module) { |
| depName := ctx.OtherModuleName(dep) |
| depTag := ctx.OtherModuleDependencyTag(dep) |
| if rustDep, ok := dep.(*Module); ok { |
| //Handle Rust Modules |
| |
| linkFile := rustDep.outputFile |
| if !linkFile.Valid() { |
| ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) |
| } |
| |
| switch depTag { |
| case dylibDepTag: |
| dylib, ok := rustDep.compiler.(libraryInterface) |
| if !ok || !dylib.dylib() { |
| ctx.ModuleErrorf("mod %q not an dylib library", depName) |
| return |
| } |
| directDylibDeps = append(directDylibDeps, rustDep) |
| mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, depName) |
| case rlibDepTag: |
| rlib, ok := rustDep.compiler.(libraryInterface) |
| if !ok || !rlib.rlib() { |
| ctx.ModuleErrorf("mod %q not an rlib library", depName) |
| return |
| } |
| depPaths.coverageFiles = append(depPaths.coverageFiles, rustDep.CoverageFiles()...) |
| directRlibDeps = append(directRlibDeps, rustDep) |
| mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, depName) |
| case procMacroDepTag: |
| directProcMacroDeps = append(directProcMacroDeps, rustDep) |
| mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, depName) |
| } |
| |
| //Append the dependencies exportedDirs |
| if lib, ok := rustDep.compiler.(*libraryDecorator); ok { |
| depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedDirs()...) |
| depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...) |
| } |
| |
| // Append this dependencies output to this mod's linkDirs so they can be exported to dependencies |
| // This can be probably be refactored by defining a common exporter interface similar to cc's |
| if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { |
| linkDir := linkPathFromFilePath(linkFile.Path()) |
| if lib, ok := mod.compiler.(*libraryDecorator); ok { |
| lib.linkDirs = append(lib.linkDirs, linkDir) |
| } else if procMacro, ok := mod.compiler.(*procMacroDecorator); ok { |
| procMacro.linkDirs = append(procMacro.linkDirs, linkDir) |
| } |
| } |
| |
| } |
| |
| if ccDep, ok := dep.(cc.LinkableInterface); ok { |
| //Handle C dependencies |
| if _, ok := ccDep.(*Module); !ok { |
| if ccDep.Module().Target().Os != ctx.Os() { |
| ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) |
| return |
| } |
| if ccDep.Module().Target().Arch.ArchType != ctx.Arch().ArchType { |
| ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName) |
| return |
| } |
| } |
| |
| linkFile := ccDep.OutputFile() |
| linkPath := linkPathFromFilePath(linkFile.Path()) |
| libName := libNameFromFilePath(linkFile.Path()) |
| depFlag := "-l" + libName |
| |
| if !linkFile.Valid() { |
| ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) |
| } |
| |
| exportDep := false |
| switch depTag { |
| case cc.StaticDepTag: |
| depFlag = "-lstatic=" + libName |
| depPaths.linkDirs = append(depPaths.linkDirs, linkPath) |
| depPaths.depFlags = append(depPaths.depFlags, depFlag) |
| depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...) |
| directStaticLibDeps = append(directStaticLibDeps, ccDep) |
| mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName) |
| case cc.SharedDepTag: |
| depFlag = "-ldylib=" + libName |
| depPaths.linkDirs = append(depPaths.linkDirs, linkPath) |
| depPaths.depFlags = append(depPaths.depFlags, depFlag) |
| directSharedLibDeps = append(directSharedLibDeps, ccDep) |
| mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName) |
| exportDep = true |
| case cc.CrtBeginDepTag: |
| depPaths.CrtBegin = linkFile |
| case cc.CrtEndDepTag: |
| depPaths.CrtEnd = linkFile |
| } |
| |
| // Make sure these dependencies are propagated |
| if lib, ok := mod.compiler.(*libraryDecorator); ok && exportDep { |
| lib.linkDirs = append(lib.linkDirs, linkPath) |
| lib.depFlags = append(lib.depFlags, depFlag) |
| } else if procMacro, ok := mod.compiler.(*procMacroDecorator); ok && exportDep { |
| procMacro.linkDirs = append(procMacro.linkDirs, linkPath) |
| procMacro.depFlags = append(procMacro.depFlags, depFlag) |
| } |
| |
| } |
| }) |
| |
| var rlibDepFiles RustLibraries |
| for _, dep := range directRlibDeps { |
| rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()}) |
| } |
| var dylibDepFiles RustLibraries |
| for _, dep := range directDylibDeps { |
| dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()}) |
| } |
| var procMacroDepFiles RustLibraries |
| for _, dep := range directProcMacroDeps { |
| procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()}) |
| } |
| |
| var staticLibDepFiles android.Paths |
| for _, dep := range directStaticLibDeps { |
| staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path()) |
| } |
| |
| var sharedLibDepFiles android.Paths |
| for _, dep := range directSharedLibDeps { |
| sharedLibDepFiles = append(sharedLibDepFiles, dep.OutputFile().Path()) |
| } |
| |
| depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...) |
| depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...) |
| depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibDepFiles...) |
| depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...) |
| depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...) |
| |
| // Dedup exported flags from dependencies |
| depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs) |
| depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags) |
| |
| return depPaths |
| } |
| |
| func (mod *Module) InstallInData() bool { |
| if mod.compiler == nil { |
| return false |
| } |
| return mod.compiler.inData() |
| } |
| |
| func linkPathFromFilePath(filepath android.Path) string { |
| return strings.Split(filepath.String(), filepath.Base())[0] |
| } |
| |
| func libNameFromFilePath(filepath android.Path) string { |
| libName := strings.TrimSuffix(filepath.Base(), filepath.Ext()) |
| if strings.HasPrefix(libName, "lib") { |
| libName = libName[3:] |
| } |
| return libName |
| } |
| |
| func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { |
| ctx := &depsContext{ |
| BottomUpMutatorContext: actx, |
| moduleContextImpl: moduleContextImpl{ |
| mod: mod, |
| }, |
| } |
| ctx.ctx = ctx |
| |
| deps := mod.deps(ctx) |
| commonDepVariations := []blueprint.Variation{} |
| if cc.VersionVariantAvailable(mod) { |
| commonDepVariations = append(commonDepVariations, |
| blueprint.Variation{Mutator: "version", Variation: ""}) |
| } |
| if !mod.Host() { |
| commonDepVariations = append(commonDepVariations, |
| blueprint.Variation{Mutator: "image", Variation: android.CoreVariation}) |
| } |
| actx.AddVariationDependencies( |
| append(commonDepVariations, []blueprint.Variation{ |
| {Mutator: "rust_libraries", Variation: "rlib"}, |
| {Mutator: "link", Variation: ""}}...), |
| rlibDepTag, deps.Rlibs...) |
| actx.AddVariationDependencies( |
| append(commonDepVariations, []blueprint.Variation{ |
| {Mutator: "rust_libraries", Variation: "dylib"}, |
| {Mutator: "link", Variation: ""}}...), |
| dylibDepTag, deps.Dylibs...) |
| |
| actx.AddVariationDependencies(append(commonDepVariations, |
| blueprint.Variation{Mutator: "link", Variation: "shared"}), |
| cc.SharedDepTag, deps.SharedLibs...) |
| actx.AddVariationDependencies(append(commonDepVariations, |
| blueprint.Variation{Mutator: "link", Variation: "static"}), |
| cc.StaticDepTag, deps.StaticLibs...) |
| |
| if deps.CrtBegin != "" { |
| actx.AddVariationDependencies(commonDepVariations, cc.CrtBeginDepTag, deps.CrtBegin) |
| } |
| if deps.CrtEnd != "" { |
| actx.AddVariationDependencies(commonDepVariations, cc.CrtEndDepTag, deps.CrtEnd) |
| } |
| |
| // proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy. |
| actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...) |
| } |
| |
| func BeginMutator(ctx android.BottomUpMutatorContext) { |
| if mod, ok := ctx.Module().(*Module); ok && mod.Enabled() { |
| mod.beginMutator(ctx) |
| } |
| } |
| |
| type baseModuleContext struct { |
| android.BaseModuleContext |
| moduleContextImpl |
| } |
| |
| func (mod *Module) beginMutator(actx android.BottomUpMutatorContext) { |
| ctx := &baseModuleContext{ |
| BaseModuleContext: actx, |
| moduleContextImpl: moduleContextImpl{ |
| mod: mod, |
| }, |
| } |
| ctx.ctx = ctx |
| |
| mod.begin(ctx) |
| } |
| |
| func (mod *Module) Name() string { |
| name := mod.ModuleBase.Name() |
| if p, ok := mod.compiler.(interface { |
| Name(string) string |
| }); ok { |
| name = p.Name(name) |
| } |
| return name |
| } |
| |
| var Bool = proptools.Bool |
| var BoolDefault = proptools.BoolDefault |
| var String = proptools.String |
| var StringPtr = proptools.StringPtr |