Merge changes from topic "rust-made-to-order-staticlibs" into main

* changes:
  rust: made-to-order rust staticlibs
  rust: refactored transformSrctoCrate
This commit is contained in:
Ivan Lozano
2024-05-17 12:40:36 +00:00
committed by Gerrit Code Review
23 changed files with 832 additions and 241 deletions

View File

@@ -37,10 +37,15 @@ func init() {
android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
android.RegisterModuleType("rust_ffi", RustFFIFactory)
android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
android.RegisterModuleType("rust_ffi_static", RustFFIStaticFactory)
android.RegisterModuleType("rust_ffi_rlib", RustFFIRlibFactory)
android.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
android.RegisterModuleType("rust_ffi_host_static", RustFFIStaticHostFactory)
android.RegisterModuleType("rust_ffi_host_rlib", RustFFIRlibHostFactory)
// TODO: Remove when all instances of rust_ffi_static have been switched to rust_ffi_rlib
// Alias rust_ffi_static to the combined rust_ffi_rlib factory
android.RegisterModuleType("rust_ffi_static", RustFFIStaticRlibFactory)
android.RegisterModuleType("rust_ffi_host_static", RustFFIStaticRlibHostFactory)
}
type VariantLibraryProperties struct {
@@ -104,6 +109,8 @@ type libraryDecorator struct {
includeDirs android.Paths
sourceProvider SourceProvider
isFFI bool
// table-of-contents file for cdylib crates to optimize out relinking when possible
tocFile android.OptionalPath
}
@@ -143,6 +150,8 @@ type libraryInterface interface {
BuildOnlyShared()
toc() android.OptionalPath
isFFILibrary() bool
}
func (library *libraryDecorator) nativeCoverage() bool {
@@ -250,7 +259,7 @@ func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) aut
}
func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
if library.static() || library.MutatedProperties.VariantIsStaticStd {
if library.static() || library.MutatedProperties.VariantIsStaticStd || (library.rlib() && library.isFFILibrary()) {
return RlibLinkage
} else if library.baseCompiler.preferRlib() {
return RlibLinkage
@@ -270,8 +279,8 @@ func RustLibraryFactory() android.Module {
return module.Init()
}
// rust_ffi produces all FFI variants (rust_ffi_shared and
// rust_ffi_static).
// rust_ffi produces all FFI variants (rust_ffi_shared, rust_ffi_static, and
// rust_ffi_rlib).
func RustFFIFactory() android.Module {
module, library := NewRustLibrary(android.HostAndDeviceSupported)
library.BuildOnlyFFI()
@@ -300,14 +309,6 @@ func RustFFISharedFactory() android.Module {
return module.Init()
}
// rust_ffi_static produces a static library (Rust crate type
// "staticlib").
func RustFFIStaticFactory() android.Module {
module, library := NewRustLibrary(android.HostAndDeviceSupported)
library.BuildOnlyStatic()
return module.Init()
}
// rust_library_host produces all Rust variants for the host
// (rust_library_dylib_host and rust_library_rlib_host).
func RustLibraryHostFactory() android.Module {
@@ -317,7 +318,7 @@ func RustLibraryHostFactory() android.Module {
}
// rust_ffi_host produces all FFI variants for the host
// (rust_ffi_static_host and rust_ffi_shared_host).
// (rust_ffi_rlib_host, rust_ffi_static_host, and rust_ffi_shared_host).
func RustFFIHostFactory() android.Module {
module, library := NewRustLibrary(android.HostSupported)
library.BuildOnlyFFI()
@@ -340,14 +341,6 @@ func RustLibraryRlibHostFactory() android.Module {
return module.Init()
}
// rust_ffi_static_host produces a static library for the host (Rust
// crate type "staticlib").
func RustFFIStaticHostFactory() android.Module {
module, library := NewRustLibrary(android.HostSupported)
library.BuildOnlyStatic()
return module.Init()
}
// rust_ffi_shared_host produces an shared library for the host (Rust
// crate type "cdylib").
func RustFFISharedHostFactory() android.Module {
@@ -356,11 +349,51 @@ func RustFFISharedHostFactory() android.Module {
return module.Init()
}
// rust_ffi_rlib_host produces an rlib for the host (Rust crate
// type "rlib").
func RustFFIRlibHostFactory() android.Module {
module, library := NewRustLibrary(android.HostSupported)
library.BuildOnlyRlibStatic()
library.isFFI = true
return module.Init()
}
// rust_ffi_rlib produces an rlib (Rust crate type "rlib").
func RustFFIRlibFactory() android.Module {
module, library := NewRustLibrary(android.HostAndDeviceSupported)
library.BuildOnlyRlib()
library.isFFI = true
return module.Init()
}
// rust_ffi_static produces a staticlib and an rlib variant
func RustFFIStaticRlibFactory() android.Module {
module, library := NewRustLibrary(android.HostAndDeviceSupported)
library.BuildOnlyRlibStatic()
library.isFFI = true
return module.Init()
}
// rust_ffi_static_host produces a staticlib and an rlib variant for the host
func RustFFIStaticRlibHostFactory() android.Module {
module, library := NewRustLibrary(android.HostSupported)
library.BuildOnlyRlibStatic()
library.isFFI = true
return module.Init()
}
func (library *libraryDecorator) BuildOnlyFFI() {
library.MutatedProperties.BuildDylib = false
library.MutatedProperties.BuildRlib = false
// we build rlibs for later static ffi linkage.
library.MutatedProperties.BuildRlib = true
library.MutatedProperties.BuildShared = true
library.MutatedProperties.BuildStatic = true
library.isFFI = true
}
func (library *libraryDecorator) BuildOnlyRust() {
@@ -384,11 +417,21 @@ func (library *libraryDecorator) BuildOnlyRlib() {
library.MutatedProperties.BuildStatic = false
}
func (library *libraryDecorator) BuildOnlyRlibStatic() {
library.MutatedProperties.BuildDylib = false
library.MutatedProperties.BuildRlib = true
library.MutatedProperties.BuildShared = false
library.MutatedProperties.BuildStatic = true
library.isFFI = true
}
func (library *libraryDecorator) BuildOnlyStatic() {
library.MutatedProperties.BuildRlib = false
library.MutatedProperties.BuildDylib = false
library.MutatedProperties.BuildShared = false
library.MutatedProperties.BuildStatic = true
library.isFFI = true
}
func (library *libraryDecorator) BuildOnlyShared() {
@@ -396,6 +439,12 @@ func (library *libraryDecorator) BuildOnlyShared() {
library.MutatedProperties.BuildDylib = false
library.MutatedProperties.BuildStatic = false
library.MutatedProperties.BuildShared = true
library.isFFI = true
}
func (library *libraryDecorator) isFFILibrary() bool {
return library.isFFI
}
func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
@@ -446,8 +495,15 @@ func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
}
// Library cfg flags common to all variants
func CommonLibraryCfgFlags(ctx android.ModuleContext, flags Flags) Flags {
return flags
}
func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags {
flags = library.baseCompiler.cfgFlags(ctx, flags)
flags = CommonLibraryCfgFlags(ctx, flags)
if library.dylib() {
// We need to add a dependency on std in order to link crates as dylibs.
// The hack to add this dependency is guarded by the following cfg so
@@ -455,8 +511,15 @@ func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags
library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib")
}
flags.RustFlags = append(flags.RustFlags, library.baseCompiler.cfgsToFlags()...)
flags.RustdocFlags = append(flags.RustdocFlags, library.baseCompiler.cfgsToFlags()...)
flags.RustFlags = append(flags.RustFlags, cfgsToFlags(library.baseCompiler.Properties.Cfgs)...)
flags.RustdocFlags = append(flags.RustdocFlags, cfgsToFlags(library.baseCompiler.Properties.Cfgs)...)
return flags
}
// Common flags applied to all libraries irrespective of properties or variant should be included here
func CommonLibraryCompilerFlags(ctx android.ModuleContext, flags Flags) Flags {
flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
return flags
}
@@ -464,11 +527,13 @@ func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags
func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
flags = library.baseCompiler.compilerFlags(ctx, flags)
flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
if library.shared() || library.static() {
flags = CommonLibraryCompilerFlags(ctx, flags)
if library.isFFI {
library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)...)
}
if library.shared() {
if ctx.Darwin() {
flags.LinkFlags = append(
@@ -494,6 +559,9 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
}
// Ensure link dirs are not duplicated
deps.linkDirs = android.FirstUniqueStrings(deps.linkDirs)
// Calculate output filename
if library.rlib() {
fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
@@ -549,9 +617,10 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
library.flagExporter.exportLinkObjects(deps.linkObjects...)
}
if library.static() || library.shared() {
// Since we have FFI rlibs, we need to collect their includes as well
if library.static() || library.shared() || library.rlib() {
android.SetProvider(ctx, cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
IncludeDirs: library.includeDirs,
IncludeDirs: android.FirstUniquePaths(library.includeDirs),
})
}
@@ -666,6 +735,11 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
return
}
// Don't produce rlib/dylib/source variants for shared or static variants
if library.shared() || library.static() {
return
}
var variants []string
// 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.
@@ -705,6 +779,9 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
// The source variant does not produce any library.
// Disable the compilation steps.
v.(*Module).compiler.SetDisabled()
case "":
// if there's an empty variant, alias it so it is the default variant
mctx.AliasVariation("")
}
}
@@ -729,20 +806,29 @@ func LibstdMutator(mctx android.BottomUpMutatorContext) {
case libraryInterface:
// Only create a variant if a library is actually being built.
if library.rlib() && !library.sysroot() {
variants := []string{"rlib-std", "dylib-std"}
modules := mctx.CreateLocalVariations(variants...)
// If this is a rust_ffi variant it only needs rlib-std
if library.isFFILibrary() {
variants := []string{"rlib-std"}
modules := mctx.CreateLocalVariations(variants...)
rlib := modules[0].(*Module)
rlib.compiler.(libraryInterface).setRlibStd()
rlib.Properties.RustSubName += RlibStdlibSuffix
} else {
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()
if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
// TODO(b/165791368)
// Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
// variants are properly supported.
dylib.Disable()
rlib := modules[0].(*Module)
dylib := modules[1].(*Module)
rlib.compiler.(libraryInterface).setRlibStd()
dylib.compiler.(libraryInterface).setDylibStd()
if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
// TODO(b/165791368)
// Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
// variants are properly supported.
dylib.Disable()
}
rlib.Properties.RustSubName += RlibStdlibSuffix
}
rlib.Properties.RustSubName += RlibStdlibSuffix
}
}
}