Rust cdylib/statliclib support for vendor snapshot.
Adds support for platform vendor_available Rust FFI libraries and binaries to be included in the vendor snapshot. Because rlib and dylibs are not yet in snapshots, libstd cannot be included in a vendor snapshot. As a result, vendor-specific Rust code can't be guaranteed to work with the platform-provided vendor_available modules built with a newer toolchain. For now, a check is added indicating vendor-specific Rust code is unsupported. This changes the linkage for vendor variants of these modules to default to rlib linkage since dylibs cannot be included in the snapshot yet. Bug: 184042776 Test: m nothing # new Soong tests pass Change-Id: I502eaa4bb962eb87ff868fcf49b435f0d2f982e6
This commit is contained in:
@@ -53,6 +53,7 @@ bootstrap_go_package {
|
|||||||
"rust_test.go",
|
"rust_test.go",
|
||||||
"source_provider_test.go",
|
"source_provider_test.go",
|
||||||
"test_test.go",
|
"test_test.go",
|
||||||
|
"vendor_snapshot_test.go",
|
||||||
],
|
],
|
||||||
pluginFor: ["soong_build"],
|
pluginFor: ["soong_build"],
|
||||||
}
|
}
|
||||||
|
@@ -137,6 +137,9 @@ func (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoD
|
|||||||
// Binaries default to dylib dependencies for device, rlib for host.
|
// Binaries default to dylib dependencies for device, rlib for host.
|
||||||
if binary.preferRlib() {
|
if binary.preferRlib() {
|
||||||
return rlibAutoDep
|
return rlibAutoDep
|
||||||
|
} else if mod, ok := ctx.Module().(*Module); ok && mod.InVendor() {
|
||||||
|
// Vendor Rust binaries should prefer rlibs.
|
||||||
|
return rlibAutoDep
|
||||||
} else if ctx.Device() {
|
} else if ctx.Device() {
|
||||||
return dylibAutoDep
|
return dylibAutoDep
|
||||||
} else {
|
} else {
|
||||||
@@ -147,6 +150,8 @@ func (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoD
|
|||||||
func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
|
func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
|
||||||
if binary.preferRlib() {
|
if binary.preferRlib() {
|
||||||
return RlibLinkage
|
return RlibLinkage
|
||||||
|
} else if ctx.RustModule().InVendor() {
|
||||||
|
return RlibLinkage
|
||||||
}
|
}
|
||||||
return binary.baseCompiler.stdLinkage(ctx)
|
return binary.baseCompiler.stdLinkage(ctx)
|
||||||
}
|
}
|
||||||
|
@@ -202,6 +202,8 @@ func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant stri
|
|||||||
|
|
||||||
func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
|
func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
|
||||||
// Rust does not support installing to the product image yet.
|
// Rust does not support installing to the product image yet.
|
||||||
|
vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
|
||||||
|
|
||||||
if Bool(mod.VendorProperties.Product_available) {
|
if Bool(mod.VendorProperties.Product_available) {
|
||||||
mctx.PropertyErrorf("product_available",
|
mctx.PropertyErrorf("product_available",
|
||||||
"Rust modules do not yet support being available to the product image")
|
"Rust modules do not yet support being available to the product image")
|
||||||
@@ -217,6 +219,9 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
|
|||||||
mctx.PropertyErrorf("vendor_ramdisk_available", "cannot be set for rust_ffi or rust_ffi_shared modules.")
|
mctx.PropertyErrorf("vendor_ramdisk_available", "cannot be set for rust_ffi or rust_ffi_shared modules.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if vendorSpecific {
|
||||||
|
mctx.PropertyErrorf("vendor", "Vendor-only non-rust_ffi Rust modules are not supported.")
|
||||||
|
}
|
||||||
|
|
||||||
cc.MutateImage(mctx, mod)
|
cc.MutateImage(mctx, mod)
|
||||||
|
|
||||||
|
@@ -99,6 +99,8 @@ type libraryDecorator struct {
|
|||||||
MutatedProperties LibraryMutatedProperties
|
MutatedProperties LibraryMutatedProperties
|
||||||
includeDirs android.Paths
|
includeDirs android.Paths
|
||||||
sourceProvider SourceProvider
|
sourceProvider SourceProvider
|
||||||
|
|
||||||
|
collectedSnapshotHeaders android.Paths
|
||||||
}
|
}
|
||||||
|
|
||||||
type libraryInterface interface {
|
type libraryInterface interface {
|
||||||
@@ -220,7 +222,10 @@ func (library *libraryDecorator) setSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
|
func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
|
||||||
if library.preferRlib() {
|
if ctx.Module().(*Module).InVendor() {
|
||||||
|
// Vendor modules should statically link libstd.
|
||||||
|
return rlibAutoDep
|
||||||
|
} else if library.preferRlib() {
|
||||||
return rlibAutoDep
|
return rlibAutoDep
|
||||||
} else if library.rlib() || library.static() {
|
} else if library.rlib() || library.static() {
|
||||||
return rlibAutoDep
|
return rlibAutoDep
|
||||||
@@ -236,7 +241,10 @@ 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 ctx.RustModule().InVendor() {
|
||||||
|
// Vendor modules should statically link libstd.
|
||||||
|
return RlibLinkage
|
||||||
|
} else if library.static() || library.MutatedProperties.VariantIsStaticStd {
|
||||||
return RlibLinkage
|
return RlibLinkage
|
||||||
} else if library.baseCompiler.preferRlib() {
|
} else if library.baseCompiler.preferRlib() {
|
||||||
return RlibLinkage
|
return RlibLinkage
|
||||||
@@ -623,6 +631,19 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
// Disable dylib Vendor Ramdisk variations until we support these.
|
// Disable dylib Vendor Ramdisk variations until we support these.
|
||||||
v.(*Module).Disable()
|
v.(*Module).Disable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variation := v.(*Module).ModuleBase.ImageVariation().Variation
|
||||||
|
if strings.HasPrefix(variation, cc.VendorVariationPrefix) &&
|
||||||
|
m.HasVendorVariant() &&
|
||||||
|
!cc.IsVendorProprietaryModule(mctx) &&
|
||||||
|
strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() {
|
||||||
|
|
||||||
|
// cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are
|
||||||
|
// produced for Dylibs; however, dylibs should not be enabled for boardVndkVersion for
|
||||||
|
// non-vendor proprietary modules.
|
||||||
|
v.(*Module).Disable()
|
||||||
|
}
|
||||||
|
|
||||||
case "source":
|
case "source":
|
||||||
v.(*Module).compiler.(libraryInterface).setSource()
|
v.(*Module).compiler.(libraryInterface).setSource()
|
||||||
// The source variant does not produce any library.
|
// The source variant does not produce any library.
|
||||||
@@ -671,3 +692,54 @@ func LibstdMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *libraryDecorator) snapshotHeaders() android.Paths {
|
||||||
|
if l.collectedSnapshotHeaders == nil {
|
||||||
|
panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
|
||||||
|
}
|
||||||
|
return l.collectedSnapshotHeaders
|
||||||
|
}
|
||||||
|
|
||||||
|
// collectHeadersForSnapshot collects all exported headers from library.
|
||||||
|
// It globs header files in the source tree for exported include directories,
|
||||||
|
// and tracks generated header files separately.
|
||||||
|
//
|
||||||
|
// This is to be called from GenerateAndroidBuildActions, and then collected
|
||||||
|
// header files can be retrieved by snapshotHeaders().
|
||||||
|
func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) {
|
||||||
|
ret := android.Paths{}
|
||||||
|
|
||||||
|
// Glob together the headers from the modules include_dirs property
|
||||||
|
for _, path := range android.CopyOfPaths(l.includeDirs) {
|
||||||
|
dir := path.String()
|
||||||
|
glob, err := ctx.GlobWithDeps(dir+"/**/*", nil)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ModuleErrorf("glob failed: %#v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, header := range glob {
|
||||||
|
// Filter out only the files with extensions that are headers.
|
||||||
|
found := false
|
||||||
|
for _, ext := range cc.HeaderExts {
|
||||||
|
if strings.HasSuffix(header, ext) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ret = append(ret, android.PathForSource(ctx, header))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Glob together the headers from C dependencies as well, starting with non-generated headers.
|
||||||
|
ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...)
|
||||||
|
|
||||||
|
// Collect generated headers from C dependencies.
|
||||||
|
ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...)
|
||||||
|
|
||||||
|
// TODO(185577950): If support for generated headers is added, they need to be collected here as well.
|
||||||
|
l.collectedSnapshotHeaders = ret
|
||||||
|
}
|
||||||
|
87
rust/rust.go
87
rust/rust.go
@@ -85,6 +85,9 @@ type BaseProperties struct {
|
|||||||
VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
|
VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
|
||||||
ExtraVariants []string `blueprint:"mutated"`
|
ExtraVariants []string `blueprint:"mutated"`
|
||||||
|
|
||||||
|
// Used by vendor snapshot to record dependencies from snapshot modules.
|
||||||
|
SnapshotSharedLibs []string `blueprint:"mutated"`
|
||||||
|
|
||||||
// Make this module available when building for vendor ramdisk.
|
// Make this module available when building for vendor ramdisk.
|
||||||
// On device without a dedicated recovery partition, the module is only
|
// On device without a dedicated recovery partition, the module is only
|
||||||
// available after switching root into
|
// available after switching root into
|
||||||
@@ -92,6 +95,20 @@ type BaseProperties struct {
|
|||||||
// the recovery variant instead (TODO(b/165791368) recovery not yet supported)
|
// the recovery variant instead (TODO(b/165791368) recovery not yet supported)
|
||||||
Vendor_ramdisk_available *bool
|
Vendor_ramdisk_available *bool
|
||||||
|
|
||||||
|
// Normally Soong uses the directory structure to decide which modules
|
||||||
|
// should be included (framework) or excluded (non-framework) from the
|
||||||
|
// different snapshots (vendor, recovery, etc.), but this property
|
||||||
|
// allows a partner to exclude a module normally thought of as a
|
||||||
|
// framework module from the vendor snapshot.
|
||||||
|
Exclude_from_vendor_snapshot *bool
|
||||||
|
|
||||||
|
// Normally Soong uses the directory structure to decide which modules
|
||||||
|
// should be included (framework) or excluded (non-framework) from the
|
||||||
|
// different snapshots (vendor, recovery, etc.), but this property
|
||||||
|
// allows a partner to exclude a module normally thought of as a
|
||||||
|
// framework module from the recovery snapshot.
|
||||||
|
Exclude_from_recovery_snapshot *bool
|
||||||
|
|
||||||
// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
|
// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
|
||||||
Min_sdk_version *string
|
Min_sdk_version *string
|
||||||
|
|
||||||
@@ -826,6 +843,14 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
|||||||
|
|
||||||
mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps)
|
mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps)
|
||||||
|
|
||||||
|
// glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
|
||||||
|
// RECOVERY_SNAPSHOT_VERSION is current.
|
||||||
|
if lib, ok := mod.compiler.(snapshotLibraryInterface); ok {
|
||||||
|
if cc.ShouldCollectHeadersForSnapshot(ctx, mod, apexInfo) {
|
||||||
|
lib.collectHeadersForSnapshot(ctx, deps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
||||||
if mod.installable(apexInfo) {
|
if mod.installable(apexInfo) {
|
||||||
mod.compiler.install(ctx)
|
mod.compiler.install(ctx)
|
||||||
@@ -1056,6 +1081,10 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
|
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
|
||||||
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
|
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
|
||||||
directSharedLibDeps = append(directSharedLibDeps, ccDep)
|
directSharedLibDeps = append(directSharedLibDeps, ccDep)
|
||||||
|
|
||||||
|
// Record baseLibName for snapshots.
|
||||||
|
mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName))
|
||||||
|
|
||||||
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName)
|
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName)
|
||||||
exportDep = true
|
exportDep = true
|
||||||
case cc.IsHeaderDepTag(depTag):
|
case cc.IsHeaderDepTag(depTag):
|
||||||
@@ -1161,6 +1190,11 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
|
|
||||||
deps := mod.deps(ctx)
|
deps := mod.deps(ctx)
|
||||||
var commonDepVariations []blueprint.Variation
|
var commonDepVariations []blueprint.Variation
|
||||||
|
var snapshotInfo *cc.SnapshotInfo
|
||||||
|
|
||||||
|
if ctx.Os() == android.Android {
|
||||||
|
deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs)
|
||||||
|
}
|
||||||
|
|
||||||
stdLinkage := "dylib-std"
|
stdLinkage := "dylib-std"
|
||||||
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
|
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
|
||||||
@@ -1168,20 +1202,25 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rlibDepVariations := commonDepVariations
|
rlibDepVariations := commonDepVariations
|
||||||
|
|
||||||
if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
|
if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
|
||||||
rlibDepVariations = append(rlibDepVariations,
|
rlibDepVariations = append(rlibDepVariations,
|
||||||
blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
|
blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rlibs
|
||||||
actx.AddVariationDependencies(
|
actx.AddVariationDependencies(
|
||||||
append(rlibDepVariations, []blueprint.Variation{
|
append(rlibDepVariations, []blueprint.Variation{
|
||||||
{Mutator: "rust_libraries", Variation: rlibVariation}}...),
|
{Mutator: "rust_libraries", Variation: rlibVariation}}...),
|
||||||
rlibDepTag, deps.Rlibs...)
|
rlibDepTag, deps.Rlibs...)
|
||||||
|
|
||||||
|
// dylibs
|
||||||
actx.AddVariationDependencies(
|
actx.AddVariationDependencies(
|
||||||
append(commonDepVariations, []blueprint.Variation{
|
append(commonDepVariations, []blueprint.Variation{
|
||||||
{Mutator: "rust_libraries", Variation: dylibVariation}}...),
|
{Mutator: "rust_libraries", Variation: dylibVariation}}...),
|
||||||
dylibDepTag, deps.Dylibs...)
|
dylibDepTag, deps.Dylibs...)
|
||||||
|
|
||||||
|
// rustlibs
|
||||||
if deps.Rustlibs != nil && !mod.compiler.Disabled() {
|
if deps.Rustlibs != nil && !mod.compiler.Disabled() {
|
||||||
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
|
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
|
||||||
if autoDep.depTag == rlibDepTag {
|
if autoDep.depTag == rlibDepTag {
|
||||||
@@ -1194,10 +1233,12 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
autoDep.depTag, deps.Rustlibs...)
|
autoDep.depTag, deps.Rustlibs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stdlibs
|
||||||
if deps.Stdlibs != nil {
|
if deps.Stdlibs != nil {
|
||||||
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
|
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
|
||||||
actx.AddVariationDependencies(
|
actx.AddVariationDependencies(
|
||||||
append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "rlib"}),
|
append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
|
||||||
rlibDepTag, deps.Stdlibs...)
|
rlibDepTag, deps.Stdlibs...)
|
||||||
} else {
|
} else {
|
||||||
actx.AddVariationDependencies(
|
actx.AddVariationDependencies(
|
||||||
@@ -1205,24 +1246,45 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
dylibDepTag, deps.Stdlibs...)
|
dylibDepTag, deps.Stdlibs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actx.AddVariationDependencies(append(commonDepVariations,
|
|
||||||
blueprint.Variation{Mutator: "link", Variation: "shared"}),
|
for _, lib := range deps.SharedLibs {
|
||||||
cc.SharedDepTag(), deps.SharedLibs...)
|
depTag := cc.SharedDepTag()
|
||||||
actx.AddVariationDependencies(append(commonDepVariations,
|
name, version := cc.StubsLibNameAndVersion(lib)
|
||||||
blueprint.Variation{Mutator: "link", Variation: "static"}),
|
|
||||||
cc.StaticDepTag(false), deps.StaticLibs...)
|
variations := []blueprint.Variation{
|
||||||
actx.AddVariationDependencies(append(commonDepVariations,
|
{Mutator: "link", Variation: "shared"},
|
||||||
blueprint.Variation{Mutator: "link", Variation: "static"}),
|
}
|
||||||
cc.StaticDepTag(true), deps.WholeStaticLibs...)
|
cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, lib := range deps.WholeStaticLibs {
|
||||||
|
depTag := cc.StaticDepTag(true)
|
||||||
|
lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
|
||||||
|
|
||||||
|
actx.AddVariationDependencies([]blueprint.Variation{
|
||||||
|
{Mutator: "link", Variation: "static"},
|
||||||
|
}, depTag, lib)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, lib := range deps.StaticLibs {
|
||||||
|
depTag := cc.StaticDepTag(false)
|
||||||
|
lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
|
||||||
|
|
||||||
|
actx.AddVariationDependencies([]blueprint.Variation{
|
||||||
|
{Mutator: "link", Variation: "static"},
|
||||||
|
}, depTag, lib)
|
||||||
|
}
|
||||||
|
|
||||||
actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...)
|
actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...)
|
||||||
|
|
||||||
crtVariations := cc.GetCrtVariations(ctx, mod)
|
crtVariations := cc.GetCrtVariations(ctx, mod)
|
||||||
if deps.CrtBegin != "" {
|
if deps.CrtBegin != "" {
|
||||||
actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, deps.CrtBegin)
|
actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag,
|
||||||
|
cc.RewriteSnapshotLib(deps.CrtBegin, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
|
||||||
}
|
}
|
||||||
if deps.CrtEnd != "" {
|
if deps.CrtEnd != "" {
|
||||||
actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, deps.CrtEnd)
|
actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag,
|
||||||
|
cc.RewriteSnapshotLib(deps.CrtEnd, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
|
||||||
}
|
}
|
||||||
|
|
||||||
if mod.sourceProvider != nil {
|
if mod.sourceProvider != nil {
|
||||||
@@ -1232,6 +1294,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
bindgen.Properties.Custom_bindgen)
|
bindgen.Properties.Custom_bindgen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy.
|
// proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy.
|
||||||
actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...)
|
actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...)
|
||||||
}
|
}
|
||||||
|
@@ -37,21 +37,28 @@ var prepareForRustTest = android.GroupFixturePreparers(
|
|||||||
|
|
||||||
genrule.PrepareForTestWithGenRuleBuildComponents,
|
genrule.PrepareForTestWithGenRuleBuildComponents,
|
||||||
|
|
||||||
PrepareForIntegrationTestWithRust,
|
PrepareForTestWithRustIncludeVndk,
|
||||||
|
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||||
|
variables.DeviceVndkVersion = StringPtr("current")
|
||||||
|
variables.ProductVndkVersion = StringPtr("current")
|
||||||
|
variables.Platform_vndk_version = StringPtr("29")
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
var rustMockedFiles = android.MockFS{
|
var rustMockedFiles = android.MockFS{
|
||||||
"foo.rs": nil,
|
"foo.rs": nil,
|
||||||
"foo.c": nil,
|
"foo.c": nil,
|
||||||
"src/bar.rs": nil,
|
"src/bar.rs": nil,
|
||||||
"src/any.h": nil,
|
"src/any.h": nil,
|
||||||
"proto.proto": nil,
|
"c_includes/c_header.h": nil,
|
||||||
"proto/buf.proto": nil,
|
"rust_includes/rust_headers.h": nil,
|
||||||
"buf.proto": nil,
|
"proto.proto": nil,
|
||||||
"foo.proto": nil,
|
"proto/buf.proto": nil,
|
||||||
"liby.so": nil,
|
"buf.proto": nil,
|
||||||
"libz.so": nil,
|
"foo.proto": nil,
|
||||||
"data.txt": nil,
|
"liby.so": nil,
|
||||||
|
"libz.so": nil,
|
||||||
|
"data.txt": nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
// testRust returns a TestContext in which a basic environment has been setup.
|
// testRust returns a TestContext in which a basic environment has been setup.
|
||||||
@@ -67,10 +74,16 @@ func testRust(t *testing.T, bp string) *android.TestContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testRustVndk(t *testing.T, bp string) *android.TestContext {
|
func testRustVndk(t *testing.T, bp string) *android.TestContext {
|
||||||
|
return testRustVndkFs(t, bp, rustMockedFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
const vendorVariant = "android_vendor.29_arm64_armv8-a_shared"
|
||||||
|
|
||||||
|
func testRustVndkFs(t *testing.T, bp string, fs android.MockFS) *android.TestContext {
|
||||||
skipTestIfOsNotSupported(t)
|
skipTestIfOsNotSupported(t)
|
||||||
result := android.GroupFixturePreparers(
|
result := android.GroupFixturePreparers(
|
||||||
prepareForRustTest,
|
prepareForRustTest,
|
||||||
rustMockedFiles.AddToFixture(),
|
fs.AddToFixture(),
|
||||||
android.FixtureModifyProductVariables(
|
android.FixtureModifyProductVariables(
|
||||||
func(variables android.FixtureProductVariables) {
|
func(variables android.FixtureProductVariables) {
|
||||||
variables.DeviceVndkVersion = StringPtr("current")
|
variables.DeviceVndkVersion = StringPtr("current")
|
||||||
@@ -80,6 +93,7 @@ func testRustVndk(t *testing.T, bp string) *android.TestContext {
|
|||||||
),
|
),
|
||||||
).RunTestWithBp(t, bp)
|
).RunTestWithBp(t, bp)
|
||||||
return result.TestContext
|
return result.TestContext
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// testRustCov returns a TestContext in which a basic environment has been
|
// testRustCov returns a TestContext in which a basic environment has been
|
||||||
@@ -115,10 +129,14 @@ func testRustError(t *testing.T, pattern string, bp string) {
|
|||||||
|
|
||||||
// testRustVndkError is similar to testRustError, but can be used to test VNDK-related errors.
|
// testRustVndkError is similar to testRustError, but can be used to test VNDK-related errors.
|
||||||
func testRustVndkError(t *testing.T, pattern string, bp string) {
|
func testRustVndkError(t *testing.T, pattern string, bp string) {
|
||||||
|
testRustVndkFsError(t, pattern, bp, rustMockedFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRustVndkFsError(t *testing.T, pattern string, bp string, fs android.MockFS) {
|
||||||
skipTestIfOsNotSupported(t)
|
skipTestIfOsNotSupported(t)
|
||||||
android.GroupFixturePreparers(
|
android.GroupFixturePreparers(
|
||||||
prepareForRustTest,
|
prepareForRustTest,
|
||||||
rustMockedFiles.AddToFixture(),
|
fs.AddToFixture(),
|
||||||
android.FixtureModifyProductVariables(
|
android.FixtureModifyProductVariables(
|
||||||
func(variables android.FixtureProductVariables) {
|
func(variables android.FixtureProductVariables) {
|
||||||
variables.DeviceVndkVersion = StringPtr("current")
|
variables.DeviceVndkVersion = StringPtr("current")
|
||||||
|
@@ -18,18 +18,34 @@ import (
|
|||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// snapshotLibraryInterface is an interface for libraries captured to VNDK / vendor snapshots.
|
||||||
|
type snapshotLibraryInterface interface {
|
||||||
|
libraryInterface
|
||||||
|
|
||||||
|
// collectHeadersForSnapshot is called in GenerateAndroidBuildActions for snapshot aware
|
||||||
|
// modules (See isSnapshotAware below).
|
||||||
|
// This function should gather all headers needed for snapshot.
|
||||||
|
collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps)
|
||||||
|
|
||||||
|
// snapshotHeaders should return collected headers by collectHeadersForSnapshot.
|
||||||
|
// Calling snapshotHeaders before collectHeadersForSnapshot is an error.
|
||||||
|
snapshotHeaders() android.Paths
|
||||||
|
}
|
||||||
|
|
||||||
func (mod *Module) ExcludeFromVendorSnapshot() bool {
|
func (mod *Module) ExcludeFromVendorSnapshot() bool {
|
||||||
// TODO Rust does not yet support snapshotting
|
return Bool(mod.Properties.Exclude_from_vendor_snapshot)
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) ExcludeFromRecoverySnapshot() bool {
|
func (mod *Module) ExcludeFromRecoverySnapshot() bool {
|
||||||
// TODO Rust does not yet support snapshotting
|
return Bool(mod.Properties.Exclude_from_recovery_snapshot)
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) IsSnapshotLibrary() bool {
|
func (mod *Module) IsSnapshotLibrary() bool {
|
||||||
// TODO Rust does not yet support snapshotting
|
if lib, ok := mod.compiler.(libraryInterface); ok {
|
||||||
|
// Rust-native dylibs and rlibs are not snapshot supported yet, so only
|
||||||
|
// return true if this module produces a C shared or static library.
|
||||||
|
return lib.shared() || lib.static()
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,8 +55,7 @@ func (mod *Module) SnapshotRuntimeLibs() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) SnapshotSharedLibs() []string {
|
func (mod *Module) SnapshotSharedLibs() []string {
|
||||||
// TODO Rust does not yet support snapshotting
|
return mod.Properties.SnapshotSharedLibs
|
||||||
return []string{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) Symlinks() []string {
|
func (mod *Module) Symlinks() []string {
|
||||||
@@ -49,6 +64,8 @@ func (mod *Module) Symlinks() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Module) SnapshotHeaders() android.Paths {
|
func (m *Module) SnapshotHeaders() android.Paths {
|
||||||
// TODO Rust does not yet support snapshotting
|
if l, ok := m.compiler.(snapshotLibraryInterface); ok {
|
||||||
|
return l.snapshotHeaders()
|
||||||
|
}
|
||||||
return android.Paths{}
|
return android.Paths{}
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,11 @@ var PrepareForIntegrationTestWithRust = android.GroupFixturePreparers(
|
|||||||
PrepareForTestWithRustDefaultModules,
|
PrepareForTestWithRustDefaultModules,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var PrepareForTestWithRustIncludeVndk = android.GroupFixturePreparers(
|
||||||
|
PrepareForIntegrationTestWithRust,
|
||||||
|
cc.PrepareForTestWithCcIncludeVndk,
|
||||||
|
)
|
||||||
|
|
||||||
func GatherRequiredDepsForTest() string {
|
func GatherRequiredDepsForTest() string {
|
||||||
bp := `
|
bp := `
|
||||||
rust_prebuilt_library {
|
rust_prebuilt_library {
|
||||||
|
265
rust/vendor_snapshot_test.go
Normal file
265
rust/vendor_snapshot_test.go
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
// Copyright 2021 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package rust
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"android/soong/android"
|
||||||
|
"android/soong/cc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVendorSnapshotCapture(t *testing.T) {
|
||||||
|
bp := `
|
||||||
|
rust_ffi {
|
||||||
|
name: "librustvendor_available",
|
||||||
|
crate_name: "rustvendor_available",
|
||||||
|
srcs: ["lib.rs"],
|
||||||
|
vendor_available: true,
|
||||||
|
include_dirs: ["rust_headers/"],
|
||||||
|
}
|
||||||
|
|
||||||
|
rust_binary {
|
||||||
|
name: "vendor_available_bin",
|
||||||
|
vendor_available: true,
|
||||||
|
srcs: ["srcs/lib.rs"],
|
||||||
|
}
|
||||||
|
|
||||||
|
`
|
||||||
|
skipTestIfOsNotSupported(t)
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForRustTest,
|
||||||
|
rustMockedFiles.AddToFixture(),
|
||||||
|
android.FixtureModifyProductVariables(
|
||||||
|
func(variables android.FixtureProductVariables) {
|
||||||
|
variables.DeviceVndkVersion = StringPtr("current")
|
||||||
|
variables.Platform_vndk_version = StringPtr("29")
|
||||||
|
},
|
||||||
|
),
|
||||||
|
).RunTestWithBp(t, bp)
|
||||||
|
ctx := result.TestContext
|
||||||
|
|
||||||
|
// Check Vendor snapshot output.
|
||||||
|
|
||||||
|
snapshotDir := "vendor-snapshot"
|
||||||
|
snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
|
||||||
|
snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
|
||||||
|
var jsonFiles []string
|
||||||
|
for _, arch := range [][]string{
|
||||||
|
[]string{"arm64", "armv8-a"},
|
||||||
|
[]string{"arm", "armv7-a-neon"},
|
||||||
|
} {
|
||||||
|
archType := arch[0]
|
||||||
|
archVariant := arch[1]
|
||||||
|
archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
|
||||||
|
|
||||||
|
// For shared libraries, only non-VNDK vendor_available modules are captured
|
||||||
|
sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
|
||||||
|
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
|
||||||
|
cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.so", sharedDir, sharedVariant)
|
||||||
|
jsonFiles = append(jsonFiles,
|
||||||
|
filepath.Join(sharedDir, "librustvendor_available.so.json"))
|
||||||
|
|
||||||
|
// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
|
||||||
|
staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant)
|
||||||
|
staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
|
||||||
|
cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.a", staticDir, staticVariant)
|
||||||
|
jsonFiles = append(jsonFiles,
|
||||||
|
filepath.Join(staticDir, "librustvendor_available.a.json"))
|
||||||
|
|
||||||
|
// For binary executables, all vendor_available modules are captured.
|
||||||
|
if archType == "arm64" {
|
||||||
|
binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
|
||||||
|
binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
|
||||||
|
cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
|
||||||
|
jsonFiles = append(jsonFiles,
|
||||||
|
filepath.Join(binaryDir, "vendor_available_bin.json"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, jsonFile := range jsonFiles {
|
||||||
|
// verify all json files exist
|
||||||
|
if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
|
||||||
|
t.Errorf("%q expected but not found; #%v", jsonFile, jsonFiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fake snapshot should have all outputs in the normal snapshot.
|
||||||
|
fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
|
||||||
|
|
||||||
|
for _, output := range snapshotSingleton.AllOutputs() {
|
||||||
|
fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
|
||||||
|
if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
|
||||||
|
t.Errorf("%q expected but not found", fakeOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVendorSnapshotDirected(t *testing.T) {
|
||||||
|
bp := `
|
||||||
|
rust_ffi_shared {
|
||||||
|
name: "librustvendor_available",
|
||||||
|
crate_name: "rustvendor_available",
|
||||||
|
srcs: ["lib.rs"],
|
||||||
|
vendor_available: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
rust_ffi_shared {
|
||||||
|
name: "librustvendor_exclude",
|
||||||
|
crate_name: "rustvendor_exclude",
|
||||||
|
srcs: ["lib.rs"],
|
||||||
|
vendor_available: true,
|
||||||
|
}
|
||||||
|
`
|
||||||
|
ctx := testRustVndk(t, bp)
|
||||||
|
ctx.Config().TestProductVariables.VendorSnapshotModules = make(map[string]bool)
|
||||||
|
ctx.Config().TestProductVariables.VendorSnapshotModules["librustvendor_available"] = true
|
||||||
|
ctx.Config().TestProductVariables.DirectedVendorSnapshot = true
|
||||||
|
|
||||||
|
// Check Vendor snapshot output.
|
||||||
|
|
||||||
|
snapshotDir := "vendor-snapshot"
|
||||||
|
snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
|
||||||
|
snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
|
||||||
|
|
||||||
|
var includeJsonFiles []string
|
||||||
|
|
||||||
|
for _, arch := range [][]string{
|
||||||
|
[]string{"arm64", "armv8-a"},
|
||||||
|
[]string{"arm", "armv7-a-neon"},
|
||||||
|
} {
|
||||||
|
archType := arch[0]
|
||||||
|
archVariant := arch[1]
|
||||||
|
archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
|
||||||
|
|
||||||
|
sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
|
||||||
|
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
|
||||||
|
|
||||||
|
// Included modules
|
||||||
|
cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.so", sharedDir, sharedVariant)
|
||||||
|
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librustvendor_available.so.json"))
|
||||||
|
|
||||||
|
// Excluded modules. Modules not included in the directed vendor snapshot
|
||||||
|
// are still include as fake modules.
|
||||||
|
cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.so", sharedDir, sharedVariant)
|
||||||
|
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librustvendor_exclude.so.json"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that each json file for an included module has a rule.
|
||||||
|
for _, jsonFile := range includeJsonFiles {
|
||||||
|
if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
|
||||||
|
t.Errorf("include json file %q not found", jsonFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVendorSnapshotExclude(t *testing.T) {
|
||||||
|
|
||||||
|
// This test verifies that the exclude_from_vendor_snapshot property
|
||||||
|
// makes its way from the Android.bp source file into the module data
|
||||||
|
// structure. It also verifies that modules are correctly included or
|
||||||
|
// excluded in the vendor snapshot based on their path (framework or
|
||||||
|
// vendor) and the exclude_from_vendor_snapshot property.
|
||||||
|
|
||||||
|
// When vendor-specific Rust modules are available, make sure to test
|
||||||
|
// that they're excluded by path here. See cc.TestVendorSnapshotExclude
|
||||||
|
// for an example.
|
||||||
|
|
||||||
|
frameworkBp := `
|
||||||
|
rust_ffi_shared {
|
||||||
|
name: "libinclude",
|
||||||
|
crate_name: "include",
|
||||||
|
srcs: ["include.rs"],
|
||||||
|
vendor_available: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
rust_ffi_shared {
|
||||||
|
name: "libexclude",
|
||||||
|
crate_name: "exclude",
|
||||||
|
srcs: ["exclude.rs"],
|
||||||
|
vendor_available: true,
|
||||||
|
exclude_from_vendor_snapshot: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
rust_ffi_shared {
|
||||||
|
name: "libavailable_exclude",
|
||||||
|
crate_name: "available_exclude",
|
||||||
|
srcs: ["lib.rs"],
|
||||||
|
vendor_available: true,
|
||||||
|
exclude_from_vendor_snapshot: true,
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
mockFS := map[string][]byte{
|
||||||
|
"framework/Android.bp": []byte(frameworkBp),
|
||||||
|
"framework/include.rs": nil,
|
||||||
|
"framework/exclude.rs": nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := testRustVndkFs(t, "", mockFS)
|
||||||
|
|
||||||
|
// Test an include and exclude framework module.
|
||||||
|
cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, vendorVariant)
|
||||||
|
cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, vendorVariant)
|
||||||
|
cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, vendorVariant)
|
||||||
|
|
||||||
|
// Verify the content of the vendor snapshot.
|
||||||
|
|
||||||
|
snapshotDir := "vendor-snapshot"
|
||||||
|
snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
|
||||||
|
snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
|
||||||
|
|
||||||
|
var includeJsonFiles []string
|
||||||
|
var excludeJsonFiles []string
|
||||||
|
|
||||||
|
for _, arch := range [][]string{
|
||||||
|
[]string{"arm64", "armv8-a"},
|
||||||
|
[]string{"arm", "armv7-a-neon"},
|
||||||
|
} {
|
||||||
|
archType := arch[0]
|
||||||
|
archVariant := arch[1]
|
||||||
|
archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
|
||||||
|
|
||||||
|
sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
|
||||||
|
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
|
||||||
|
|
||||||
|
// Included modules
|
||||||
|
cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
|
||||||
|
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
|
||||||
|
|
||||||
|
// Excluded modules
|
||||||
|
cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
|
||||||
|
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
|
||||||
|
cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
|
||||||
|
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that each json file for an included module has a rule.
|
||||||
|
for _, jsonFile := range includeJsonFiles {
|
||||||
|
if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
|
||||||
|
t.Errorf("include json file %q not found", jsonFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that each json file for an excluded module has no rule.
|
||||||
|
for _, jsonFile := range excludeJsonFiles {
|
||||||
|
if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
|
||||||
|
t.Errorf("exclude json file %q found", jsonFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user