summaryrefslogtreecommitdiff
path: root/rust/rust.go
diff options
context:
space:
mode:
Diffstat (limited to 'rust/rust.go')
-rw-r--r--rust/rust.go193
1 files changed, 155 insertions, 38 deletions
diff --git a/rust/rust.go b/rust/rust.go
index fc8db8655..6d6b55efe 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -15,10 +15,13 @@
package rust
import (
- "android/soong/bloaty"
"fmt"
"strings"
+ "android/soong/bazel"
+ "android/soong/bloaty"
+ "android/soong/ui/metrics/bp2build_metrics_proto"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -66,7 +69,6 @@ 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"`
@@ -168,6 +170,10 @@ type Module struct {
// For apex variants, this is set as apex.min_sdk_version
apexSdkVersion android.ApiLevel
+
+ transitiveAndroidMkSharedLibs *android.DepSet[string]
+
+ android.BazelModuleBase
}
func (mod *Module) Header() bool {
@@ -432,12 +438,18 @@ type Deps struct {
}
type PathDeps struct {
- DyLibs RustLibraries
- RLibs RustLibraries
+ Dylibs *android.DepSet[RustLibrary]
+ Rlibs *android.DepSet[RustLibrary]
+ ProcMacros *android.DepSet[RustLibrary]
LibDeps android.Paths
WholeStaticLibs android.Paths
- ProcMacros RustLibraries
AfdoProfiles android.Paths
+ // These paths are files needed to run the build tools and will be located under
+ // __SBOX_SANDBOX_DIR__/tools/...
+ BuildToolDeps android.Paths
+ // These paths are files needed to run the build tools and will be located under
+ // __SBOX_SANDBOX_DIR__/...
+ BuildToolSrcDeps android.Paths
// depFlags and depLinkFlags are rustc and linker (clang) flags.
depFlags []string
@@ -445,7 +457,7 @@ type PathDeps struct {
// 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
+ linkDirs android.Paths
linkObjects android.Paths
// Used by bindgen modules which call clang
@@ -460,6 +472,13 @@ type PathDeps struct {
// Paths to generated source files
SrcDeps android.Paths
srcProviderFiles android.Paths
+
+ // Paths to specific build tools
+ Rustc android.Path
+ Clang android.Path
+ Llvm_ar android.Path
+ Clippy_driver android.Path
+ Rustdoc android.Path
}
type RustLibraries []RustLibrary
@@ -479,6 +498,8 @@ type compiler interface {
compilerDeps(ctx DepsContext, deps Deps) Deps
crateName() string
rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath
+ crateRoot(ctx ModuleContext) android.Path
+ compilationSourcesAndData(ctx ModuleContext) android.Paths
// Output directory in which source-generated code from dependencies is
// copied. This is equivalent to Cargo's OUT_DIR variable.
@@ -508,7 +529,7 @@ type compiler interface {
}
type exportedFlagsProducer interface {
- exportLinkDirs(...string)
+ exportLinkDirs(...android.Path)
exportLinkObjects(...android.Path)
}
@@ -517,13 +538,13 @@ type xref interface {
}
type flagExporter struct {
- linkDirs []string
+ linkDirs android.Paths
linkObjects android.Paths
libDeps android.Paths
}
-func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
- flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
+func (flagExporter *flagExporter) exportLinkDirs(dirs ...android.Path) {
+ flagExporter.linkDirs = android.FirstUniquePaths(append(flagExporter.linkDirs, dirs...))
}
func (flagExporter *flagExporter) exportLinkObjects(flags ...android.Path) {
@@ -550,7 +571,7 @@ func NewFlagExporter() *flagExporter {
type FlagExporterInfo struct {
Flags []string
- LinkDirs []string // TODO: this should be android.Paths
+ LinkDirs android.Paths
LinkObjects android.Paths
LibDeps android.Paths
}
@@ -920,6 +941,14 @@ func (mod *Module) ccToolchain(ctx android.BaseModuleContext) cc_config.Toolchai
func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
+type RustInfo struct {
+ TransitiveRlibs *android.DepSet[RustLibrary]
+ TransitiveDylibs *android.DepSet[RustLibrary]
+ TransitiveProcMacros *android.DepSet[RustLibrary]
+}
+
+var RustInfoProvider = blueprint.NewProvider(RustInfo{})
+
func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
ctx := &moduleContext{
ModuleContext: actx,
@@ -1029,6 +1058,12 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
}
+
+ ctx.SetProvider(RustInfoProvider, RustInfo{
+ TransitiveRlibs: deps.Rlibs,
+ TransitiveDylibs: deps.Dylibs,
+ TransitiveProcMacros: deps.ProcMacros,
+ })
}
func (mod *Module) deps(ctx DepsContext) Deps {
@@ -1087,6 +1122,7 @@ func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
var _ android.LicenseAnnotationsDependencyTag = dependencyTag{}
var (
+ buildToolDepTag = dependencyTag{name: "buildToolTag"}
customBindgenDepTag = dependencyTag{name: "customBindgenTag"}
rlibDepTag = dependencyTag{name: "rlibTag", library: true}
dylibDepTag = dependencyTag{name: "dylib", library: true, dynamic: true}
@@ -1218,6 +1254,11 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
})
}
+ var transitiveAndroidMkSharedLibs []*android.DepSet[string]
+ var directAndroidMkSharedLibs []string
+ transitiveRlibs := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
+ transitiveDylibs := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
+ transitiveProcMacros := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
@@ -1230,6 +1271,17 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return
}
+ rustInfo := ctx.OtherModuleProvider(dep, RustInfoProvider).(RustInfo)
+ if rustInfo.TransitiveDylibs != nil {
+ transitiveDylibs.Transitive(rustInfo.TransitiveDylibs)
+ }
+ if rustInfo.TransitiveRlibs != nil {
+ transitiveRlibs.Transitive(rustInfo.TransitiveRlibs)
+ }
+ if rustInfo.TransitiveProcMacros != nil {
+ transitiveProcMacros.Transitive(rustInfo.TransitiveProcMacros)
+ }
+
if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() {
//Handle Rust Modules
makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
@@ -1244,9 +1296,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directDylibDeps = append(directDylibDeps, rustDep)
mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName)
mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName))
+ transitiveDylibs.Direct(RustLibrary{
+ Path: rustDep.UnstrippedOutputFile(),
+ CrateName: rustDep.CrateName(),
+ })
case rlibDepTag:
-
rlib, ok := rustDep.compiler.(libraryInterface)
if !ok || !rlib.rlib() {
ctx.ModuleErrorf("mod %q not an rlib library", makeLibName)
@@ -1255,12 +1310,22 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directRlibDeps = append(directRlibDeps, rustDep)
mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName))
+ transitiveRlibs.Direct(RustLibrary{
+ Path: rustDep.UnstrippedOutputFile(),
+ CrateName: rustDep.CrateName(),
+ })
case procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, rustDep)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
+ transitiveProcMacros.Direct(RustLibrary{
+ Path: rustDep.UnstrippedOutputFile(),
+ CrateName: rustDep.CrateName(),
+ })
}
+ 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.
@@ -1292,9 +1357,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
linkFile := rustDep.UnstrippedOutputFile()
- linkDir := linkPathFromFilePath(linkFile)
if lib, ok := mod.compiler.(exportedFlagsProducer); ok {
- lib.exportLinkDirs(linkDir)
+ lib.exportLinkDirs(linkFile.Dir())
}
}
@@ -1321,7 +1385,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return
}
- linkPath := linkPathFromFilePath(linkObject.Path())
+ linkPath := linkObject.Path().Dir()
exportDep := false
switch {
@@ -1375,7 +1439,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
return
}
- linkPath = linkPathFromFilePath(linkObject.Path())
+ linkPath = linkObject.Path().Dir()
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
@@ -1388,7 +1452,7 @@ 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)
@@ -1410,6 +1474,25 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
} else {
switch {
+ case depTag == buildToolDepTag:
+ buildTool := ctx.OtherModuleProvider(dep, android.PrebuiltBuildToolInfoProvider).(android.PrebuiltBuildToolInfo)
+ depPaths.BuildToolDeps = append(depPaths.BuildToolDeps, buildTool.Src)
+ depPaths.BuildToolDeps = append(depPaths.BuildToolDeps, buildTool.Deps...)
+ switch android.RemoveOptionalPrebuiltPrefix(dep.Name()) {
+ case "rustc":
+ depPaths.Rustc = buildTool.Src
+ // rustc expects the standard cc toolchain libraries (libdl, libm, libc, etc.)
+ // not to be under the __SBOX_SANDBOX_DIR__/ directory
+ depPaths.BuildToolSrcDeps = append(depPaths.BuildToolSrcDeps, buildTool.Deps...)
+ case "clang++":
+ depPaths.Clang = buildTool.Src
+ case "llvm-ar":
+ depPaths.Llvm_ar = buildTool.Src
+ case "clippy-driver":
+ depPaths.Clippy_driver = buildTool.Src
+ case "rustdoc":
+ depPaths.Rustdoc = buildTool.Src
+ }
case depTag == cc.CrtBeginDepTag:
depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, ""))
case depTag == cc.CrtEndDepTag:
@@ -1425,19 +1508,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
})
- 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())
@@ -1461,20 +1531,22 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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.linkDirs = android.FirstUniquePaths(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)
+ depPaths.Rlibs = transitiveRlibs.Build()
+ depPaths.Dylibs = transitiveDylibs.Build()
+ depPaths.ProcMacros = transitiveProcMacros.Build()
+ mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
+
return depPaths
}
@@ -1497,10 +1569,6 @@ 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()
@@ -1543,6 +1611,15 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
}
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "rustc")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "clippy-driver")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "rustdoc")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "clang++")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "clang++.real")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "lld")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "ld.lld")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "llvm-ar")
+
// rlibs
rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation})
for _, lib := range deps.Rlibs {
@@ -1833,6 +1910,46 @@ func (c *Module) Partition() string {
return ""
}
+func (m *Module) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if ctx.ModuleType() == "rust_library_host" || ctx.ModuleType() == "rust_library" {
+ libraryBp2build(ctx, m)
+ } else if ctx.ModuleType() == "rust_proc_macro" {
+ procMacroBp2build(ctx, m)
+ } else if ctx.ModuleType() == "rust_binary_host" {
+ binaryBp2build(ctx, m)
+ } else if ctx.ModuleType() == "rust_protobuf_host" {
+ protoLibraryBp2build(ctx, m)
+ } else {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
+ }
+}
+
+// This is a workaround by assuming the conventions that rust crate repos are structured
+// while waiting for the sandboxing work to complete.
+// TODO(b/297344471): When crate_root prop is set which enforces inputs sandboxing,
+// always use `srcs` and `compile_data` props to generate `srcs` and `compile_data` attributes
+// instead of using globs.
+func srcsAndCompileDataAttrs(ctx android.Bp2buildMutatorContext, c baseCompiler) (bazel.LabelList, bazel.LabelList) {
+ var srcs bazel.LabelList
+ var compileData bazel.LabelList
+
+ if c.Properties.Srcs[0] == "src/lib.rs" {
+ srcs = android.BazelLabelForModuleSrc(ctx, []string{"src/**/*.rs"})
+ compileData = android.BazelLabelForModuleSrc(
+ ctx,
+ []string{
+ "src/**/*.proto",
+ "examples/**/*.rs",
+ "**/*.md",
+ },
+ )
+ } else {
+ srcs = android.BazelLabelForModuleSrc(ctx, c.Properties.Srcs)
+ }
+
+ return srcs, compileData
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String