summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/androidmk.go6
-rw-r--r--rust/bindgen.go10
-rw-r--r--rust/bindgen_test.go7
-rw-r--r--rust/builder_test.go6
-rw-r--r--rust/compiler.go13
-rw-r--r--rust/library.go40
-rw-r--r--rust/rust.go42
-rw-r--r--rust/rust_test.go27
-rw-r--r--rust/source_provider.go19
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
+}