diff options
-rw-r--r-- | rust/androidmk.go | 6 | ||||
-rw-r--r-- | rust/bindgen.go | 10 | ||||
-rw-r--r-- | rust/bindgen_test.go | 7 | ||||
-rw-r--r-- | rust/builder_test.go | 6 | ||||
-rw-r--r-- | rust/compiler.go | 13 | ||||
-rw-r--r-- | rust/library.go | 40 | ||||
-rw-r--r-- | rust/rust.go | 42 | ||||
-rw-r--r-- | rust/rust_test.go | 27 | ||||
-rw-r--r-- | rust/source_provider.go | 19 |
9 files changed, 134 insertions, 36 deletions
diff --git a/rust/androidmk.go b/rust/androidmk.go index babbf9123..580601734 100644 --- a/rust/androidmk.go +++ b/rust/androidmk.go @@ -55,7 +55,6 @@ func (mod *Module) AndroidMk() android.AndroidMkData { ret := android.AndroidMkData{ OutputFile: mod.outputFile, Include: "$(BUILD_SYSTEM)/soong_rust_prebuilt.mk", - SubName: mod.subName, Extra: []android.AndroidMkExtraFunc{ func(w io.Writer, outputFile android.Path) { if len(mod.Properties.AndroidMkRlibs) > 0 { @@ -76,9 +75,11 @@ func (mod *Module) AndroidMk() android.AndroidMkData { }, }, } - if mod.compiler != nil { + + if mod.compiler != nil && !mod.compiler.Disabled() { mod.subAndroidMk(&ret, mod.compiler) } else if mod.sourceProvider != nil { + // If the compiler is disabled, this is a SourceProvider. mod.subAndroidMk(&ret, mod.sourceProvider) } ret.SubName += mod.Properties.SubName @@ -162,6 +163,7 @@ func (sourceProvider *baseSourceProvider) AndroidMk(ctx AndroidMkContext, ret *a outFile := sourceProvider.outputFile ret.Class = "ETC" ret.OutputFile = android.OptionalPathForPath(outFile) + ret.SubName += sourceProvider.subName ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { _, file := filepath.Split(outFile.String()) stem, suffix, _ := android.SplitFileExt(file) diff --git a/rust/bindgen.go b/rust/bindgen.go index e8bbb35f1..304f8ec38 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -61,7 +61,7 @@ type BindgenProperties struct { Wrapper_src *string `android:"path,arch_variant"` // list of bindgen-specific flags and options - Flags []string `android:"arch_variant"` + Bindgen_flags []string `android:"arch_variant"` // list of clang flags required to correctly interpret the headers. Cflags []string `android:"arch_variant"` @@ -121,7 +121,7 @@ func (b *bindgenDecorator) generateSource(ctx android.ModuleContext, deps PathDe } bindgenFlags := defaultBindgenFlags - bindgenFlags = append(bindgenFlags, strings.Join(b.Properties.Flags, " ")) + bindgenFlags = append(bindgenFlags, strings.Join(b.Properties.Bindgen_flags, " ")) wrapperFile := android.OptionalPathForModuleSrc(ctx, b.Properties.Wrapper_src) if !wrapperFile.Valid() { @@ -170,7 +170,13 @@ func NewRustBindgen(hod android.HostOrDeviceSupported) (*Module, *bindgenDecorat baseSourceProvider: NewSourceProvider(), Properties: BindgenProperties{}, } + + _, library := NewRustLibrary(hod) + library.BuildOnlyRust() + library.sourceProvider = bindgen + module.sourceProvider = bindgen + module.compiler = library return module, bindgen } diff --git a/rust/bindgen_test.go b/rust/bindgen_test.go index 2122ec12c..c42834843 100644 --- a/rust/bindgen_test.go +++ b/rust/bindgen_test.go @@ -24,8 +24,10 @@ func TestRustBindgen(t *testing.T) { rust_bindgen { name: "libbindgen", wrapper_src: "src/any.h", - stem: "bindings", - flags: ["--bindgen-flag"], + crate_name: "bindgen", + stem: "libbindgen", + source_stem: "bindings", + bindgen_flags: ["--bindgen-flag"], cflags: ["--clang-flag"], shared_libs: ["libfoo_shared"], static_libs: ["libfoo_static"], @@ -38,7 +40,6 @@ func TestRustBindgen(t *testing.T) { name: "libfoo_static", export_include_dirs: ["static_include"], } - `) libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a").Output("bindings.rs") if !strings.Contains(libbindgen.Args["flags"], "--bindgen-flag") { diff --git a/rust/builder_test.go b/rust/builder_test.go index 04b67d9bd..5c11cb7b5 100644 --- a/rust/builder_test.go +++ b/rust/builder_test.go @@ -28,12 +28,14 @@ func TestSourceProviderCollision(t *testing.T) { } rust_bindgen { name: "libbindings1", - stem: "bindings", + source_stem: "bindings", + crate_name: "bindings1", wrapper_src: "src/any.h", } rust_bindgen { name: "libbindings2", - stem: "bindings", + source_stem: "bindings", + crate_name: "bindings2", wrapper_src: "src/any.h", } `) diff --git a/rust/compiler.go b/rust/compiler.go index 040219dc4..ec059c37c 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -81,7 +81,10 @@ type BaseCompilerProperties struct { // list of C static library dependencies Static_libs []string `android:"arch_variant"` - // crate name, required for libraries. This must be the expected extern crate name used in source + // crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider + // modules which create library variants (rust_bindgen). This must be the expected extern crate name used in + // source, and is required to conform to an enforced format matching library output files (if the output file is + // lib<someName><suffix>, the crate_name property must be <someName>). Crate_name string `android:"arch_variant"` // list of features to enable for this crate @@ -120,6 +123,14 @@ type baseCompiler struct { distFile android.OptionalPath } +func (compiler *baseCompiler) Disabled() bool { + return false +} + +func (compiler *baseCompiler) SetDisabled() { + panic("baseCompiler does not implement SetDisabled()") +} + func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath { panic("baseCompiler does not implement coverageOutputZipPath()") } diff --git a/rust/library.go b/rust/library.go index 6d5eca0d7..6766d618b 100644 --- a/rust/library.go +++ b/rust/library.go @@ -69,6 +69,10 @@ type LibraryMutatedProperties struct { VariantIsShared bool `blueprint:"mutated"` // This variant is a static library VariantIsStatic bool `blueprint:"mutated"` + + // This variant is disabled and should not be compiled + // (used for SourceProvider variants that produce only source) + VariantIsDisabled bool `blueprint:"mutated"` } type libraryDecorator struct { @@ -78,6 +82,7 @@ type libraryDecorator struct { Properties LibraryCompilerProperties MutatedProperties LibraryMutatedProperties includeDirs android.Paths + sourceProvider SourceProvider } type libraryInterface interface { @@ -367,8 +372,13 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) F func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path { var outputFile android.WritablePath + var srcPath android.Path - srcPath, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs) + if library.sourceProvider != nil { + srcPath = library.sourceProvider.Srcs()[0] + } else { + srcPath, _ = srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs) + } flags.RustFlags = append(flags.RustFlags, deps.depFlags...) @@ -430,6 +440,14 @@ func (library *libraryDecorator) getStem(ctx ModuleContext) string { return stem + String(library.baseCompiler.Properties.Suffix) } +func (library *libraryDecorator) Disabled() bool { + return library.MutatedProperties.VariantIsDisabled +} + +func (library *libraryDecorator) SetDisabled() { + library.MutatedProperties.VariantIsDisabled = true +} + var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+") func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) { @@ -455,12 +473,23 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) { switch library := m.compiler.(type) { case libraryInterface: if library.buildRlib() && library.buildDylib() { - modules := mctx.CreateLocalVariations("rlib", "dylib") + variants := []string{"rlib", "dylib"} + if m.sourceProvider != nil { + variants = append(variants, "") + } + modules := mctx.CreateLocalVariations(variants...) + rlib := modules[0].(*Module) dylib := modules[1].(*Module) - rlib.compiler.(libraryInterface).setRlib() dylib.compiler.(libraryInterface).setDylib() + + if m.sourceProvider != nil { + // This library is SourceProvider generated, so the non-library-producing + // variant needs to disable it's compiler and skip installation. + sourceProvider := modules[2].(*Module) + sourceProvider.compiler.SetDisabled() + } } else if library.buildRlib() { modules := mctx.CreateLocalVariations("rlib") modules[0].(*Module).compiler.(libraryInterface).setRlib() @@ -468,6 +497,11 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) { modules := mctx.CreateLocalVariations("dylib") modules[0].(*Module).compiler.(libraryInterface).setDylib() } + + if m.sourceProvider != nil { + // Alias the non-library variant to the empty-string variant. + mctx.AliasVariation("") + } } } } diff --git a/rust/rust.go b/rust/rust.go index 5d383e1a8..1192836a5 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -63,7 +63,8 @@ type BaseProperties struct { AndroidMkSharedLibs []string AndroidMkStaticLibs []string - SubName string `blueprint:"mutated"` + SubName string `blueprint:"mutated"` + PreventInstall bool HideFromMake bool } @@ -83,9 +84,9 @@ type Module struct { cachedToolchain config.Toolchain sourceProvider SourceProvider subAndroidMkOnce map[subAndroidMkProvider]bool - outputFile android.OptionalPath - subName string + outputFile android.OptionalPath + generatedFile android.OptionalPath } func (mod *Module) OutputFiles(tag string) (android.Paths, error) { @@ -285,6 +286,9 @@ type compiler interface { relativeInstallPath() string nativeCoverage() bool + + Disabled() bool + SetDisabled() } type exportedFlagsProducer interface { @@ -667,16 +671,21 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { flags, deps = mod.clippy.flags(ctx, flags, deps) } - if mod.compiler != nil { + // SourceProvider needs to call generateSource() before compiler calls compile() so it can provide the source. + // TODO(b/162588681) This shouldn't have to run for every variant. + if mod.sourceProvider != nil { + generatedFile := mod.sourceProvider.generateSource(ctx, deps) + mod.generatedFile = android.OptionalPathForPath(generatedFile) + mod.sourceProvider.setSubName(ctx.ModuleSubDir()) + } + + if mod.compiler != nil && !mod.compiler.Disabled() { outputFile := mod.compiler.compile(ctx, flags, deps) + mod.outputFile = android.OptionalPathForPath(outputFile) - if !mod.Properties.PreventInstall { + if mod.outputFile.Valid() && !mod.Properties.PreventInstall { mod.compiler.install(ctx, mod.outputFile.Path()) } - } else if mod.sourceProvider != nil { - outputFile := mod.sourceProvider.generateSource(ctx, deps) - mod.outputFile = android.OptionalPathForPath(outputFile) - mod.subName = ctx.ModuleSubDir() } } @@ -685,7 +694,8 @@ func (mod *Module) deps(ctx DepsContext) Deps { if mod.compiler != nil { deps = mod.compiler.compilerDeps(ctx, deps) - } else if mod.sourceProvider != nil { + } + if mod.sourceProvider != nil { deps = mod.sourceProvider.sourceProviderDeps(ctx, deps) } @@ -755,11 +765,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() { //Handle Rust Modules - linkFile := rustDep.outputFile - if !linkFile.Valid() { - ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) - } - switch depTag { case dylibDepTag: dylib, ok := rustDep.compiler.(libraryInterface) @@ -808,6 +813,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { + linkFile := rustDep.outputFile + if !linkFile.Valid() { + ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", + depName, ctx.ModuleName()) + return + } linkDir := linkPathFromFilePath(linkFile.Path()) if lib, ok := mod.compiler.(exportedFlagsProducer); ok { lib.exportLinkDirs(linkDir) @@ -826,7 +837,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { return } } - linkFile := ccDep.OutputFile() linkPath := linkPathFromFilePath(linkFile.Path()) libName := libNameFromFilePath(linkFile.Path()) diff --git a/rust/rust_test.go b/rust/rust_test.go index b3bbddbc6..04de48b19 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -233,6 +233,7 @@ func TestSourceProviderDeps(t *testing.T) { ":my_generator", ":libbindings", ], + rlibs: ["libbindings"], } rust_proc_macro { name: "libprocmacro", @@ -241,6 +242,7 @@ func TestSourceProviderDeps(t *testing.T) { ":my_generator", ":libbindings", ], + rlibs: ["libbindings"], crate_name: "procmacro", } rust_library { @@ -248,7 +250,9 @@ func TestSourceProviderDeps(t *testing.T) { srcs: [ "foo.rs", ":my_generator", - ":libbindings"], + ":libbindings", + ], + rlibs: ["libbindings"], crate_name: "foo", } genrule { @@ -260,7 +264,8 @@ func TestSourceProviderDeps(t *testing.T) { } rust_bindgen { name: "libbindings", - stem: "bindings", + crate_name: "bindings", + source_stem: "bindings", host_supported: true, wrapper_src: "src/any.h", } @@ -289,6 +294,21 @@ func TestSourceProviderDeps(t *testing.T) { if !android.SuffixInList(libprocmacro.Implicits.Strings(), "/out/any.rs") { t.Errorf("genrule generated source not included as implicit input for libprocmacro; Implicits %#v", libfoo.Implicits.Strings()) } + + // Check that our bindings are picked up as crate dependencies as well + libfooMod := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module) + if !android.InList("libbindings", libfooMod.Properties.AndroidMkRlibs) { + t.Errorf("bindgen dependency not detected as a rlib dependency (dependency missing from AndroidMkRlibs)") + } + fizzBuzzMod := ctx.ModuleForTests("fizz-buzz-dep", "android_arm64_armv8-a").Module().(*Module) + if !android.InList("libbindings", fizzBuzzMod.Properties.AndroidMkRlibs) { + t.Errorf("bindgen dependency not detected as a rlib dependency (dependency missing from AndroidMkRlibs)") + } + libprocmacroMod := ctx.ModuleForTests("libprocmacro", "linux_glibc_x86_64").Module().(*Module) + if !android.InList("libbindings", libprocmacroMod.Properties.AndroidMkRlibs) { + t.Errorf("bindgen dependency not detected as a rlib dependency (dependency missing from AndroidMkRlibs)") + } + } func TestSourceProviderTargetMismatch(t *testing.T) { @@ -305,7 +325,8 @@ func TestSourceProviderTargetMismatch(t *testing.T) { } rust_bindgen { name: "libbindings", - stem: "bindings", + crate_name: "bindings", + source_stem: "bindings", wrapper_src: "src/any.h", } `) diff --git a/rust/source_provider.go b/rust/source_provider.go index da6147a15..8bb784951 100644 --- a/rust/source_provider.go +++ b/rust/source_provider.go @@ -19,8 +19,13 @@ import ( ) type SourceProviderProperties struct { - // sets name of the output - Stem *string `android:"arch_variant"` + // name for the generated source file. Defaults to module name (e.g. moduleNameFoo.rs is produced by default). + // Importantly, the inherited "stem" property for this module sets the output filename for the generated library + // variants only + Source_stem *string `android:"arch_variant"` + + // crate name, used for the library variant of this source provider. See additional details in rust_library. + Crate_name string `android:"arch_variant"` } type baseSourceProvider struct { @@ -28,6 +33,7 @@ type baseSourceProvider struct { outputFile android.Path subAndroidMkOnce map[subAndroidMkProvider]bool + subName string } var _ SourceProvider = (*baseSourceProvider)(nil) @@ -37,6 +43,7 @@ type SourceProvider interface { Srcs() android.Paths sourceProviderProps() []interface{} sourceProviderDeps(ctx DepsContext, deps Deps) Deps + setSubName(subName string) } func (sp *baseSourceProvider) Srcs() android.Paths { @@ -59,8 +66,8 @@ func NewSourceProvider() *baseSourceProvider { func (sp *baseSourceProvider) getStem(ctx android.ModuleContext) string { stem := ctx.ModuleName() - if String(sp.Properties.Stem) != "" { - stem = String(sp.Properties.Stem) + if String(sp.Properties.Source_stem) != "" { + stem = String(sp.Properties.Source_stem) } return stem } @@ -68,3 +75,7 @@ func (sp *baseSourceProvider) getStem(ctx android.ModuleContext) string { func (sp *baseSourceProvider) sourceProviderDeps(ctx DepsContext, deps Deps) Deps { return deps } + +func (sp *baseSourceProvider) setSubName(subName string) { + sp.subName = subName +} |