Enforce correct variant usage for rust_bindgen.

Modules defined in the srcs property are automatically added as
dependencies with AddDependency(), which will use any variant available.
This can cause incorrect architecture bindings to be silently pulled in,
such as when a host module uses a rust_bindgen module that doesn't
create a host variant.

This moves populating depPaths.SrcDeps over to depsToPaths and adds a
check for SourceProviders to make sure the correct OS and architecture
is being used.

Bug: 161826371
Test: Soong no longer silently pulls in bindings for the wrong
      target.
Test: New Soong test to catch this case passes.
Change-Id: I2b3651cf6fc7dabf4081434df1c455e637f5b3a4
This commit is contained in:
Ivan Lozano 2020-07-22 16:09:13 -04:00
parent 188f2ee1ee
commit 07cbaf4d89
5 changed files with 62 additions and 6 deletions

View File

@ -106,8 +106,7 @@ func (binary *binaryDecorator) nativeCoverage() bool {
func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
srcPath, paths := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
deps.SrcDeps = append(deps.SrcDeps, paths...)
srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
outputFile := android.PathForModuleOut(ctx, fileName)
binary.unstrippedOutputFile = outputFile

View File

@ -368,8 +368,7 @@ 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
srcPath, paths := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
deps.SrcDeps = append(deps.SrcDeps, paths...)
srcPath, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)

View File

@ -65,8 +65,7 @@ func (procMacro *procMacroDecorator) compile(ctx ModuleContext, flags Flags, dep
fileName := procMacro.getStem(ctx) + ctx.toolchain().ProcMacroSuffix()
outputFile := android.PathForModuleOut(ctx, fileName)
srcPath, paths := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
deps.SrcDeps = append(deps.SrcDeps, paths...)
srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
procMacro.unstrippedOutputFile = outputFile

View File

@ -743,6 +743,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directProcMacroDeps := []*Module{}
directSharedLibDeps := [](cc.LinkableInterface){}
directStaticLibDeps := [](cc.LinkableInterface){}
directSrcProvidersDeps := []*Module{}
directSrcDeps := [](android.SourceFileProducer){}
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
@ -776,6 +778,24 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
case procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, rustDep)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, depName)
case android.SourceDepTag:
// Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
// OS/Arch variant is used.
var helper string
if ctx.Host() {
helper = "missing 'host_supported'?"
} else {
helper = "device module defined?"
}
if dep.Target().Os != ctx.Os() {
ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper)
return
} else if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper)
return
}
directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
}
//Append the dependencies exportedDirs
@ -793,6 +813,14 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
if srcDep, ok := dep.(android.SourceFileProducer); ok {
switch depTag {
case android.SourceDepTag:
// These are usually genrules which don't have per-target variants.
directSrcDeps = append(directSrcDeps, srcDep)
}
}
if ccDep, ok := dep.(cc.LinkableInterface); ok {
//Handle C dependencies
if _, ok := ccDep.(*Module); !ok {
@ -868,11 +896,22 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
sharedLibDepFiles = append(sharedLibDepFiles, dep.OutputFile().Path())
}
var srcProviderDepFiles android.Paths
for _, dep := range directSrcProvidersDeps {
srcs, _ := dep.OutputFiles("")
srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
}
for _, dep := range directSrcDeps {
srcs := dep.Srcs()
srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
}
depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
depPaths.SharedLibs = append(depPaths.SharedLibs, 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)

View File

@ -291,6 +291,26 @@ func TestSourceProviderDeps(t *testing.T) {
}
}
func TestSourceProviderTargetMismatch(t *testing.T) {
// This might error while building the dependency tree or when calling depsToPaths() depending on the lunched
// target, which results in two different errors. So don't check the error, just confirm there is one.
testRustError(t, ".*", `
rust_proc_macro {
name: "libprocmacro",
srcs: [
"foo.rs",
":libbindings",
],
crate_name: "procmacro",
}
rust_bindgen {
name: "libbindings",
stem: "bindings",
wrapper_src: "src/any.h",
}
`)
}
// Test to make sure proc_macros use host variants when building device modules.
func TestProcMacroDeviceDeps(t *testing.T) {
ctx := testRust(t, `