From bb3add11046ec3fde6401e42ff480bf589cd5567 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Thu, 25 Jun 2020 09:34:12 -0700 Subject: [PATCH] rust: Suppress default sysroot unconditionally With proper prebuilt modules, we can avoid any rustc implicit sysroot searching. Asd a bonus, this should make rust-project.json generation correctly grab otherwise implicit dependencies. Prebuilt rlibs may include several dependency rlibs. Without a link_dirs attribute, every dependency (even if unexported) would need a separate module. Previously we were casing out on exact structs, which might be OK when libraryDecorator and procMacroDecorator were the only possibilities, but repeating the logic for three types is too much. Using an interface makes this logic scale better. Bug: 159591910 Test: cd external/rust; mma; m crosvm.experimental Change-Id: Ia1124e09f48cd05e39f094bbcb988622ebd2272f --- rust/builder.go | 42 ++++++++++++++----------------- rust/compiler.go | 2 -- rust/library.go | 33 ++++--------------------- rust/prebuilt.go | 5 ++++ rust/proc_macro.go | 3 +++ rust/rust.go | 61 ++++++++++++++++++++++++++++++++++------------ 6 files changed, 76 insertions(+), 70 deletions(-) diff --git a/rust/builder.go b/rust/builder.go index b0ab29743..16d730603 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -70,37 +70,37 @@ func init() { } func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, - outputFile android.WritablePath, includeDirs []string) buildOutput { + outputFile android.WritablePath, linkDirs []string) buildOutput { flags.RustFlags = append(flags.RustFlags, "-C lto") - return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "bin", includeDirs) + return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "bin", linkDirs) } func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, - outputFile android.WritablePath, includeDirs []string) buildOutput { - return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "rlib", includeDirs) + outputFile android.WritablePath, linkDirs []string) buildOutput { + return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "rlib", linkDirs) } func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, - outputFile android.WritablePath, includeDirs []string) buildOutput { - return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "dylib", includeDirs) + outputFile android.WritablePath, linkDirs []string) buildOutput { + return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "dylib", linkDirs) } func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, - outputFile android.WritablePath, includeDirs []string) buildOutput { + outputFile android.WritablePath, linkDirs []string) buildOutput { flags.RustFlags = append(flags.RustFlags, "-C lto") - return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "staticlib", includeDirs) + return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "staticlib", linkDirs) } func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, - outputFile android.WritablePath, includeDirs []string) buildOutput { + outputFile android.WritablePath, linkDirs []string) buildOutput { flags.RustFlags = append(flags.RustFlags, "-C lto") - return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "cdylib", includeDirs) + return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "cdylib", linkDirs) } func TransformSrctoProcMacro(ctx ModuleContext, mainSrc android.Path, deps PathDeps, - flags Flags, outputFile android.WritablePath, includeDirs []string) buildOutput { - return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "proc-macro", includeDirs) + flags Flags, outputFile android.WritablePath, linkDirs []string) buildOutput { + return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "proc-macro", linkDirs) } func rustLibsToPaths(libs RustLibraries) android.Paths { @@ -112,7 +112,7 @@ func rustLibsToPaths(libs RustLibraries) android.Paths { } func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags, - outputFile android.WritablePath, crate_type string, includeDirs []string) buildOutput { + outputFile android.WritablePath, crate_type string, linkDirs []string) buildOutput { var inputs android.Paths var implicits android.Paths @@ -137,16 +137,10 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl rustcFlags = append(rustcFlags, "--target="+targetTriple) linkFlags = append(linkFlags, "-target "+targetTriple) } - // TODO(b/159718669): Once we have defined static libraries in the host - // prebuilts Blueprint file, sysroot should be unconditionally sourced - // from /dev/null. Explicitly set sysroot to avoid clippy-driver to - // internally call rustc. - if ctx.Host() && ctx.TargetPrimary() { - rustcFlags = append(rustcFlags, "--sysroot=${config.RustPath}") - } else { - // If we're not targeting the host primary arch, do not use a sysroot. - rustcFlags = append(rustcFlags, "--sysroot=/dev/null") - } + + // Suppress an implicit sysroot + rustcFlags = append(rustcFlags, "--sysroot=/dev/null") + // Collect linker flags linkFlags = append(linkFlags, flags.GlobalLinkFlags...) linkFlags = append(linkFlags, flags.LinkFlags...) @@ -162,7 +156,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String()) } - for _, path := range includeDirs { + for _, path := range linkDirs { libFlags = append(libFlags, "-L "+path) } diff --git a/rust/compiler.go b/rust/compiler.go index bda2cec17..92a3b07f2 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -103,8 +103,6 @@ type BaseCompilerProperties struct { type baseCompiler struct { Properties BaseCompilerProperties - depFlags []string - linkDirs []string coverageFile android.Path //rustc generates a single gcno file // Install related diff --git a/rust/library.go b/rust/library.go index 3dc2559e9..8b8e797a2 100644 --- a/rust/library.go +++ b/rust/library.go @@ -19,7 +19,6 @@ import ( "strings" "android/soong/android" - "android/soong/rust/config" ) func init() { @@ -74,6 +73,7 @@ type LibraryMutatedProperties struct { type libraryDecorator struct { *baseCompiler + *flagExporter Properties LibraryCompilerProperties MutatedProperties LibraryMutatedProperties @@ -111,22 +111,6 @@ func (library *libraryDecorator) nativeCoverage() bool { return true } -func (library *libraryDecorator) exportedDirs() []string { - return library.linkDirs -} - -func (library *libraryDecorator) exportedDepFlags() []string { - return library.depFlags -} - -func (library *libraryDecorator) reexportDirs(dirs ...string) { - library.linkDirs = android.FirstUniqueStrings(append(library.linkDirs, dirs...)) -} - -func (library *libraryDecorator) reexportDepFlags(flags ...string) { - library.depFlags = android.FirstUniqueStrings(append(library.depFlags, flags...)) -} - func (library *libraryDecorator) rlib() bool { return library.MutatedProperties.VariantIsRlib } @@ -199,6 +183,7 @@ func (library *libraryDecorator) autoDep() autoDep { var _ compiler = (*libraryDecorator)(nil) var _ libraryInterface = (*libraryDecorator)(nil) +var _ exportedFlagsProducer = (*libraryDecorator)(nil) // rust_library produces all rust variants. func RustLibraryFactory() android.Module { @@ -337,6 +322,7 @@ func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorat BuildStatic: false, }, baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem), + flagExporter: NewFlagExporter(), } module.compiler = library @@ -351,15 +337,6 @@ func (library *libraryDecorator) compilerProps() []interface{} { } func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { - - // TODO(b/155498724) Remove if C static libraries no longer require libstd as an rlib dependency. - if !ctx.Host() && library.static() { - library.setNoStdlibs() - for _, stdlib := range config.Stdlibs { - deps.Rlibs = append(deps.Rlibs, stdlib) - } - } - deps = library.baseCompiler.compilerDeps(ctx, deps) if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) { @@ -438,8 +415,8 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa library.coverageOutputZipFile = TransformCoverageFilesToZip(ctx, coverageFiles, library.getStem(ctx)) if library.rlib() || library.dylib() { - library.reexportDirs(deps.linkDirs...) - library.reexportDepFlags(deps.depFlags...) + library.exportLinkDirs(deps.linkDirs...) + library.exportDepFlags(deps.depFlags...) } library.unstrippedOutputFile = outputFile diff --git a/rust/prebuilt.go b/rust/prebuilt.go index cddd447ec..67d649d35 100644 --- a/rust/prebuilt.go +++ b/rust/prebuilt.go @@ -27,6 +27,8 @@ func init() { type PrebuiltProperties struct { // path to the prebuilt file Srcs []string `android:"path,arch_variant"` + // directories containing associated rlib dependencies + Link_dirs []string `android:"path,arch_variant"` } type prebuiltLibraryDecorator struct { @@ -35,6 +37,7 @@ type prebuiltLibraryDecorator struct { } var _ compiler = (*prebuiltLibraryDecorator)(nil) +var _ exportedFlagsProducer = (*prebuiltLibraryDecorator)(nil) func PrebuiltLibraryFactory() android.Module { module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported) @@ -90,6 +93,8 @@ func (prebuilt *prebuiltLibraryDecorator) compilerProps() []interface{} { } func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path { + prebuilt.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...) + srcPath := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) prebuilt.unstrippedOutputFile = srcPath diff --git a/rust/proc_macro.go b/rust/proc_macro.go index b04808702..2719161e5 100644 --- a/rust/proc_macro.go +++ b/rust/proc_macro.go @@ -27,6 +27,7 @@ type ProcMacroCompilerProperties struct { type procMacroDecorator struct { *baseCompiler + *flagExporter Properties ProcMacroCompilerProperties } @@ -35,6 +36,7 @@ type procMacroInterface interface { } var _ compiler = (*procMacroDecorator)(nil) +var _ exportedFlagsProducer = (*procMacroDecorator)(nil) func ProcMacroFactory() android.Module { module, _ := NewProcMacro(android.HostSupportedNoCross) @@ -46,6 +48,7 @@ func NewProcMacro(hod android.HostOrDeviceSupported) (*Module, *procMacroDecorat procMacro := &procMacroDecorator{ baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem), + flagExporter: NewFlagExporter(), } module.compiler = procMacro diff --git a/rust/rust.go b/rust/rust.go index c80ede2da..72301a718 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -262,6 +262,43 @@ type compiler interface { nativeCoverage() bool } +type exportedFlagsProducer interface { + exportedLinkDirs() []string + exportedDepFlags() []string + exportLinkDirs(...string) + exportDepFlags(...string) +} + +type flagExporter struct { + depFlags []string + linkDirs []string +} + +func (flagExporter *flagExporter) exportedLinkDirs() []string { + return flagExporter.linkDirs +} + +func (flagExporter *flagExporter) exportedDepFlags() []string { + return flagExporter.depFlags +} + +func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) { + flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...)) +} + +func (flagExporter *flagExporter) exportDepFlags(flags ...string) { + flagExporter.depFlags = android.FirstUniqueStrings(append(flagExporter.depFlags, flags...)) +} + +var _ exportedFlagsProducer = (*flagExporter)(nil) + +func NewFlagExporter() *flagExporter { + return &flagExporter{ + depFlags: []string{}, + linkDirs: []string{}, + } +} + func (mod *Module) isCoverageVariant() bool { return mod.coverage.Properties.IsCoverageVariant } @@ -416,7 +453,7 @@ func (mod *Module) Module() android.Module { func (mod *Module) StubsVersions() []string { // For now, Rust has no stubs versions. if mod.compiler != nil { - if _, ok := mod.compiler.(*libraryDecorator); ok { + if _, ok := mod.compiler.(libraryInterface); ok { return []string{} } } @@ -708,19 +745,15 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } //Append the dependencies exportedDirs - if lib, ok := rustDep.compiler.(*libraryDecorator); ok { - depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedDirs()...) + if lib, ok := rustDep.compiler.(exportedFlagsProducer); ok { + depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedLinkDirs()...) depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...) } - // Append this dependencies output to this mod's linkDirs so they can be exported to dependencies - // This can be probably be refactored by defining a common exporter interface similar to cc's if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { linkDir := linkPathFromFilePath(linkFile.Path()) - if lib, ok := mod.compiler.(*libraryDecorator); ok { - lib.linkDirs = append(lib.linkDirs, linkDir) - } else if procMacro, ok := mod.compiler.(*procMacroDecorator); ok { - procMacro.linkDirs = append(procMacro.linkDirs, linkDir) + if lib, ok := mod.compiler.(exportedFlagsProducer); ok { + lib.exportLinkDirs(linkDir) } } @@ -771,14 +804,10 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } // Make sure these dependencies are propagated - if lib, ok := mod.compiler.(*libraryDecorator); ok && exportDep { - lib.linkDirs = append(lib.linkDirs, linkPath) - lib.depFlags = append(lib.depFlags, depFlag) - } else if procMacro, ok := mod.compiler.(*procMacroDecorator); ok && exportDep { - procMacro.linkDirs = append(procMacro.linkDirs, linkPath) - procMacro.depFlags = append(procMacro.depFlags, depFlag) + if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep { + lib.exportLinkDirs(linkPath) + lib.exportDepFlags(depFlag) } - } })