Merge "Include compos-module-sdk in the SDK build."
diff --git a/android/androidmk.go b/android/androidmk.go
index feaef1f..f48c06b 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -29,6 +29,7 @@
"os"
"path/filepath"
"reflect"
+ "runtime"
"sort"
"strings"
@@ -902,6 +903,13 @@
return true
}
+ // On Mac, only expose host darwin modules to Make, as that's all we claim to support.
+ // In reality, some of them depend on device-built (Java) modules, so we can't disable all
+ // device modules in Soong, but we can hide them from Make (and thus the build user interface)
+ if runtime.GOOS == "darwin" && module.Os() != Darwin {
+ return true
+ }
+
return !module.Enabled() ||
module.commonProperties.HideFromMake ||
// Make does not understand LinuxBionic
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 8eda9b2..ecfb008 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -18,6 +18,7 @@
"fmt"
"io"
"reflect"
+ "runtime"
"strings"
"testing"
@@ -155,6 +156,11 @@
}
func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testing.T) {
+ if runtime.GOOS == "darwin" {
+ // Device modules are not exported on Mac, so this test doesn't work.
+ t.SkipNow()
+ }
+
bp := `
custom {
name: "foo",
diff --git a/android/bazel.go b/android/bazel.go
index e4eaa37..91ca969 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -243,6 +243,11 @@
"brotli-fuzzer-corpus", // b/202015218: outputs are in location incompatible with bazel genrule handling.
+ // b/203369847: multiple genrules in the same package creating the same file
+ // //development/sdk/...
+ "platform_tools_properties",
+ "build_tools_source_properties",
+
// //external/libcap/...
"libcap", // http://b/198595332, depends on _makenames, a cc_binary
"cap_names.h", // http://b/198596102, depends on _makenames, a cc_binary
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index b2f8eaa..0ec9bcb 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -60,7 +60,7 @@
module_type: "test",
config_namespace: "acme",
variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
- bool_variables: ["feature2", "unused_feature"],
+ bool_variables: ["feature2", "unused_feature", "always_true"],
value_variables: ["size", "unused_size"],
properties: ["cflags", "srcs", "defaults"],
}
@@ -148,6 +148,11 @@
cflags: ["DEFAULT_B"],
}
+ test_defaults {
+ name: "foo_defaults_always_true",
+ cflags: ["DEFAULT_ALWAYS_TRUE"],
+ }
+
acme_test {
name: "foo_with_defaults",
cflags: ["-DGENERIC"],
@@ -176,6 +181,15 @@
FEATURE3: {
cflags: ["-DFEATURE3"],
},
+ always_true: {
+ defaults: ["foo_defaults_always_true"],
+ conditions_default: {
+ // verify that conditions_default is skipped if the
+ // soong config variable is true by specifying a
+ // non-existent module in conditions_default
+ defaults: ["//nonexistent:defaults"],
+ }
+ },
},
}
`
@@ -205,6 +219,7 @@
"unused_feature": "true", // unused
"unused_size": "1", // unused
"unused_string_var": "a", // unused
+ "always_true": "true",
},
}),
fooExpectedFlags: []string{
@@ -217,6 +232,7 @@
},
fooDefaultsExpectedFlags: []string{
"DEFAULT_A",
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
"-DSIZE=42",
@@ -227,7 +243,10 @@
{
name: "empty_prop_for_string_var",
preparer: fixtureForVendorVars(map[string]map[string]string{
- "acme": {"board": "soc_c"}}),
+ "acme": {
+ "board": "soc_c",
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -236,6 +255,7 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
@@ -243,7 +263,10 @@
{
name: "unused_string_var",
preparer: fixtureForVendorVars(map[string]map[string]string{
- "acme": {"board": "soc_d"}}),
+ "acme": {
+ "board": "soc_d",
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -253,14 +276,18 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
},
{
- name: "conditions_default",
- preparer: fixtureForVendorVars(map[string]map[string]string{}),
+ name: "conditions_default",
+ preparer: fixtureForVendorVars(map[string]map[string]string{
+ "acme": {
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -270,6 +297,7 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go
index a76da8b..d64eb7a 100644
--- a/android_sdk/sdk_repo_host.go
+++ b/android_sdk/sdk_repo_host.go
@@ -241,11 +241,10 @@
func (s *sdkRepoHost) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
- // TODO: per-OS PHONY
fmt.Fprintln(w, ".PHONY:", name, "sdk_repo", "sdk-repo-"+name)
fmt.Fprintln(w, "sdk_repo", "sdk-repo-"+name+":", strings.Join(s.FilesToInstall().Strings(), " "))
- fmt.Fprintf(w, "$(call dist-for-goals,sdk_repo sdk-repo-%s,%s:new_%s-$(FILE_NAME_TAG).zip)\n\n", s.BaseModuleName(), s.outputFile.String(), s.outputBaseName)
+ fmt.Fprintf(w, "$(call dist-for-goals,sdk_repo sdk-repo-%s,%s:%s-$(FILE_NAME_TAG).zip)\n\n", s.BaseModuleName(), s.outputFile.String(), s.outputBaseName)
},
}
}
diff --git a/apex/apex.go b/apex/apex.go
index 9c2c679..0bca093 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1151,8 +1151,8 @@
zipApexType = "zip"
flattenedApexType = "flattened"
- ext4FsType = "ext4"
- f2fsFsType = "f2fs"
+ ext4FsType = "ext4"
+ f2fsFsType = "f2fs"
erofsFsType = "erofs"
)
@@ -1683,6 +1683,9 @@
if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
return false
}
+ if mod, ok := child.(android.Module); ok && !mod.Enabled() {
+ return false
+ }
depName := ctx.OtherModuleName(child)
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
switch depTag {
diff --git a/bazel/aquery.go b/bazel/aquery.go
index 8741afb..0dedcf4 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -246,7 +246,8 @@
outDir := proptools.ShellEscapeIncludingSpaces(filepath.Dir(out))
out = proptools.ShellEscapeIncludingSpaces(out)
in := proptools.ShellEscapeIncludingSpaces(inputPaths[0])
- buildStatement.Command = fmt.Sprintf("mkdir -p %[1]s && rm -f %[2]s && ln -rsf %[3]s %[2]s", outDir, out, in)
+ // Use hard links, because some soong actions expect real files (for example, `cp -d`).
+ buildStatement.Command = fmt.Sprintf("mkdir -p %[1]s && rm -f %[2]s && ln -f %[3]s %[2]s", outDir, out, in)
buildStatement.SymlinkPaths = outputPaths[:]
} else if len(actionEntry.Arguments) < 1 {
return nil, fmt.Errorf("received action with no command: [%v]", buildStatement)
diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go
index 43e4155..88066c8 100644
--- a/bazel/aquery_test.go
+++ b/bazel/aquery_test.go
@@ -859,7 +859,7 @@
BuildStatement{
Command: "mkdir -p one/symlink_subdir && " +
"rm -f one/symlink_subdir/symlink && " +
- "ln -rsf one/file_subdir/file one/symlink_subdir/symlink",
+ "ln -f one/file_subdir/file one/symlink_subdir/symlink",
InputPaths: []string{"one/file_subdir/file"},
OutputPaths: []string{"one/symlink_subdir/symlink"},
SymlinkPaths: []string{"one/symlink_subdir/symlink"},
@@ -923,7 +923,7 @@
BuildStatement{
Command: "mkdir -p 'one/symlink subdir' && " +
"rm -f 'one/symlink subdir/symlink' && " +
- "ln -rsf 'one/file subdir/file' 'one/symlink subdir/symlink'",
+ "ln -f 'one/file subdir/file' 'one/symlink subdir/symlink'",
InputPaths: []string{"one/file subdir/file"},
OutputPaths: []string{"one/symlink subdir/symlink"},
SymlinkPaths: []string{"one/symlink subdir/symlink"},
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 83f0037..40f16f3 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -79,54 +79,21 @@
return flags
}
-// This function 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) 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
-
- ccModule := module.(*Module)
- sharedLibraries = append(sharedLibraries, ccModule.UnstrippedOutputFile())
- ctx.VisitDirectDeps(module, func(dep android.Module) {
- if isValidSharedDependency(dep) && !seen[dep.Name()] {
- fringe = append(fringe, dep)
- }
- })
+func UnstrippedOutputFile(module android.Module) android.Path {
+ if mod, ok := module.(LinkableInterface); ok {
+ return mod.UnstrippedOutputFile()
}
-
- return sharedLibraries
+ panic("UnstrippedOutputFile called on non-LinkableInterface module: " + module.Name())
}
-// This function takes a module and determines if it is a unique shared library
+// 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:
// - The module is not an installable shared library, or
// - The module is a header or stub, or
// - The module is a prebuilt and its source is available, or
// - The module is a versioned member of an SDK snapshot.
-func isValidSharedDependency(dependency android.Module) bool {
+func IsValidSharedDependency(dependency android.Module) bool {
// TODO(b/144090547): We should be parsing these modules using
// ModuleDependencyTag instead of the current brute-force checking.
@@ -246,7 +213,7 @@
}
seen[child.Name()] = true
- if isValidSharedDependency(child) {
+ if IsValidSharedDependency(child) {
sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
return true
}
@@ -304,7 +271,6 @@
// their architecture & target/host specific zip file.
type ccFuzzPackager struct {
fuzz.FuzzPackager
- sharedLibInstallStrings []string
}
func fuzzPackagingFactory() android.Singleton {
@@ -317,14 +283,14 @@
// archive}).
archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)
- // Map tracking whether each shared library has an install rule to avoid duplicate install rules from
- // multiple fuzzers that depend on the same shared library.
- sharedLibraryInstalled := make(map[string]bool)
-
// List of individual fuzz targets, so that 'make fuzz' also installs the targets
// to the correct output directories as well.
s.FuzzTargets = make(map[string]bool)
+ // Map tracking whether each shared library has an install rule to avoid duplicate install rules from
+ // multiple fuzzers that depend on the same shared library.
+ sharedLibraryInstalled := make(map[string]bool)
+
ctx.VisitAllModules(func(module android.Module) {
ccModule, ok := module.(*Module)
if !ok || ccModule.Properties.PreventInstall {
@@ -351,7 +317,7 @@
archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
// Grab the list of required shared libraries.
- sharedLibraries := collectAllSharedDependencies(ctx, module)
+ sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, UnstrippedOutputFile, IsValidSharedDependency)
var files []fuzz.FileToZip
builder := android.NewRuleBuilder(pctx, ctx)
@@ -359,39 +325,8 @@
// Package the corpus, data, dict and config into a zipfile.
files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder)
- // Find and mark all the transiently-dependent shared libraries for
- // packaging.
- for _, library := range sharedLibraries {
- files = append(files, fuzz.FileToZip{library, "lib"})
-
- // For each architecture-specific shared library dependency, we need to
- // install it to the output directory. Setup the install destination here,
- // which will be used by $(copy-many-files) in the Make backend.
- installDestination := sharedLibraryInstallLocation(
- library, ccModule.Host(), archString)
- if sharedLibraryInstalled[installDestination] {
- continue
- }
- sharedLibraryInstalled[installDestination] = true
-
- // Escape all the variables, as the install destination here will be called
- // via. $(eval) in Make.
- installDestination = strings.ReplaceAll(
- installDestination, "$", "$$")
- s.sharedLibInstallStrings = append(s.sharedLibInstallStrings,
- library.String()+":"+installDestination)
-
- // Ensure that on device, the library is also reinstalled to the /symbols/
- // dir. Symbolized DSO's are always installed to the device when fuzzing, but
- // we want symbolization tools (like `stack`) to be able to find the symbols
- // in $ANDROID_PRODUCT_OUT/symbols automagically.
- if !ccModule.Host() {
- symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString)
- symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
- s.sharedLibInstallStrings = append(s.sharedLibInstallStrings,
- library.String()+":"+symbolsInstallDestination)
- }
- }
+ // Package shared libraries
+ files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...)
// The executable.
files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""})
@@ -409,15 +344,54 @@
func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
packages := s.Packages.Strings()
sort.Strings(packages)
- sort.Strings(s.sharedLibInstallStrings)
+ sort.Strings(s.FuzzPackager.SharedLibInstallStrings)
// TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's
// ready to handle phony targets created in Soong. In the meantime, this
// exports the phony 'fuzz' target and dependencies on packages to
// core/main.mk so that we can use dist-for-goals.
ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
ctx.Strict("FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
- strings.Join(s.sharedLibInstallStrings, " "))
+ strings.Join(s.FuzzPackager.SharedLibInstallStrings, " "))
// Preallocate the slice of fuzz targets to minimise memory allocations.
s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS")
}
+
+// GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for
+// packaging.
+func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip {
+ var files []fuzz.FileToZip
+
+ for _, library := range sharedLibraries {
+ files = append(files, fuzz.FileToZip{library, "lib"})
+
+ // For each architecture-specific shared library dependency, we need to
+ // install it to the output directory. Setup the install destination here,
+ // which will be used by $(copy-many-files) in the Make backend.
+ installDestination := sharedLibraryInstallLocation(
+ library, module.Host(), archString)
+ if (*sharedLibraryInstalled)[installDestination] {
+ continue
+ }
+ (*sharedLibraryInstalled)[installDestination] = true
+
+ // Escape all the variables, as the install destination here will be called
+ // via. $(eval) in Make.
+ installDestination = strings.ReplaceAll(
+ installDestination, "$", "$$")
+ s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
+ library.String()+":"+installDestination)
+
+ // Ensure that on device, the library is also reinstalled to the /symbols/
+ // dir. Symbolized DSO's are always installed to the device when fuzzing, but
+ // we want symbolization tools (like `stack`) to be able to find the symbols
+ // in $ANDROID_PRODUCT_OUT/symbols automagically.
+ if !module.Host() {
+ symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString)
+ symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
+ s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
+ library.String()+":"+symbolsInstallDestination)
+ }
+ }
+ return files
+}
diff --git a/cc/installer.go b/cc/installer.go
index f95b493..2522610 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -29,6 +29,9 @@
// Install output directly in {partition}/, not in any subdir. This is only intended for use by
// init_first_stage.
Install_in_root *bool `android:"arch_variant"`
+
+ // Install output directly in {partition}/xbin
+ Install_in_xbin *bool `android:"arch_vvariant"`
}
type installLocation int
@@ -73,6 +76,8 @@
if installer.installInRoot() {
dir = ""
+ } else if installer.installInXbin() {
+ dir = "xbin"
}
if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
@@ -123,3 +128,7 @@
func (installer *baseInstaller) installInRoot() bool {
return Bool(installer.Properties.Install_in_root)
}
+
+func (installer *baseInstaller) installInXbin() bool {
+ return Bool(installer.Properties.Install_in_xbin)
+}
diff --git a/cc/linkable.go b/cc/linkable.go
index b510508..560c9de 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -110,6 +110,7 @@
BaseModuleName() string
OutputFile() android.OptionalPath
+ UnstrippedOutputFile() android.Path
CoverageFiles() android.Paths
NonCcVariants() bool
diff --git a/cmd/multiproduct_kati/Android.bp b/cmd/multiproduct_kati/Android.bp
index e5be6c0..20ca2a3 100644
--- a/cmd/multiproduct_kati/Android.bp
+++ b/cmd/multiproduct_kati/Android.bp
@@ -31,4 +31,14 @@
testSrcs: [
"main_test.go",
],
+ linux: {
+ srcs: [
+ "main_linux.go",
+ ],
+ },
+ darwin: {
+ srcs: [
+ "main_darwin.go",
+ ],
+ },
}
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 3c9cac1..0577c86 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -166,15 +166,6 @@
MainLogsDir string
}
-func detectTotalRAM() uint64 {
- var info syscall.Sysinfo_t
- err := syscall.Sysinfo(&info)
- if err != nil {
- panic(err)
- }
- return info.Totalram * uint64(info.Unit)
-}
-
func findNamedProducts(soongUi string, log logger.Logger) []string {
cmd := exec.Command(soongUi, "--dumpvars-mode", "--vars=all_named_products")
output, err := cmd.Output()
@@ -301,7 +292,7 @@
jobs = runtime.NumCPU() / 4
ramGb := int(detectTotalRAM() / (1024 * 1024 * 1024))
- if ramJobs := ramGb / 25; ramGb > 0 && jobs > ramJobs {
+ if ramJobs := ramGb / 30; ramGb > 0 && jobs > ramJobs {
jobs = ramJobs
}
diff --git a/cmd/multiproduct_kati/main_darwin.go b/cmd/multiproduct_kati/main_darwin.go
new file mode 100644
index 0000000..3d1b12a
--- /dev/null
+++ b/cmd/multiproduct_kati/main_darwin.go
@@ -0,0 +1,20 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// 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 main
+
+func detectTotalRAM() uint64 {
+ // unimplemented stub on darwin
+ return 0
+}
diff --git a/cmd/multiproduct_kati/main_linux.go b/cmd/multiproduct_kati/main_linux.go
new file mode 100644
index 0000000..db74496
--- /dev/null
+++ b/cmd/multiproduct_kati/main_linux.go
@@ -0,0 +1,28 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// 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 main
+
+import (
+ "syscall"
+)
+
+func detectTotalRAM() uint64 {
+ var info syscall.Sysinfo_t
+ err := syscall.Sysinfo(&info)
+ if err != nil {
+ panic(err)
+ }
+ return info.Totalram * uint64(info.Unit)
+}
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index ccadc0f..8861d1b 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -42,8 +42,9 @@
}
type FuzzPackager struct {
- Packages android.Paths
- FuzzTargets map[string]bool
+ Packages android.Paths
+ FuzzTargets map[string]bool
+ SharedLibInstallStrings []string
}
type FileToZip struct {
@@ -251,3 +252,42 @@
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
+}
diff --git a/java/proto.go b/java/proto.go
index 8731822..2fa22b6 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -24,7 +24,7 @@
func genProto(ctx android.ModuleContext, protoFiles android.Paths, flags android.ProtoFlags) android.Paths {
// Shard proto files into groups of 100 to avoid having to recompile all of them if one changes and to avoid
// hitting command line length limits.
- shards := android.ShardPaths(protoFiles, 100)
+ shards := android.ShardPaths(protoFiles, 50)
srcJarFiles := make(android.Paths, 0, len(shards))
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 3ae8ab9..b377fd8 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -1162,17 +1162,21 @@
}
// Either pattern or text should be const, and the
// non-const one should be varRefExpr
- if xInList, ok = xPattern.(*stringLiteralExpr); ok {
+ if xInList, ok = xPattern.(*stringLiteralExpr); ok && !strings.ContainsRune(xInList.literal, '%') && xText.typ() == starlarkTypeList {
expr = xText
} else if xInList, ok = xText.(*stringLiteralExpr); ok {
expr = xPattern
} else {
- return &callExpr{
+ expr = &callExpr{
object: nil,
name: filterFuncCall.name,
args: filterFuncCall.args,
returnType: starlarkTypeBool,
}
+ if negate {
+ expr = ¬Expr{expr: expr}
+ }
+ return expr
}
case *variableRefExpr:
if v, ok := xPattern.(*variableRefExpr); ok {
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 434500b..fe1fa08 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -360,20 +360,27 @@
endif
ifneq (,$(filter true, $(v1)$(v2)))
endif
+ifeq (,$(filter barbet coral%,$(TARGET_PRODUCT)))
+else ifneq (,$(filter barbet%,$(TARGET_PRODUCT)))
+endif
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
- if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]:
+ if not rblf.filter("userdebug eng", g["TARGET_BUILD_VARIANT"]):
pass
- if g["TARGET_BUILD_VARIANT"] == "userdebug":
+ if rblf.filter("userdebug", g["TARGET_BUILD_VARIANT"]):
pass
if "plaf" in g.get("PLATFORM_LIST", []):
pass
if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]:
pass
- if "%s%s" % (_v1, _v2) == "true":
+ if rblf.filter("true", "%s%s" % (_v1, _v2)):
+ pass
+ if not rblf.filter("barbet coral%", g["TARGET_PRODUCT"]):
+ pass
+ elif rblf.filter("barbet%", g["TARGET_PRODUCT"]):
pass
`,
},
diff --git a/rust/fuzz.go b/rust/fuzz.go
index 5fb56ff..a628b61 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -111,6 +111,10 @@
// List of individual fuzz targets.
s.FuzzTargets = make(map[string]bool)
+ // Map tracking whether each shared library has an install rule to avoid duplicate install rules from
+ // multiple fuzzers that depend on the same shared library.
+ sharedLibraryInstalled := make(map[string]bool)
+
ctx.VisitAllModules(func(module android.Module) {
// Discard non-fuzz targets.
rustModule, ok := module.(*Module)
@@ -145,6 +149,12 @@
// The executable.
files = append(files, fuzz.FileToZip{rustModule.unstrippedOutputFile.Path(), ""})
+ // 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, &sharedLibraryInstalled)...)
+
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok {
return
diff --git a/rust/rust.go b/rust/rust.go
index 93dbd00..13169f1 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -594,6 +594,13 @@
return false
}
+func (mod *Module) UnstrippedOutputFile() android.Path {
+ if mod.unstrippedOutputFile.Valid() {
+ return mod.unstrippedOutputFile.Path()
+ }
+ return nil
+}
+
func (mod *Module) IncludeDirs() android.Paths {
if mod.compiler != nil {
if library, ok := mod.compiler.(*libraryDecorator); ok {