123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800 |
- // 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 (
- "android/soong/bloaty"
- "fmt"
- "strings"
- "github.com/google/blueprint"
- "github.com/google/blueprint/proptools"
- "android/soong/android"
- "android/soong/cc"
- cc_config "android/soong/cc/config"
- "android/soong/fuzz"
- "android/soong/multitree"
- "android/soong/rust/config"
- "android/soong/snapshot"
- )
- var pctx = android.NewPackageContext("android/soong/rust")
- func init() {
- android.RegisterModuleType("rust_defaults", defaultsFactory)
- android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
- ctx.BottomUp("rust_stdlinkage", LibstdMutator).Parallel()
- ctx.BottomUp("rust_begin", BeginMutator).Parallel()
- })
- android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator).Parallel()
- })
- pctx.Import("android/soong/rust/config")
- pctx.ImportAs("cc_config", "android/soong/cc/config")
- android.InitRegistrationContext.RegisterParallelSingletonType("kythe_rust_extract", kytheExtractRustFactory)
- }
- 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
- ClippyFlags []string // Flags that apply to clippy-driver, during the linting
- RustdocFlags []string // Flags that apply to rustdoc
- Toolchain config.Toolchain
- Coverage bool
- Clippy bool
- EmitXrefs bool // If true, emit rules to aid cross-referencing
- }
- type BaseProperties struct {
- AndroidMkRlibs []string `blueprint:"mutated"`
- AndroidMkDylibs []string `blueprint:"mutated"`
- AndroidMkProcMacroLibs []string `blueprint:"mutated"`
- AndroidMkSharedLibs []string `blueprint:"mutated"`
- AndroidMkStaticLibs []string `blueprint:"mutated"`
- ImageVariationPrefix string `blueprint:"mutated"`
- VndkVersion string `blueprint:"mutated"`
- SubName string `blueprint:"mutated"`
- // SubName is used by CC for tracking image variants / SDK versions. RustSubName is used for Rust-specific
- // subnaming which shouldn't be visible to CC modules (such as the rlib stdlinkage subname). This should be
- // appended before SubName.
- RustSubName string `blueprint:"mutated"`
- // Set by imageMutator
- CoreVariantNeeded bool `blueprint:"mutated"`
- VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
- RamdiskVariantNeeded bool `blueprint:"mutated"`
- RecoveryVariantNeeded bool `blueprint:"mutated"`
- ExtraVariants []string `blueprint:"mutated"`
- // Allows this module to use non-APEX version of libraries. Useful
- // for building binaries that are started before APEXes are activated.
- Bootstrap *bool
- // Used by vendor snapshot to record dependencies from snapshot modules.
- SnapshotSharedLibs []string `blueprint:"mutated"`
- SnapshotStaticLibs []string `blueprint:"mutated"`
- // Make this module available when building for ramdisk.
- // On device without a dedicated recovery partition, the module is only
- // available after switching root into
- // /first_stage_ramdisk. To expose the module before switching root, install
- // the recovery variant instead.
- Ramdisk_available *bool
- // Make this module available when building for vendor ramdisk.
- // On device without a dedicated recovery partition, the module is only
- // available after switching root into
- // /first_stage_ramdisk. To expose the module before switching root, install
- // the recovery variant instead
- Vendor_ramdisk_available *bool
- // Normally Soong uses the directory structure to decide which modules
- // should be included (framework) or excluded (non-framework) from the
- // different snapshots (vendor, recovery, etc.), but this property
- // allows a partner to exclude a module normally thought of as a
- // framework module from the vendor snapshot.
- Exclude_from_vendor_snapshot *bool
- // Normally Soong uses the directory structure to decide which modules
- // should be included (framework) or excluded (non-framework) from the
- // different snapshots (vendor, recovery, etc.), but this property
- // allows a partner to exclude a module normally thought of as a
- // framework module from the recovery snapshot.
- Exclude_from_recovery_snapshot *bool
- // Make this module available when building for recovery
- Recovery_available *bool
- // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
- Min_sdk_version *string
- HideFromMake bool `blueprint:"mutated"`
- PreventInstall bool `blueprint:"mutated"`
- Installable *bool
- }
- type Module struct {
- fuzz.FuzzModule
- VendorProperties cc.VendorProperties
- Properties BaseProperties
- hod android.HostOrDeviceSupported
- multilib android.Multilib
- makeLinkType string
- afdo *afdo
- compiler compiler
- coverage *coverage
- clippy *clippy
- sanitize *sanitize
- cachedToolchain config.Toolchain
- sourceProvider SourceProvider
- subAndroidMkOnce map[SubAndroidMkProvider]bool
- // Output file to be installed, may be stripped or unstripped.
- outputFile android.OptionalPath
- // Cross-reference input file
- kytheFiles android.Paths
- docTimestampFile android.OptionalPath
- hideApexVariantFromMake bool
- // For apex variants, this is set as apex.min_sdk_version
- apexSdkVersion android.ApiLevel
- }
- func (mod *Module) Header() bool {
- //TODO: If Rust libraries provide header variants, this needs to be updated.
- return false
- }
- func (mod *Module) SetPreventInstall() {
- mod.Properties.PreventInstall = true
- }
- func (mod *Module) SetHideFromMake() {
- mod.Properties.HideFromMake = true
- }
- func (mod *Module) HiddenFromMake() bool {
- return mod.Properties.HideFromMake
- }
- func (mod *Module) SanitizePropDefined() bool {
- // Because compiler is not set for some Rust modules where sanitize might be set, check that compiler is also not
- // nil since we need compiler to actually sanitize.
- return mod.sanitize != nil && mod.compiler != nil
- }
- func (mod *Module) IsPrebuilt() bool {
- if _, ok := mod.compiler.(*prebuiltLibraryDecorator); ok {
- return true
- }
- return false
- }
- func (mod *Module) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "":
- if mod.sourceProvider != nil && (mod.compiler == nil || mod.compiler.Disabled()) {
- return mod.sourceProvider.Srcs(), nil
- } else {
- if mod.OutputFile().Valid() {
- return android.Paths{mod.OutputFile().Path()}, nil
- }
- return android.Paths{}, nil
- }
- case "unstripped":
- if mod.compiler != nil {
- return android.PathsIfNonNil(mod.compiler.unstrippedOutputFilePath()), nil
- }
- return nil, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
- }
- func (mod *Module) SelectedStl() string {
- return ""
- }
- func (mod *Module) NonCcVariants() bool {
- if mod.compiler != nil {
- if _, ok := mod.compiler.(libraryInterface); ok {
- return false
- }
- }
- panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName()))
- }
- func (mod *Module) Static() bool {
- if mod.compiler != nil {
- if library, ok := mod.compiler.(libraryInterface); ok {
- return library.static()
- }
- }
- return false
- }
- func (mod *Module) Shared() bool {
- if mod.compiler != nil {
- if library, ok := mod.compiler.(libraryInterface); ok {
- return library.shared()
- }
- }
- return false
- }
- func (mod *Module) Dylib() bool {
- if mod.compiler != nil {
- if library, ok := mod.compiler.(libraryInterface); ok {
- return library.dylib()
- }
- }
- return false
- }
- func (mod *Module) Rlib() bool {
- if mod.compiler != nil {
- if library, ok := mod.compiler.(libraryInterface); ok {
- return library.rlib()
- }
- }
- return false
- }
- func (mod *Module) Binary() bool {
- if binary, ok := mod.compiler.(binaryInterface); ok {
- return binary.binary()
- }
- return false
- }
- func (mod *Module) StaticExecutable() bool {
- if !mod.Binary() {
- return false
- }
- return mod.StaticallyLinked()
- }
- func (mod *Module) Object() bool {
- // Rust has no modules which produce only object files.
- return false
- }
- func (mod *Module) Toc() android.OptionalPath {
- if mod.compiler != nil {
- if lib, ok := mod.compiler.(libraryInterface); ok {
- return lib.toc()
- }
- }
- panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName()))
- }
- func (mod *Module) UseSdk() bool {
- return false
- }
- func (mod *Module) RelativeInstallPath() string {
- if mod.compiler != nil {
- return mod.compiler.relativeInstallPath()
- }
- return ""
- }
- func (mod *Module) UseVndk() bool {
- return mod.Properties.VndkVersion != ""
- }
- func (mod *Module) Bootstrap() bool {
- return Bool(mod.Properties.Bootstrap)
- }
- func (mod *Module) MustUseVendorVariant() bool {
- return true
- }
- func (mod *Module) SubName() string {
- return mod.Properties.SubName
- }
- func (mod *Module) IsVndk() bool {
- // TODO(b/165791368)
- return false
- }
- func (mod *Module) IsVndkExt() bool {
- return false
- }
- func (mod *Module) IsVndkSp() bool {
- return false
- }
- func (mod *Module) IsVndkPrebuiltLibrary() bool {
- // Rust modules do not provide VNDK prebuilts
- return false
- }
- func (mod *Module) IsVendorPublicLibrary() bool {
- return mod.VendorProperties.IsVendorPublicLibrary
- }
- func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool {
- // Rust modules to not provide Sdk variants
- return false
- }
- func (c *Module) IsVndkPrivate() bool {
- return false
- }
- func (c *Module) IsLlndk() bool {
- return false
- }
- func (c *Module) IsLlndkPublic() bool {
- return false
- }
- func (mod *Module) KernelHeadersDecorator() bool {
- return false
- }
- func (m *Module) NeedsLlndkVariants() bool {
- return false
- }
- func (m *Module) NeedsVendorPublicLibraryVariants() bool {
- return false
- }
- func (mod *Module) HasLlndkStubs() bool {
- return false
- }
- func (mod *Module) StubsVersion() string {
- panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", mod.BaseModuleName()))
- }
- func (mod *Module) SdkVersion() string {
- return ""
- }
- func (mod *Module) AlwaysSdk() bool {
- return false
- }
- func (mod *Module) IsSdkVariant() bool {
- return false
- }
- func (mod *Module) SplitPerApiLevel() bool {
- return false
- }
- func (mod *Module) XrefRustFiles() android.Paths {
- return mod.kytheFiles
- }
- type Deps struct {
- Dylibs []string
- Rlibs []string
- Rustlibs []string
- Stdlibs []string
- ProcMacros []string
- SharedLibs []string
- StaticLibs []string
- WholeStaticLibs []string
- HeaderLibs []string
- // Used for data dependencies adjacent to tests
- DataLibs []string
- DataBins []string
- CrtBegin, CrtEnd []string
- }
- type PathDeps struct {
- DyLibs RustLibraries
- RLibs RustLibraries
- LibDeps android.Paths
- WholeStaticLibs android.Paths
- ProcMacros RustLibraries
- AfdoProfiles android.Paths
- // depFlags and depLinkFlags are rustc and linker (clang) flags.
- depFlags []string
- depLinkFlags []string
- // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker.
- // Both of these are exported and propagate to dependencies.
- linkDirs []string
- linkObjects android.Paths
- // Used by bindgen modules which call clang
- depClangFlags []string
- depIncludePaths android.Paths
- depGeneratedHeaders android.Paths
- depSystemIncludePaths android.Paths
- CrtBegin android.Paths
- CrtEnd android.Paths
- // Paths to generated source files
- SrcDeps android.Paths
- srcProviderFiles android.Paths
- }
- type RustLibraries []RustLibrary
- type RustLibrary struct {
- Path android.Path
- CrateName string
- }
- type compiler interface {
- initialize(ctx ModuleContext)
- compilerFlags(ctx ModuleContext, flags Flags) Flags
- cfgFlags(ctx ModuleContext, flags Flags) Flags
- featureFlags(ctx ModuleContext, flags Flags) Flags
- compilerProps() []interface{}
- compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput
- compilerDeps(ctx DepsContext, deps Deps) Deps
- crateName() string
- rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath
- // Output directory in which source-generated code from dependencies is
- // copied. This is equivalent to Cargo's OUT_DIR variable.
- CargoOutDir() android.OptionalPath
- // CargoPkgVersion returns the value of the Cargo_pkg_version property.
- CargoPkgVersion() string
- // CargoEnvCompat returns whether Cargo environment variables should be used.
- CargoEnvCompat() bool
- inData() bool
- install(ctx ModuleContext)
- relativeInstallPath() string
- everInstallable() bool
- nativeCoverage() bool
- Disabled() bool
- SetDisabled()
- stdLinkage(ctx *depsContext) RustLinkage
- noStdlibs() bool
- unstrippedOutputFilePath() android.Path
- strippedOutputFilePath() android.OptionalPath
- }
- type exportedFlagsProducer interface {
- exportLinkDirs(...string)
- exportLinkObjects(...android.Path)
- }
- type xref interface {
- XrefRustFiles() android.Paths
- }
- type flagExporter struct {
- linkDirs []string
- linkObjects android.Paths
- libDeps android.Paths
- }
- func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
- flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
- }
- func (flagExporter *flagExporter) exportLinkObjects(flags ...android.Path) {
- flagExporter.linkObjects = android.FirstUniquePaths(append(flagExporter.linkObjects, flags...))
- }
- func (flagExporter *flagExporter) exportLibDeps(paths ...android.Path) {
- flagExporter.libDeps = android.FirstUniquePaths(append(flagExporter.libDeps, paths...))
- }
- func (flagExporter *flagExporter) setProvider(ctx ModuleContext) {
- ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
- LinkDirs: flagExporter.linkDirs,
- LinkObjects: flagExporter.linkObjects,
- LibDeps: flagExporter.libDeps,
- })
- }
- var _ exportedFlagsProducer = (*flagExporter)(nil)
- func NewFlagExporter() *flagExporter {
- return &flagExporter{}
- }
- type FlagExporterInfo struct {
- Flags []string
- LinkDirs []string // TODO: this should be android.Paths
- LinkObjects android.Paths
- LibDeps android.Paths
- }
- var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{})
- 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) VndkVersion() string {
- return mod.Properties.VndkVersion
- }
- func (mod *Module) PreventInstall() bool {
- return mod.Properties.PreventInstall
- }
- 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{},
- &cc.AfdoProperties{},
- &cc.VendorProperties{},
- &BenchmarkProperties{},
- &BindgenProperties{},
- &BaseCompilerProperties{},
- &BinaryCompilerProperties{},
- &LibraryCompilerProperties{},
- &ProcMacroCompilerProperties{},
- &PrebuiltProperties{},
- &SourceProviderProperties{},
- &TestProperties{},
- &cc.CoverageProperties{},
- &cc.RustBindgenClangProperties{},
- &ClippyProperties{},
- &SanitizeProperties{},
- )
- 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.(libraryInterface); ok {
- return true
- }
- }
- return false
- }
- func (mod *Module) CcLibraryInterface() bool {
- if mod.compiler != nil {
- // use build{Static,Shared}() instead of {static,shared}() here because this might be called before
- // VariantIs{Static,Shared} is set.
- if lib, ok := mod.compiler.(libraryInterface); ok && (lib.buildShared() || lib.buildStatic()) {
- return true
- }
- }
- return false
- }
- func (mod *Module) RustLibraryInterface() bool {
- if mod.compiler != nil {
- if _, ok := mod.compiler.(libraryInterface); ok {
- return true
- }
- }
- return false
- }
- func (mod *Module) IsFuzzModule() bool {
- if _, ok := mod.compiler.(*fuzzDecorator); ok {
- return true
- }
- return false
- }
- func (mod *Module) FuzzModuleStruct() fuzz.FuzzModule {
- return mod.FuzzModule
- }
- func (mod *Module) FuzzPackagedModule() fuzz.FuzzPackagedModule {
- if fuzzer, ok := mod.compiler.(*fuzzDecorator); ok {
- return fuzzer.fuzzPackagedModule
- }
- panic(fmt.Errorf("FuzzPackagedModule called on non-fuzz module: %q", mod.BaseModuleName()))
- }
- func (mod *Module) FuzzSharedLibraries() android.RuleBuilderInstalls {
- if fuzzer, ok := mod.compiler.(*fuzzDecorator); ok {
- return fuzzer.sharedLibraries
- }
- panic(fmt.Errorf("FuzzSharedLibraries called on non-fuzz module: %q", mod.BaseModuleName()))
- }
- func (mod *Module) UnstrippedOutputFile() android.Path {
- if mod.compiler != nil {
- return mod.compiler.unstrippedOutputFilePath()
- }
- return nil
- }
- 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) 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()))
- }
- func (mod *Module) Module() android.Module {
- return mod
- }
- func (mod *Module) OutputFile() android.OptionalPath {
- return mod.outputFile
- }
- func (mod *Module) CoverageFiles() android.Paths {
- if mod.compiler != nil {
- return android.Paths{}
- }
- panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName()))
- }
- // Rust does not produce gcno files, and therefore does not produce a coverage archive.
- func (mod *Module) CoverageOutputFile() android.OptionalPath {
- return android.OptionalPath{}
- }
- func (mod *Module) IsNdk(config android.Config) bool {
- return false
- }
- func (mod *Module) IsStubs() bool {
- return false
- }
- func (mod *Module) installable(apexInfo android.ApexInfo) bool {
- if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) {
- return false
- }
- // The apex variant is not installable because it is included in the APEX and won't appear
- // in the system partition as a standalone file.
- if !apexInfo.IsForPlatform() {
- return false
- }
- return mod.OutputFile().Valid() && !mod.Properties.PreventInstall
- }
- func (ctx moduleContext) apexVariationName() string {
- return ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).ApexVariationName
- }
- var _ cc.LinkableInterface = (*Module)(nil)
- func (mod *Module) Init() android.Module {
- mod.AddProperties(&mod.Properties)
- mod.AddProperties(&mod.VendorProperties)
- if mod.afdo != nil {
- mod.AddProperties(mod.afdo.props()...)
- }
- if mod.compiler != nil {
- mod.AddProperties(mod.compiler.compilerProps()...)
- }
- if mod.coverage != nil {
- mod.AddProperties(mod.coverage.props()...)
- }
- if mod.clippy != nil {
- mod.AddProperties(mod.clippy.props()...)
- }
- if mod.sourceProvider != nil {
- mod.AddProperties(mod.sourceProvider.SourceProviderProps()...)
- }
- if mod.sanitize != nil {
- mod.AddProperties(mod.sanitize.props()...)
- }
- android.InitAndroidArchModule(mod, mod.hod, mod.multilib)
- android.InitApexModule(mod)
- android.InitDefaultableModule(mod)
- 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.afdo = &afdo{}
- module.coverage = &coverage{}
- module.clippy = &clippy{}
- module.sanitize = &sanitize{}
- return module
- }
- type ModuleContext interface {
- android.ModuleContext
- ModuleContextIntf
- }
- type BaseModuleContext interface {
- android.BaseModuleContext
- ModuleContextIntf
- }
- type DepsContext interface {
- android.BottomUpMutatorContext
- ModuleContextIntf
- }
- type ModuleContextIntf interface {
- RustModule() *Module
- toolchain() config.Toolchain
- }
- type depsContext struct {
- android.BottomUpMutatorContext
- }
- type moduleContext struct {
- android.ModuleContext
- }
- type baseModuleContext struct {
- android.BaseModuleContext
- }
- func (ctx *moduleContext) RustModule() *Module {
- return ctx.Module().(*Module)
- }
- func (ctx *moduleContext) toolchain() config.Toolchain {
- return ctx.RustModule().toolchain(ctx)
- }
- func (ctx *depsContext) RustModule() *Module {
- return ctx.Module().(*Module)
- }
- func (ctx *depsContext) toolchain() config.Toolchain {
- return ctx.RustModule().toolchain(ctx)
- }
- func (ctx *baseModuleContext) RustModule() *Module {
- return ctx.Module().(*Module)
- }
- func (ctx *baseModuleContext) toolchain() config.Toolchain {
- return ctx.RustModule().toolchain(ctx)
- }
- func (mod *Module) nativeCoverage() bool {
- // Bug: http://b/137883967 - native-bridge modules do not currently work with coverage
- if mod.Target().NativeBridge == android.NativeBridgeEnabled {
- return false
- }
- return mod.compiler != nil && mod.compiler.nativeCoverage()
- }
- func (mod *Module) EverInstallable() bool {
- return mod.compiler != nil &&
- // Check to see whether the module is actually ever installable.
- mod.compiler.everInstallable()
- }
- func (mod *Module) Installable() *bool {
- return mod.Properties.Installable
- }
- func (mod *Module) ProcMacro() bool {
- if pm, ok := mod.compiler.(procMacroInterface); ok {
- return pm.ProcMacro()
- }
- return false
- }
- 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 (mod *Module) ccToolchain(ctx android.BaseModuleContext) cc_config.Toolchain {
- return cc_config.FindToolchain(ctx.Os(), ctx.Arch())
- }
- func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- }
- func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
- ctx := &moduleContext{
- ModuleContext: actx,
- }
- apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
- if !apexInfo.IsForPlatform() {
- mod.hideApexVariantFromMake = true
- }
- toolchain := mod.toolchain(ctx)
- mod.makeLinkType = cc.GetMakeLinkType(actx, mod)
- mod.Properties.SubName = cc.GetSubnameProperty(actx, mod)
- if !toolchain.Supported() {
- // This toolchain's unsupported, there's nothing to do for this mod.
- return
- }
- deps := mod.depsToPaths(ctx)
- flags := Flags{
- Toolchain: toolchain,
- }
- // Calculate rustc flags
- if mod.afdo != nil {
- flags, deps = mod.afdo.flags(actx, flags, deps)
- }
- if mod.compiler != nil {
- flags = mod.compiler.compilerFlags(ctx, flags)
- flags = mod.compiler.cfgFlags(ctx, flags)
- flags = mod.compiler.featureFlags(ctx, flags)
- }
- if mod.coverage != nil {
- flags, deps = mod.coverage.flags(ctx, flags, deps)
- }
- if mod.clippy != nil {
- flags, deps = mod.clippy.flags(ctx, flags, deps)
- }
- if mod.sanitize != nil {
- flags, deps = mod.sanitize.flags(ctx, flags, deps)
- }
- // SourceProvider needs to call GenerateSource() before compiler calls
- // compile() so it can provide the source. A SourceProvider has
- // multiple variants (e.g. source, rlib, dylib). Only the "source"
- // variant is responsible for effectively generating the source. The
- // remaining variants relies on the "source" variant output.
- if mod.sourceProvider != nil {
- if mod.compiler.(libraryInterface).source() {
- mod.sourceProvider.GenerateSource(ctx, deps)
- mod.sourceProvider.setSubName(ctx.ModuleSubDir())
- } else {
- sourceMod := actx.GetDirectDepWithTag(mod.Name(), sourceDepTag)
- sourceLib := sourceMod.(*Module).compiler.(*libraryDecorator)
- mod.sourceProvider.setOutputFiles(sourceLib.sourceProvider.Srcs())
- }
- }
- if mod.compiler != nil && !mod.compiler.Disabled() {
- mod.compiler.initialize(ctx)
- buildOutput := mod.compiler.compile(ctx, flags, deps)
- if ctx.Failed() {
- return
- }
- mod.outputFile = android.OptionalPathForPath(buildOutput.outputFile)
- if buildOutput.kytheFile != nil {
- mod.kytheFiles = append(mod.kytheFiles, buildOutput.kytheFile)
- }
- bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), android.OptionalPathForPath(mod.compiler.unstrippedOutputFilePath()))
- mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps)
- if mod.docTimestampFile.Valid() {
- ctx.CheckbuildFile(mod.docTimestampFile.Path())
- }
- // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
- // RECOVERY_SNAPSHOT_VERSION is current.
- if lib, ok := mod.compiler.(snapshotLibraryInterface); ok {
- if cc.ShouldCollectHeadersForSnapshot(ctx, mod, apexInfo) {
- lib.collectHeadersForSnapshot(ctx, deps)
- }
- }
- apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
- if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) && !mod.ProcMacro() {
- // If the module has been specifically configure to not be installed then
- // hide from make as otherwise it will break when running inside make as the
- // output path to install will not be specified. Not all uninstallable
- // modules can be hidden from make as some are needed for resolving make
- // side dependencies. In particular, proc-macros need to be captured in the
- // host snapshot.
- mod.HideFromMake()
- } else if !mod.installable(apexInfo) {
- mod.SkipInstall()
- }
- // Still call install though, the installs will be stored as PackageSpecs to allow
- // using the outputs in a genrule.
- if mod.OutputFile().Valid() {
- mod.compiler.install(ctx)
- if ctx.Failed() {
- return
- }
- }
- ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
- }
- }
- func (mod *Module) deps(ctx DepsContext) Deps {
- deps := Deps{}
- if mod.compiler != nil {
- deps = mod.compiler.compilerDeps(ctx, deps)
- }
- if mod.sourceProvider != nil {
- deps = mod.sourceProvider.SourceProviderDeps(ctx, deps)
- }
- if mod.coverage != nil {
- deps = mod.coverage.deps(ctx, deps)
- }
- if mod.sanitize != nil {
- deps = mod.sanitize.deps(ctx, deps)
- }
- deps.Rlibs = android.LastUniqueStrings(deps.Rlibs)
- deps.Dylibs = android.LastUniqueStrings(deps.Dylibs)
- deps.Rustlibs = android.LastUniqueStrings(deps.Rustlibs)
- deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros)
- deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
- deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
- deps.Stdlibs = android.LastUniqueStrings(deps.Stdlibs)
- deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs)
- return deps
- }
- type dependencyTag struct {
- blueprint.BaseDependencyTag
- name string
- library bool
- procMacro bool
- dynamic bool
- }
- // InstallDepNeeded returns true for rlibs, dylibs, and proc macros so that they or their transitive
- // dependencies (especially C/C++ shared libs) are installed as dependencies of a rust binary.
- func (d dependencyTag) InstallDepNeeded() bool {
- return d.library || d.procMacro
- }
- var _ android.InstallNeededDependencyTag = dependencyTag{}
- func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
- if d.library && d.dynamic {
- return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
- }
- return nil
- }
- var _ android.LicenseAnnotationsDependencyTag = dependencyTag{}
- var (
- customBindgenDepTag = dependencyTag{name: "customBindgenTag"}
- rlibDepTag = dependencyTag{name: "rlibTag", library: true}
- dylibDepTag = dependencyTag{name: "dylib", library: true, dynamic: true}
- procMacroDepTag = dependencyTag{name: "procMacro", procMacro: true}
- testPerSrcDepTag = dependencyTag{name: "rust_unit_tests"}
- sourceDepTag = dependencyTag{name: "source"}
- dataLibDepTag = dependencyTag{name: "data lib"}
- dataBinDepTag = dependencyTag{name: "data bin"}
- )
- func IsDylibDepTag(depTag blueprint.DependencyTag) bool {
- tag, ok := depTag.(dependencyTag)
- return ok && tag == dylibDepTag
- }
- func IsRlibDepTag(depTag blueprint.DependencyTag) bool {
- tag, ok := depTag.(dependencyTag)
- return ok && tag == rlibDepTag
- }
- type autoDep struct {
- variation string
- depTag dependencyTag
- }
- var (
- rlibVariation = "rlib"
- dylibVariation = "dylib"
- rlibAutoDep = autoDep{variation: rlibVariation, depTag: rlibDepTag}
- dylibAutoDep = autoDep{variation: dylibVariation, depTag: dylibDepTag}
- )
- type autoDeppable interface {
- autoDep(ctx android.BottomUpMutatorContext) autoDep
- }
- func (mod *Module) begin(ctx BaseModuleContext) {
- if mod.coverage != nil {
- mod.coverage.begin(ctx)
- }
- if mod.sanitize != nil {
- mod.sanitize.begin(ctx)
- }
- }
- func (mod *Module) Prebuilt() *android.Prebuilt {
- if p, ok := mod.compiler.(rustPrebuilt); ok {
- return p.prebuilt()
- }
- return nil
- }
- func rustMakeLibName(ctx android.ModuleContext, c cc.LinkableInterface, dep cc.LinkableInterface, depName string) string {
- if rustDep, ok := dep.(*Module); ok {
- // Use base module name for snapshots when exporting to Makefile.
- if snapshotPrebuilt, ok := rustDep.compiler.(cc.SnapshotInterface); ok {
- baseName := rustDep.BaseModuleName()
- return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix() + rustDep.AndroidMkSuffix()
- }
- }
- return cc.MakeLibName(ctx, c, dep, depName)
- }
- func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
- var depPaths PathDeps
- directRlibDeps := []*Module{}
- directDylibDeps := []*Module{}
- directProcMacroDeps := []*Module{}
- directSharedLibDeps := []cc.SharedLibraryInfo{}
- directStaticLibDeps := [](cc.LinkableInterface){}
- directSrcProvidersDeps := []*Module{}
- directSrcDeps := [](android.SourceFileProducer){}
- // For the dependency from platform to apex, use the latest stubs
- mod.apexSdkVersion = android.FutureApiLevel
- apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
- if !apexInfo.IsForPlatform() {
- mod.apexSdkVersion = apexInfo.MinSdkVersion
- }
- if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
- // In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
- // so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
- // (b/144430859)
- mod.apexSdkVersion = android.FutureApiLevel
- }
- skipModuleList := map[string]bool{}
- var apiImportInfo multitree.ApiImportInfo
- hasApiImportInfo := false
- ctx.VisitDirectDeps(func(dep android.Module) {
- if dep.Name() == "api_imports" {
- apiImportInfo = ctx.OtherModuleProvider(dep, multitree.ApiImportsProvider).(multitree.ApiImportInfo)
- hasApiImportInfo = true
- }
- })
- if hasApiImportInfo {
- targetStubModuleList := map[string]string{}
- targetOrigModuleList := map[string]string{}
- // Search for dependency which both original module and API imported library with APEX stub exists
- ctx.VisitDirectDeps(func(dep android.Module) {
- depName := ctx.OtherModuleName(dep)
- if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok {
- targetStubModuleList[apiLibrary] = depName
- }
- })
- ctx.VisitDirectDeps(func(dep android.Module) {
- depName := ctx.OtherModuleName(dep)
- if origLibrary, ok := targetStubModuleList[depName]; ok {
- targetOrigModuleList[origLibrary] = depName
- }
- })
- // Decide which library should be used between original and API imported library
- ctx.VisitDirectDeps(func(dep android.Module) {
- depName := ctx.OtherModuleName(dep)
- if apiLibrary, ok := targetOrigModuleList[depName]; ok {
- if cc.ShouldUseStubForApex(ctx, dep) {
- skipModuleList[depName] = true
- } else {
- skipModuleList[apiLibrary] = true
- }
- }
- })
- }
- ctx.VisitDirectDeps(func(dep android.Module) {
- depName := ctx.OtherModuleName(dep)
- depTag := ctx.OtherModuleDependencyTag(dep)
- if _, exists := skipModuleList[depName]; exists {
- return
- }
- if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() {
- //Handle Rust Modules
- makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
- 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, makeLibName)
- case rlibDepTag:
- rlib, ok := rustDep.compiler.(libraryInterface)
- if !ok || !rlib.rlib() {
- ctx.ModuleErrorf("mod %q not an rlib library", makeLibName)
- return
- }
- directRlibDeps = append(directRlibDeps, rustDep)
- mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
- case procMacroDepTag:
- directProcMacroDeps = append(directProcMacroDeps, rustDep)
- mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
- }
- if android.IsSourceDepTagWithOutputTag(depTag, "") {
- // Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
- // OS/Arch variant is used.
- var helper string
- if ctx.Host() {
- helper = "missing 'host_supported'?"
- } else {
- helper = "device module defined?"
- }
- if dep.Target().Os != ctx.Os() {
- ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper)
- return
- } else if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
- ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper)
- return
- }
- directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
- }
- //Append the dependencies exportedDirs, except for proc-macros which target a different arch/OS
- if depTag != procMacroDepTag {
- exportedInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
- depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
- depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
- depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
- depPaths.LibDeps = append(depPaths.LibDeps, exportedInfo.LibDeps...)
- }
- if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
- linkFile := rustDep.UnstrippedOutputFile()
- linkDir := linkPathFromFilePath(linkFile)
- if lib, ok := mod.compiler.(exportedFlagsProducer); ok {
- lib.exportLinkDirs(linkDir)
- }
- }
- } else if ccDep, ok := dep.(cc.LinkableInterface); ok {
- //Handle C dependencies
- makeLibName := cc.MakeLibName(ctx, mod, ccDep, depName)
- 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
- }
- }
- linkObject := ccDep.OutputFile()
- linkPath := linkPathFromFilePath(linkObject.Path())
- if !linkObject.Valid() {
- ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
- }
- exportDep := false
- switch {
- case cc.IsStaticDepTag(depTag):
- if cc.IsWholeStaticLib(depTag) {
- // rustc will bundle static libraries when they're passed with "-lstatic=<lib>". This will fail
- // if the library is not prefixed by "lib".
- if mod.Binary() {
- // Binaries may sometimes need to link whole static libraries that don't start with 'lib'.
- // Since binaries don't need to 'rebundle' these like libraries and only use these for the
- // final linkage, pass the args directly to the linker to handle these cases.
- depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", linkObject.Path().String(), "-Wl,--no-whole-archive"}...)
- } else if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
- depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
- depPaths.WholeStaticLibs = append(depPaths.WholeStaticLibs, linkObject.Path())
- } else {
- ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName())
- }
- }
- // Add this to linkObjects to pass the library directly to the linker as well. This propagates
- // to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant.
- depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
- depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
- exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
- depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
- depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
- depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
- depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
- directStaticLibDeps = append(directStaticLibDeps, ccDep)
- // Record baseLibName for snapshots.
- mod.Properties.SnapshotStaticLibs = append(mod.Properties.SnapshotStaticLibs, cc.BaseLibName(depName))
- mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, makeLibName)
- case cc.IsSharedDepTag(depTag):
- // For the shared lib dependencies, we may link to the stub variant
- // of the dependency depending on the context (e.g. if this
- // dependency crosses the APEX boundaries).
- sharedLibraryInfo, exportedInfo := cc.ChooseStubOrImpl(ctx, dep)
- // Re-get linkObject as ChooseStubOrImpl actually tells us which
- // object (either from stub or non-stub) to use.
- linkObject = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary)
- linkPath = linkPathFromFilePath(linkObject.Path())
- depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
- depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
- depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
- depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
- depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
- depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
- directSharedLibDeps = append(directSharedLibDeps, sharedLibraryInfo)
- // Record baseLibName for snapshots.
- mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName))
- mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName)
- exportDep = true
- case cc.IsHeaderDepTag(depTag):
- exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
- depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
- depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
- depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
- case depTag == cc.CrtBeginDepTag:
- depPaths.CrtBegin = append(depPaths.CrtBegin, linkObject.Path())
- case depTag == cc.CrtEndDepTag:
- depPaths.CrtEnd = append(depPaths.CrtEnd, linkObject.Path())
- }
- // Make sure these dependencies are propagated
- if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep {
- lib.exportLinkDirs(linkPath)
- if linkObject.Valid() {
- lib.exportLinkObjects(linkObject.Path())
- }
- }
- } else {
- switch {
- case depTag == cc.CrtBeginDepTag:
- depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, ""))
- case depTag == cc.CrtEndDepTag:
- depPaths.CrtEnd = append(depPaths.CrtEnd, android.OutputFileForModule(ctx, dep, ""))
- }
- }
- if srcDep, ok := dep.(android.SourceFileProducer); ok {
- if android.IsSourceDepTagWithOutputTag(depTag, "") {
- // These are usually genrules which don't have per-target variants.
- directSrcDeps = append(directSrcDeps, srcDep)
- }
- }
- })
- var rlibDepFiles RustLibraries
- for _, dep := range directRlibDeps {
- rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
- }
- var dylibDepFiles RustLibraries
- for _, dep := range directDylibDeps {
- dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
- }
- var procMacroDepFiles RustLibraries
- for _, dep := range directProcMacroDeps {
- procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
- }
- var libDepFiles android.Paths
- for _, dep := range directStaticLibDeps {
- libDepFiles = append(libDepFiles, dep.OutputFile().Path())
- }
- for _, dep := range directSharedLibDeps {
- if dep.TableOfContents.Valid() {
- libDepFiles = append(libDepFiles, dep.TableOfContents.Path())
- } else {
- libDepFiles = append(libDepFiles, dep.SharedLibrary)
- }
- }
- var srcProviderDepFiles android.Paths
- for _, dep := range directSrcProvidersDeps {
- srcs, _ := dep.OutputFiles("")
- srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
- }
- for _, dep := range directSrcDeps {
- srcs := dep.Srcs()
- srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
- }
- depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
- depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
- depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...)
- depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
- depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
- // Dedup exported flags from dependencies
- depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
- depPaths.linkObjects = android.FirstUniquePaths(depPaths.linkObjects)
- depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
- depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
- depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
- depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths)
- return depPaths
- }
- func (mod *Module) InstallInData() bool {
- if mod.compiler == nil {
- return false
- }
- return mod.compiler.inData()
- }
- func (mod *Module) InstallInRamdisk() bool {
- return mod.InRamdisk()
- }
- func (mod *Module) InstallInVendorRamdisk() bool {
- return mod.InVendorRamdisk()
- }
- func (mod *Module) InstallInRecovery() bool {
- return mod.InRecovery()
- }
- func linkPathFromFilePath(filepath android.Path) string {
- return strings.Split(filepath.String(), filepath.Base())[0]
- }
- // usePublicApi returns true if the rust variant should link against NDK (publicapi)
- func (r *Module) usePublicApi() bool {
- return r.Device() && r.UseSdk()
- }
- // useVendorApi returns true if the rust variant should link against LLNDK (vendorapi)
- func (r *Module) useVendorApi() bool {
- return r.Device() && (r.InVendor() || r.InProduct())
- }
- func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
- ctx := &depsContext{
- BottomUpMutatorContext: actx,
- }
- deps := mod.deps(ctx)
- var commonDepVariations []blueprint.Variation
- var snapshotInfo *cc.SnapshotInfo
- apiImportInfo := cc.GetApiImports(mod, actx)
- if mod.usePublicApi() || mod.useVendorApi() {
- for idx, lib := range deps.SharedLibs {
- deps.SharedLibs[idx] = cc.GetReplaceModuleName(lib, apiImportInfo.SharedLibs)
- }
- }
- if ctx.Os() == android.Android {
- deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs)
- }
- stdLinkage := "dylib-std"
- if mod.compiler.stdLinkage(ctx) == RlibLinkage {
- stdLinkage = "rlib-std"
- }
- rlibDepVariations := commonDepVariations
- if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
- rlibDepVariations = append(rlibDepVariations,
- blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
- }
- // rlibs
- rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation})
- for _, lib := range deps.Rlibs {
- depTag := rlibDepTag
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
- actx.AddVariationDependencies(rlibDepVariations, depTag, lib)
- }
- // dylibs
- actx.AddVariationDependencies(
- append(commonDepVariations, []blueprint.Variation{
- {Mutator: "rust_libraries", Variation: dylibVariation}}...),
- dylibDepTag, deps.Dylibs...)
- // rustlibs
- if deps.Rustlibs != nil && !mod.compiler.Disabled() {
- autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
- for _, lib := range deps.Rustlibs {
- if autoDep.depTag == rlibDepTag {
- // Handle the rlib deptag case
- addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations)
- } else {
- // autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however.
- // Check for the existence of the dylib deptag variant. Select it if available,
- // otherwise select the rlib variant.
- autoDepVariations := append(commonDepVariations,
- blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
- if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) {
- actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib)
- } else {
- // If there's no dylib dependency available, try to add the rlib dependency instead.
- addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations)
- }
- }
- }
- }
- // stdlibs
- if deps.Stdlibs != nil {
- if mod.compiler.stdLinkage(ctx) == RlibLinkage {
- for _, lib := range deps.Stdlibs {
- depTag := rlibDepTag
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
- actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
- depTag, lib)
- }
- } else {
- actx.AddVariationDependencies(
- append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"}),
- dylibDepTag, deps.Stdlibs...)
- }
- }
- for _, lib := range deps.SharedLibs {
- depTag := cc.SharedDepTag()
- name, version := cc.StubsLibNameAndVersion(lib)
- variations := []blueprint.Variation{
- {Mutator: "link", Variation: "shared"},
- }
- // For core variant, add a dep on the implementation (if it exists) and its .apiimport (if it exists)
- // GenerateAndroidBuildActions will pick the correct impl/stub based on the api_domain boundary
- if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) {
- cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
- }
- if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok {
- cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, apiLibraryName, version, false)
- }
- }
- for _, lib := range deps.WholeStaticLibs {
- depTag := cc.StaticDepTag(true)
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
- actx.AddVariationDependencies([]blueprint.Variation{
- {Mutator: "link", Variation: "static"},
- }, depTag, lib)
- }
- for _, lib := range deps.StaticLibs {
- depTag := cc.StaticDepTag(false)
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
- actx.AddVariationDependencies([]blueprint.Variation{
- {Mutator: "link", Variation: "static"},
- }, depTag, lib)
- }
- actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...)
- crtVariations := cc.GetCrtVariations(ctx, mod)
- for _, crt := range deps.CrtBegin {
- actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag,
- cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
- }
- for _, crt := range deps.CrtEnd {
- actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag,
- cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
- }
- if mod.sourceProvider != nil {
- if bindgen, ok := mod.sourceProvider.(*bindgenDecorator); ok &&
- bindgen.Properties.Custom_bindgen != "" {
- actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), customBindgenDepTag,
- bindgen.Properties.Custom_bindgen)
- }
- }
- actx.AddVariationDependencies([]blueprint.Variation{
- {Mutator: "link", Variation: "shared"},
- }, dataLibDepTag, deps.DataLibs...)
- actx.AddVariationDependencies(nil, dataBinDepTag, deps.DataBins...)
- // 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...)
- mod.afdo.addDep(ctx, actx)
- }
- // addRlibDependency will add an rlib dependency, rewriting to the snapshot library if available.
- func addRlibDependency(actx android.BottomUpMutatorContext, lib string, mod *Module, snapshotInfo **cc.SnapshotInfo, variations []blueprint.Variation) {
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, snapshotInfo, actx).Rlibs)
- actx.AddVariationDependencies(variations, rlibDepTag, lib)
- }
- func BeginMutator(ctx android.BottomUpMutatorContext) {
- if mod, ok := ctx.Module().(*Module); ok && mod.Enabled() {
- mod.beginMutator(ctx)
- }
- }
- func (mod *Module) beginMutator(actx android.BottomUpMutatorContext) {
- ctx := &baseModuleContext{
- BaseModuleContext: actx,
- }
- 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
- }
- func (mod *Module) disableClippy() {
- if mod.clippy != nil {
- mod.clippy.Properties.Clippy_lints = proptools.StringPtr("none")
- }
- }
- var _ android.HostToolProvider = (*Module)(nil)
- var _ snapshot.RelativeInstallPath = (*Module)(nil)
- func (mod *Module) HostToolPath() android.OptionalPath {
- if !mod.Host() {
- return android.OptionalPath{}
- }
- if binary, ok := mod.compiler.(*binaryDecorator); ok {
- return android.OptionalPathForPath(binary.baseCompiler.path)
- } else if pm, ok := mod.compiler.(*procMacroDecorator); ok {
- // Even though proc-macros aren't strictly "tools", since they target the compiler
- // and act as compiler plugins, we treat them similarly.
- return android.OptionalPathForPath(pm.baseCompiler.path)
- }
- return android.OptionalPath{}
- }
- var _ android.ApexModule = (*Module)(nil)
- func (mod *Module) MinSdkVersion() string {
- return String(mod.Properties.Min_sdk_version)
- }
- // Implements android.ApexModule
- func (mod *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
- minSdkVersion := mod.MinSdkVersion()
- if minSdkVersion == "apex_inherit" {
- return nil
- }
- if minSdkVersion == "" {
- return fmt.Errorf("min_sdk_version is not specificed")
- }
- // Not using nativeApiLevelFromUser because the context here is not
- // necessarily a native context.
- ver, err := android.ApiLevelFromUser(ctx, minSdkVersion)
- if err != nil {
- return err
- }
- if ver.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", ver)
- }
- return nil
- }
- // Implements android.ApexModule
- func (mod *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
- depTag := ctx.OtherModuleDependencyTag(dep)
- if ccm, ok := dep.(*cc.Module); ok {
- if ccm.HasStubsVariants() {
- if cc.IsSharedDepTag(depTag) {
- // dynamic dep to a stubs lib crosses APEX boundary
- return false
- }
- if cc.IsRuntimeDepTag(depTag) {
- // runtime dep to a stubs lib also crosses APEX boundary
- return false
- }
- if cc.IsHeaderDepTag(depTag) {
- return false
- }
- }
- if mod.Static() && cc.IsSharedDepTag(depTag) {
- // shared_lib dependency from a static lib is considered as crossing
- // the APEX boundary because the dependency doesn't actually is
- // linked; the dependency is used only during the compilation phase.
- return false
- }
- }
- if depTag == procMacroDepTag || depTag == customBindgenDepTag {
- return false
- }
- return true
- }
- // Overrides ApexModule.IsInstallabeToApex()
- func (mod *Module) IsInstallableToApex() bool {
- if mod.compiler != nil {
- if lib, ok := mod.compiler.(libraryInterface); ok && (lib.shared() || lib.dylib()) {
- return true
- }
- if _, ok := mod.compiler.(*binaryDecorator); ok {
- return true
- }
- }
- return false
- }
- // If a library file has a "lib" prefix, extract the library name without the prefix.
- func libNameFromFilePath(filepath android.Path) (string, bool) {
- libName := strings.TrimSuffix(filepath.Base(), filepath.Ext())
- if strings.HasPrefix(libName, "lib") {
- libName = libName[3:]
- return libName, true
- }
- return "", false
- }
- func kytheExtractRustFactory() android.Singleton {
- return &kytheExtractRustSingleton{}
- }
- type kytheExtractRustSingleton struct {
- }
- func (k kytheExtractRustSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- var xrefTargets android.Paths
- ctx.VisitAllModules(func(module android.Module) {
- if rustModule, ok := module.(xref); ok {
- xrefTargets = append(xrefTargets, rustModule.XrefRustFiles()...)
- }
- })
- if len(xrefTargets) > 0 {
- ctx.Phony("xref_rust", xrefTargets...)
- }
- }
- func (c *Module) Partition() string {
- return ""
- }
- var Bool = proptools.Bool
- var BoolDefault = proptools.BoolDefault
- var String = proptools.String
- var StringPtr = proptools.StringPtr
- var _ android.OutputFileProducer = (*Module)(nil)
|