rust: made-to-order rust staticlibs
Whenever any two Rust static libraries are included as static libraries anywhere in a CC dependency tree, we sometimes get duplicate symbol errors. To avoid this, we no longer directly link multiple rust static libs to CC modules. Instead, we build rust_ffi_rlib modules and produce the actual static library that gets linked against the CC module based on that CC module's full list of Rust rlib dependencies. This introduces a new static_rlibs property for cc modules to define the rust_ffi_rlib dependencies, which are then used to generate the module above. This CL is intended to deprecate rust_ffi_static. It leaves rust_ffi_static and rust_ffi static variants in place until the remaining rust_ffi_static declarations and uses can be removed. In the meantime, rust_ffi_static produces rust_ffi_rlib variants as well to make the transition easier. Bug: 254469782 Test: m # with no changes Test: m libapexsupport # with static_rlibs Test: m libunwindstack # with static_rlibs Test: m netsimd # with static_rlibs, no duplicate symbols Test: m blueprint_tests # New Soong tests Change-Id: I47e27ac967ef0cad46d398ebf59d8275929ae28a
This commit is contained in:
@@ -302,6 +302,24 @@ func RemoveFromList(s string, list []string) (bool, []string) {
|
|||||||
return removed, result
|
return removed, result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FirstUniqueFunc returns all unique elements of a slice, keeping the first copy of
|
||||||
|
// each. It does not modify the input slice. The eq function should return true
|
||||||
|
// if two elements can be considered equal.
|
||||||
|
func FirstUniqueFunc[SortableList ~[]Sortable, Sortable any](list SortableList, eq func(a, b Sortable) bool) SortableList {
|
||||||
|
k := 0
|
||||||
|
outer:
|
||||||
|
for i := 0; i < len(list); i++ {
|
||||||
|
for j := 0; j < k; j++ {
|
||||||
|
if eq(list[i], list[j]) {
|
||||||
|
continue outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list[k] = list[i]
|
||||||
|
k++
|
||||||
|
}
|
||||||
|
return list[:k]
|
||||||
|
}
|
||||||
|
|
||||||
// FirstUniqueStrings returns all unique elements of a slice of strings, keeping the first copy of
|
// FirstUniqueStrings returns all unique elements of a slice of strings, keeping the first copy of
|
||||||
// each. It does not modify the input slice.
|
// each. It does not modify the input slice.
|
||||||
func FirstUniqueStrings(list []string) []string {
|
func FirstUniqueStrings(list []string) []string {
|
||||||
|
@@ -702,7 +702,12 @@ var (
|
|||||||
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
|
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
|
||||||
binVariations := target.Variations()
|
binVariations := target.Variations()
|
||||||
libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
|
libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
|
||||||
rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
|
rustLibVariations := append(
|
||||||
|
target.Variations(), []blueprint.Variation{
|
||||||
|
{Mutator: "rust_libraries", Variation: "dylib"},
|
||||||
|
{Mutator: "link", Variation: ""},
|
||||||
|
}...,
|
||||||
|
)
|
||||||
|
|
||||||
// Append "image" variation
|
// Append "image" variation
|
||||||
binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
|
binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
|
||||||
|
@@ -18,6 +18,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -425,6 +426,10 @@ func (binary *binaryDecorator) link(ctx ModuleContext,
|
|||||||
validations = append(validations, objs.tidyDepFiles...)
|
validations = append(validations, objs.tidyDepFiles...)
|
||||||
linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
|
linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
|
||||||
|
|
||||||
|
if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil {
|
||||||
|
deps.StaticLibs = append(deps.StaticLibs, generatedLib)
|
||||||
|
}
|
||||||
|
|
||||||
// Register link action.
|
// Register link action.
|
||||||
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
|
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
|
||||||
deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
|
deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
|
||||||
|
@@ -19,6 +19,7 @@ package cc
|
|||||||
// functions.
|
// functions.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -330,6 +331,15 @@ var (
|
|||||||
CommandDeps: []string{"$cxxExtractor", "$kytheVnames"},
|
CommandDeps: []string{"$cxxExtractor", "$kytheVnames"},
|
||||||
},
|
},
|
||||||
"cFlags")
|
"cFlags")
|
||||||
|
|
||||||
|
// Function pointer for producting staticlibs from rlibs. Corresponds to
|
||||||
|
// rust.TransformRlibstoStaticlib(), initialized in soong-rust (rust/builder.go init())
|
||||||
|
//
|
||||||
|
// This is required since soong-rust depends on soong-cc, so soong-cc cannot depend on soong-rust
|
||||||
|
// without resulting in a circular dependency. Setting this function pointer in soong-rust allows
|
||||||
|
// soong-cc to call into this particular function.
|
||||||
|
TransformRlibstoStaticlib (func(ctx android.ModuleContext, mainSrc android.Path, deps []RustRlibDep,
|
||||||
|
outputFile android.WritablePath) android.Path) = nil
|
||||||
)
|
)
|
||||||
|
|
||||||
func PwdPrefix() string {
|
func PwdPrefix() string {
|
||||||
@@ -774,6 +784,47 @@ func transformObjToStaticLib(ctx android.ModuleContext,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a Rust staticlib from a list of rlibDeps. Returns nil if TransformRlibstoStaticlib is nil or rlibDeps is empty.
|
||||||
|
func generateRustStaticlib(ctx android.ModuleContext, rlibDeps []RustRlibDep) android.Path {
|
||||||
|
if TransformRlibstoStaticlib == nil && len(rlibDeps) > 0 {
|
||||||
|
// This should only be reachable if a module defines static_rlibs and
|
||||||
|
// soong-rust hasn't been loaded alongside soong-cc (e.g. in soong-cc tests).
|
||||||
|
panic(fmt.Errorf("TransformRlibstoStaticlib is not set and static_rlibs is defined in %s", ctx.ModuleName()))
|
||||||
|
} else if len(rlibDeps) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
output := android.PathForModuleOut(ctx, "generated_rust_staticlib", "lib"+ctx.ModuleName()+"_rust_staticlib.a")
|
||||||
|
stemFile := output.ReplaceExtension(ctx, "rs")
|
||||||
|
crateNames := []string{}
|
||||||
|
|
||||||
|
// Collect crate names
|
||||||
|
for _, lib := range rlibDeps {
|
||||||
|
// Exclude libstd so this can support no_std builds.
|
||||||
|
if lib.CrateName != "libstd" {
|
||||||
|
crateNames = append(crateNames, lib.CrateName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deduplicate any crateNames just to be safe
|
||||||
|
crateNames = android.FirstUniqueStrings(crateNames)
|
||||||
|
|
||||||
|
// Write the source file
|
||||||
|
android.WriteFileRule(ctx, stemFile, genRustStaticlibSrcFile(crateNames))
|
||||||
|
|
||||||
|
return TransformRlibstoStaticlib(ctx, stemFile, rlibDeps, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genRustStaticlibSrcFile(crateNames []string) string {
|
||||||
|
lines := []string{
|
||||||
|
"// @Soong generated Source",
|
||||||
|
}
|
||||||
|
for _, crate := range crateNames {
|
||||||
|
lines = append(lines, fmt.Sprintf("extern crate %s;", crate))
|
||||||
|
}
|
||||||
|
return strings.Join(lines, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
// Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
|
// Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
|
||||||
// and shared libraries, to a shared library (.so) or dynamic executable
|
// and shared libraries, to a shared library (.so) or dynamic executable
|
||||||
func transformObjToDynamicBinary(ctx android.ModuleContext,
|
func transformObjToDynamicBinary(ctx android.ModuleContext,
|
||||||
|
65
cc/cc.go
65
cc/cc.go
@@ -99,6 +99,7 @@ type Deps struct {
|
|||||||
StaticLibs, LateStaticLibs, WholeStaticLibs []string
|
StaticLibs, LateStaticLibs, WholeStaticLibs []string
|
||||||
HeaderLibs []string
|
HeaderLibs []string
|
||||||
RuntimeLibs []string
|
RuntimeLibs []string
|
||||||
|
Rlibs []string
|
||||||
|
|
||||||
// UnexportedStaticLibs are static libraries that are also passed to -Wl,--exclude-libs= to
|
// UnexportedStaticLibs are static libraries that are also passed to -Wl,--exclude-libs= to
|
||||||
// prevent automatically exporting symbols.
|
// prevent automatically exporting symbols.
|
||||||
@@ -144,6 +145,17 @@ type Deps struct {
|
|||||||
LlndkHeaderLibs []string
|
LlndkHeaderLibs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A struct which to collect flags for rlib dependencies
|
||||||
|
type RustRlibDep struct {
|
||||||
|
LibPath android.Path // path to the rlib
|
||||||
|
LinkDirs []string // flags required for dependency (e.g. -L flags)
|
||||||
|
CrateName string // crateNames associated with rlibDeps
|
||||||
|
}
|
||||||
|
|
||||||
|
func EqRustRlibDeps(a RustRlibDep, b RustRlibDep) bool {
|
||||||
|
return a.LibPath == b.LibPath
|
||||||
|
}
|
||||||
|
|
||||||
// PathDeps is a struct containing file paths to dependencies of a module.
|
// PathDeps is a struct containing file paths to dependencies of a module.
|
||||||
// It's constructed in depsToPath() by traversing the direct dependencies of the current module.
|
// It's constructed in depsToPath() by traversing the direct dependencies of the current module.
|
||||||
// It's used to construct flags for various build statements (such as for compiling and linking).
|
// It's used to construct flags for various build statements (such as for compiling and linking).
|
||||||
@@ -156,6 +168,8 @@ type PathDeps struct {
|
|||||||
SharedLibsDeps, EarlySharedLibsDeps, LateSharedLibsDeps android.Paths
|
SharedLibsDeps, EarlySharedLibsDeps, LateSharedLibsDeps android.Paths
|
||||||
// Paths to .a files
|
// Paths to .a files
|
||||||
StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
|
StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
|
||||||
|
// Paths and crateNames for RustStaticLib dependencies
|
||||||
|
RustRlibDeps []RustRlibDep
|
||||||
|
|
||||||
// Transitive static library dependencies of static libraries for use in ordering.
|
// Transitive static library dependencies of static libraries for use in ordering.
|
||||||
TranstiveStaticLibrariesForOrdering *android.DepSet[android.Path]
|
TranstiveStaticLibrariesForOrdering *android.DepSet[android.Path]
|
||||||
@@ -184,6 +198,7 @@ type PathDeps struct {
|
|||||||
ReexportedFlags []string
|
ReexportedFlags []string
|
||||||
ReexportedGeneratedHeaders android.Paths
|
ReexportedGeneratedHeaders android.Paths
|
||||||
ReexportedDeps android.Paths
|
ReexportedDeps android.Paths
|
||||||
|
ReexportedRustRlibDeps []RustRlibDep
|
||||||
|
|
||||||
// Paths to crt*.o files
|
// Paths to crt*.o files
|
||||||
CrtBegin, CrtEnd android.Paths
|
CrtBegin, CrtEnd android.Paths
|
||||||
@@ -297,6 +312,7 @@ type BaseProperties struct {
|
|||||||
|
|
||||||
AndroidMkSharedLibs []string `blueprint:"mutated"`
|
AndroidMkSharedLibs []string `blueprint:"mutated"`
|
||||||
AndroidMkStaticLibs []string `blueprint:"mutated"`
|
AndroidMkStaticLibs []string `blueprint:"mutated"`
|
||||||
|
AndroidMkRlibs []string `blueprint:"mutated"`
|
||||||
AndroidMkRuntimeLibs []string `blueprint:"mutated"`
|
AndroidMkRuntimeLibs []string `blueprint:"mutated"`
|
||||||
AndroidMkWholeStaticLibs []string `blueprint:"mutated"`
|
AndroidMkWholeStaticLibs []string `blueprint:"mutated"`
|
||||||
AndroidMkHeaderLibs []string `blueprint:"mutated"`
|
AndroidMkHeaderLibs []string `blueprint:"mutated"`
|
||||||
@@ -653,6 +669,7 @@ const (
|
|||||||
headerLibraryDependency = iota
|
headerLibraryDependency = iota
|
||||||
sharedLibraryDependency
|
sharedLibraryDependency
|
||||||
staticLibraryDependency
|
staticLibraryDependency
|
||||||
|
rlibLibraryDependency
|
||||||
)
|
)
|
||||||
|
|
||||||
func (k libraryDependencyKind) String() string {
|
func (k libraryDependencyKind) String() string {
|
||||||
@@ -663,6 +680,8 @@ func (k libraryDependencyKind) String() string {
|
|||||||
return "sharedLibraryDependency"
|
return "sharedLibraryDependency"
|
||||||
case staticLibraryDependency:
|
case staticLibraryDependency:
|
||||||
return "staticLibraryDependency"
|
return "staticLibraryDependency"
|
||||||
|
case rlibLibraryDependency:
|
||||||
|
return "rlibLibraryDependency"
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unknown libraryDependencyKind %d", k))
|
panic(fmt.Errorf("unknown libraryDependencyKind %d", k))
|
||||||
}
|
}
|
||||||
@@ -740,6 +759,11 @@ func (d libraryDependencyTag) static() bool {
|
|||||||
return d.Kind == staticLibraryDependency
|
return d.Kind == staticLibraryDependency
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rlib returns true if the libraryDependencyTag is tagging an rlib dependency.
|
||||||
|
func (d libraryDependencyTag) rlib() bool {
|
||||||
|
return d.Kind == rlibLibraryDependency
|
||||||
|
}
|
||||||
|
|
||||||
func (d libraryDependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
|
func (d libraryDependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
|
||||||
if d.shared() {
|
if d.shared() {
|
||||||
return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
|
return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
|
||||||
@@ -1108,6 +1132,14 @@ func (c *Module) RustLibraryInterface() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Module) CrateName() string {
|
||||||
|
panic(fmt.Errorf("CrateName called on non-Rust module: %q", c.BaseModuleName()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Module) ExportedCrateLinkDirs() []string {
|
||||||
|
panic(fmt.Errorf("ExportedCrateLinkDirs called on non-Rust module: %q", c.BaseModuleName()))
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Module) IsFuzzModule() bool {
|
func (c *Module) IsFuzzModule() bool {
|
||||||
if _, ok := c.compiler.(*fuzzBinary); ok {
|
if _, ok := c.compiler.(*fuzzBinary); ok {
|
||||||
return true
|
return true
|
||||||
@@ -2300,6 +2332,7 @@ func (c *Module) deps(ctx DepsContext) Deps {
|
|||||||
|
|
||||||
deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs)
|
deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs)
|
||||||
deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
|
deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
|
||||||
|
deps.Rlibs = android.LastUniqueStrings(deps.Rlibs)
|
||||||
deps.LateStaticLibs = android.LastUniqueStrings(deps.LateStaticLibs)
|
deps.LateStaticLibs = android.LastUniqueStrings(deps.LateStaticLibs)
|
||||||
deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
|
deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
|
||||||
deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
|
deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
|
||||||
@@ -2607,6 +2640,15 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
}, depTag, lib)
|
}, depTag, lib)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, lib := range deps.Rlibs {
|
||||||
|
depTag := libraryDependencyTag{Kind: rlibLibraryDependency}
|
||||||
|
actx.AddVariationDependencies([]blueprint.Variation{
|
||||||
|
{Mutator: "link", Variation: ""},
|
||||||
|
{Mutator: "rust_libraries", Variation: "rlib"},
|
||||||
|
{Mutator: "rust_stdlinkage", Variation: "rlib-std"},
|
||||||
|
}, depTag, lib)
|
||||||
|
}
|
||||||
|
|
||||||
// staticUnwinderDep is treated as staticDep for Q apexes
|
// staticUnwinderDep is treated as staticDep for Q apexes
|
||||||
// so that native libraries/binaries are linked with static unwinder
|
// so that native libraries/binaries are linked with static unwinder
|
||||||
// because Q libc doesn't have unwinder APIs
|
// because Q libc doesn't have unwinder APIs
|
||||||
@@ -3216,6 +3258,14 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
|
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case libDepTag.rlib():
|
||||||
|
rlibDep := RustRlibDep{LibPath: linkFile.Path(), CrateName: ccDep.CrateName(), LinkDirs: ccDep.ExportedCrateLinkDirs()}
|
||||||
|
depPaths.ReexportedRustRlibDeps = append(depPaths.ReexportedRustRlibDeps, rlibDep)
|
||||||
|
depPaths.RustRlibDeps = append(depPaths.RustRlibDeps, rlibDep)
|
||||||
|
depPaths.IncludeDirs = append(depPaths.IncludeDirs, depExporterInfo.IncludeDirs...)
|
||||||
|
depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, depExporterInfo.IncludeDirs...)
|
||||||
|
|
||||||
case libDepTag.static():
|
case libDepTag.static():
|
||||||
staticLibraryInfo, isStaticLib := android.OtherModuleProvider(ctx, dep, StaticLibraryInfoProvider)
|
staticLibraryInfo, isStaticLib := android.OtherModuleProvider(ctx, dep, StaticLibraryInfoProvider)
|
||||||
if !isStaticLib {
|
if !isStaticLib {
|
||||||
@@ -3268,6 +3318,12 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
|
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We re-export the Rust static_rlibs so rlib dependencies don't need to be redeclared by cc_library_static dependents.
|
||||||
|
// E.g. libfoo (cc_library_static) depends on libfoo.ffi (a rust_ffi rlib), libbar depending on libfoo shouldn't have to also add libfoo.ffi to static_rlibs.
|
||||||
|
depPaths.ReexportedRustRlibDeps = append(depPaths.ReexportedRustRlibDeps, depExporterInfo.RustRlibDeps...)
|
||||||
|
depPaths.RustRlibDeps = append(depPaths.RustRlibDeps, depExporterInfo.RustRlibDeps...)
|
||||||
|
|
||||||
if libDepTag.unexportedSymbols {
|
if libDepTag.unexportedSymbols {
|
||||||
depPaths.LdFlags = append(depPaths.LdFlags,
|
depPaths.LdFlags = append(depPaths.LdFlags,
|
||||||
"-Wl,--exclude-libs="+staticLibraryInfo.StaticLibrary.Base())
|
"-Wl,--exclude-libs="+staticLibraryInfo.StaticLibrary.Base())
|
||||||
@@ -3320,6 +3376,12 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
depPaths.SystemIncludeDirs = append(depPaths.SystemIncludeDirs, depExporterInfo.SystemIncludeDirs...)
|
depPaths.SystemIncludeDirs = append(depPaths.SystemIncludeDirs, depExporterInfo.SystemIncludeDirs...)
|
||||||
depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, depExporterInfo.Deps...)
|
depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, depExporterInfo.Deps...)
|
||||||
depPaths.Flags = append(depPaths.Flags, depExporterInfo.Flags...)
|
depPaths.Flags = append(depPaths.Flags, depExporterInfo.Flags...)
|
||||||
|
depPaths.RustRlibDeps = append(depPaths.RustRlibDeps, depExporterInfo.RustRlibDeps...)
|
||||||
|
|
||||||
|
// Only re-export RustRlibDeps for cc static libs
|
||||||
|
if c.static() {
|
||||||
|
depPaths.ReexportedRustRlibDeps = append(depPaths.ReexportedRustRlibDeps, depExporterInfo.RustRlibDeps...)
|
||||||
|
}
|
||||||
|
|
||||||
if libDepTag.reexportFlags {
|
if libDepTag.reexportFlags {
|
||||||
reexportExporter(depExporterInfo)
|
reexportExporter(depExporterInfo)
|
||||||
@@ -3392,11 +3454,14 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
depPaths.IncludeDirs = android.FirstUniquePaths(depPaths.IncludeDirs)
|
depPaths.IncludeDirs = android.FirstUniquePaths(depPaths.IncludeDirs)
|
||||||
depPaths.SystemIncludeDirs = android.FirstUniquePaths(depPaths.SystemIncludeDirs)
|
depPaths.SystemIncludeDirs = android.FirstUniquePaths(depPaths.SystemIncludeDirs)
|
||||||
depPaths.GeneratedDeps = android.FirstUniquePaths(depPaths.GeneratedDeps)
|
depPaths.GeneratedDeps = android.FirstUniquePaths(depPaths.GeneratedDeps)
|
||||||
|
depPaths.RustRlibDeps = android.FirstUniqueFunc(depPaths.RustRlibDeps, EqRustRlibDeps)
|
||||||
|
|
||||||
depPaths.ReexportedDirs = android.FirstUniquePaths(depPaths.ReexportedDirs)
|
depPaths.ReexportedDirs = android.FirstUniquePaths(depPaths.ReexportedDirs)
|
||||||
depPaths.ReexportedSystemDirs = android.FirstUniquePaths(depPaths.ReexportedSystemDirs)
|
depPaths.ReexportedSystemDirs = android.FirstUniquePaths(depPaths.ReexportedSystemDirs)
|
||||||
depPaths.ReexportedFlags = android.FirstUniqueStrings(depPaths.ReexportedFlags)
|
depPaths.ReexportedFlags = android.FirstUniqueStrings(depPaths.ReexportedFlags)
|
||||||
depPaths.ReexportedDeps = android.FirstUniquePaths(depPaths.ReexportedDeps)
|
depPaths.ReexportedDeps = android.FirstUniquePaths(depPaths.ReexportedDeps)
|
||||||
depPaths.ReexportedGeneratedHeaders = android.FirstUniquePaths(depPaths.ReexportedGeneratedHeaders)
|
depPaths.ReexportedGeneratedHeaders = android.FirstUniquePaths(depPaths.ReexportedGeneratedHeaders)
|
||||||
|
depPaths.ReexportedRustRlibDeps = android.FirstUniqueFunc(depPaths.ReexportedRustRlibDeps, EqRustRlibDeps)
|
||||||
|
|
||||||
if c.sabi != nil {
|
if c.sabi != nil {
|
||||||
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
|
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
|
||||||
|
@@ -772,6 +772,9 @@ type RustBindgenClangProperties struct {
|
|||||||
// be added to the include path using -I
|
// be added to the include path using -I
|
||||||
Local_include_dirs []string `android:"arch_variant,variant_prepend"`
|
Local_include_dirs []string `android:"arch_variant,variant_prepend"`
|
||||||
|
|
||||||
|
// list of Rust static libraries.
|
||||||
|
Static_rlibs []string `android:"arch_variant,variant_prepend"`
|
||||||
|
|
||||||
// list of static libraries that provide headers for this binding.
|
// list of static libraries that provide headers for this binding.
|
||||||
Static_libs []string `android:"arch_variant,variant_prepend"`
|
Static_libs []string `android:"arch_variant,variant_prepend"`
|
||||||
|
|
||||||
|
@@ -597,7 +597,7 @@ func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilde
|
|||||||
ctx.WalkDeps(func(child, parent android.Module) bool {
|
ctx.WalkDeps(func(child, parent android.Module) bool {
|
||||||
|
|
||||||
// If this is a Rust module which is not rust_ffi_shared, we still want to bundle any transitive
|
// If this is a Rust module which is not rust_ffi_shared, we still want to bundle any transitive
|
||||||
// shared dependencies (even for rust_ffi_static)
|
// shared dependencies (even for rust_ffi_rlib or rust_ffi_static)
|
||||||
if rustmod, ok := child.(LinkableInterface); ok && rustmod.RustLibraryInterface() && !rustmod.Shared() {
|
if rustmod, ok := child.(LinkableInterface); ok && rustmod.RustLibraryInterface() && !rustmod.Shared() {
|
||||||
if recursed[ctx.OtherModuleName(child)] {
|
if recursed[ctx.OtherModuleName(child)] {
|
||||||
return false
|
return false
|
||||||
|
@@ -274,11 +274,12 @@ func LibraryHostSharedFactory() android.Module {
|
|||||||
type flagExporter struct {
|
type flagExporter struct {
|
||||||
Properties FlagExporterProperties
|
Properties FlagExporterProperties
|
||||||
|
|
||||||
dirs android.Paths // Include directories to be included with -I
|
dirs android.Paths // Include directories to be included with -I
|
||||||
systemDirs android.Paths // System include directories to be included with -isystem
|
systemDirs android.Paths // System include directories to be included with -isystem
|
||||||
flags []string // Exported raw flags.
|
flags []string // Exported raw flags.
|
||||||
deps android.Paths
|
deps android.Paths
|
||||||
headers android.Paths
|
headers android.Paths
|
||||||
|
rustRlibDeps []RustRlibDep
|
||||||
}
|
}
|
||||||
|
|
||||||
// exportedIncludes returns the effective include paths for this module and
|
// exportedIncludes returns the effective include paths for this module and
|
||||||
@@ -339,6 +340,10 @@ func (f *flagExporter) reexportDeps(deps ...android.Path) {
|
|||||||
f.deps = append(f.deps, deps...)
|
f.deps = append(f.deps, deps...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *flagExporter) reexportRustStaticDeps(deps ...RustRlibDep) {
|
||||||
|
f.rustRlibDeps = append(f.rustRlibDeps, deps...)
|
||||||
|
}
|
||||||
|
|
||||||
// addExportedGeneratedHeaders does nothing but collects generated header files.
|
// addExportedGeneratedHeaders does nothing but collects generated header files.
|
||||||
// This can be differ to exportedDeps which may contain phony files to minimize ninja.
|
// This can be differ to exportedDeps which may contain phony files to minimize ninja.
|
||||||
func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) {
|
func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) {
|
||||||
@@ -356,6 +361,8 @@ func (f *flagExporter) setProvider(ctx android.ModuleContext) {
|
|||||||
// Used sparingly, for extra files that need to be explicitly exported to dependers,
|
// Used sparingly, for extra files that need to be explicitly exported to dependers,
|
||||||
// or for phony files to minimize ninja.
|
// or for phony files to minimize ninja.
|
||||||
Deps: f.deps,
|
Deps: f.deps,
|
||||||
|
// Used for exporting rlib deps of static libraries to dependents.
|
||||||
|
RustRlibDeps: f.rustRlibDeps,
|
||||||
// For exported generated headers, such as exported aidl headers, proto headers, or
|
// For exported generated headers, such as exported aidl headers, proto headers, or
|
||||||
// sysprop headers.
|
// sysprop headers.
|
||||||
GeneratedHeaders: f.headers,
|
GeneratedHeaders: f.headers,
|
||||||
@@ -1132,9 +1139,14 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
|
|||||||
linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
|
linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
|
||||||
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
|
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
|
||||||
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
|
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
|
||||||
|
|
||||||
|
if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil {
|
||||||
|
deps.StaticLibs = append(deps.StaticLibs, generatedLib)
|
||||||
|
}
|
||||||
|
|
||||||
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
|
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
|
||||||
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
|
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin,
|
||||||
linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyDepFiles)
|
deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyDepFiles)
|
||||||
|
|
||||||
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
|
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
|
||||||
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
|
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
|
||||||
@@ -1594,6 +1606,10 @@ func (library *libraryDecorator) link(ctx ModuleContext,
|
|||||||
library.reexportDeps(deps.ReexportedDeps...)
|
library.reexportDeps(deps.ReexportedDeps...)
|
||||||
library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
|
library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
|
||||||
|
|
||||||
|
if library.static() && len(deps.ReexportedRustRlibDeps) > 0 {
|
||||||
|
library.reexportRustStaticDeps(deps.ReexportedRustRlibDeps...)
|
||||||
|
}
|
||||||
|
|
||||||
// Optionally export aidl headers.
|
// Optionally export aidl headers.
|
||||||
if Bool(library.Properties.Aidl.Export_aidl_headers) {
|
if Bool(library.Properties.Aidl.Export_aidl_headers) {
|
||||||
if library.baseCompiler.hasAidl(deps) {
|
if library.baseCompiler.hasAidl(deps) {
|
||||||
@@ -2121,14 +2137,12 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
// Header only
|
// Header only
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
|
} else if library, ok := mctx.Module().(LinkableInterface); ok && (library.CcLibraryInterface() || library.RustLibraryInterface()) {
|
||||||
|
|
||||||
// Non-cc.Modules may need an empty variant for their mutators.
|
// Non-cc.Modules may need an empty variant for their mutators.
|
||||||
variations := []string{}
|
variations := []string{}
|
||||||
if library.NonCcVariants() {
|
if library.NonCcVariants() {
|
||||||
variations = append(variations, "")
|
variations = append(variations, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
isLLNDK := false
|
isLLNDK := false
|
||||||
if m, ok := mctx.Module().(*Module); ok {
|
if m, ok := mctx.Module().(*Module); ok {
|
||||||
isLLNDK = m.IsLlndk()
|
isLLNDK = m.IsLlndk()
|
||||||
|
@@ -73,6 +73,12 @@ type LinkableInterface interface {
|
|||||||
// RustLibraryInterface returns true if this is a Rust library module
|
// RustLibraryInterface returns true if this is a Rust library module
|
||||||
RustLibraryInterface() bool
|
RustLibraryInterface() bool
|
||||||
|
|
||||||
|
// CrateName returns the crateName for a Rust library, panics if not a Rust library.
|
||||||
|
CrateName() string
|
||||||
|
|
||||||
|
// DepFlags returns a slice of Rustc string flags, panics if not a Rust library
|
||||||
|
ExportedCrateLinkDirs() []string
|
||||||
|
|
||||||
// BaseModuleName returns the android.ModuleBase.BaseModuleName() value for this module.
|
// BaseModuleName returns the android.ModuleBase.BaseModuleName() value for this module.
|
||||||
BaseModuleName() string
|
BaseModuleName() string
|
||||||
|
|
||||||
@@ -380,6 +386,7 @@ type FlagExporterInfo struct {
|
|||||||
SystemIncludeDirs android.Paths // System include directories to be included with -isystem
|
SystemIncludeDirs android.Paths // System include directories to be included with -isystem
|
||||||
Flags []string // Exported raw flags.
|
Flags []string // Exported raw flags.
|
||||||
Deps android.Paths
|
Deps android.Paths
|
||||||
|
RustRlibDeps []RustRlibDep
|
||||||
GeneratedHeaders android.Paths
|
GeneratedHeaders android.Paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
cc/linker.go
35
cc/linker.go
@@ -39,6 +39,9 @@ type BaseLinkerProperties struct {
|
|||||||
// the dependency's .a file will be linked into this module using -Wl,--whole-archive.
|
// the dependency's .a file will be linked into this module using -Wl,--whole-archive.
|
||||||
Whole_static_libs []string `android:"arch_variant,variant_prepend"`
|
Whole_static_libs []string `android:"arch_variant,variant_prepend"`
|
||||||
|
|
||||||
|
// list of Rust libs that should be statically linked into this module.
|
||||||
|
Static_rlibs []string `android:"arch_variant"`
|
||||||
|
|
||||||
// list of modules that should be statically linked into this module.
|
// list of modules that should be statically linked into this module.
|
||||||
Static_libs []string `android:"arch_variant,variant_prepend"`
|
Static_libs []string `android:"arch_variant,variant_prepend"`
|
||||||
|
|
||||||
@@ -116,10 +119,14 @@ type BaseLinkerProperties struct {
|
|||||||
// product variant of the C/C++ module.
|
// product variant of the C/C++ module.
|
||||||
Static_libs []string
|
Static_libs []string
|
||||||
|
|
||||||
// list of ehader libs that only should be used to build vendor or product
|
// list of header libs that only should be used to build vendor or product
|
||||||
// variant of the C/C++ module.
|
// variant of the C/C++ module.
|
||||||
Header_libs []string
|
Header_libs []string
|
||||||
|
|
||||||
|
// list of Rust libs that should be statically linked to build vendor or product
|
||||||
|
// variant.
|
||||||
|
Static_rlibs []string
|
||||||
|
|
||||||
// list of shared libs that should not be used to build vendor or
|
// list of shared libs that should not be used to build vendor or
|
||||||
// product variant of the C/C++ module.
|
// product variant of the C/C++ module.
|
||||||
Exclude_shared_libs []string
|
Exclude_shared_libs []string
|
||||||
@@ -148,6 +155,10 @@ type BaseLinkerProperties struct {
|
|||||||
// variant of the C/C++ module.
|
// variant of the C/C++ module.
|
||||||
Static_libs []string
|
Static_libs []string
|
||||||
|
|
||||||
|
// list of Rust libs that should be statically linked to build the recovery
|
||||||
|
// variant.
|
||||||
|
Static_rlibs []string
|
||||||
|
|
||||||
// list of shared libs that should not be used to build
|
// list of shared libs that should not be used to build
|
||||||
// the recovery variant of the C/C++ module.
|
// the recovery variant of the C/C++ module.
|
||||||
Exclude_shared_libs []string
|
Exclude_shared_libs []string
|
||||||
@@ -165,10 +176,14 @@ type BaseLinkerProperties struct {
|
|||||||
Exclude_runtime_libs []string
|
Exclude_runtime_libs []string
|
||||||
}
|
}
|
||||||
Ramdisk struct {
|
Ramdisk struct {
|
||||||
// list of static libs that only should be used to build the recovery
|
// list of static libs that only should be used to build the ramdisk
|
||||||
// variant of the C/C++ module.
|
// variant of the C/C++ module.
|
||||||
Static_libs []string
|
Static_libs []string
|
||||||
|
|
||||||
|
// list of Rust libs that should be statically linked to build the ramdisk
|
||||||
|
// variant.
|
||||||
|
Static_rlibs []string
|
||||||
|
|
||||||
// list of shared libs that should not be used to build
|
// list of shared libs that should not be used to build
|
||||||
// the ramdisk variant of the C/C++ module.
|
// the ramdisk variant of the C/C++ module.
|
||||||
Exclude_shared_libs []string
|
Exclude_shared_libs []string
|
||||||
@@ -183,9 +198,13 @@ type BaseLinkerProperties struct {
|
|||||||
}
|
}
|
||||||
Vendor_ramdisk struct {
|
Vendor_ramdisk struct {
|
||||||
// list of shared libs that should not be used to build
|
// list of shared libs that should not be used to build
|
||||||
// the recovery variant of the C/C++ module.
|
// the vendor ramdisk variant of the C/C++ module.
|
||||||
Exclude_shared_libs []string
|
Exclude_shared_libs []string
|
||||||
|
|
||||||
|
// list of Rust libs that should be statically linked to build the vendor ramdisk
|
||||||
|
// variant.
|
||||||
|
Static_rlibs []string
|
||||||
|
|
||||||
// list of static libs that should not be used to build
|
// list of static libs that should not be used to build
|
||||||
// the vendor ramdisk variant of the C/C++ module.
|
// the vendor ramdisk variant of the C/C++ module.
|
||||||
Exclude_static_libs []string
|
Exclude_static_libs []string
|
||||||
@@ -201,6 +220,10 @@ type BaseLinkerProperties struct {
|
|||||||
// variants.
|
// variants.
|
||||||
Shared_libs []string
|
Shared_libs []string
|
||||||
|
|
||||||
|
// list of Rust libs that should be statically linked to build the vendor ramdisk
|
||||||
|
// variant.
|
||||||
|
Static_rlibs []string
|
||||||
|
|
||||||
// list of ehader libs that only should be used to build platform variant of
|
// list of ehader libs that only should be used to build platform variant of
|
||||||
// the C/C++ module.
|
// the C/C++ module.
|
||||||
Header_libs []string
|
Header_libs []string
|
||||||
@@ -291,6 +314,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||||||
deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
|
deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...)
|
||||||
deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Header_libs...)
|
deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Header_libs...)
|
||||||
deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
|
deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
|
||||||
|
deps.Rlibs = append(deps.Rlibs, linker.Properties.Static_rlibs...)
|
||||||
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
|
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
|
||||||
deps.RuntimeLibs = append(deps.RuntimeLibs, linker.Properties.Runtime_libs...)
|
deps.RuntimeLibs = append(deps.RuntimeLibs, linker.Properties.Runtime_libs...)
|
||||||
|
|
||||||
@@ -333,6 +357,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor.Exclude_static_libs)
|
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor.Exclude_static_libs)
|
||||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
|
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
|
||||||
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor.Exclude_runtime_libs)
|
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor.Exclude_runtime_libs)
|
||||||
|
deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Vendor.Static_rlibs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.inProduct() {
|
if ctx.inProduct() {
|
||||||
@@ -345,6 +370,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Product.Exclude_static_libs)
|
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Product.Exclude_static_libs)
|
||||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Product.Exclude_static_libs)
|
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Product.Exclude_static_libs)
|
||||||
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Product.Exclude_runtime_libs)
|
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Product.Exclude_runtime_libs)
|
||||||
|
deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Product.Static_rlibs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.inRecovery() {
|
if ctx.inRecovery() {
|
||||||
@@ -358,6 +384,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Recovery.Exclude_static_libs)
|
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Recovery.Exclude_static_libs)
|
||||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs)
|
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs)
|
||||||
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Recovery.Exclude_runtime_libs)
|
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Recovery.Exclude_runtime_libs)
|
||||||
|
deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Recovery.Static_rlibs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.inRamdisk() {
|
if ctx.inRamdisk() {
|
||||||
@@ -368,6 +395,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Ramdisk.Exclude_static_libs)
|
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Ramdisk.Exclude_static_libs)
|
||||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Ramdisk.Exclude_static_libs)
|
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Ramdisk.Exclude_static_libs)
|
||||||
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Ramdisk.Exclude_runtime_libs)
|
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Ramdisk.Exclude_runtime_libs)
|
||||||
|
deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Ramdisk.Static_rlibs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.inVendorRamdisk() {
|
if ctx.inVendorRamdisk() {
|
||||||
@@ -377,6 +405,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
|
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
|
||||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
|
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
|
||||||
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_runtime_libs)
|
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_runtime_libs)
|
||||||
|
deps.Rlibs = append(deps.Rlibs, linker.Properties.Target.Vendor_ramdisk.Static_rlibs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.useSdk() {
|
if !ctx.useSdk() {
|
||||||
|
@@ -299,6 +299,7 @@ func commonDefaultModules() string {
|
|||||||
system_shared_libs: [],
|
system_shared_libs: [],
|
||||||
stl: "none",
|
stl: "none",
|
||||||
vendor_available: true,
|
vendor_available: true,
|
||||||
|
vendor_ramdisk_available: true,
|
||||||
product_available: true,
|
product_available: true,
|
||||||
recovery_available: true,
|
recovery_available: true,
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
@@ -570,17 +571,17 @@ var PrepareForTestWithCcDefaultModules = android.GroupFixturePreparers(
|
|||||||
|
|
||||||
// Additional files needed in tests that disallow non-existent source.
|
// Additional files needed in tests that disallow non-existent source.
|
||||||
android.MockFS{
|
android.MockFS{
|
||||||
"defaults/cc/common/libc.map.txt": nil,
|
"defaults/cc/common/libc.map.txt": nil,
|
||||||
"defaults/cc/common/libdl.map.txt": nil,
|
"defaults/cc/common/libdl.map.txt": nil,
|
||||||
"defaults/cc/common/libft2.map.txt": nil,
|
"defaults/cc/common/libft2.map.txt": nil,
|
||||||
"defaults/cc/common/libm.map.txt": nil,
|
"defaults/cc/common/libm.map.txt": nil,
|
||||||
"defaults/cc/common/ndk_libc++_shared": nil,
|
"defaults/cc/common/ndk_libc++_shared": nil,
|
||||||
"defaults/cc/common/crtbegin_so.c": nil,
|
"defaults/cc/common/crtbegin_so.c": nil,
|
||||||
"defaults/cc/common/crtbegin.c": nil,
|
"defaults/cc/common/crtbegin.c": nil,
|
||||||
"defaults/cc/common/crtend_so.c": nil,
|
"defaults/cc/common/crtend_so.c": nil,
|
||||||
"defaults/cc/common/crtend.c": nil,
|
"defaults/cc/common/crtend.c": nil,
|
||||||
"defaults/cc/common/crtbrand.c": nil,
|
"defaults/cc/common/crtbrand.c": nil,
|
||||||
"external/compiler-rt/lib/cfi/cfi_blocklist.txt": nil,
|
"external/compiler-rt/lib/cfi/cfi_blocklist.txt": nil,
|
||||||
|
|
||||||
"defaults/cc/common/libclang_rt.ubsan_minimal.android_arm64.a": nil,
|
"defaults/cc/common/libclang_rt.ubsan_minimal.android_arm64.a": nil,
|
||||||
"defaults/cc/common/libclang_rt.ubsan_minimal.android_arm.a": nil,
|
"defaults/cc/common/libclang_rt.ubsan_minimal.android_arm.a": nil,
|
||||||
|
@@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
"android/soong/cc"
|
||||||
"android/soong/rust/config"
|
"android/soong/rust/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -118,6 +119,7 @@ type buildOutput struct {
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
|
pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
|
||||||
|
cc.TransformRlibstoStaticlib = TransformRlibstoStaticlib
|
||||||
}
|
}
|
||||||
|
|
||||||
type transformProperties struct {
|
type transformProperties struct {
|
||||||
@@ -166,6 +168,48 @@ func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps,
|
|||||||
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib"))
|
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, deps []cc.RustRlibDep,
|
||||||
|
outputFile android.WritablePath) android.Path {
|
||||||
|
|
||||||
|
var rustPathDeps PathDeps
|
||||||
|
var rustFlags Flags
|
||||||
|
|
||||||
|
for _, rlibDep := range deps {
|
||||||
|
rustPathDeps.RLibs = append(rustPathDeps.RLibs, RustLibrary{Path: rlibDep.LibPath, CrateName: rlibDep.CrateName})
|
||||||
|
rustPathDeps.linkDirs = append(rustPathDeps.linkDirs, rlibDep.LinkDirs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
ccModule := ctx.(cc.ModuleContext).Module().(*cc.Module)
|
||||||
|
toolchain := config.FindToolchain(ctx.Os(), ctx.Arch())
|
||||||
|
t := transformProperties{
|
||||||
|
// Crate name can be a predefined value as this is a staticlib and
|
||||||
|
// it does not need to be unique. The crate name is used for name
|
||||||
|
// mangling, but it is mixed with the metadata for that purpose, which we
|
||||||
|
// already set to the module name.
|
||||||
|
crateName: "generated_rust_staticlib",
|
||||||
|
is64Bit: toolchain.Is64Bit(),
|
||||||
|
targetTriple: toolchain.RustTriple(),
|
||||||
|
bootstrap: ccModule.Bootstrap(),
|
||||||
|
inRecovery: ccModule.InRecovery(),
|
||||||
|
inRamdisk: ccModule.InRamdisk(),
|
||||||
|
inVendorRamdisk: ccModule.InVendorRamdisk(),
|
||||||
|
|
||||||
|
// crateType indicates what type of crate to build
|
||||||
|
crateType: "staticlib",
|
||||||
|
|
||||||
|
// synthetic indicates whether this is an actual Rust module or not
|
||||||
|
synthetic: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
rustFlags = CommonDefaultFlags(ctx, toolchain, rustFlags)
|
||||||
|
rustFlags = CommonLibraryCompilerFlags(ctx, rustFlags)
|
||||||
|
rustFlags.GlobalRustFlags = append(rustFlags.GlobalRustFlags, "-C lto=thin")
|
||||||
|
|
||||||
|
rustFlags.EmitXrefs = false
|
||||||
|
|
||||||
|
return transformSrctoCrate(ctx, mainSrc, rustPathDeps, rustFlags, outputFile, t).outputFile
|
||||||
|
}
|
||||||
|
|
||||||
func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
|
func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
|
||||||
outputFile android.WritablePath) buildOutput {
|
outputFile android.WritablePath) buildOutput {
|
||||||
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
|
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
|
||||||
|
@@ -46,6 +46,9 @@ func TestSourceProviderCollision(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCompilationOutputFiles(t *testing.T) {
|
func TestCompilationOutputFiles(t *testing.T) {
|
||||||
|
|
||||||
|
// Note: Rustdoc output is produced for the PrimaryModule, so if the variant
|
||||||
|
// order changes, then it may be produced for a different variant.
|
||||||
ctx := testRust(t, `
|
ctx := testRust(t, `
|
||||||
rust_library {
|
rust_library {
|
||||||
name: "libfizz_buzz",
|
name: "libfizz_buzz",
|
||||||
@@ -125,6 +128,16 @@ func TestCompilationOutputFiles(t *testing.T) {
|
|||||||
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/rustdoc.timestamp",
|
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/rustdoc.timestamp",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
testName: "rust_ffi rlib",
|
||||||
|
moduleName: "librust_ffi",
|
||||||
|
variant: "android_arm64_armv8-a_rlib_rlib-std",
|
||||||
|
expectedFiles: []string{
|
||||||
|
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_rlib_rlib-std/librust_ffi.rlib",
|
||||||
|
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_rlib_rlib-std/librust_ffi.rlib.clippy",
|
||||||
|
"out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_rlib_rlib-std/meta_lic",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
testName: "rust_ffi shared",
|
testName: "rust_ffi shared",
|
||||||
moduleName: "librust_ffi",
|
moduleName: "librust_ffi",
|
||||||
|
@@ -47,7 +47,7 @@ func (cov *coverage) deps(ctx DepsContext, deps Deps) Deps {
|
|||||||
|
|
||||||
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
|
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
|
||||||
if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
|
if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
|
||||||
ctx.AddVariationDependencies([]blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}, rlibDepTag, ProfilerBuiltins)
|
ctx.AddVariationDependencies([]blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}, {Mutator: "link", Variation: ""}}, rlibDepTag, ProfilerBuiltins)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -120,13 +120,17 @@ func TestCCFuzzDepBundling(t *testing.T) {
|
|||||||
}
|
}
|
||||||
cc_fuzz {
|
cc_fuzz {
|
||||||
name: "fuzz_static_libtest",
|
name: "fuzz_static_libtest",
|
||||||
|
static_rlibs: ["libtest_fuzzing"],
|
||||||
|
}
|
||||||
|
cc_fuzz {
|
||||||
|
name: "fuzz_staticffi_libtest",
|
||||||
static_libs: ["libtest_fuzzing"],
|
static_libs: ["libtest_fuzzing"],
|
||||||
}
|
}
|
||||||
|
|
||||||
`)
|
`)
|
||||||
|
|
||||||
fuzz_shared_libtest := ctx.ModuleForTests("fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
|
fuzz_shared_libtest := ctx.ModuleForTests("fuzz_shared_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
|
||||||
fuzz_static_libtest := ctx.ModuleForTests("fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
|
fuzz_static_libtest := ctx.ModuleForTests("fuzz_static_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
|
||||||
|
fuzz_staticffi_libtest := ctx.ModuleForTests("fuzz_staticffi_libtest", "android_arm64_armv8-a_fuzzer").Module().(cc.LinkableInterface)
|
||||||
|
|
||||||
if !strings.Contains(fuzz_shared_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
|
if !strings.Contains(fuzz_shared_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
|
||||||
t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", fuzz_shared_libtest.FuzzSharedLibraries().String())
|
t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_shared ('libcc_transitive_dep'): %#v", fuzz_shared_libtest.FuzzSharedLibraries().String())
|
||||||
@@ -134,4 +138,7 @@ func TestCCFuzzDepBundling(t *testing.T) {
|
|||||||
if !strings.Contains(fuzz_static_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
|
if !strings.Contains(fuzz_static_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
|
||||||
t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_static_libtest.FuzzSharedLibraries().String())
|
t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_static ('libcc_transitive_dep'): %#v", fuzz_static_libtest.FuzzSharedLibraries().String())
|
||||||
}
|
}
|
||||||
|
if !strings.Contains(fuzz_staticffi_libtest.FuzzSharedLibraries().String(), ":libcc_transitive_dep.so") {
|
||||||
|
t.Errorf("cc_fuzz does not contain the expected bundled transitive shared libs from rust_ffi_rlib ('libcc_transitive_dep'): %#v", fuzz_staticffi_libtest.FuzzSharedLibraries().String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,33 +22,45 @@ import (
|
|||||||
"android/soong/cc"
|
"android/soong/cc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test that cc modules can link against vendor_available rust_ffi_static libraries.
|
// Test that cc modules can link against vendor_available rust_ffi_rlib/rust_ffi_static libraries.
|
||||||
func TestVendorLinkage(t *testing.T) {
|
func TestVendorLinkage(t *testing.T) {
|
||||||
ctx := testRust(t, `
|
ctx := testRust(t, `
|
||||||
cc_binary {
|
cc_binary {
|
||||||
name: "fizz_vendor",
|
name: "fizz_vendor_available",
|
||||||
static_libs: ["libfoo_vendor"],
|
static_libs: ["libfoo_vendor_static"],
|
||||||
|
static_rlibs: ["libfoo_vendor"],
|
||||||
|
vendor_available: true,
|
||||||
|
}
|
||||||
|
cc_binary {
|
||||||
|
name: "fizz_soc_specific",
|
||||||
|
static_rlibs: ["libfoo_vendor"],
|
||||||
soc_specific: true,
|
soc_specific: true,
|
||||||
}
|
}
|
||||||
rust_ffi_static {
|
rust_ffi_rlib {
|
||||||
name: "libfoo_vendor",
|
name: "libfoo_vendor",
|
||||||
crate_name: "foo",
|
crate_name: "foo",
|
||||||
srcs: ["foo.rs"],
|
srcs: ["foo.rs"],
|
||||||
vendor_available: true,
|
vendor_available: true,
|
||||||
}
|
}
|
||||||
|
rust_ffi_static {
|
||||||
|
name: "libfoo_vendor_static",
|
||||||
|
crate_name: "foo",
|
||||||
|
srcs: ["foo.rs"],
|
||||||
|
vendor_available: true,
|
||||||
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
vendorBinary := ctx.ModuleForTests("fizz_vendor", "android_vendor_arm64_armv8-a").Module().(*cc.Module)
|
vendorBinary := ctx.ModuleForTests("fizz_vendor_available", "android_vendor_arm64_armv8-a").Module().(*cc.Module)
|
||||||
|
|
||||||
if !android.InList("libfoo_vendor.vendor", vendorBinary.Properties.AndroidMkStaticLibs) {
|
if !android.InList("libfoo_vendor_static.vendor", vendorBinary.Properties.AndroidMkStaticLibs) {
|
||||||
t.Errorf("vendorBinary should have a dependency on libfoo_vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs)
|
t.Errorf("vendorBinary should have a dependency on libfoo_vendor_static.vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that variants which use the vndk emit the appropriate cfg flag.
|
// Test that variants which use the vndk emit the appropriate cfg flag.
|
||||||
func TestImageCfgFlag(t *testing.T) {
|
func TestImageCfgFlag(t *testing.T) {
|
||||||
ctx := testRust(t, `
|
ctx := testRust(t, `
|
||||||
rust_ffi_static {
|
rust_ffi_shared {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
crate_name: "foo",
|
crate_name: "foo",
|
||||||
srcs: ["foo.rs"],
|
srcs: ["foo.rs"],
|
||||||
@@ -57,7 +69,7 @@ func TestImageCfgFlag(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
vendor := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_static").Rule("rustc")
|
vendor := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_shared").Rule("rustc")
|
||||||
|
|
||||||
if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
|
if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
|
||||||
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
|
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
|
||||||
@@ -69,7 +81,7 @@ func TestImageCfgFlag(t *testing.T) {
|
|||||||
t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
|
t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
|
||||||
}
|
}
|
||||||
|
|
||||||
product := ctx.ModuleForTests("libfoo", "android_product_arm64_armv8-a_static").Rule("rustc")
|
product := ctx.ModuleForTests("libfoo", "android_product_arm64_armv8-a_shared").Rule("rustc")
|
||||||
if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") {
|
if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") {
|
||||||
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
|
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
|
||||||
}
|
}
|
||||||
@@ -80,7 +92,7 @@ func TestImageCfgFlag(t *testing.T) {
|
|||||||
t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
|
t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
|
||||||
}
|
}
|
||||||
|
|
||||||
system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Rule("rustc")
|
system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("rustc")
|
||||||
if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") {
|
if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") {
|
||||||
t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
|
t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
|
||||||
}
|
}
|
||||||
@@ -93,27 +105,34 @@ func TestImageCfgFlag(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries.
|
// Test that cc modules can link against vendor_ramdisk_available rust_ffi_rlib and rust_ffi_static libraries.
|
||||||
func TestVendorRamdiskLinkage(t *testing.T) {
|
func TestVendorRamdiskLinkage(t *testing.T) {
|
||||||
ctx := testRust(t, `
|
ctx := testRust(t, `
|
||||||
cc_library_static {
|
cc_library_shared {
|
||||||
name: "libcc_vendor_ramdisk",
|
name: "libcc_vendor_ramdisk",
|
||||||
static_libs: ["libfoo_vendor_ramdisk"],
|
static_rlibs: ["libfoo_vendor_ramdisk"],
|
||||||
|
static_libs: ["libfoo_static_vendor_ramdisk"],
|
||||||
system_shared_libs: [],
|
system_shared_libs: [],
|
||||||
vendor_ramdisk_available: true,
|
vendor_ramdisk_available: true,
|
||||||
}
|
}
|
||||||
rust_ffi_static {
|
rust_ffi_rlib {
|
||||||
name: "libfoo_vendor_ramdisk",
|
name: "libfoo_vendor_ramdisk",
|
||||||
crate_name: "foo",
|
crate_name: "foo",
|
||||||
srcs: ["foo.rs"],
|
srcs: ["foo.rs"],
|
||||||
vendor_ramdisk_available: true,
|
vendor_ramdisk_available: true,
|
||||||
}
|
}
|
||||||
|
rust_ffi_static {
|
||||||
|
name: "libfoo_static_vendor_ramdisk",
|
||||||
|
crate_name: "foo",
|
||||||
|
srcs: ["foo.rs"],
|
||||||
|
vendor_ramdisk_available: true,
|
||||||
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_static").Module().(*cc.Module)
|
vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_shared").Module().(*cc.Module)
|
||||||
|
|
||||||
if !android.InList("libfoo_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) {
|
if !android.InList("libfoo_static_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) {
|
||||||
t.Errorf("libcc_vendor_ramdisk should have a dependency on libfoo_vendor_ramdisk")
|
t.Errorf("libcc_vendor_ramdisk should have a dependency on libfoo_static_vendor_ramdisk")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
147
rust/library.go
147
rust/library.go
@@ -37,10 +37,15 @@ func init() {
|
|||||||
android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
|
android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
|
||||||
android.RegisterModuleType("rust_ffi", RustFFIFactory)
|
android.RegisterModuleType("rust_ffi", RustFFIFactory)
|
||||||
android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
|
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", RustFFIHostFactory)
|
||||||
android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
|
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 {
|
type VariantLibraryProperties struct {
|
||||||
@@ -104,6 +109,8 @@ type libraryDecorator struct {
|
|||||||
includeDirs android.Paths
|
includeDirs android.Paths
|
||||||
sourceProvider SourceProvider
|
sourceProvider SourceProvider
|
||||||
|
|
||||||
|
isFFI bool
|
||||||
|
|
||||||
// table-of-contents file for cdylib crates to optimize out relinking when possible
|
// table-of-contents file for cdylib crates to optimize out relinking when possible
|
||||||
tocFile android.OptionalPath
|
tocFile android.OptionalPath
|
||||||
}
|
}
|
||||||
@@ -143,6 +150,8 @@ type libraryInterface interface {
|
|||||||
BuildOnlyShared()
|
BuildOnlyShared()
|
||||||
|
|
||||||
toc() android.OptionalPath
|
toc() android.OptionalPath
|
||||||
|
|
||||||
|
isFFILibrary() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryDecorator) nativeCoverage() 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 {
|
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
|
return RlibLinkage
|
||||||
} else if library.baseCompiler.preferRlib() {
|
} else if library.baseCompiler.preferRlib() {
|
||||||
return RlibLinkage
|
return RlibLinkage
|
||||||
@@ -270,8 +279,8 @@ func RustLibraryFactory() android.Module {
|
|||||||
return module.Init()
|
return module.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// rust_ffi produces all FFI variants (rust_ffi_shared and
|
// rust_ffi produces all FFI variants (rust_ffi_shared, rust_ffi_static, and
|
||||||
// rust_ffi_static).
|
// rust_ffi_rlib).
|
||||||
func RustFFIFactory() android.Module {
|
func RustFFIFactory() android.Module {
|
||||||
module, library := NewRustLibrary(android.HostAndDeviceSupported)
|
module, library := NewRustLibrary(android.HostAndDeviceSupported)
|
||||||
library.BuildOnlyFFI()
|
library.BuildOnlyFFI()
|
||||||
@@ -300,14 +309,6 @@ func RustFFISharedFactory() android.Module {
|
|||||||
return module.Init()
|
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_host produces all Rust variants for the host
|
||||||
// (rust_library_dylib_host and rust_library_rlib_host).
|
// (rust_library_dylib_host and rust_library_rlib_host).
|
||||||
func RustLibraryHostFactory() android.Module {
|
func RustLibraryHostFactory() android.Module {
|
||||||
@@ -317,7 +318,7 @@ func RustLibraryHostFactory() android.Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rust_ffi_host produces all FFI variants for the host
|
// 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 {
|
func RustFFIHostFactory() android.Module {
|
||||||
module, library := NewRustLibrary(android.HostSupported)
|
module, library := NewRustLibrary(android.HostSupported)
|
||||||
library.BuildOnlyFFI()
|
library.BuildOnlyFFI()
|
||||||
@@ -340,14 +341,6 @@ func RustLibraryRlibHostFactory() android.Module {
|
|||||||
return module.Init()
|
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
|
// rust_ffi_shared_host produces an shared library for the host (Rust
|
||||||
// crate type "cdylib").
|
// crate type "cdylib").
|
||||||
func RustFFISharedHostFactory() android.Module {
|
func RustFFISharedHostFactory() android.Module {
|
||||||
@@ -356,11 +349,51 @@ func RustFFISharedHostFactory() android.Module {
|
|||||||
return module.Init()
|
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() {
|
func (library *libraryDecorator) BuildOnlyFFI() {
|
||||||
library.MutatedProperties.BuildDylib = false
|
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.BuildShared = true
|
||||||
library.MutatedProperties.BuildStatic = true
|
library.MutatedProperties.BuildStatic = true
|
||||||
|
|
||||||
|
library.isFFI = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryDecorator) BuildOnlyRust() {
|
func (library *libraryDecorator) BuildOnlyRust() {
|
||||||
@@ -384,11 +417,21 @@ func (library *libraryDecorator) BuildOnlyRlib() {
|
|||||||
library.MutatedProperties.BuildStatic = false
|
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() {
|
func (library *libraryDecorator) BuildOnlyStatic() {
|
||||||
library.MutatedProperties.BuildRlib = false
|
library.MutatedProperties.BuildRlib = false
|
||||||
library.MutatedProperties.BuildDylib = false
|
library.MutatedProperties.BuildDylib = false
|
||||||
library.MutatedProperties.BuildShared = false
|
library.MutatedProperties.BuildShared = false
|
||||||
library.MutatedProperties.BuildStatic = true
|
library.MutatedProperties.BuildStatic = true
|
||||||
|
|
||||||
|
library.isFFI = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryDecorator) BuildOnlyShared() {
|
func (library *libraryDecorator) BuildOnlyShared() {
|
||||||
@@ -396,6 +439,12 @@ func (library *libraryDecorator) BuildOnlyShared() {
|
|||||||
library.MutatedProperties.BuildDylib = false
|
library.MutatedProperties.BuildDylib = false
|
||||||
library.MutatedProperties.BuildStatic = false
|
library.MutatedProperties.BuildStatic = false
|
||||||
library.MutatedProperties.BuildShared = true
|
library.MutatedProperties.BuildShared = true
|
||||||
|
|
||||||
|
library.isFFI = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (library *libraryDecorator) isFFILibrary() bool {
|
||||||
|
return library.isFFI
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
|
func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
|
||||||
@@ -480,10 +529,11 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) F
|
|||||||
|
|
||||||
flags = CommonLibraryCompilerFlags(ctx, flags)
|
flags = CommonLibraryCompilerFlags(ctx, flags)
|
||||||
|
|
||||||
if library.shared() || library.static() {
|
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.Include_dirs)...)
|
||||||
library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)...)
|
library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if library.shared() {
|
if library.shared() {
|
||||||
if ctx.Darwin() {
|
if ctx.Darwin() {
|
||||||
flags.LinkFlags = append(
|
flags.LinkFlags = append(
|
||||||
@@ -509,6 +559,9 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
|
|||||||
deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
|
deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure link dirs are not duplicated
|
||||||
|
deps.linkDirs = android.FirstUniqueStrings(deps.linkDirs)
|
||||||
|
|
||||||
// Calculate output filename
|
// Calculate output filename
|
||||||
if library.rlib() {
|
if library.rlib() {
|
||||||
fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
|
fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
|
||||||
@@ -564,9 +617,10 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
|
|||||||
library.flagExporter.exportLinkObjects(deps.linkObjects...)
|
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{
|
android.SetProvider(ctx, cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
|
||||||
IncludeDirs: library.includeDirs,
|
IncludeDirs: android.FirstUniquePaths(library.includeDirs),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -681,6 +735,11 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't produce rlib/dylib/source variants for shared or static variants
|
||||||
|
if library.shared() || library.static() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var variants []string
|
var variants []string
|
||||||
// The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
|
// 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.
|
// depend on this variant. It must be the first variant to be declared.
|
||||||
@@ -720,6 +779,9 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
// The source variant does not produce any library.
|
// The source variant does not produce any library.
|
||||||
// Disable the compilation steps.
|
// Disable the compilation steps.
|
||||||
v.(*Module).compiler.SetDisabled()
|
v.(*Module).compiler.SetDisabled()
|
||||||
|
case "":
|
||||||
|
// if there's an empty variant, alias it so it is the default variant
|
||||||
|
mctx.AliasVariation("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,20 +806,29 @@ func LibstdMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
case libraryInterface:
|
case libraryInterface:
|
||||||
// Only create a variant if a library is actually being built.
|
// Only create a variant if a library is actually being built.
|
||||||
if library.rlib() && !library.sysroot() {
|
if library.rlib() && !library.sysroot() {
|
||||||
variants := []string{"rlib-std", "dylib-std"}
|
// If this is a rust_ffi variant it only needs rlib-std
|
||||||
modules := mctx.CreateLocalVariations(variants...)
|
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)
|
rlib := modules[0].(*Module)
|
||||||
dylib := modules[1].(*Module)
|
dylib := modules[1].(*Module)
|
||||||
rlib.compiler.(libraryInterface).setRlibStd()
|
rlib.compiler.(libraryInterface).setRlibStd()
|
||||||
dylib.compiler.(libraryInterface).setDylibStd()
|
dylib.compiler.(libraryInterface).setDylibStd()
|
||||||
if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
|
if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
|
||||||
// TODO(b/165791368)
|
// TODO(b/165791368)
|
||||||
// Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
|
// Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
|
||||||
// variants are properly supported.
|
// variants are properly supported.
|
||||||
dylib.Disable()
|
dylib.Disable()
|
||||||
|
}
|
||||||
|
rlib.Properties.RustSubName += RlibStdlibSuffix
|
||||||
}
|
}
|
||||||
rlib.Properties.RustSubName += RlibStdlibSuffix
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -37,9 +37,10 @@ func TestLibraryVariants(t *testing.T) {
|
|||||||
}`)
|
}`)
|
||||||
|
|
||||||
// Test all variants are being built.
|
// Test all variants are being built.
|
||||||
|
libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static").Rule("rustc")
|
||||||
libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
|
libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
|
||||||
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
|
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
|
||||||
libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static").Rule("rustc")
|
libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
|
||||||
libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared").Rule("rustc")
|
libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared").Rule("rustc")
|
||||||
|
|
||||||
rlibCrateType := "rlib"
|
rlibCrateType := "rlib"
|
||||||
@@ -62,6 +63,11 @@ func TestLibraryVariants(t *testing.T) {
|
|||||||
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", staticCrateType, libfooStatic.Args["rustcFlags"])
|
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", staticCrateType, libfooStatic.Args["rustcFlags"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test crate type for FFI rlibs is correct
|
||||||
|
if !strings.Contains(libfooFFIRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
|
||||||
|
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooFFIRlib.Args["rustcFlags"])
|
||||||
|
}
|
||||||
|
|
||||||
// Test crate type for C shared libraries is correct.
|
// Test crate type for C shared libraries is correct.
|
||||||
if !strings.Contains(libfooShared.Args["rustcFlags"], "crate-type="+sharedCrateType) {
|
if !strings.Contains(libfooShared.Args["rustcFlags"], "crate-type="+sharedCrateType) {
|
||||||
t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.Args["rustcFlags"])
|
t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.Args["rustcFlags"])
|
||||||
@@ -182,15 +188,20 @@ func TestSharedLibraryToc(t *testing.T) {
|
|||||||
|
|
||||||
func TestStaticLibraryLinkage(t *testing.T) {
|
func TestStaticLibraryLinkage(t *testing.T) {
|
||||||
ctx := testRust(t, `
|
ctx := testRust(t, `
|
||||||
rust_ffi_static {
|
rust_ffi {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
srcs: ["foo.rs"],
|
srcs: ["foo.rs"],
|
||||||
crate_name: "foo",
|
crate_name: "foo",
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
|
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_rlib-std")
|
||||||
|
libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
|
||||||
|
|
||||||
if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkRlibs) {
|
if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkRlibs) {
|
||||||
|
t.Errorf("Static libstd rlib expected to be a dependency of Rust rlib libraries. Rlib deps are: %#v",
|
||||||
|
libfoo.Module().(*Module).Properties.AndroidMkDylibs)
|
||||||
|
}
|
||||||
|
if !android.InList("libstd", libfooStatic.Module().(*Module).Properties.AndroidMkRlibs) {
|
||||||
t.Errorf("Static libstd rlib expected to be a dependency of Rust static libraries. Rlib deps are: %#v",
|
t.Errorf("Static libstd rlib expected to be a dependency of Rust static libraries. Rlib deps are: %#v",
|
||||||
libfoo.Module().(*Module).Properties.AndroidMkDylibs)
|
libfoo.Module().(*Module).Properties.AndroidMkDylibs)
|
||||||
}
|
}
|
||||||
@@ -198,6 +209,12 @@ func TestStaticLibraryLinkage(t *testing.T) {
|
|||||||
|
|
||||||
func TestNativeDependencyOfRlib(t *testing.T) {
|
func TestNativeDependencyOfRlib(t *testing.T) {
|
||||||
ctx := testRust(t, `
|
ctx := testRust(t, `
|
||||||
|
rust_ffi_rlib {
|
||||||
|
name: "libffi_rlib",
|
||||||
|
crate_name: "ffi_rlib",
|
||||||
|
rlibs: ["librust_rlib"],
|
||||||
|
srcs: ["foo.rs"],
|
||||||
|
}
|
||||||
rust_ffi_static {
|
rust_ffi_static {
|
||||||
name: "libffi_static",
|
name: "libffi_static",
|
||||||
crate_name: "ffi_static",
|
crate_name: "ffi_static",
|
||||||
@@ -224,10 +241,12 @@ func TestNativeDependencyOfRlib(t *testing.T) {
|
|||||||
rustRlibRlibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_rlib-std")
|
rustRlibRlibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_rlib-std")
|
||||||
rustRlibDylibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_dylib-std")
|
rustRlibDylibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_dylib-std")
|
||||||
ffiStatic := ctx.ModuleForTests("libffi_static", "android_arm64_armv8-a_static")
|
ffiStatic := ctx.ModuleForTests("libffi_static", "android_arm64_armv8-a_static")
|
||||||
|
ffiRlib := ctx.ModuleForTests("libffi_rlib", "android_arm64_armv8-a_rlib_rlib-std")
|
||||||
|
|
||||||
modules := []android.TestingModule{
|
modules := []android.TestingModule{
|
||||||
rustRlibRlibStd,
|
rustRlibRlibStd,
|
||||||
rustRlibDylibStd,
|
rustRlibDylibStd,
|
||||||
|
ffiRlib,
|
||||||
ffiStatic,
|
ffiStatic,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,27 +309,28 @@ func TestAutoDeps(t *testing.T) {
|
|||||||
|
|
||||||
libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std")
|
libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std")
|
||||||
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib")
|
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib")
|
||||||
|
libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std")
|
||||||
libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static")
|
libfooStatic := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_static")
|
||||||
libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared")
|
libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared")
|
||||||
|
|
||||||
for _, static := range []android.TestingModule{libfooRlib, libfooStatic} {
|
for _, static := range []android.TestingModule{libfooRlib, libfooStatic, libfooFFIRlib} {
|
||||||
if !android.InList("libbar.rlib-std", static.Module().(*Module).Properties.AndroidMkRlibs) {
|
if !android.InList("libbar.rlib-std", static.Module().(*Module).Properties.AndroidMkRlibs) {
|
||||||
t.Errorf("libbar not present as rlib dependency in static lib")
|
t.Errorf("libbar not present as rlib dependency in static lib: %s", static.Module().Name())
|
||||||
}
|
}
|
||||||
if android.InList("libbar", static.Module().(*Module).Properties.AndroidMkDylibs) {
|
if android.InList("libbar", static.Module().(*Module).Properties.AndroidMkDylibs) {
|
||||||
t.Errorf("libbar present as dynamic dependency in static lib")
|
t.Errorf("libbar present as dynamic dependency in static lib: %s", static.Module().Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dyn := range []android.TestingModule{libfooDylib, libfooShared} {
|
for _, dyn := range []android.TestingModule{libfooDylib, libfooShared} {
|
||||||
if !android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkDylibs) {
|
if !android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkDylibs) {
|
||||||
t.Errorf("libbar not present as dynamic dependency in dynamic lib")
|
t.Errorf("libbar not present as dynamic dependency in dynamic lib: %s", dyn.Module().Name())
|
||||||
}
|
}
|
||||||
if android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
|
if android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
|
||||||
t.Errorf("libbar present as rlib dependency in dynamic lib")
|
t.Errorf("libbar present as rlib dependency in dynamic lib: %s", dyn.Module().Name())
|
||||||
}
|
}
|
||||||
if !android.InList("librlib_only", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
|
if !android.InList("librlib_only", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
|
||||||
t.Errorf("librlib_only should be selected by rustlibs as an rlib.")
|
t.Errorf("librlib_only should be selected by rustlibs as an rlib: %s.", dyn.Module().Name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,6 +395,7 @@ func TestLibstdLinkage(t *testing.T) {
|
|||||||
|
|
||||||
libbarShared := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module().(*Module)
|
libbarShared := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module().(*Module)
|
||||||
libbarStatic := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_static").Module().(*Module)
|
libbarStatic := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_static").Module().(*Module)
|
||||||
|
libbarFFIRlib := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
|
||||||
|
|
||||||
// prefer_rlib works the same for both rust_library and rust_ffi, so a single check is sufficient here.
|
// prefer_rlib works the same for both rust_library and rust_ffi, so a single check is sufficient here.
|
||||||
libbarRlibStd := ctx.ModuleForTests("libbar.prefer_rlib", "android_arm64_armv8-a_shared").Module().(*Module)
|
libbarRlibStd := ctx.ModuleForTests("libbar.prefer_rlib", "android_arm64_armv8-a_shared").Module().(*Module)
|
||||||
@@ -398,6 +419,12 @@ func TestLibstdLinkage(t *testing.T) {
|
|||||||
if !android.InList("libfoo.rlib-std", libbarStatic.Properties.AndroidMkRlibs) {
|
if !android.InList("libfoo.rlib-std", libbarStatic.Properties.AndroidMkRlibs) {
|
||||||
t.Errorf("Device rust_ffi_static does not link dependent rustlib rlib-std variant")
|
t.Errorf("Device rust_ffi_static does not link dependent rustlib rlib-std variant")
|
||||||
}
|
}
|
||||||
|
if !android.InList("libstd", libbarFFIRlib.Properties.AndroidMkRlibs) {
|
||||||
|
t.Errorf("Device rust_ffi_rlib does not link libstd as an rlib")
|
||||||
|
}
|
||||||
|
if !android.InList("libfoo.rlib-std", libbarFFIRlib.Properties.AndroidMkRlibs) {
|
||||||
|
t.Errorf("Device rust_ffi_rlib does not link dependent rustlib rlib-std variant")
|
||||||
|
}
|
||||||
if !android.InList("libstd", libbarRlibStd.Properties.AndroidMkRlibs) {
|
if !android.InList("libstd", libbarRlibStd.Properties.AndroidMkRlibs) {
|
||||||
t.Errorf("rust_ffi with prefer_rlib does not link libstd as an rlib")
|
t.Errorf("rust_ffi with prefer_rlib does not link libstd as an rlib")
|
||||||
}
|
}
|
||||||
|
@@ -76,6 +76,7 @@ func (procMacro *procMacroDecorator) compile(ctx ModuleContext, flags Flags, dep
|
|||||||
srcPath := crateRootPath(ctx, procMacro)
|
srcPath := crateRootPath(ctx, procMacro)
|
||||||
ret := TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile)
|
ret := TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile)
|
||||||
procMacro.baseCompiler.unstrippedOutputFile = outputFile
|
procMacro.baseCompiler.unstrippedOutputFile = outputFile
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
59
rust/rust.go
59
rust/rust.go
@@ -158,6 +158,8 @@ type Module struct {
|
|||||||
sourceProvider SourceProvider
|
sourceProvider SourceProvider
|
||||||
subAndroidMkOnce map[SubAndroidMkProvider]bool
|
subAndroidMkOnce map[SubAndroidMkProvider]bool
|
||||||
|
|
||||||
|
exportedLinkDirs []string
|
||||||
|
|
||||||
// Output file to be installed, may be stripped or unstripped.
|
// Output file to be installed, may be stripped or unstripped.
|
||||||
outputFile android.OptionalPath
|
outputFile android.OptionalPath
|
||||||
|
|
||||||
@@ -234,8 +236,8 @@ func (mod *Module) SelectedStl() string {
|
|||||||
|
|
||||||
func (mod *Module) NonCcVariants() bool {
|
func (mod *Module) NonCcVariants() bool {
|
||||||
if mod.compiler != nil {
|
if mod.compiler != nil {
|
||||||
if _, ok := mod.compiler.(libraryInterface); ok {
|
if library, ok := mod.compiler.(libraryInterface); ok {
|
||||||
return false
|
return library.buildRlib() || library.buildDylib()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName()))
|
panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName()))
|
||||||
@@ -465,6 +467,11 @@ type PathDeps struct {
|
|||||||
linkDirs []string
|
linkDirs []string
|
||||||
linkObjects []string
|
linkObjects []string
|
||||||
|
|
||||||
|
// exportedLinkDirs are exported linkDirs for direct rlib dependencies to
|
||||||
|
// cc_library_static dependants of rlibs.
|
||||||
|
// Track them separately from linkDirs so superfluous -L flags don't get emitted.
|
||||||
|
exportedLinkDirs []string
|
||||||
|
|
||||||
// Used by bindgen modules which call clang
|
// Used by bindgen modules which call clang
|
||||||
depClangFlags []string
|
depClangFlags []string
|
||||||
depIncludePaths android.Paths
|
depIncludePaths android.Paths
|
||||||
@@ -477,6 +484,9 @@ type PathDeps struct {
|
|||||||
// Paths to generated source files
|
// Paths to generated source files
|
||||||
SrcDeps android.Paths
|
SrcDeps android.Paths
|
||||||
srcProviderFiles android.Paths
|
srcProviderFiles android.Paths
|
||||||
|
|
||||||
|
// Used by Generated Libraries
|
||||||
|
depExportedRlibs []cc.RustRlibDep
|
||||||
}
|
}
|
||||||
|
|
||||||
type RustLibraries []RustLibrary
|
type RustLibraries []RustLibrary
|
||||||
@@ -543,6 +553,10 @@ func (mod *Module) VndkVersion() string {
|
|||||||
return mod.Properties.VndkVersion
|
return mod.Properties.VndkVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mod *Module) ExportedCrateLinkDirs() []string {
|
||||||
|
return mod.exportedLinkDirs
|
||||||
|
}
|
||||||
|
|
||||||
func (mod *Module) PreventInstall() bool {
|
func (mod *Module) PreventInstall() bool {
|
||||||
return mod.Properties.PreventInstall
|
return mod.Properties.PreventInstall
|
||||||
}
|
}
|
||||||
@@ -657,15 +671,6 @@ func (mod *Module) UnstrippedOutputFile() android.Path {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) IncludeDirs() android.Paths {
|
|
||||||
if mod.compiler != nil {
|
|
||||||
if library, ok := mod.compiler.(*libraryDecorator); ok {
|
|
||||||
return library.includeDirs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
panic(fmt.Errorf("IncludeDirs called on non-library module: %q", mod.BaseModuleName()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mod *Module) SetStatic() {
|
func (mod *Module) SetStatic() {
|
||||||
if mod.compiler != nil {
|
if mod.compiler != nil {
|
||||||
if library, ok := mod.compiler.(libraryInterface); ok {
|
if library, ok := mod.compiler.(libraryInterface); ok {
|
||||||
@@ -914,6 +919,10 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deps := mod.depsToPaths(ctx)
|
deps := mod.depsToPaths(ctx)
|
||||||
|
// Export linkDirs for CC rust generatedlibs
|
||||||
|
mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.exportedLinkDirs...)
|
||||||
|
mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.linkDirs...)
|
||||||
|
|
||||||
flags := Flags{
|
flags := Flags{
|
||||||
Toolchain: toolchain,
|
Toolchain: toolchain,
|
||||||
}
|
}
|
||||||
@@ -991,6 +1000,9 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
|||||||
if ctx.Failed() {
|
if ctx.Failed() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Export your own directory as a linkDir
|
||||||
|
mod.exportedLinkDirs = append(mod.exportedLinkDirs, linkPathFromFilePath(mod.OutputFile().Path()))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
|
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
|
||||||
@@ -1223,7 +1235,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() {
|
if rustDep, ok := dep.(*Module); ok && !rustDep.Static() && !rustDep.Shared() {
|
||||||
//Handle Rust Modules
|
//Handle Rust Modules
|
||||||
makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
|
makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
|
||||||
|
|
||||||
@@ -1249,9 +1261,16 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
|
mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
|
||||||
mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName))
|
mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName))
|
||||||
|
|
||||||
|
// rust_ffi rlibs may export include dirs, so collect those here.
|
||||||
|
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
|
||||||
|
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
|
||||||
|
depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path()))
|
||||||
|
|
||||||
case procMacroDepTag:
|
case procMacroDepTag:
|
||||||
directProcMacroDeps = append(directProcMacroDeps, rustDep)
|
directProcMacroDeps = append(directProcMacroDeps, rustDep)
|
||||||
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
|
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
|
||||||
|
// proc_macro link dirs need to be exported, so collect those here.
|
||||||
|
depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path()))
|
||||||
|
|
||||||
case sourceDepTag:
|
case sourceDepTag:
|
||||||
if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
|
if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
|
||||||
@@ -1281,12 +1300,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
|
directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider)
|
||||||
//Append the dependencies exportedDirs, except for proc-macros which target a different arch/OS
|
//Append the dependencies exportedDirs, except for proc-macros which target a different arch/OS
|
||||||
if depTag != procMacroDepTag {
|
if depTag != procMacroDepTag {
|
||||||
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider)
|
|
||||||
depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
|
|
||||||
depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
|
depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
|
||||||
depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
|
depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
|
||||||
|
depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
|
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
|
||||||
@@ -1296,6 +1315,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
lib.exportLinkDirs(linkDir)
|
lib.exportLinkDirs(linkDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if depTag == sourceDepTag {
|
if depTag == sourceDepTag {
|
||||||
if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() {
|
if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() {
|
||||||
if _, ok := rustDep.sourceProvider.(*protobufDecorator); ok {
|
if _, ok := rustDep.sourceProvider.(*protobufDecorator); ok {
|
||||||
@@ -1560,6 +1580,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rlibDepVariations := commonDepVariations
|
rlibDepVariations := commonDepVariations
|
||||||
|
rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
|
||||||
|
|
||||||
if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
|
if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
|
||||||
rlibDepVariations = append(rlibDepVariations,
|
rlibDepVariations = append(rlibDepVariations,
|
||||||
@@ -1575,6 +1596,8 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
|
|
||||||
// dylibs
|
// dylibs
|
||||||
dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation})
|
dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation})
|
||||||
|
dylibDepVariations = append(dylibDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
|
||||||
|
|
||||||
for _, lib := range deps.Dylibs {
|
for _, lib := range deps.Dylibs {
|
||||||
actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib)
|
actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib)
|
||||||
}
|
}
|
||||||
@@ -1594,7 +1617,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
// otherwise select the rlib variant.
|
// otherwise select the rlib variant.
|
||||||
autoDepVariations := append(commonDepVariations,
|
autoDepVariations := append(commonDepVariations,
|
||||||
blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
|
blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
|
||||||
|
autoDepVariations = append(autoDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
|
||||||
if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) {
|
if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) {
|
||||||
actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib)
|
actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib)
|
||||||
|
|
||||||
@@ -1609,7 +1632,11 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
for _, lib := range deps.Rustlibs {
|
for _, lib := range deps.Rustlibs {
|
||||||
srcProviderVariations := append(commonDepVariations,
|
srcProviderVariations := append(commonDepVariations,
|
||||||
blueprint.Variation{Mutator: "rust_libraries", Variation: "source"})
|
blueprint.Variation{Mutator: "rust_libraries", Variation: "source"})
|
||||||
|
srcProviderVariations = append(srcProviderVariations, blueprint.Variation{Mutator: "link", Variation: ""})
|
||||||
|
|
||||||
|
// Only add rustlib dependencies if they're source providers themselves.
|
||||||
|
// This is used to track which crate names need to be added to the source generated
|
||||||
|
// in the rust_protobuf mod.rs.
|
||||||
if actx.OtherModuleDependencyVariantExists(srcProviderVariations, lib) {
|
if actx.OtherModuleDependencyVariantExists(srcProviderVariations, lib) {
|
||||||
actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib)
|
actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib)
|
||||||
}
|
}
|
||||||
@@ -1621,7 +1648,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
if deps.Stdlibs != nil {
|
if deps.Stdlibs != nil {
|
||||||
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
|
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
|
||||||
for _, lib := range deps.Stdlibs {
|
for _, lib := range deps.Stdlibs {
|
||||||
actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
|
actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}, {Mutator: "link", Variation: ""}}...),
|
||||||
rlibDepTag, lib)
|
rlibDepTag, lib)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -150,15 +150,11 @@ func TestDepsTracking(t *testing.T) {
|
|||||||
host_supported: true,
|
host_supported: true,
|
||||||
name: "cc_stubs_dep",
|
name: "cc_stubs_dep",
|
||||||
}
|
}
|
||||||
rust_ffi_host_static {
|
cc_library_host_static {
|
||||||
name: "libstatic",
|
name: "libstatic",
|
||||||
srcs: ["foo.rs"],
|
|
||||||
crate_name: "static",
|
|
||||||
}
|
}
|
||||||
rust_ffi_host_static {
|
cc_library_host_static {
|
||||||
name: "libwholestatic",
|
name: "libwholestatic",
|
||||||
srcs: ["foo.rs"],
|
|
||||||
crate_name: "wholestatic",
|
|
||||||
}
|
}
|
||||||
rust_ffi_host_shared {
|
rust_ffi_host_shared {
|
||||||
name: "libshared",
|
name: "libshared",
|
||||||
@@ -435,6 +431,105 @@ func TestRustAliases(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRustRlibs(t *testing.T) {
|
||||||
|
ctx := testRust(t, `
|
||||||
|
rust_ffi_rlib {
|
||||||
|
name: "libbar",
|
||||||
|
crate_name: "bar",
|
||||||
|
srcs: ["src/lib.rs"],
|
||||||
|
export_include_dirs: ["bar_includes"]
|
||||||
|
}
|
||||||
|
|
||||||
|
rust_ffi_rlib {
|
||||||
|
name: "libfoo",
|
||||||
|
crate_name: "foo",
|
||||||
|
srcs: ["src/lib.rs"],
|
||||||
|
export_include_dirs: ["foo_includes"]
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_shared {
|
||||||
|
name: "libcc_shared",
|
||||||
|
srcs:["foo.c"],
|
||||||
|
static_rlibs: ["libbar"],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_static {
|
||||||
|
name: "libcc_static",
|
||||||
|
srcs:["foo.c"],
|
||||||
|
static_rlibs: ["libfoo"],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "ccBin",
|
||||||
|
srcs:["foo.c"],
|
||||||
|
static_rlibs: ["libbar"],
|
||||||
|
static_libs: ["libcc_static"],
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_rlib_rlib-std").Rule("rustc")
|
||||||
|
libcc_shared_rustc := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("rustc")
|
||||||
|
libcc_shared_ld := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("ld")
|
||||||
|
libcc_shared_cc := ctx.ModuleForTests("libcc_shared", "android_arm64_armv8-a_shared").Rule("cc")
|
||||||
|
ccbin_rustc := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("rustc")
|
||||||
|
ccbin_ld := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("ld")
|
||||||
|
ccbin_cc := ctx.ModuleForTests("ccBin", "android_arm64_armv8-a").Rule("cc")
|
||||||
|
|
||||||
|
if !strings.Contains(libbar.Args["rustcFlags"], "crate-type=rlib") {
|
||||||
|
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", "rlib", libbar.Args["rustcFlags"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure there's a rustc command, and it's producing a staticlib
|
||||||
|
if !strings.Contains(libcc_shared_rustc.Args["rustcFlags"], "crate-type=staticlib") {
|
||||||
|
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v",
|
||||||
|
"staticlib", libcc_shared_rustc.Args["rustcFlags"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the static lib is included in the ld command
|
||||||
|
if !strings.Contains(libcc_shared_ld.Args["libFlags"], "generated_rust_staticlib/liblibcc_shared_rust_staticlib.a") {
|
||||||
|
t.Errorf("missing generated static library in linker step libFlags %#v, libFlags: %#v",
|
||||||
|
"libcc_shared.generated_rust_staticlib.a", libcc_shared_ld.Args["libFlags"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the static lib includes are in the cc command
|
||||||
|
if !strings.Contains(libcc_shared_cc.Args["cFlags"], "-Ibar_includes") {
|
||||||
|
t.Errorf("missing rlibs includes, expecting %#v, cFlags: %#v",
|
||||||
|
"-Ibar_includes", libcc_shared_cc.Args["cFlags"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure there's a rustc command, and it's producing a staticlib
|
||||||
|
if !strings.Contains(ccbin_rustc.Args["rustcFlags"], "crate-type=staticlib") {
|
||||||
|
t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", "staticlib", ccbin_rustc.Args["rustcFlags"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the static lib is included in the cc command
|
||||||
|
if !strings.Contains(ccbin_ld.Args["libFlags"], "generated_rust_staticlib/libccBin_rust_staticlib.a") {
|
||||||
|
t.Errorf("missing generated static library in linker step libFlags, expecting %#v, libFlags: %#v",
|
||||||
|
"ccBin.generated_rust_staticlib.a", ccbin_ld.Args["libFlags"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the static lib includes are in the ld command
|
||||||
|
if !strings.Contains(ccbin_cc.Args["cFlags"], "-Ibar_includes") {
|
||||||
|
t.Errorf("missing rlibs includes, expecting %#v, cFlags: %#v",
|
||||||
|
"-Ibar_includes", ccbin_cc.Args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that direct dependencies and indirect dependencies are
|
||||||
|
// propagating correctly to the generated rlib.
|
||||||
|
if !strings.Contains(ccbin_rustc.Args["libFlags"], "--extern foo=") {
|
||||||
|
t.Errorf("Missing indirect dependency libfoo when writing generated Rust staticlib: %#v", ccbin_rustc.Args["libFlags"])
|
||||||
|
}
|
||||||
|
if !strings.Contains(ccbin_rustc.Args["libFlags"], "--extern bar=") {
|
||||||
|
t.Errorf("Missing direct dependency libbar when writing generated Rust staticlib: %#v", ccbin_rustc.Args["libFlags"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test indirect includes propagation
|
||||||
|
if !strings.Contains(ccbin_cc.Args["cFlags"], "-Ifoo_includes") {
|
||||||
|
t.Errorf("missing rlibs includes, expecting %#v, cFlags: %#v",
|
||||||
|
"-Ifoo_includes", ccbin_cc.Args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func assertString(t *testing.T, got, expected string) {
|
func assertString(t *testing.T, got, expected string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if got != expected {
|
if got != expected {
|
||||||
|
@@ -49,16 +49,28 @@ var PrepareForIntegrationTestWithRust = android.GroupFixturePreparers(
|
|||||||
func GatherRequiredDepsForTest() string {
|
func GatherRequiredDepsForTest() string {
|
||||||
bp := `
|
bp := `
|
||||||
rust_prebuilt_library {
|
rust_prebuilt_library {
|
||||||
name: "libstd",
|
name: "libstd",
|
||||||
crate_name: "std",
|
crate_name: "std",
|
||||||
rlib: {
|
rlib: {
|
||||||
srcs: ["libstd.rlib"],
|
srcs: ["libstd/libstd.rlib"],
|
||||||
},
|
},
|
||||||
dylib: {
|
dylib: {
|
||||||
srcs: ["libstd.so"],
|
srcs: ["libstd/libstd.so"],
|
||||||
},
|
},
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
sysroot: true,
|
sysroot: true,
|
||||||
|
}
|
||||||
|
rust_prebuilt_library {
|
||||||
|
name: "libcore.sysroot",
|
||||||
|
crate_name: "core",
|
||||||
|
rlib: {
|
||||||
|
srcs: ["libcore/libcore.rlib"],
|
||||||
|
},
|
||||||
|
dylib: {
|
||||||
|
srcs: ["libcore/libcore.so"],
|
||||||
|
},
|
||||||
|
host_supported: true,
|
||||||
|
sysroot: true,
|
||||||
}
|
}
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// Device module requirements
|
// Device module requirements
|
||||||
@@ -176,10 +188,12 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
|
|||||||
ctx.RegisterModuleType("rust_fuzz_host", RustFuzzHostFactory)
|
ctx.RegisterModuleType("rust_fuzz_host", RustFuzzHostFactory)
|
||||||
ctx.RegisterModuleType("rust_ffi", RustFFIFactory)
|
ctx.RegisterModuleType("rust_ffi", RustFFIFactory)
|
||||||
ctx.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
|
ctx.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
|
||||||
ctx.RegisterModuleType("rust_ffi_static", RustFFIStaticFactory)
|
ctx.RegisterModuleType("rust_ffi_rlib", RustFFIRlibFactory)
|
||||||
|
ctx.RegisterModuleType("rust_ffi_static", RustFFIStaticRlibFactory)
|
||||||
ctx.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
|
ctx.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
|
||||||
ctx.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
|
ctx.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
|
||||||
ctx.RegisterModuleType("rust_ffi_host_static", RustFFIStaticHostFactory)
|
ctx.RegisterModuleType("rust_ffi_host_rlib", RustFFIRlibHostFactory)
|
||||||
|
ctx.RegisterModuleType("rust_ffi_host_static", RustFFIStaticRlibHostFactory)
|
||||||
ctx.RegisterModuleType("rust_proc_macro", ProcMacroFactory)
|
ctx.RegisterModuleType("rust_proc_macro", ProcMacroFactory)
|
||||||
ctx.RegisterModuleType("rust_protobuf", RustProtobufFactory)
|
ctx.RegisterModuleType("rust_protobuf", RustProtobufFactory)
|
||||||
ctx.RegisterModuleType("rust_protobuf_host", RustProtobufHostFactory)
|
ctx.RegisterModuleType("rust_protobuf_host", RustProtobufHostFactory)
|
||||||
|
Reference in New Issue
Block a user