Convert rust_libraries and rust_stdlinkage mutators to TransitionMutators

Replace rust.LibraryMutator and rust.LibstdMutator with
TransitionMutators.

Bug: 319288033
Flag: EXEMPT refactor
Test: all soong tests pass
Test: no change to build.ninja
Change-Id: Ia24a582119d39889279d7b93bac9259685153619
This commit is contained in:
Colin Cross
2024-05-20 12:22:27 -07:00
parent 17f9dc5f76
commit 8a49a3dd76
9 changed files with 172 additions and 138 deletions

View File

@@ -99,7 +99,6 @@ endif`,
}, },
}, },
}, },
} }
func TestParse(t *testing.T) { func TestParse(t *testing.T) {

View File

@@ -703,7 +703,6 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeM
rustLibVariations := append( rustLibVariations := append(
target.Variations(), []blueprint.Variation{ target.Variations(), []blueprint.Variation{
{Mutator: "rust_libraries", Variation: "dylib"}, {Mutator: "rust_libraries", Variation: "dylib"},
{Mutator: "link", Variation: ""},
}..., }...,
) )

View File

@@ -47,7 +47,7 @@ func (cov *coverage) deps(ctx DepsContext, deps Deps) Deps {
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency. // no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() { if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
ctx.AddVariationDependencies([]blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}, {Mutator: "link", Variation: ""}}, rlibDepTag, ProfilerBuiltins) ctx.AddVariationDependencies([]blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}, rlibDepTag, ProfilerBuiltins)
} }
} }

View File

@@ -20,6 +20,8 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/google/blueprint"
"android/soong/android" "android/soong/android"
"android/soong/cc" "android/soong/cc"
) )
@@ -692,31 +694,28 @@ func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name stri
} }
} }
// LibraryMutator mutates the libraries into variants according to the type libraryTransitionMutator struct{}
// build{Rlib,Dylib} attributes.
func LibraryMutator(mctx android.BottomUpMutatorContext) { func (libraryTransitionMutator) Split(ctx android.BaseModuleContext) []string {
// Only mutate on Rust libraries. m, ok := ctx.Module().(*Module)
m, ok := mctx.Module().(*Module)
if !ok || m.compiler == nil { if !ok || m.compiler == nil {
return return []string{""}
} }
library, ok := m.compiler.(libraryInterface) library, ok := m.compiler.(libraryInterface)
if !ok { if !ok {
return return []string{""}
} }
// Don't produce rlib/dylib/source variants for shared or static variants // Don't produce rlib/dylib/source variants for shared or static variants
if library.shared() || library.static() { if library.shared() || library.static() {
return return []string{""}
} }
var variants []string var variants []string
// The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib) // The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
// depend on this variant. It must be the first variant to be declared. // depend on this variant. It must be the first variant to be declared.
sourceVariant := false
if m.sourceProvider != nil { if m.sourceProvider != nil {
variants = append(variants, "source") variants = append(variants, sourceVariation)
sourceVariant = true
} }
if library.buildRlib() { if library.buildRlib() {
variants = append(variants, rlibVariation) variants = append(variants, rlibVariation)
@@ -726,82 +725,128 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
} }
if len(variants) == 0 { if len(variants) == 0 {
return []string{""}
}
return variants
}
func (libraryTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
return ""
}
func (libraryTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
m, ok := ctx.Module().(*Module)
if !ok || m.compiler == nil {
return ""
}
library, ok := m.compiler.(libraryInterface)
if !ok {
return ""
}
if incomingVariation == "" {
if m.sourceProvider != nil {
return sourceVariation
}
if library.shared() {
return ""
}
if library.buildRlib() {
return rlibVariation
}
if library.buildDylib() {
return dylibVariation
}
}
return incomingVariation
}
func (libraryTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
m, ok := ctx.Module().(*Module)
if !ok || m.compiler == nil {
return
}
library, ok := m.compiler.(libraryInterface)
if !ok {
return return
} }
modules := mctx.CreateLocalVariations(variants...)
// The order of the variations (modules) matches the variant names provided. Iterate switch variation {
// through the new variation modules and set their mutated properties.
var emptyVariant = false
var rlibVariant = false
for i, v := range modules {
switch variants[i] {
case rlibVariation: case rlibVariation:
v.(*Module).compiler.(libraryInterface).setRlib() library.setRlib()
rlibVariant = true
case dylibVariation: case dylibVariation:
v.(*Module).compiler.(libraryInterface).setDylib() library.setDylib()
if v.(*Module).ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation { if m.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
// TODO(b/165791368) // TODO(b/165791368)
// Disable dylib Vendor Ramdisk variations until we support these. // Disable dylib Vendor Ramdisk variations until we support these.
v.(*Module).Disable() m.Disable()
} }
case "source": case sourceVariation:
v.(*Module).compiler.(libraryInterface).setSource() library.setSource()
// The source variant does not produce any library. // The source variant does not produce any library.
// Disable the compilation steps. // Disable the compilation steps.
v.(*Module).compiler.SetDisabled() m.compiler.SetDisabled()
case "":
emptyVariant = true
}
}
if rlibVariant && library.isFFILibrary() {
// If an rlib variant is set and this is an FFI library, make it the
// default variant so CC can link against it appropriately.
mctx.AliasVariation(rlibVariation)
} else if emptyVariant {
// If there's an empty variant, alias it so it is the default variant
mctx.AliasVariation("")
} }
// If a source variant is created, add an inter-variant dependency // If a source variant is created, add an inter-variant dependency
// between the other variants and the source variant. // between the other variants and the source variant.
if sourceVariant { if m.sourceProvider != nil && variation != sourceVariation {
sv := modules[0] ctx.AddVariationDependencies(
for _, v := range modules[1:] { []blueprint.Variation{
if !v.Enabled(mctx) { {"rust_libraries", sourceVariation},
continue },
} sourceDepTag, ctx.ModuleName())
mctx.AddInterVariantDependency(sourceDepTag, v, sv)
}
// Alias the source variation so it can be named directly in "srcs" properties.
mctx.AliasVariation("source")
} }
} }
func LibstdMutator(mctx android.BottomUpMutatorContext) { type libstdTransitionMutator struct{}
if m, ok := mctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
switch library := m.compiler.(type) { func (libstdTransitionMutator) Split(ctx android.BaseModuleContext) []string {
case libraryInterface: if m, ok := ctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
// Only create a variant if a library is actually being built. // Only create a variant if a library is actually being built.
if library, ok := m.compiler.(libraryInterface); ok {
if library.rlib() && !library.sysroot() { if library.rlib() && !library.sysroot() {
// If this is a rust_ffi variant it only needs rlib-std
if library.isFFILibrary() { if library.isFFILibrary() {
variants := []string{"rlib-std"} return []string{"rlib-std"}
modules := mctx.CreateLocalVariations(variants...) } else {
rlib := modules[0].(*Module) return []string{"rlib-std", "dylib-std"}
}
}
}
}
return []string{""}
}
func (libstdTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
return ""
}
func (libstdTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
if m, ok := ctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
if library, ok := m.compiler.(libraryInterface); ok {
if library.shared() {
return ""
}
if library.rlib() && !library.sysroot() {
if incomingVariation != "" {
return incomingVariation
}
return "rlib-std"
}
}
}
return ""
}
func (libstdTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
if variation == "rlib-std" {
rlib := ctx.Module().(*Module)
rlib.compiler.(libraryInterface).setRlibStd() rlib.compiler.(libraryInterface).setRlibStd()
rlib.Properties.RustSubName += RlibStdlibSuffix rlib.Properties.RustSubName += RlibStdlibSuffix
mctx.AliasVariation("rlib-std") } else if variation == "dylib-std" {
} else { dylib := ctx.Module().(*Module)
variants := []string{"rlib-std", "dylib-std"}
modules := mctx.CreateLocalVariations(variants...)
rlib := modules[0].(*Module)
dylib := modules[1].(*Module)
rlib.compiler.(libraryInterface).setRlibStd()
dylib.compiler.(libraryInterface).setDylibStd() dylib.compiler.(libraryInterface).setDylibStd()
if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation { if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
// TODO(b/165791368) // TODO(b/165791368)
@@ -809,9 +854,5 @@ func LibstdMutator(mctx android.BottomUpMutatorContext) {
// variants are properly supported. // variants are properly supported.
dylib.Disable() dylib.Disable()
} }
rlib.Properties.RustSubName += RlibStdlibSuffix
}
}
}
} }
} }

View File

@@ -37,20 +37,24 @@ var pctx = android.NewPackageContext("android/soong/rust")
func init() { func init() {
android.RegisterModuleType("rust_defaults", defaultsFactory) android.RegisterModuleType("rust_defaults", defaultsFactory)
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { android.PreDepsMutators(registerPreDepsMutators)
ctx.BottomUp("rust_libraries", LibraryMutator).Parallel() android.PostDepsMutators(registerPostDepsMutators)
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/android") pctx.Import("android/soong/android")
pctx.Import("android/soong/rust/config") pctx.Import("android/soong/rust/config")
pctx.ImportAs("cc_config", "android/soong/cc/config") pctx.ImportAs("cc_config", "android/soong/cc/config")
android.InitRegistrationContext.RegisterParallelSingletonType("kythe_rust_extract", kytheExtractRustFactory) android.InitRegistrationContext.RegisterParallelSingletonType("kythe_rust_extract", kytheExtractRustFactory)
} }
func registerPreDepsMutators(ctx android.RegisterMutatorsContext) {
ctx.Transition("rust_libraries", &libraryTransitionMutator{})
ctx.Transition("rust_stdlinkage", &libstdTransitionMutator{})
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
}
func registerPostDepsMutators(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator).Parallel()
}
type Flags struct { type Flags struct {
GlobalRustFlags []string // Flags that apply globally to rust GlobalRustFlags []string // Flags that apply globally to rust
GlobalLinkFlags []string // Flags that apply globally to linker GlobalLinkFlags []string // Flags that apply globally to linker
@@ -1128,6 +1132,7 @@ type autoDep struct {
} }
var ( var (
sourceVariation = "source"
rlibVariation = "rlib" rlibVariation = "rlib"
dylibVariation = "dylib" dylibVariation = "dylib"
rlibAutoDep = autoDep{variation: rlibVariation, depTag: rlibDepTag} rlibAutoDep = autoDep{variation: rlibVariation, depTag: rlibDepTag}
@@ -1613,7 +1618,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
} }
rlibDepVariations := commonDepVariations rlibDepVariations := commonDepVariations
rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() { if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
rlibDepVariations = append(rlibDepVariations, rlibDepVariations = append(rlibDepVariations,
@@ -1629,7 +1633,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
// dylibs // dylibs
dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation}) dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation})
dylibDepVariations = append(dylibDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
for _, lib := range deps.Dylibs { for _, lib := range deps.Dylibs {
actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib) actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib)
@@ -1650,7 +1653,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
// otherwise select the rlib variant. // otherwise select the rlib variant.
autoDepVariations := append(commonDepVariations, autoDepVariations := append(commonDepVariations,
blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}) blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
autoDepVariations = append(autoDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) { if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) {
actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib) actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib)
@@ -1664,8 +1666,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
} else if _, ok := mod.sourceProvider.(*protobufDecorator); ok { } else if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
for _, lib := range deps.Rustlibs { for _, lib := range deps.Rustlibs {
srcProviderVariations := append(commonDepVariations, srcProviderVariations := append(commonDepVariations,
blueprint.Variation{Mutator: "rust_libraries", Variation: "source"}) blueprint.Variation{Mutator: "rust_libraries", Variation: sourceVariation})
srcProviderVariations = append(srcProviderVariations, blueprint.Variation{Mutator: "link", Variation: ""})
// Only add rustlib dependencies if they're source providers themselves. // 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 // This is used to track which crate names need to be added to the source generated
@@ -1681,7 +1682,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
if deps.Stdlibs != nil { if deps.Stdlibs != nil {
if mod.compiler.stdLinkage(ctx) == RlibLinkage { if mod.compiler.stdLinkage(ctx) == RlibLinkage {
for _, lib := range deps.Stdlibs { for _, lib := range deps.Stdlibs {
actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}, {Mutator: "link", Variation: ""}}...), actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
rlibDepTag, lib) rlibDepTag, lib)
} }
} else { } else {

View File

@@ -60,6 +60,7 @@ var rustMockedFiles = android.MockFS{
// testRust returns a TestContext in which a basic environment has been setup. // testRust returns a TestContext in which a basic environment has been setup.
// This environment contains a few mocked files. See rustMockedFiles for the list of these files. // This environment contains a few mocked files. See rustMockedFiles for the list of these files.
func testRust(t *testing.T, bp string) *android.TestContext { func testRust(t *testing.T, bp string) *android.TestContext {
t.Helper()
skipTestIfOsNotSupported(t) skipTestIfOsNotSupported(t)
result := android.GroupFixturePreparers( result := android.GroupFixturePreparers(
prepareForRustTest, prepareForRustTest,

View File

@@ -200,15 +200,8 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
ctx.RegisterModuleType("rust_prebuilt_library", PrebuiltLibraryFactory) ctx.RegisterModuleType("rust_prebuilt_library", PrebuiltLibraryFactory)
ctx.RegisterModuleType("rust_prebuilt_dylib", PrebuiltDylibFactory) ctx.RegisterModuleType("rust_prebuilt_dylib", PrebuiltDylibFactory)
ctx.RegisterModuleType("rust_prebuilt_rlib", PrebuiltRlibFactory) ctx.RegisterModuleType("rust_prebuilt_rlib", PrebuiltRlibFactory)
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.PreDepsMutators(registerPreDepsMutators)
// rust mutators
ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
ctx.BottomUp("rust_stdlinkage", LibstdMutator).Parallel()
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
ctx.RegisterParallelSingletonType("rust_project_generator", rustProjectGeneratorSingleton) ctx.RegisterParallelSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
ctx.RegisterParallelSingletonType("kythe_rust_extract", kytheExtractRustFactory) ctx.RegisterParallelSingletonType("kythe_rust_extract", kytheExtractRustFactory)
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.PostDepsMutators(registerPostDepsMutators)
ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator).Parallel()
})
} }