diff options
Diffstat (limited to 'rust/rust.go')
| -rw-r--r-- | rust/rust.go | 560 |
1 files changed, 343 insertions, 217 deletions
diff --git a/rust/rust.go b/rust/rust.go index 7b520cdb0..9dae75ee5 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -15,10 +15,13 @@ package rust import ( - "android/soong/bloaty" "fmt" + "strconv" "strings" + "android/soong/bloaty" + "android/soong/testing" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -28,7 +31,6 @@ import ( "android/soong/fuzz" "android/soong/multitree" "android/soong/rust/config" - "android/soong/snapshot" ) var pctx = android.NewPackageContext("android/soong/rust") @@ -43,9 +45,10 @@ func init() { android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator).Parallel() }) + pctx.Import("android/soong/android") pctx.Import("android/soong/rust/config") pctx.ImportAs("cc_config", "android/soong/cc/config") - android.InitRegistrationContext.RegisterSingletonType("kythe_rust_extract", kytheExtractRustFactory) + android.InitRegistrationContext.RegisterParallelSingletonType("kythe_rust_extract", kytheExtractRustFactory) } type Flags struct { @@ -65,12 +68,12 @@ type BaseProperties struct { AndroidMkRlibs []string `blueprint:"mutated"` AndroidMkDylibs []string `blueprint:"mutated"` AndroidMkProcMacroLibs []string `blueprint:"mutated"` - AndroidMkSharedLibs []string `blueprint:"mutated"` AndroidMkStaticLibs []string `blueprint:"mutated"` + AndroidMkHeaderLibs []string `blueprint:"mutated"` - ImageVariationPrefix string `blueprint:"mutated"` - VndkVersion string `blueprint:"mutated"` - SubName string `blueprint:"mutated"` + ImageVariation 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 @@ -78,6 +81,8 @@ type BaseProperties struct { RustSubName string `blueprint:"mutated"` // Set by imageMutator + ProductVariantNeeded bool `blueprint:"mutated"` + VendorVariantNeeded bool `blueprint:"mutated"` CoreVariantNeeded bool `blueprint:"mutated"` VendorRamdiskVariantNeeded bool `blueprint:"mutated"` RamdiskVariantNeeded bool `blueprint:"mutated"` @@ -91,6 +96,8 @@ type BaseProperties struct { // Used by vendor snapshot to record dependencies from snapshot modules. SnapshotSharedLibs []string `blueprint:"mutated"` SnapshotStaticLibs []string `blueprint:"mutated"` + SnapshotRlibs []string `blueprint:"mutated"` + SnapshotDylibs []string `blueprint:"mutated"` // Make this module available when building for ramdisk. // On device without a dedicated recovery partition, the module is only @@ -139,8 +146,9 @@ type Module struct { Properties BaseProperties - hod android.HostOrDeviceSupported - multilib android.Multilib + hod android.HostOrDeviceSupported + multilib android.Multilib + testModule bool makeLinkType string @@ -153,6 +161,8 @@ type Module struct { sourceProvider SourceProvider subAndroidMkOnce map[SubAndroidMkProvider]bool + exportedLinkDirs []string + // Output file to be installed, may be stripped or unstripped. outputFile android.OptionalPath @@ -165,6 +175,8 @@ type Module struct { // For apex variants, this is set as apex.min_sdk_version apexSdkVersion android.ApiLevel + + transitiveAndroidMkSharedLibs *android.DepSet[string] } func (mod *Module) Header() bool { @@ -197,35 +209,14 @@ func (mod *Module) IsPrebuilt() bool { 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 + if library, ok := mod.compiler.(libraryInterface); ok { + return library.buildRlib() || library.buildDylib() } } panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName())) @@ -258,6 +249,24 @@ func (mod *Module) Dylib() bool { return false } +func (mod *Module) Source() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok && mod.sourceProvider != nil { + return library.source() + } + } + return false +} + +func (mod *Module) RlibStd() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok && library.rlib() { + return library.rlibStd() + } + } + panic(fmt.Errorf("RlibStd() called on non-rlib module: %q", mod.BaseModuleName())) +} + func (mod *Module) Rlib() bool { if mod.compiler != nil { if library, ok := mod.compiler.(libraryInterface); ok { @@ -314,27 +323,10 @@ 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 @@ -357,10 +349,6 @@ func (c *Module) IsLlndk() bool { return false } -func (c *Module) IsLlndkPublic() bool { - return false -} - func (mod *Module) KernelHeadersDecorator() bool { return false } @@ -420,21 +408,27 @@ type Deps struct { } type PathDeps struct { - DyLibs RustLibraries - RLibs RustLibraries - LibDeps android.Paths - WholeStaticLibs android.Paths - ProcMacros RustLibraries - AfdoProfiles android.Paths + DyLibs RustLibraries + RLibs RustLibraries + SharedLibs android.Paths + SharedLibDeps android.Paths + StaticLibs 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. + // 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 + linkObjects []string + + // exportedLinkDirs are exported linkDirs for direct rlib dependencies to + // cc_library_static dependants of rlibs. + // Track them separately from linkDirs so superfluous -L flags don't get emitted. + exportedLinkDirs []string // Used by bindgen modules which call clang depClangFlags []string @@ -457,47 +451,9 @@ type RustLibrary struct { 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) + exportLinkObjects(...string) } type xref interface { @@ -506,27 +462,22 @@ type xref interface { type flagExporter struct { linkDirs []string - linkObjects android.Paths - libDeps android.Paths + ccLinkDirs []string + linkObjects []string } 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) exportLinkObjects(flags ...string) { + flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...)) } func (flagExporter *flagExporter) setProvider(ctx ModuleContext) { - ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{ + android.SetProvider(ctx, FlagExporterInfoProvider, FlagExporterInfo{ LinkDirs: flagExporter.linkDirs, LinkObjects: flagExporter.linkObjects, - LibDeps: flagExporter.libDeps, }) } @@ -539,11 +490,10 @@ func NewFlagExporter() *flagExporter { type FlagExporterInfo struct { Flags []string LinkDirs []string // TODO: this should be android.Paths - LinkObjects android.Paths - LibDeps android.Paths + LinkObjects []string // TODO: this should be android.Paths } -var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{}) +var FlagExporterInfoProvider = blueprint.NewProvider[FlagExporterInfo]() func (mod *Module) isCoverageVariant() bool { return mod.coverage.Properties.IsCoverageVariant @@ -551,7 +501,7 @@ func (mod *Module) isCoverageVariant() bool { var _ cc.Coverage = (*Module)(nil) -func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { +func (mod *Module) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool { return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant } @@ -559,6 +509,10 @@ func (mod *Module) VndkVersion() string { return mod.Properties.VndkVersion } +func (mod *Module) ExportedCrateLinkDirs() []string { + return mod.exportedLinkDirs +} + func (mod *Module) PreventInstall() bool { return mod.Properties.PreventInstall } @@ -601,6 +555,7 @@ func DefaultsFactory(props ...interface{}) android.Module { &cc.RustBindgenClangProperties{}, &ClippyProperties{}, &SanitizeProperties{}, + &fuzz.FuzzProperties{}, ) android.InitDefaultsModule(module) @@ -631,6 +586,15 @@ func (mod *Module) CcLibraryInterface() bool { 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 @@ -649,7 +613,7 @@ func (mod *Module) FuzzPackagedModule() fuzz.FuzzPackagedModule { panic(fmt.Errorf("FuzzPackagedModule called on non-fuzz module: %q", mod.BaseModuleName())) } -func (mod *Module) FuzzSharedLibraries() android.Paths { +func (mod *Module) FuzzSharedLibraries() android.RuleBuilderInstalls { if fuzzer, ok := mod.compiler.(*fuzzDecorator); ok { return fuzzer.sharedLibraries } @@ -663,15 +627,6 @@ func (mod *Module) UnstrippedOutputFile() android.Path { 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 { @@ -701,6 +656,24 @@ func (mod *Module) BuildStaticVariant() bool { panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName())) } +func (mod *Module) BuildRlibVariant() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok { + return library.buildRlib() + } + } + panic(fmt.Errorf("BuildRlibVariant called on non-library module: %q", mod.BaseModuleName())) +} + +func (mod *Module) IsRustFFI() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok { + return library.isFFILibrary() + } + } + return false +} + func (mod *Module) BuildSharedVariant() bool { if mod.compiler != nil { if library, ok := mod.compiler.(libraryInterface); ok { @@ -753,7 +726,8 @@ func (mod *Module) installable(apexInfo android.ApexInfo) bool { } func (ctx moduleContext) apexVariationName() string { - return ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).ApexVariationName + apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) + return apexInfo.ApexVariationName } var _ cc.LinkableInterface = (*Module)(nil) @@ -903,7 +877,7 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { ModuleContext: actx, } - apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo) + apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider) if !apexInfo.IsForPlatform() { mod.hideApexVariantFromMake = true } @@ -919,6 +893,10 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } deps := mod.depsToPaths(ctx) + // Export linkDirs for CC rust generatedlibs + mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.exportedLinkDirs...) + mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.linkDirs...) + flags := Flags{ Toolchain: toolchain, } @@ -956,6 +934,7 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { sourceLib := sourceMod.(*Module).compiler.(*libraryDecorator) mod.sourceProvider.setOutputFiles(sourceLib.sourceProvider.Srcs()) } + android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: mod.sourceProvider.Srcs().Strings()}) } if mod.compiler != nil && !mod.compiler.Disabled() { @@ -975,15 +954,7 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { 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) + apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider) 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 @@ -1003,10 +974,71 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if ctx.Failed() { return } + // Export your own directory as a linkDir + mod.exportedLinkDirs = append(mod.exportedLinkDirs, linkPathFromFilePath(mod.OutputFile().Path())) + } ctx.Phony("rust", ctx.RustModule().OutputFile().Path()) } + if mod.testModule { + android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{}) + } + + mod.setOutputFiles(ctx) + + buildComplianceMetadataInfo(ctx, mod, deps) +} + +func (mod *Module) setOutputFiles(ctx ModuleContext) { + if mod.sourceProvider != nil && (mod.compiler == nil || mod.compiler.Disabled()) { + ctx.SetOutputFiles(mod.sourceProvider.Srcs(), "") + } else if mod.OutputFile().Valid() { + ctx.SetOutputFiles(android.Paths{mod.OutputFile().Path()}, "") + } else { + ctx.SetOutputFiles(android.Paths{}, "") + } + if mod.compiler != nil { + ctx.SetOutputFiles(android.PathsIfNonNil(mod.compiler.unstrippedOutputFilePath()), "unstripped") + } +} + +func buildComplianceMetadataInfo(ctx *moduleContext, mod *Module, deps PathDeps) { + // Dump metadata that can not be done in android/compliance-metadata.go + metadataInfo := ctx.ComplianceMetadataInfo() + metadataInfo.SetStringValue(android.ComplianceMetadataProp.IS_STATIC_LIB, strconv.FormatBool(mod.Static())) + metadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, mod.outputFile.String()) + + // Static libs + staticDeps := ctx.GetDirectDepsWithTag(rlibDepTag) + staticDepNames := make([]string, 0, len(staticDeps)) + for _, dep := range staticDeps { + staticDepNames = append(staticDepNames, dep.Name()) + } + ccStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(false)) + for _, dep := range ccStaticDeps { + staticDepNames = append(staticDepNames, dep.Name()) + } + + staticDepPaths := make([]string, 0, len(deps.StaticLibs)+len(deps.RLibs)) + // C static libraries + for _, dep := range deps.StaticLibs { + staticDepPaths = append(staticDepPaths, dep.String()) + } + // Rust static libraries + for _, dep := range deps.RLibs { + staticDepPaths = append(staticDepPaths, dep.Path.String()) + } + metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames)) + metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths)) + + // C Whole static libs + ccWholeStaticDeps := ctx.GetDirectDepsWithTag(cc.StaticDepTag(true)) + wholeStaticDepNames := make([]string, 0, len(ccWholeStaticDeps)) + for _, dep := range ccStaticDeps { + wholeStaticDepNames = append(wholeStaticDepNames, dep.Name()) + } + metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames)) } func (mod *Module) deps(ctx DepsContext) Deps { @@ -1062,6 +1094,12 @@ func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { return nil } +func (d dependencyTag) PropagateAconfigValidation() bool { + return d == rlibDepTag || d == sourceDepTag +} + +var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{} + var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} var ( @@ -1069,7 +1107,6 @@ var ( 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"} @@ -1117,6 +1154,11 @@ func (mod *Module) Prebuilt() *android.Prebuilt { return nil } +func (mod *Module) Symlinks() []string { + // TODO update this to return the list of symlinks when Rust supports defining symlinks + 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. @@ -1128,6 +1170,14 @@ func rustMakeLibName(ctx android.ModuleContext, c cc.LinkableInterface, dep cc.L return cc.MakeLibName(ctx, c, dep, depName) } +func collectIncludedProtos(mod *Module, dep *Module) { + if protoMod, ok := mod.sourceProvider.(*protobufDecorator); ok { + if _, ok := dep.sourceProvider.(*protobufDecorator); ok { + protoMod.additionalCrates = append(protoMod.additionalCrates, dep.CrateName()) + } + } +} + func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { var depPaths PathDeps @@ -1141,7 +1191,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // For the dependency from platform to apex, use the latest stubs mod.apexSdkVersion = android.FutureApiLevel - apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if !apexInfo.IsForPlatform() { mod.apexSdkVersion = apexInfo.MinSdkVersion } @@ -1160,7 +1210,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { ctx.VisitDirectDeps(func(dep android.Module) { if dep.Name() == "api_imports" { - apiImportInfo = ctx.OtherModuleProvider(dep, multitree.ApiImportsProvider).(multitree.ApiImportInfo) + apiImportInfo, _ = android.OtherModuleProvider(ctx, dep, multitree.ApiImportsProvider) hasApiImportInfo = true } }) @@ -1196,19 +1246,26 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { }) } + var transitiveAndroidMkSharedLibs []*android.DepSet[string] + var directAndroidMkSharedLibs []string + 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() { + + if depTag == android.DarwinUniversalVariantTag { + return + } + + if rustDep, ok := dep.(*Module); ok && !rustDep.Static() && !rustDep.Shared() { //Handle Rust Modules makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName) - switch depTag { - case dylibDepTag: + switch { + case depTag == dylibDepTag: dylib, ok := rustDep.compiler.(libraryInterface) if !ok || !dylib.dylib() { ctx.ModuleErrorf("mod %q not an dylib library", depName) @@ -1216,8 +1273,9 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } directDylibDeps = append(directDylibDeps, rustDep) mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName) - case rlibDepTag: + mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName)) + case depTag == rlibDepTag: rlib, ok := rustDep.compiler.(libraryInterface) if !ok || !rlib.rlib() { ctx.ModuleErrorf("mod %q not an rlib library", makeLibName) @@ -1225,11 +1283,36 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } directRlibDeps = append(directRlibDeps, rustDep) mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName) - case procMacroDepTag: + mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName)) + + // rust_ffi rlibs may export include dirs, so collect those here. + exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) + depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) + depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path())) + + case depTag == procMacroDepTag: directProcMacroDeps = append(directProcMacroDeps, rustDep) mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName) + // proc_macro link dirs need to be exported, so collect those here. + depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path())) + + case depTag == sourceDepTag: + if _, ok := mod.sourceProvider.(*protobufDecorator); ok { + collectIncludedProtos(mod, rustDep) + } + case cc.IsStaticDepTag(depTag): + // Rust FFI rlibs should not be declared in a Rust modules + // "static_libs" list as we can't handle them properly at the + // moment (for example, they only produce an rlib-std variant). + // Instead, a normal rust_library variant should be used. + ctx.PropertyErrorf("static_libs", + "found '%s' in static_libs; use a rust_library module in rustlibs instead of a rust_ffi module in static_libs", + depName) + } + transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs) + 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. @@ -1250,13 +1333,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep) } + exportedInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider) //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...) + depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...) } if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { @@ -1267,6 +1349,14 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } } + if depTag == sourceDepTag { + if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() { + if _, ok := rustDep.sourceProvider.(*protobufDecorator); ok { + exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) + depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) + } + } + } } else if ccDep, ok := dep.(cc.LinkableInterface); ok { //Handle C dependencies makeLibName := cc.MakeLibName(ctx, mod, ccDep, depName) @@ -1281,12 +1371,17 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } } linkObject := ccDep.OutputFile() - linkPath := linkPathFromFilePath(linkObject.Path()) - if !linkObject.Valid() { - ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) + if !ctx.Config().AllowMissingDependencies() { + ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) + } else { + ctx.AddMissingDependencies([]string{depName}) + } + return } + linkPath := linkPathFromFilePath(linkObject.Path()) + exportDep := false switch { case cc.IsStaticDepTag(depTag): @@ -1300,7 +1395,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { 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()) } @@ -1308,10 +1402,10 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // 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.linkObjects = append(depPaths.linkObjects, linkObject.String()) depPaths.linkDirs = append(depPaths.linkDirs, linkPath) - exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo) + exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) @@ -1331,10 +1425,18 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Re-get linkObject as ChooseStubOrImpl actually tells us which // object (either from stub or non-stub) to use. linkObject = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary) + if !linkObject.Valid() { + if !ctx.Config().AllowMissingDependencies() { + ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) + } else { + ctx.AddMissingDependencies([]string{depName}) + } + return + } linkPath = linkPathFromFilePath(linkObject.Path()) depPaths.linkDirs = append(depPaths.linkDirs, linkPath) - depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...) + depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String()) depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) @@ -1344,13 +1446,14 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Record baseLibName for snapshots. mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName)) - mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName) + directAndroidMkSharedLibs = append(directAndroidMkSharedLibs, makeLibName) exportDep = true case cc.IsHeaderDepTag(depTag): - exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo) + exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) + mod.Properties.AndroidMkHeaderLibs = append(mod.Properties.AndroidMkHeaderLibs, makeLibName) case depTag == cc.CrtBeginDepTag: depPaths.CrtBegin = append(depPaths.CrtBegin, linkObject.Path()) case depTag == cc.CrtEndDepTag: @@ -1360,9 +1463,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Make sure these dependencies are propagated if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep { lib.exportLinkDirs(linkPath) - if linkObject.Valid() { - lib.exportLinkObjects(linkObject.Path()) - } + lib.exportLinkObjects(linkObject.String()) } } else { switch { @@ -1381,35 +1482,53 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } }) + mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs) + var rlibDepFiles RustLibraries + aliases := mod.compiler.Aliases() for _, dep := range directRlibDeps { - rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) + crateName := dep.CrateName() + if alias, aliased := aliases[crateName]; aliased { + crateName = alias + } + rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName}) } var dylibDepFiles RustLibraries for _, dep := range directDylibDeps { - dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) + crateName := dep.CrateName() + if alias, aliased := aliases[crateName]; aliased { + crateName = alias + } + dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName}) } var procMacroDepFiles RustLibraries for _, dep := range directProcMacroDeps { - procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) + crateName := dep.CrateName() + if alias, aliased := aliases[crateName]; aliased { + crateName = alias + } + procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName}) } - var libDepFiles android.Paths + var staticLibDepFiles android.Paths for _, dep := range directStaticLibDeps { - libDepFiles = append(libDepFiles, dep.OutputFile().Path()) + staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path()) } + var sharedLibFiles android.Paths + var sharedLibDepFiles android.Paths for _, dep := range directSharedLibDeps { + sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary) if dep.TableOfContents.Valid() { - libDepFiles = append(libDepFiles, dep.TableOfContents.Path()) + sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path()) } else { - libDepFiles = append(libDepFiles, dep.SharedLibrary) + sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary) } } var srcProviderDepFiles android.Paths for _, dep := range directSrcProvidersDeps { - srcs, _ := dep.OutputFiles("") + srcs := android.OutputFilesForModule(ctx, dep, "") srcProviderDepFiles = append(srcProviderDepFiles, srcs...) } for _, dep := range directSrcDeps { @@ -1419,13 +1538,15 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...) depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...) - depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...) + depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibFiles...) + depPaths.SharedLibDeps = append(depPaths.SharedLibDeps, sharedLibDepFiles...) + depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...) 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.linkObjects = android.FirstUniqueStrings(depPaths.linkObjects) depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags) depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags) depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths) @@ -1474,7 +1595,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps := mod.deps(ctx) var commonDepVariations []blueprint.Variation - var snapshotInfo *cc.SnapshotInfo apiImportInfo := cc.GetApiImports(mod, actx) if mod.usePublicApi() || mod.useVendorApi() { @@ -1484,7 +1604,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { } if ctx.Os() == android.Android { - deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs) + deps.SharedLibs, _ = cc.FilterNdkLibs(mod, ctx.Config(), deps.SharedLibs) } stdLinkage := "dylib-std" @@ -1493,6 +1613,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { } rlibDepVariations := commonDepVariations + rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "link", Variation: ""}) if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() { rlibDepVariations = append(rlibDepVariations, @@ -1503,53 +1624,71 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { 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...) + dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation}) + dylibDepVariations = append(dylibDepVariations, blueprint.Variation{Mutator: "link", Variation: ""}) + + for _, lib := range deps.Dylibs { + actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib) + } // 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) + if deps.Rustlibs != nil { + if !mod.compiler.Disabled() { + for _, lib := range deps.Rustlibs { + autoDep := mod.compiler.(autoDeppable).autoDep(ctx) + if autoDep.depTag == rlibDepTag { + // Handle the rlib deptag case + actx.AddVariationDependencies(rlibDepVariations, rlibDepTag, lib) + } else { - // If there's no dylib dependency available, try to add the rlib dependency instead. - addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations) + // 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}) + autoDepVariations = append(autoDepVariations, blueprint.Variation{Mutator: "link", 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. + actx.AddVariationDependencies(rlibDepVariations, rlibDepTag, lib) + + } + } + } + } else if _, ok := mod.sourceProvider.(*protobufDecorator); ok { + for _, lib := range deps.Rustlibs { + srcProviderVariations := append(commonDepVariations, + blueprint.Variation{Mutator: "rust_libraries", Variation: "source"}) + srcProviderVariations = append(srcProviderVariations, blueprint.Variation{Mutator: "link", Variation: ""}) + + // Only add rustlib dependencies if they're source providers themselves. + // This is used to track which crate names need to be added to the source generated + // in the rust_protobuf mod.rs. + if actx.OtherModuleDependencyVariantExists(srcProviderVariations, lib) { + actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib) } } } } + // 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) + actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}, {Mutator: "link", Variation: ""}}...), + rlibDepTag, lib) } } else { - actx.AddVariationDependencies( - append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"}), - dylibDepTag, deps.Stdlibs...) + for _, lib := range deps.Stdlibs { + actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib) + + } } } @@ -1573,7 +1712,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { 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"}, @@ -1582,7 +1720,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { 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"}, @@ -1593,12 +1730,10 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { crtVariations := cc.GetCrtVariations(ctx, mod) for _, crt := range deps.CrtBegin { - actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, - cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects)) + actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, crt) } for _, crt := range deps.CrtEnd { - actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, - cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects)) + actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, crt) } if mod.sourceProvider != nil { @@ -1621,14 +1756,8 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { 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() { + if mod, ok := ctx.Module().(*Module); ok && mod.Enabled(ctx) { mod.beginMutator(ctx) } } @@ -1658,7 +1787,6 @@ func (mod *Module) disableClippy() { } var _ android.HostToolProvider = (*Module)(nil) -var _ snapshot.RelativeInstallPath = (*Module)(nil) func (mod *Module) HostToolPath() android.OptionalPath { if !mod.Host() { @@ -1787,5 +1915,3 @@ var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var String = proptools.String var StringPtr = proptools.StringPtr - -var _ android.OutputFileProducer = (*Module)(nil) |