Merge changes I154a6f3a,I79f0c20a,I605ae9af,I647c7305,I95e96e3e, ...
* changes: Move fuzzer's CollectAllSharedDependencies into GenerateAndroidBuildActions Support AllowMissingDependencies in prebuilt_apex modules Support AllowMissingDependencies for apex dependencies Add AllowMissingDependencies support for prebuilt_etc module with no src property Make OutputFileForModule work for AllowMissingDependencies Fix panics when target arch is riscv64
This commit is contained in:
@@ -15,10 +15,32 @@
|
||||
package android
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(m.Run())
|
||||
var buildDir string
|
||||
|
||||
func setUp() {
|
||||
var err error
|
||||
buildDir, err = ioutil.TempDir("", "android_test")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func tearDown() {
|
||||
os.RemoveAll(buildDir)
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
run := func() int {
|
||||
setUp()
|
||||
defer tearDown()
|
||||
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
os.Exit(run())
|
||||
}
|
||||
|
@@ -3546,10 +3546,29 @@ func OutputFileForModule(ctx PathContext, module blueprint.Module, tag string) P
|
||||
reportPathError(ctx, err)
|
||||
return nil
|
||||
}
|
||||
if len(paths) == 0 {
|
||||
type addMissingDependenciesIntf interface {
|
||||
AddMissingDependencies([]string)
|
||||
OtherModuleName(blueprint.Module) string
|
||||
}
|
||||
if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
|
||||
mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
|
||||
} else {
|
||||
ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
|
||||
}
|
||||
// Return a fake output file to avoid nil dereferences of Path objects later.
|
||||
// This should never get used for an actual build as the error or missing
|
||||
// dependency has already been reported.
|
||||
p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
|
||||
if err != nil {
|
||||
reportPathError(ctx, err)
|
||||
return nil
|
||||
}
|
||||
return p
|
||||
}
|
||||
if len(paths) > 1 {
|
||||
ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
|
||||
pathContextName(ctx, module))
|
||||
return nil
|
||||
}
|
||||
return paths[0]
|
||||
}
|
||||
@@ -3561,18 +3580,12 @@ func outputFilesForModule(ctx PathContext, module blueprint.Module, tag string)
|
||||
return nil, fmt.Errorf("failed to get output file from module %q: %s",
|
||||
pathContextName(ctx, module), err.Error())
|
||||
}
|
||||
if len(paths) == 0 {
|
||||
return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module))
|
||||
}
|
||||
return paths, nil
|
||||
} else if sourceFileProducer, ok := module.(SourceFileProducer); ok {
|
||||
if tag != "" {
|
||||
return nil, fmt.Errorf("module %q is a SourceFileProducer, not an OutputFileProducer, and so does not support tag %q", pathContextName(ctx, module), tag)
|
||||
}
|
||||
paths := sourceFileProducer.Srcs()
|
||||
if len(paths) == 0 {
|
||||
return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module))
|
||||
}
|
||||
return paths, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module))
|
||||
|
@@ -15,6 +15,7 @@
|
||||
package android
|
||||
|
||||
import (
|
||||
"github.com/google/blueprint"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
@@ -978,3 +979,88 @@ func TestSetAndroidMkEntriesWithTestOptions(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeBlueprintModule struct{}
|
||||
|
||||
func (fakeBlueprintModule) Name() string { return "foo" }
|
||||
|
||||
func (fakeBlueprintModule) GenerateBuildActions(blueprint.ModuleContext) {}
|
||||
|
||||
type sourceProducerTestModule struct {
|
||||
fakeBlueprintModule
|
||||
source Path
|
||||
}
|
||||
|
||||
func (s sourceProducerTestModule) Srcs() Paths { return Paths{s.source} }
|
||||
|
||||
type outputFileProducerTestModule struct {
|
||||
fakeBlueprintModule
|
||||
output map[string]Path
|
||||
error map[string]error
|
||||
}
|
||||
|
||||
func (o outputFileProducerTestModule) OutputFiles(tag string) (Paths, error) {
|
||||
return PathsIfNonNil(o.output[tag]), o.error[tag]
|
||||
}
|
||||
|
||||
type pathContextAddMissingDependenciesWrapper struct {
|
||||
PathContext
|
||||
missingDeps []string
|
||||
}
|
||||
|
||||
func (p *pathContextAddMissingDependenciesWrapper) AddMissingDependencies(deps []string) {
|
||||
p.missingDeps = append(p.missingDeps, deps...)
|
||||
}
|
||||
func (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module blueprint.Module) string {
|
||||
return module.Name()
|
||||
}
|
||||
|
||||
func TestOutputFileForModule(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
module blueprint.Module
|
||||
tag string
|
||||
env map[string]string
|
||||
config func(*config)
|
||||
expected string
|
||||
missingDeps []string
|
||||
}{
|
||||
{
|
||||
name: "SourceFileProducer",
|
||||
module: &sourceProducerTestModule{source: PathForTesting("foo.txt")},
|
||||
expected: "foo.txt",
|
||||
},
|
||||
{
|
||||
name: "OutputFileProducer",
|
||||
module: &outputFileProducerTestModule{output: map[string]Path{"": PathForTesting("foo.txt")}},
|
||||
expected: "foo.txt",
|
||||
},
|
||||
{
|
||||
name: "OutputFileProducer_tag",
|
||||
module: &outputFileProducerTestModule{output: map[string]Path{"foo": PathForTesting("foo.txt")}},
|
||||
tag: "foo",
|
||||
expected: "foo.txt",
|
||||
},
|
||||
{
|
||||
name: "OutputFileProducer_AllowMissingDependencies",
|
||||
config: func(config *config) {
|
||||
config.TestProductVariables.Allow_missing_dependencies = boolPtr(true)
|
||||
},
|
||||
module: &outputFileProducerTestModule{},
|
||||
missingDeps: []string{"foo"},
|
||||
expected: "missing_output_file/foo",
|
||||
},
|
||||
}
|
||||
for _, tt := range testcases {
|
||||
config := TestConfig(buildDir, tt.env, "", nil)
|
||||
if tt.config != nil {
|
||||
tt.config(config.config)
|
||||
}
|
||||
ctx := &pathContextAddMissingDependenciesWrapper{
|
||||
PathContext: PathContextForTesting(config),
|
||||
}
|
||||
got := OutputFileForModule(ctx, tt.module, tt.tag)
|
||||
AssertPathRelativeToTopEquals(t, "expected source path", tt.expected, got)
|
||||
AssertArrayString(t, "expected missing deps", tt.missingDeps, ctx.missingDeps)
|
||||
}
|
||||
}
|
||||
|
13
apex/apex.go
13
apex/apex.go
@@ -286,6 +286,9 @@ type apexArchBundleProperties struct {
|
||||
Arm64 struct {
|
||||
ApexNativeDependencies
|
||||
}
|
||||
Riscv64 struct {
|
||||
ApexNativeDependencies
|
||||
}
|
||||
X86 struct {
|
||||
ApexNativeDependencies
|
||||
}
|
||||
@@ -787,6 +790,8 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||
depsList = append(depsList, a.archProperties.Arch.Arm.ApexNativeDependencies)
|
||||
case android.Arm64:
|
||||
depsList = append(depsList, a.archProperties.Arch.Arm64.ApexNativeDependencies)
|
||||
case android.Riscv64:
|
||||
depsList = append(depsList, a.archProperties.Arch.Riscv64.ApexNativeDependencies)
|
||||
case android.X86:
|
||||
depsList = append(depsList, a.archProperties.Arch.X86.ApexNativeDependencies)
|
||||
case android.X86_64:
|
||||
@@ -1559,7 +1564,7 @@ func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, h
|
||||
dirInApex = filepath.Join(dirInApex, "bionic")
|
||||
}
|
||||
|
||||
fileToCopy := ccMod.OutputFile().Path()
|
||||
fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
|
||||
androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
|
||||
return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
|
||||
}
|
||||
@@ -1570,7 +1575,7 @@ func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFil
|
||||
dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
|
||||
}
|
||||
dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
|
||||
fileToCopy := cc.OutputFile().Path()
|
||||
fileToCopy := android.OutputFileForModule(ctx, cc, "")
|
||||
androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
|
||||
af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
|
||||
af.symlinks = cc.Symlinks()
|
||||
@@ -1583,7 +1588,7 @@ func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module
|
||||
if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
|
||||
dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
|
||||
}
|
||||
fileToCopy := rustm.OutputFile().Path()
|
||||
fileToCopy := android.OutputFileForModule(ctx, rustm, "")
|
||||
androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
|
||||
af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
|
||||
return af
|
||||
@@ -1602,7 +1607,7 @@ func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) a
|
||||
if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
|
||||
dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
|
||||
}
|
||||
fileToCopy := rustm.OutputFile().Path()
|
||||
fileToCopy := android.OutputFileForModule(ctx, rustm, "")
|
||||
androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
|
||||
return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
|
||||
}
|
||||
|
@@ -537,7 +537,11 @@ func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext,
|
||||
}
|
||||
|
||||
if src == "" {
|
||||
ctx.OtherModuleErrorf(prebuilt, "prebuilt_apex does not support %q", multiTargets[0].Arch.String())
|
||||
if ctx.Config().AllowMissingDependencies() {
|
||||
ctx.AddMissingDependencies([]string{ctx.OtherModuleName(prebuilt)})
|
||||
} else {
|
||||
ctx.OtherModuleErrorf(prebuilt, "prebuilt_apex does not support %q", multiTargets[0].Arch.String())
|
||||
}
|
||||
// Drop through to return an empty string as the src (instead of nil) to avoid the prebuilt
|
||||
// logic from reporting a more general, less useful message.
|
||||
}
|
||||
|
@@ -28,6 +28,8 @@ func minApiForArch(ctx android.BaseModuleContext,
|
||||
return ctx.Config().MinSupportedSdkVersion()
|
||||
case android.Arm64, android.X86_64:
|
||||
return android.FirstLp64Version
|
||||
case android.Riscv64:
|
||||
return android.FutureApiLevel
|
||||
default:
|
||||
panic(fmt.Errorf("Unknown arch %q", arch))
|
||||
}
|
||||
|
5
cc/cc.go
5
cc/cc.go
@@ -3330,6 +3330,11 @@ func (c *Module) OutputFiles(tag string) (android.Paths, error) {
|
||||
return android.Paths{c.outputFile.Path()}, nil
|
||||
}
|
||||
return android.Paths{}, nil
|
||||
case "unstripped":
|
||||
if c.linker != nil {
|
||||
return android.PathsIfNonNil(c.linker.unstrippedOutputFilePath()), nil
|
||||
}
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
|
||||
}
|
||||
|
75
cc/fuzz.go
75
cc/fuzz.go
@@ -103,6 +103,7 @@ type fuzzBinary struct {
|
||||
*baseCompiler
|
||||
fuzzPackagedModule fuzz.FuzzPackagedModule
|
||||
installedSharedDeps []string
|
||||
sharedLibraries android.Paths
|
||||
}
|
||||
|
||||
func (fuzz *fuzzBinary) fuzzBinary() bool {
|
||||
@@ -142,13 +143,6 @@ func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||
return flags
|
||||
}
|
||||
|
||||
func UnstrippedOutputFile(module android.Module) android.Path {
|
||||
if mod, ok := module.(LinkableInterface); ok {
|
||||
return mod.UnstrippedOutputFile()
|
||||
}
|
||||
panic("UnstrippedOutputFile called on non-LinkableInterface module: " + module.Name())
|
||||
}
|
||||
|
||||
// IsValidSharedDependency takes a module and determines if it is a unique shared library
|
||||
// that should be installed in the fuzz target output directories. This function
|
||||
// returns true, unless:
|
||||
@@ -270,22 +264,9 @@ func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
|
||||
}
|
||||
|
||||
// Grab the list of required shared libraries.
|
||||
seen := make(map[string]bool)
|
||||
var sharedLibraries android.Paths
|
||||
ctx.WalkDeps(func(child, parent android.Module) bool {
|
||||
if seen[child.Name()] {
|
||||
return false
|
||||
}
|
||||
seen[child.Name()] = true
|
||||
fuzzBin.sharedLibraries = CollectAllSharedDependencies(ctx)
|
||||
|
||||
if IsValidSharedDependency(child) {
|
||||
sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
for _, lib := range sharedLibraries {
|
||||
for _, lib := range fuzzBin.sharedLibraries {
|
||||
fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
|
||||
sharedLibraryInstallLocation(
|
||||
lib, ctx.Host(), installBase, ctx.Arch().ArchType.String()))
|
||||
@@ -412,9 +393,6 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString)
|
||||
archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
|
||||
|
||||
// Grab the list of required shared libraries.
|
||||
sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, UnstrippedOutputFile, IsValidSharedDependency)
|
||||
|
||||
var files []fuzz.FileToZip
|
||||
builder := android.NewRuleBuilder(pctx, ctx)
|
||||
|
||||
@@ -422,10 +400,10 @@ func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
files = s.PackageArtifacts(ctx, module, fpm, archDir, builder)
|
||||
|
||||
// Package shared libraries
|
||||
files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
|
||||
files = append(files, GetSharedLibsToZip(fuzzModule.sharedLibraries, ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
|
||||
|
||||
// The executable.
|
||||
files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""})
|
||||
files = append(files, fuzz.FileToZip{android.OutputFileForModule(ctx, ccModule, "unstripped"), ""})
|
||||
|
||||
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fpm, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
|
||||
if !ok {
|
||||
@@ -494,3 +472,46 @@ func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface,
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// CollectAllSharedDependencies search over the provided module's dependencies using
|
||||
// VisitDirectDeps and WalkDeps to enumerate all shared library dependencies.
|
||||
// VisitDirectDeps is used first to avoid incorrectly using the core libraries (sanitizer
|
||||
// runtimes, libc, libdl, etc.) from a dependency. This may cause issues when dependencies
|
||||
// have explicit sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
|
||||
func CollectAllSharedDependencies(ctx android.ModuleContext) android.Paths {
|
||||
seen := make(map[string]bool)
|
||||
recursed := make(map[string]bool)
|
||||
|
||||
var sharedLibraries android.Paths
|
||||
|
||||
// Enumerate the first level of dependencies, as we discard all non-library
|
||||
// modules in the BFS loop below.
|
||||
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||
if !IsValidSharedDependency(dep) {
|
||||
return
|
||||
}
|
||||
if seen[ctx.OtherModuleName(dep)] {
|
||||
return
|
||||
}
|
||||
seen[ctx.OtherModuleName(dep)] = true
|
||||
sharedLibraries = append(sharedLibraries, android.OutputFileForModule(ctx, dep, "unstripped"))
|
||||
})
|
||||
|
||||
ctx.WalkDeps(func(child, parent android.Module) bool {
|
||||
if !IsValidSharedDependency(child) {
|
||||
return false
|
||||
}
|
||||
if !seen[ctx.OtherModuleName(child)] {
|
||||
seen[ctx.OtherModuleName(child)] = true
|
||||
sharedLibraries = append(sharedLibraries, android.OutputFileForModule(ctx, child, "unstripped"))
|
||||
}
|
||||
|
||||
if recursed[ctx.OtherModuleName(child)] {
|
||||
return false
|
||||
}
|
||||
recursed[ctx.OtherModuleName(child)] = true
|
||||
return true
|
||||
})
|
||||
|
||||
return sharedLibraries
|
||||
}
|
||||
|
@@ -296,27 +296,37 @@ func (p *PrebuiltEtc) ExcludeFromRecoverySnapshot() bool {
|
||||
}
|
||||
|
||||
func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
if p.properties.Src == nil {
|
||||
ctx.PropertyErrorf("src", "missing prebuilt source file")
|
||||
return
|
||||
}
|
||||
p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
|
||||
|
||||
// Determine the output file basename.
|
||||
// If Filename is set, use the name specified by the property.
|
||||
// If Filename_from_src is set, use the source file name.
|
||||
// Otherwise use the module name.
|
||||
filename := proptools.String(p.properties.Filename)
|
||||
filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
|
||||
if filename != "" {
|
||||
if filenameFromSrc {
|
||||
ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
|
||||
return
|
||||
if p.properties.Src != nil {
|
||||
p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
|
||||
|
||||
// Determine the output file basename.
|
||||
// If Filename is set, use the name specified by the property.
|
||||
// If Filename_from_src is set, use the source file name.
|
||||
// Otherwise use the module name.
|
||||
if filename != "" {
|
||||
if filenameFromSrc {
|
||||
ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
|
||||
return
|
||||
}
|
||||
} else if filenameFromSrc {
|
||||
filename = p.sourceFilePath.Base()
|
||||
} else {
|
||||
filename = ctx.ModuleName()
|
||||
}
|
||||
} else if ctx.Config().AllowMissingDependencies() {
|
||||
// If no srcs was set and AllowMissingDependencies is enabled then
|
||||
// mark the module as missing dependencies and set a fake source path
|
||||
// and file name.
|
||||
ctx.AddMissingDependencies([]string{"MISSING_PREBUILT_SRC_FILE"})
|
||||
p.sourceFilePath = android.PathForModuleSrc(ctx)
|
||||
if filename == "" {
|
||||
filename = ctx.ModuleName()
|
||||
}
|
||||
} else if filenameFromSrc {
|
||||
filename = p.sourceFilePath.Base()
|
||||
} else {
|
||||
filename = ctx.ModuleName()
|
||||
ctx.PropertyErrorf("src", "missing prebuilt source file")
|
||||
return
|
||||
}
|
||||
p.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
|
||||
|
||||
|
@@ -195,6 +195,30 @@ func TestPrebuiltEtcHost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrebuiltEtcAllowMissingDependencies(t *testing.T) {
|
||||
result := android.GroupFixturePreparers(
|
||||
prepareForPrebuiltEtcTest,
|
||||
android.PrepareForTestDisallowNonExistentPaths,
|
||||
android.FixtureModifyConfig(
|
||||
func(config android.Config) {
|
||||
config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
|
||||
}),
|
||||
).RunTestWithBp(t, `
|
||||
prebuilt_etc {
|
||||
name: "foo.conf",
|
||||
filename_from_src: true,
|
||||
arch: {
|
||||
x86: {
|
||||
src: "x86.conf",
|
||||
},
|
||||
},
|
||||
}
|
||||
`)
|
||||
|
||||
android.AssertStringEquals(t, "expected error rule", "android/soong/android.Error",
|
||||
result.ModuleForTests("foo.conf", "android_arm64_armv8-a").Output("foo.conf").Rule.String())
|
||||
}
|
||||
|
||||
func TestPrebuiltRootInstallDirPath(t *testing.T) {
|
||||
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
|
||||
prebuilt_root {
|
||||
|
@@ -379,42 +379,3 @@ func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets str
|
||||
sort.Strings(fuzzTargets)
|
||||
ctx.Strict(targets, strings.Join(fuzzTargets, " "))
|
||||
}
|
||||
|
||||
// CollectAllSharedDependencies performs a breadth-first search over the provided module's
|
||||
// dependencies using `visitDirectDeps` to enumerate all shared library
|
||||
// dependencies. We require breadth-first expansion, as otherwise we may
|
||||
// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
|
||||
// from a dependency. This may cause issues when dependencies have explicit
|
||||
// sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
|
||||
func CollectAllSharedDependencies(ctx android.SingletonContext, module android.Module, unstrippedOutputFile func(module android.Module) android.Path, isValidSharedDependency func(dependency android.Module) bool) android.Paths {
|
||||
var fringe []android.Module
|
||||
|
||||
seen := make(map[string]bool)
|
||||
|
||||
// Enumerate the first level of dependencies, as we discard all non-library
|
||||
// modules in the BFS loop below.
|
||||
ctx.VisitDirectDeps(module, func(dep android.Module) {
|
||||
if isValidSharedDependency(dep) {
|
||||
fringe = append(fringe, dep)
|
||||
}
|
||||
})
|
||||
|
||||
var sharedLibraries android.Paths
|
||||
|
||||
for i := 0; i < len(fringe); i++ {
|
||||
module := fringe[i]
|
||||
if seen[module.Name()] {
|
||||
continue
|
||||
}
|
||||
seen[module.Name()] = true
|
||||
|
||||
sharedLibraries = append(sharedLibraries, unstrippedOutputFile(module))
|
||||
ctx.VisitDirectDeps(module, func(dep android.Module) {
|
||||
if isValidSharedDependency(dep) && !seen[dep.Name()] {
|
||||
fringe = append(fringe, dep)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return sharedLibraries
|
||||
}
|
||||
|
@@ -90,10 +90,11 @@ func (as *AndroidAppSet) APKCertsFile() android.Path {
|
||||
}
|
||||
|
||||
var TargetCpuAbi = map[string]string{
|
||||
"arm": "ARMEABI_V7A",
|
||||
"arm64": "ARM64_V8A",
|
||||
"x86": "X86",
|
||||
"x86_64": "X86_64",
|
||||
"arm": "ARMEABI_V7A",
|
||||
"arm64": "ARM64_V8A",
|
||||
"riscv64": "RISCV64",
|
||||
"x86": "X86",
|
||||
"x86_64": "X86_64",
|
||||
}
|
||||
|
||||
func SupportedAbis(ctx android.ModuleContext) []string {
|
||||
|
@@ -25,7 +25,7 @@ var (
|
||||
Riscv64ArchFeatureRustFlags = map[string][]string{"": {}}
|
||||
Riscv64LinkFlags = []string{}
|
||||
|
||||
Riscv64ArchVariantRustFlags = map[string][]string{}
|
||||
Riscv64ArchVariantRustFlags = map[string][]string{"": {}}
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
15
rust/fuzz.go
15
rust/fuzz.go
@@ -34,6 +34,7 @@ type fuzzDecorator struct {
|
||||
*binaryDecorator
|
||||
|
||||
fuzzPackagedModule fuzz.FuzzPackagedModule
|
||||
sharedLibraries android.Paths
|
||||
}
|
||||
|
||||
var _ compiler = (*fuzzDecorator)(nil)
|
||||
@@ -86,6 +87,15 @@ func (fuzzer *fuzzDecorator) compilerProps() []interface{} {
|
||||
&fuzzer.fuzzPackagedModule.FuzzProperties)
|
||||
}
|
||||
|
||||
func (fuzzer *fuzzDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
|
||||
out := fuzzer.binaryDecorator.compile(ctx, flags, deps)
|
||||
|
||||
// Grab the list of required shared libraries.
|
||||
fuzzer.sharedLibraries = cc.CollectAllSharedDependencies(ctx)
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage {
|
||||
return RlibLinkage
|
||||
}
|
||||
@@ -149,11 +159,8 @@ func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
// The executable.
|
||||
files = append(files, fuzz.FileToZip{rustModule.UnstrippedOutputFile(), ""})
|
||||
|
||||
// Grab the list of required shared libraries.
|
||||
sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, cc.UnstrippedOutputFile, cc.IsValidSharedDependency)
|
||||
|
||||
// Package shared libraries
|
||||
files = append(files, cc.GetSharedLibsToZip(sharedLibraries, rustModule, &s.FuzzPackager, archString, "lib", &sharedLibraryInstalled)...)
|
||||
files = append(files, cc.GetSharedLibsToZip(fuzzModule.sharedLibraries, rustModule, &s.FuzzPackager, archString, "lib", &sharedLibraryInstalled)...)
|
||||
|
||||
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
|
||||
if !ok {
|
||||
|
Reference in New Issue
Block a user