Merge "Add test for missing certificate with AllowMissingDependencies"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index e7bd920..07db3c2 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -164,6 +164,7 @@
"external/lzma/C": Bp2BuildDefaultTrueRecursively,
"external/mdnsresponder": Bp2BuildDefaultTrueRecursively,
"external/minijail": Bp2BuildDefaultTrueRecursively,
+ "external/musl": Bp2BuildDefaultTrueRecursively,
"external/objenesis": Bp2BuildDefaultTrueRecursively,
"external/openscreen": Bp2BuildDefaultTrueRecursively,
"external/ow2-asm": Bp2BuildDefaultTrueRecursively,
@@ -364,6 +365,7 @@
"external/guava":/* recursive = */ true,
"external/jsr305":/* recursive = */ true,
"external/protobuf":/* recursive = */ false,
+ "external/python/absl-py":/* recursive = */ true,
// this BUILD file is globbed by //external/icu/icu4c/source:icu4c_test_data's "data/**/*".
"external/icu/icu4c/source/data/unidata/norm2":/* recursive = */ false,
@@ -731,8 +733,7 @@
"platform_tools_properties", "build_tools_source_properties", // TODO(b/203369847): multiple genrules in the same package creating the same file
// aar support
- "prebuilt_car-ui-androidx-core-common", // TODO(b/224773339), genrule dependency creates an .aar, not a .jar
- "prebuilt_platform-robolectric-4.5.1-prebuilt", // aosp/1999250, needs .aar support in Jars
+ "prebuilt_car-ui-androidx-core-common", // TODO(b/224773339), genrule dependency creates an .aar, not a .jar
// ERROR: The dependencies for the following 1 jar(s) are not complete.
// 1.bazel-out/android_target-fastbuild/bin/prebuilts/tools/common/m2/_aar/robolectric-monitor-1.0.2-alpha1/classes_and_libs_merged.jar
"prebuilt_robolectric-monitor-1.0.2-alpha1",
@@ -793,6 +794,7 @@
"libstatslog", // depends on unconverted modules: libstatspull, statsd-aidl-ndk
"libstatslog_art", // depends on unconverted modules: statslog_art.cpp, statslog_art.h
"linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_*
+ "malloc-rss-benchmark", // depends on unconverted modules: libmeminfo
"pbtombstone", "crash_dump", // depends on libdebuggerd, libunwindstack
"robolectric-sqlite4java-0.282", // depends on unconverted modules: robolectric-sqlite4java-import, robolectric-sqlite4java-native
"static_crasher", // depends on unconverted modules: libdebuggerd_handler
@@ -1305,6 +1307,9 @@
// TODO(b/254476335): disable the following due to this bug
"libapexinfo",
"libapexinfo_tests",
+
+ // uses glob in $(locations)
+ "libc_musl_sysroot",
}
Bp2buildCcLibraryStaticOnlyList = []string{}
@@ -1350,7 +1355,6 @@
"prebuilt_kotlin-stdlib-jdk8",
"prebuilt_kotlin-test",
// TODO(b/217750501) exclude_files property not supported
- "prebuilt_platform-robolectric-4.5.1-prebuilt",
"prebuilt_currysrc_org.eclipse",
}
@@ -1361,5 +1365,9 @@
// Staging-mode allowlist. Modules in this list are only built
// by Bazel with --bazel-mode-staging. This list should contain modules
// which will soon be added to the prod allowlist.
- StagingMixedBuildsEnabledList = []string{"com.android.tzdata"}
+ // It is implicit that all modules in ProdMixedBuildsEnabledList will
+ // also be built - do not add them to this list.
+ StagingMixedBuildsEnabledList = []string{
+ "com.android.adbd",
+ }
)
diff --git a/android/androidmk.go b/android/androidmk.go
index 846d506..6346401 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -489,11 +489,11 @@
// Write the license variables to Make for AndroidMkData.Custom(..) methods that do not call WriteAndroidMkData(..)
// It's required to propagate the license metadata even for module types that have non-standard interfaces to Make.
func (a *AndroidMkEntries) WriteLicenseVariables(w io.Writer) {
- fmt.Fprintln(w, "LOCAL_LICENSE_KINDS :=", strings.Join(a.EntryMap["LOCAL_LICENSE_KINDS"], " "))
- fmt.Fprintln(w, "LOCAL_LICENSE_CONDITIONS :=", strings.Join(a.EntryMap["LOCAL_LICENSE_CONDITIONS"], " "))
- fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", strings.Join(a.EntryMap["LOCAL_NOTICE_FILE"], " "))
+ AndroidMkEmitAssignList(w, "LOCAL_LICENSE_KINDS", a.EntryMap["LOCAL_LICENSE_KINDS"])
+ AndroidMkEmitAssignList(w, "LOCAL_LICENSE_CONDITIONS", a.EntryMap["LOCAL_LICENSE_CONDITIONS"])
+ AndroidMkEmitAssignList(w, "LOCAL_NOTICE_FILE", a.EntryMap["LOCAL_NOTICE_FILE"])
if pn, ok := a.EntryMap["LOCAL_LICENSE_PACKAGE_NAME"]; ok {
- fmt.Fprintln(w, "LOCAL_LICENSE_PACKAGE_NAME :=", strings.Join(pn, " "))
+ AndroidMkEmitAssignList(w, "LOCAL_LICENSE_PACKAGE_NAME", pn)
}
}
@@ -672,7 +672,7 @@
w.Write(a.header.Bytes())
for _, name := range a.entryOrder {
- fmt.Fprintln(w, name+" := "+strings.Join(a.EntryMap[name], " "))
+ AndroidMkEmitAssignList(w, name, a.EntryMap[name])
}
w.Write(a.footer.Bytes())
}
@@ -972,3 +972,28 @@
}
return testFiles
}
+
+// AndroidMkEmitAssignList emits the line
+//
+// VAR := ITEM ...
+//
+// Items are the elements to the given set of lists
+// If all the passed lists are empty, no line will be emitted
+func AndroidMkEmitAssignList(w io.Writer, varName string, lists ...[]string) {
+ doPrint := false
+ for _, l := range lists {
+ if doPrint = len(l) > 0; doPrint {
+ break
+ }
+ }
+ if !doPrint {
+ return
+ }
+ fmt.Fprint(w, varName, " :=")
+ for _, l := range lists {
+ for _, item := range l {
+ fmt.Fprint(w, " ", item)
+ }
+ }
+ fmt.Fprintln(w)
+}
diff --git a/android/arch_list.go b/android/arch_list.go
index cbf8e7a..578904c 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -31,6 +31,8 @@
"amberlake",
"atom",
"broadwell",
+ "goldmont",
+ "goldmont-plus",
"haswell",
"icelake",
"ivybridge",
@@ -40,12 +42,15 @@
"skylake",
"stoneyridge",
"tigerlake",
+ "tremont",
"whiskeylake",
"x86_64",
},
X86_64: {
"amberlake",
"broadwell",
+ "goldmont",
+ "goldmont-plus",
"haswell",
"icelake",
"ivybridge",
@@ -55,6 +60,7 @@
"skylake",
"stoneyridge",
"tigerlake",
+ "tremont",
"whiskeylake",
},
}
@@ -168,6 +174,24 @@
"aes_ni",
"popcnt",
},
+ "goldmont": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "popcnt",
+ "movbe",
+ },
+ "goldmont-plus": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "popcnt",
+ "movbe",
+ },
"haswell": {
"ssse3",
"sse4",
@@ -257,6 +281,15 @@
"aes_ni",
"popcnt",
},
+ "tremont": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "popcnt",
+ "movbe",
+ },
"whiskeylake": {
"ssse3",
"sse4",
@@ -304,6 +337,22 @@
"aes_ni",
"popcnt",
},
+ "goldmont": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "popcnt",
+ },
+ "goldmont-plus": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "popcnt",
+ },
"haswell": {
"ssse3",
"sse4",
@@ -390,6 +439,14 @@
"aes_ni",
"popcnt",
},
+ "tremont": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "popcnt",
+ },
"whiskeylake": {
"ssse3",
"sse4",
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 122495f..0b768a7 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -16,13 +16,13 @@
import (
"bytes"
- "errors"
"fmt"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
+ "sort"
"strings"
"sync"
@@ -375,108 +375,96 @@
return []bazel.AqueryDepset{}
}
-func NewBazelContext(c *config) (BazelContext, error) {
- var modulesDefaultToBazel bool
+func GetBazelEnabledAndDisabledModules(buildMode SoongBuildMode, forceEnabled map[string]struct{}) (map[string]bool, map[string]bool) {
disabledModules := map[string]bool{}
enabledModules := map[string]bool{}
-
- switch c.BuildMode {
- case BazelProdMode:
- modulesDefaultToBazel = false
-
- for _, enabledProdModule := range allowlists.ProdMixedBuildsEnabledList {
- enabledModules[enabledProdModule] = true
+ addToStringSet := func(set map[string]bool, items []string) {
+ for _, item := range items {
+ set[item] = true
}
+ }
- for enabledAdHocModule := range c.BazelModulesForceEnabledByFlag() {
+ switch buildMode {
+ case BazelProdMode:
+ addToStringSet(enabledModules, allowlists.ProdMixedBuildsEnabledList)
+ for enabledAdHocModule := range forceEnabled {
enabledModules[enabledAdHocModule] = true
}
case BazelStagingMode:
- modulesDefaultToBazel = false
// Staging mode includes all prod modules plus all staging modules.
- for _, enabledProdModule := range allowlists.ProdMixedBuildsEnabledList {
- enabledModules[enabledProdModule] = true
- }
- for _, enabledStagingMode := range allowlists.StagingMixedBuildsEnabledList {
- enabledModules[enabledStagingMode] = true
- }
-
- for enabledAdHocModule := range c.BazelModulesForceEnabledByFlag() {
+ addToStringSet(enabledModules, allowlists.ProdMixedBuildsEnabledList)
+ addToStringSet(enabledModules, allowlists.StagingMixedBuildsEnabledList)
+ for enabledAdHocModule := range forceEnabled {
enabledModules[enabledAdHocModule] = true
}
case BazelDevMode:
- modulesDefaultToBazel = true
-
// Don't use partially-converted cc_library targets in mixed builds,
// since mixed builds would generally rely on both static and shared
// variants of a cc_library.
for staticOnlyModule := range GetBp2BuildAllowList().ccLibraryStaticOnly {
disabledModules[staticOnlyModule] = true
}
- for _, disabledDevModule := range allowlists.MixedBuildsDisabledList {
- disabledModules[disabledDevModule] = true
- }
+ addToStringSet(disabledModules, allowlists.MixedBuildsDisabledList)
default:
+ panic("Expected BazelProdMode, BazelStagingMode, or BazelDevMode")
+ }
+ return enabledModules, disabledModules
+}
+
+func GetBazelEnabledModules(buildMode SoongBuildMode) []string {
+ enabledModules, disabledModules := GetBazelEnabledAndDisabledModules(buildMode, nil)
+ enabledList := make([]string, 0, len(enabledModules))
+ for module := range enabledModules {
+ if !disabledModules[module] {
+ enabledList = append(enabledList, module)
+ }
+ }
+ sort.Strings(enabledList)
+ return enabledList
+}
+
+func NewBazelContext(c *config) (BazelContext, error) {
+ if c.BuildMode != BazelProdMode && c.BuildMode != BazelStagingMode && c.BuildMode != BazelDevMode {
return noopBazelContext{}, nil
}
- p, err := bazelPathsFromConfig(c)
- if err != nil {
- return nil, err
- }
+ enabledModules, disabledModules := GetBazelEnabledAndDisabledModules(c.BuildMode, c.BazelModulesForceEnabledByFlag())
+ paths := bazelPaths{
+ soongOutDir: c.soongOutDir,
+ }
+ var missing []string
+ vars := []struct {
+ name string
+ ptr *string
+ }{
+ {"BAZEL_HOME", &paths.homeDir},
+ {"BAZEL_PATH", &paths.bazelPath},
+ {"BAZEL_OUTPUT_BASE", &paths.outputBase},
+ {"BAZEL_WORKSPACE", &paths.workspaceDir},
+ {"BAZEL_METRICS_DIR", &paths.metricsDir},
+ {"BAZEL_DEPS_FILE", &paths.bazelDepsFile},
+ }
+ for _, v := range vars {
+ if s := c.Getenv(v.name); len(s) > 1 {
+ *v.ptr = s
+ } else {
+ missing = append(missing, v.name)
+ }
+ }
+ if len(missing) > 0 {
+ return nil, fmt.Errorf("missing required env vars to use bazel: %s", missing)
+ }
return &bazelContext{
bazelRunner: &builtinBazelRunner{},
- paths: p,
+ paths: &paths,
requests: make(map[cqueryKey]bool),
- modulesDefaultToBazel: modulesDefaultToBazel,
+ modulesDefaultToBazel: c.BuildMode == BazelDevMode,
bazelEnabledModules: enabledModules,
bazelDisabledModules: disabledModules,
}, nil
}
-func bazelPathsFromConfig(c *config) (*bazelPaths, error) {
- p := bazelPaths{
- soongOutDir: c.soongOutDir,
- }
- var missingEnvVars []string
- if len(c.Getenv("BAZEL_HOME")) > 1 {
- p.homeDir = c.Getenv("BAZEL_HOME")
- } else {
- missingEnvVars = append(missingEnvVars, "BAZEL_HOME")
- }
- if len(c.Getenv("BAZEL_PATH")) > 1 {
- p.bazelPath = c.Getenv("BAZEL_PATH")
- } else {
- missingEnvVars = append(missingEnvVars, "BAZEL_PATH")
- }
- if len(c.Getenv("BAZEL_OUTPUT_BASE")) > 1 {
- p.outputBase = c.Getenv("BAZEL_OUTPUT_BASE")
- } else {
- missingEnvVars = append(missingEnvVars, "BAZEL_OUTPUT_BASE")
- }
- if len(c.Getenv("BAZEL_WORKSPACE")) > 1 {
- p.workspaceDir = c.Getenv("BAZEL_WORKSPACE")
- } else {
- missingEnvVars = append(missingEnvVars, "BAZEL_WORKSPACE")
- }
- if len(c.Getenv("BAZEL_METRICS_DIR")) > 1 {
- p.metricsDir = c.Getenv("BAZEL_METRICS_DIR")
- } else {
- missingEnvVars = append(missingEnvVars, "BAZEL_METRICS_DIR")
- }
- if len(c.Getenv("BAZEL_DEPS_FILE")) > 1 {
- p.bazelDepsFile = c.Getenv("BAZEL_DEPS_FILE")
- } else {
- missingEnvVars = append(missingEnvVars, "BAZEL_DEPS_FILE")
- }
- if len(missingEnvVars) > 0 {
- return nil, errors.New(fmt.Sprintf("missing required env vars to use bazel: %s", missingEnvVars))
- } else {
- return &p, nil
- }
-}
-
func (p *bazelPaths) BazelMetricsDir() string {
return p.metricsDir
}
@@ -1137,7 +1125,7 @@
}
// Register bazel-owned build statements (obtained from the aquery invocation).
-func createCommand(cmd *RuleBuilderCommand, buildStatement bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx PathContext) {
+func createCommand(cmd *RuleBuilderCommand, buildStatement bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx BuilderContext) {
// executionRoot is the action cwd.
cmd.Text(fmt.Sprintf("cd '%s' &&", executionRoot))
@@ -1156,7 +1144,14 @@
}
// The actual Bazel action.
- cmd.Text(buildStatement.Command)
+ if len(buildStatement.Command) > 16*1024 {
+ commandFile := PathForBazelOut(ctx, buildStatement.OutputPaths[0]+".sh")
+ WriteFileRule(ctx, commandFile, buildStatement.Command)
+
+ cmd.Text("bash").Text(buildStatement.OutputPaths[0] + ".sh").Implicit(commandFile)
+ } else {
+ cmd.Text(buildStatement.Command)
+ }
for _, outputPath := range buildStatement.OutputPaths {
cmd.ImplicitOutput(PathForBazelOut(ctx, outputPath))
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
index bc16cb5..10bbf31 100644
--- a/android/bazel_handler_test.go
+++ b/android/bazel_handler_test.go
@@ -129,7 +129,8 @@
}
cmd := RuleBuilderCommand{}
- createCommand(&cmd, got[0], "test/exec_root", "test/bazel_out", PathContextForTesting(TestConfig("out", nil, "", nil)))
+ ctx := builderContextForTests{PathContextForTesting(TestConfig("out", nil, "", nil))}
+ createCommand(&cmd, got[0], "test/exec_root", "test/bazel_out", ctx)
if actual, expected := cmd.buf.String(), testCase.command; expected != actual {
t.Errorf("expected: [%s], actual: [%s]", expected, actual)
}
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index b2ea22f..3b159d3 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -458,6 +458,11 @@
return fmt.Sprintf("//%s:%s", moduleDir, moduleName)
}
+// ModuleFromBazelLabel reverses the logic in bp2buildModuleLabel
+func ModuleFromBazelLabel(label string) string {
+ return strings.Split(label, ":")[1]
+}
+
// BazelOutPath is a Bazel output path compatible to be used for mixed builds within Soong/Ninja.
type BazelOutPath struct {
OutputPath
diff --git a/android/config.go b/android/config.go
index 9d9ab30..9c1a484 100644
--- a/android/config.go
+++ b/android/config.go
@@ -21,7 +21,6 @@
"bytes"
"encoding/json"
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"reflect"
@@ -70,6 +69,26 @@
type SoongBuildMode int
+type CmdArgs struct {
+ bootstrap.Args
+ RunGoTests bool
+ OutDir string
+ SoongOutDir string
+
+ SymlinkForestMarker string
+ Bp2buildMarker string
+ BazelQueryViewDir string
+ BazelApiBp2buildDir string
+ ModuleGraphFile string
+ ModuleActionsFile string
+ DocFile string
+
+ BazelMode bool
+ BazelModeDev bool
+ BazelModeStaging bool
+ BazelForceEnabledModules string
+}
+
// Build modes that soong_build can run as.
const (
// Don't use bazel at all during module analysis.
@@ -307,7 +326,7 @@
return fmt.Errorf("cannot marshal config data: %s", err.Error())
}
- f, err := ioutil.TempFile(filepath.Dir(filename), "config")
+ f, err := os.CreateTemp(filepath.Dir(filename), "config")
if err != nil {
return fmt.Errorf("cannot create empty config file %s: %s", filename, err.Error())
}
@@ -404,20 +423,19 @@
// NewConfig creates a new Config object. The srcDir argument specifies the path
// to the root source directory. It also loads the config file, if found.
-func NewConfig(moduleListFile string, buildMode SoongBuildMode, runGoTests bool, outDir, soongOutDir string, availableEnv map[string]string,
- bazelForceEnabledModules []string) (Config, error) {
+func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) {
// Make a config with default options.
config := &config{
- ProductVariablesFileName: filepath.Join(soongOutDir, productVariablesFileName),
+ ProductVariablesFileName: filepath.Join(cmdArgs.SoongOutDir, productVariablesFileName),
env: availableEnv,
- outDir: outDir,
- soongOutDir: soongOutDir,
- runGoTests: runGoTests,
+ outDir: cmdArgs.OutDir,
+ soongOutDir: cmdArgs.SoongOutDir,
+ runGoTests: cmdArgs.RunGoTests,
multilibConflicts: make(map[ArchType]bool),
- moduleListFile: moduleListFile,
+ moduleListFile: cmdArgs.ModuleListFile,
fs: pathtools.NewOsFs(absSrcDir),
mixedBuildDisabledModules: make(map[string]struct{}),
mixedBuildEnabledModules: make(map[string]struct{}),
@@ -430,7 +448,7 @@
// Soundness check of the build and source directories. This won't catch strange
// configurations with symlinks, but at least checks the obvious case.
- absBuildDir, err := filepath.Abs(soongOutDir)
+ absBuildDir, err := filepath.Abs(cmdArgs.SoongOutDir)
if err != nil {
return Config{}, err
}
@@ -450,7 +468,7 @@
return Config{}, err
}
- KatiEnabledMarkerFile := filepath.Join(soongOutDir, ".soong.kati_enabled")
+ KatiEnabledMarkerFile := filepath.Join(cmdArgs.SoongOutDir, ".soong.kati_enabled")
if _, err := os.Stat(absolutePath(KatiEnabledMarkerFile)); err == nil {
config.katiEnabled = true
}
@@ -503,11 +521,32 @@
config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
}
- config.BuildMode = buildMode
+ if cmdArgs.SymlinkForestMarker != "" {
+ config.BuildMode = SymlinkForest
+ } else if cmdArgs.Bp2buildMarker != "" {
+ config.BuildMode = Bp2build
+ } else if cmdArgs.BazelQueryViewDir != "" {
+ config.BuildMode = GenerateQueryView
+ } else if cmdArgs.BazelApiBp2buildDir != "" {
+ config.BuildMode = ApiBp2build
+ } else if cmdArgs.ModuleGraphFile != "" {
+ config.BuildMode = GenerateModuleGraph
+ } else if cmdArgs.DocFile != "" {
+ config.BuildMode = GenerateDocFile
+ } else if cmdArgs.BazelModeDev {
+ config.BuildMode = BazelDevMode
+ } else if cmdArgs.BazelMode {
+ config.BuildMode = BazelProdMode
+ } else if cmdArgs.BazelModeStaging {
+ config.BuildMode = BazelStagingMode
+ } else {
+ config.BuildMode = AnalysisNoBazel
+ }
+
config.BazelContext, err = NewBazelContext(config)
config.Bp2buildPackageConfig = GetBp2BuildAllowList()
- for _, module := range bazelForceEnabledModules {
+ for _, module := range strings.Split(cmdArgs.BazelForceEnabledModules, ",") {
config.bazelForceEnabledModules[module] = struct{}{}
}
@@ -1150,7 +1189,7 @@
return nil, nil
}
ctx.AddNinjaFileDeps(path.String())
- return ioutil.ReadFile(absolutePath(path.String()))
+ return os.ReadFile(absolutePath(path.String()))
}
func (c *deviceConfig) WithDexpreopt() bool {
@@ -1169,7 +1208,7 @@
return c.multilibConflicts[arch]
}
-func (c *config) PrebuiltHiddenApiDir(ctx PathContext) string {
+func (c *config) PrebuiltHiddenApiDir(_ PathContext) string {
return String(c.productVariables.PrebuiltHiddenApiDir)
}
diff --git a/android/gen_notice.go b/android/gen_notice.go
index 28fddbc..091345b 100644
--- a/android/gen_notice.go
+++ b/android/gen_notice.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "path/filepath"
"strings"
"github.com/google/blueprint/proptools"
@@ -73,6 +74,7 @@
out(ctx, gm.output, ctx.ModuleName(gm),
proptools.StringDefault(gm.properties.ArtifactName, defaultName),
[]string{
+ filepath.Join(ctx.Config().OutDir(), "target", "product", ctx.Config().DeviceName()) + "/",
ctx.Config().OutDir() + "/",
ctx.Config().SoongOutDir() + "/",
}, modules...)
diff --git a/android/module.go b/android/module.go
index 681f724..bf9737a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -27,7 +27,6 @@
"text/scanner"
"android/soong/bazel"
-
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
diff --git a/android/proto.go b/android/proto.go
index 8204f77..09e50c8 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -234,10 +234,13 @@
}
}
+ tags := ApexAvailableTags(ctx.Module())
+
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
- CommonAttributes{Name: info.Name},
- &attrs)
+ CommonAttributes{Name: info.Name, Tags: tags},
+ &attrs,
+ )
protoLibraries.Add(&bazel.Label{
Label: ":" + info.Name,
diff --git a/android/register.go b/android/register.go
index 6cfc205..9a3d3aa 100644
--- a/android/register.go
+++ b/android/register.go
@@ -35,7 +35,7 @@
// tests.
componentName() string
- // register registers this component in the supplied context.
+ // registers this component in the supplied context.
register(ctx *Context)
}
@@ -124,7 +124,7 @@
return func() blueprint.Singleton {
singleton := factory()
if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
- registerSingletonMakeVarsProvider(ctx.config, makevars)
+ ctx.registerSingletonMakeVarsProvider(makevars)
}
return &singletonAdaptor{Singleton: singleton}
}
@@ -165,29 +165,30 @@
return ctx
}
-// RegisterForBazelConversion registers an alternate shadow pipeline of
-// singletons, module types and mutators to register for converting Blueprint
-// files to semantically equivalent BUILD files.
-func (ctx *Context) RegisterForBazelConversion() {
+// Helper function to register the module types used in bp2build and
+// api_bp2build.
+func registerModuleTypes(ctx *Context) {
for _, t := range moduleTypes {
t.register(ctx)
}
-
// Required for SingletonModule types, even though we are not using them.
for _, t := range singletons {
t.register(ctx)
}
+}
+// RegisterForBazelConversion registers an alternate shadow pipeline of
+// singletons, module types and mutators to register for converting Blueprint
+// files to semantically equivalent BUILD files.
+func (ctx *Context) RegisterForBazelConversion() {
+ registerModuleTypes(ctx)
RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators)
}
// RegisterForApiBazelConversion is similar to RegisterForBazelConversion except that
// it only generates API targets in the generated workspace
func (ctx *Context) RegisterForApiBazelConversion() {
- for _, t := range moduleTypes {
- t.register(ctx)
- }
-
+ registerModuleTypes(ctx)
RegisterMutatorsForApiBazelConversion(ctx, bp2buildPreArchMutators)
}
@@ -207,6 +208,14 @@
singletons.registerAll(ctx)
}
+func (ctx *Context) Config() Config {
+ return ctx.config
+}
+
+func (ctx *Context) registerSingletonMakeVarsProvider(makevars SingletonMakeVarsProvider) {
+ registerSingletonMakeVarsProvider(ctx.config, makevars)
+}
+
func collateGloballyRegisteredSingletons() sortableComponents {
allSingletons := append(sortableComponents(nil), singletons...)
allSingletons = append(allSingletons,
@@ -334,7 +343,7 @@
PreArchMutators(f)
}
-func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
+func (ctx *initRegistrationContext) HardCodedPreArchMutators(_ RegisterMutatorFunc) {
// Nothing to do as the mutators are hard code in preArch in mutator.go
}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 0fc971b..b76f6bd 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -154,9 +154,7 @@
if a.primaryApexType && !symbolFilesNotNeeded {
fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated)
}
- if len(fi.symlinks) > 0 {
- fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " "))
- }
+ android.AndroidMkEmitAssignList(w, "LOCAL_MODULE_SYMLINKS", fi.symlinks)
newDataPaths := []android.DataPath{}
for _, path := range fi.dataPaths {
dataOutPath := modulePath + ":" + path.SrcPath.Rel()
@@ -165,9 +163,7 @@
seenDataOutPaths[dataOutPath] = true
}
}
- if len(newDataPaths) > 0 {
- fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(android.AndroidMkDataPaths(newDataPaths), " "))
- }
+ android.AndroidMkEmitAssignList(w, "LOCAL_TEST_DATA", android.AndroidMkDataPaths(newDataPaths))
} else {
modulePath = pathWhenActivated
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", pathWhenActivated)
@@ -236,9 +232,7 @@
// we will have foo.apk.apk
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.stem(), ".apk"))
if app, ok := fi.module.(*java.AndroidApp); ok {
- if jniCoverageOutputs := app.JniCoverageOutputs(); len(jniCoverageOutputs) > 0 {
- fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", strings.Join(jniCoverageOutputs.Strings(), " "))
- }
+ android.AndroidMkEmitAssignList(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE", app.JniCoverageOutputs().Strings())
if jniLibSymbols := app.JNISymbolsInstalls(modulePath); len(jniLibSymbols) > 0 {
fmt.Fprintln(w, "LOCAL_SOONG_JNI_LIBS_SYMBOLS :=", jniLibSymbols.String())
}
@@ -275,7 +269,7 @@
}
for _, name := range commonProperties {
if value, ok := apexAndroidMkData.Entries.EntryMap[name]; ok {
- fmt.Fprintln(w, name+" := "+strings.Join(value, " "))
+ android.AndroidMkEmitAssignList(w, name, value)
}
}
@@ -285,9 +279,7 @@
for _, o := range a.overridableProperties.Overrides {
patterns = append(patterns, "%."+o+a.suffix)
}
- if len(patterns) > 0 {
- fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(patterns, " "))
- }
+ android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", patterns)
}
// File_contexts of flattened APEXes should be merged into file_contexts.bin
@@ -306,13 +298,6 @@
}
func (a *apexBundle) writeRequiredModules(w io.Writer, moduleNames []string) {
- if len(moduleNames) > 0 {
- fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(moduleNames, " "))
- }
- if len(a.requiredDeps) > 0 {
- fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.requiredDeps, " "))
- }
-
var required []string
var targetRequired []string
var hostRequired []string
@@ -324,16 +309,9 @@
targetRequired = append(targetRequired, fi.targetRequiredModuleNames...)
hostRequired = append(hostRequired, fi.hostRequiredModuleNames...)
}
-
- if len(required) > 0 {
- fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(required, " "))
- }
- if len(targetRequired) > 0 {
- fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES +=", strings.Join(targetRequired, " "))
- }
- if len(hostRequired) > 0 {
- fmt.Fprintln(w, "LOCAL_HOST_REQUIRED_MODULES +=", strings.Join(hostRequired, " "))
- }
+ android.AndroidMkEmitAssignList(w, "LOCAL_REQUIRED_MODULES", moduleNames, a.requiredDeps, required)
+ android.AndroidMkEmitAssignList(w, "LOCAL_TARGET_REQUIRED_MODULES", targetRequired)
+ android.AndroidMkEmitAssignList(w, "LOCAL_HOST_REQUIRED_MODULES", hostRequired)
}
func (a *apexBundle) androidMkForType() android.AndroidMkData {
@@ -383,13 +361,11 @@
}
for _, name := range commonProperties {
if value, ok := data.Entries.EntryMap[name]; ok {
- fmt.Fprintln(w, name+" := "+strings.Join(value, " "))
+ android.AndroidMkEmitAssignList(w, name, value)
}
}
- if len(a.overridableProperties.Overrides) > 0 {
- fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(a.overridableProperties.Overrides, " "))
- }
+ android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", a.overridableProperties.Overrides)
a.writeRequiredModules(w, moduleNames)
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
@@ -397,10 +373,7 @@
if apexType == imageApex {
fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
}
- if len(a.lintReports) > 0 {
- fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).LINT_REPORTS :=",
- strings.Join(a.lintReports.Strings(), " "))
- }
+ android.AndroidMkEmitAssignList(w, "ALL_MODULES.$(my_register_name).LINT_REPORTS", a.lintReports.Strings())
if a.installedFilesFile != nil {
goal := "checkbuild"
diff --git a/apex/apex.go b/apex/apex.go
index 8e1783e..36ce658 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -734,12 +734,14 @@
}
}
-// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
-// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
-func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
- deviceConfig := ctx.DeviceConfig()
+// getImageVariationPair returns a pair for the image variation name as its
+// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
+// suffix indicates the vndk version when it's vendor or product.
+// getImageVariation can simply join the result of this function to get the
+// image variation name.
+func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
if a.vndkApex {
- return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
+ return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
}
var prefix string
@@ -757,10 +759,17 @@
vndkVersion = deviceConfig.PlatformVndkVersion()
}
if vndkVersion != "" {
- return prefix + vndkVersion
+ return prefix, vndkVersion
}
- return android.CoreVariation // The usual case
+ return android.CoreVariation, "" // The usual case
+}
+
+// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
+// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
+func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
+ prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
+ return prefix + vndkVersion
}
func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -1897,6 +1906,12 @@
a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[0])
a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyInfo[1])
+ // Ensure ApexInfo.RequiresLibs are installed as part of a bundle build
+ for _, bazelLabel := range outputs.RequiresLibs {
+ // convert Bazel label back to Soong module name
+ a.requiredDeps = append(a.requiredDeps, android.ModuleFromBazelLabel(bazelLabel))
+ }
+
apexType := a.properties.ApexType
switch apexType {
case imageApex:
@@ -3078,31 +3093,7 @@
// Module separator
//
m["com.android.btservices"] = []string{
- "bluetooth-protos-lite",
- "internal_include_headers",
- "libaudio-a2dp-hw-utils",
- "libaudio-hearing-aid-hw-utils",
- "libbluetooth",
- "libbluetooth-types",
- "libbluetooth-types-header",
- "libbluetooth_gd",
- "libbluetooth_headers",
- "libbluetooth_jni",
- "libbt-audio-hal-interface",
- "libbt-bta",
- "libbt-common",
- "libbt-hci",
- "libbt-platform-protos-lite",
- "libbt-protos-lite",
- "libbt-sbc-decoder",
- "libbt-sbc-encoder",
- "libbt-stack",
- "libbt-utils",
- "libbtcore",
- "libbtdevice",
- "libbte",
- "libbtif",
- "libchrome",
+ // empty
}
//
// Module separator
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 883c3c8..c0bdfc4 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2997,7 +2997,7 @@
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += libc.vendor libm.vendor libdl.vendor\n")
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++.vendor.myapex:64 mylib.vendor.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex libc.vendor libm.vendor libdl.vendor\n")
}
func TestAndroidMkWritesCommonProperties(t *testing.T) {
@@ -4130,6 +4130,41 @@
ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n")
}
+func TestOverrideApexManifestDefaultVersion(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ apex_name: "com.android.myapex",
+ native_shared_libs: ["mylib"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+ `, android.FixtureMergeEnv(map[string]string{
+ "OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234",
+ }))
+
+ module := ctx.ModuleForTests("myapex", "android_common_com.android.myapex_image")
+ apexManifestRule := module.Rule("apexManifestRule")
+ ensureContains(t, apexManifestRule.Args["default_version"], "1234")
+}
+
func TestCompileMultilibProp(t *testing.T) {
testCases := []struct {
compileMultiLibProp string
@@ -5664,7 +5699,7 @@
var builder strings.Builder
mk.Custom(&builder, ab.Name(), "TARGET_", "", mk)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += myapex.flattened")
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := apex_manifest.pb.myapex apex_pubkey.myapex myapex.flattened\n")
}
func TestErrorsIfDepsAreNotEnabled(t *testing.T) {
@@ -7018,9 +7053,9 @@
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += a b\n")
- ensureContains(t, androidMk, "LOCAL_HOST_REQUIRED_MODULES += c d\n")
- ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES += e f\n")
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex a b\n")
+ ensureContains(t, androidMk, "LOCAL_HOST_REQUIRED_MODULES := c d\n")
+ ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES := e f\n")
}
func TestSymlinksFromApexToSystem(t *testing.T) {
@@ -7202,7 +7237,7 @@
ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n")
ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n")
// `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib`
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += mylib.myapex:64 myotherlib:64 apex_manifest.pb.myapex apex_pubkey.myapex\n")
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 myotherlib:64 apex_manifest.pb.myapex apex_pubkey.myapex\n")
}
func TestApexWithJniLibs(t *testing.T) {
@@ -8715,7 +8750,7 @@
// The make level dependency needs to be on otherlib - prebuilt_otherlib isn't
// a thing there.
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherlib\n")
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++:64 mylib.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex otherlib\n")
}
func TestExcludeDependency(t *testing.T) {
@@ -9109,7 +9144,7 @@
var builder strings.Builder
data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex")
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex apex_manifest.pb.myapex apex_pubkey.myapex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex\n")
}
func TestAndroidMk_DexpreoptBuiltInstalledForApex_Prebuilt(t *testing.T) {
@@ -9185,7 +9220,7 @@
var builder strings.Builder
data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherapex")
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex apex_manifest.pb.myapex apex_pubkey.myapex otherapex")
}
func TestAndroidMk_RequiredDeps(t *testing.T) {
@@ -9209,7 +9244,7 @@
var builder strings.Builder
data.Custom(&builder, bundle.BaseModuleName(), "TARGET_", "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += foo")
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := apex_manifest.pb.myapex apex_pubkey.myapex foo\n")
flattenedBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
flattenedBundle.requiredDeps = append(flattenedBundle.requiredDeps, "foo")
@@ -9217,7 +9252,7 @@
var flattenedBuilder strings.Builder
flattenedData.Custom(&flattenedBuilder, flattenedBundle.BaseModuleName(), "TARGET_", "", flattenedData)
flattenedAndroidMk := flattenedBuilder.String()
- ensureContains(t, flattenedAndroidMk, "LOCAL_REQUIRED_MODULES += foo")
+ ensureContains(t, flattenedAndroidMk, "LOCAL_REQUIRED_MODULES := apex_manifest.pb.myapex.flattened apex_pubkey.myapex.flattened foo\n")
}
func TestApexOutputFileProducer(t *testing.T) {
@@ -9800,11 +9835,11 @@
JavaSymbolsUsedByApex: "foo_using.xml",
BundleFile: "apex_bundle.zip",
InstalledFiles: "installed-files.txt",
+ RequiresLibs: []string{"//path/c:c", "//path/d:d"},
// unused
PackageName: "pkg_name",
ProvidesLibs: []string{"a", "b"},
- RequiresLibs: []string{"c", "d"},
},
},
}
@@ -9860,4 +9895,7 @@
if w := "$(call dist-for-goals,checkbuild,out/bazel/execroot/__main__/installed-files.txt:foo-installed-files.txt)"; !strings.Contains(data, w) {
t.Errorf("Expected %q in androidmk data, but did not find %q", w, data)
}
+ if w := "LOCAL_REQUIRED_MODULES := c d"; !strings.Contains(data, w) {
+ t.Errorf("Expected %q in androidmk data, but did not find it in %q", w, data)
+ }
}
diff --git a/apex/builder.go b/apex/builder.go
index 9e368b6..82a523c 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -235,7 +235,17 @@
optCommands = append(optCommands, "-a jniLibs "+strings.Join(jniLibs, " "))
}
+ if android.InList(":vndk", requireNativeLibs) {
+ if _, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig()); vndkVersion != "" {
+ optCommands = append(optCommands, "-v vndkVersion "+vndkVersion)
+ }
+ }
+
manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json")
+ defaultVersion := android.DefaultUpdatableModuleVersion
+ if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
+ defaultVersion = override
+ }
ctx.Build(pctx, android.BuildParams{
Rule: apexManifestRule,
Input: src,
@@ -243,7 +253,7 @@
Args: map[string]string{
"provideNativeLibs": strings.Join(provideNativeLibs, " "),
"requireNativeLibs": strings.Join(requireNativeLibs, " "),
- "default_version": android.DefaultUpdatableModuleVersion,
+ "default_version": defaultVersion,
"opt": strings.Join(optCommands, " "),
},
})
diff --git a/apex/deapexer.go b/apex/deapexer.go
index 8c9030a..fed9cd1 100644
--- a/apex/deapexer.go
+++ b/apex/deapexer.go
@@ -140,6 +140,8 @@
Tool(android.PathForSource(ctx, "build/soong/scripts/unpack-prebuilt-apex.sh")).
BuiltTool("deapexer").
BuiltTool("debugfs").
+ BuiltTool("blkid").
+ BuiltTool("fsck.erofs").
Input(p.inputApex).
Text(deapexerOutput.String())
for _, p := range exportedPaths {
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 6fdd50a..0997a68 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -830,6 +830,7 @@
srcsSupplier := func(ctx android.BaseModuleContext, prebuilt android.Module) []string {
return p.properties.prebuiltSrcs(ctx)
}
+ defaultAllowPrerelease := ctx.Config().IsEnvTrue("SOONG_ALLOW_PRERELEASE_APEXES")
apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set")
p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base())
// Filter out NativeBridge archs (b/260115309)
@@ -842,7 +843,7 @@
Output: p.extractedApex,
Args: map[string]string{
"abis": strings.Join(abis, ","),
- "allow-prereleased": strconv.FormatBool(proptools.Bool(p.properties.Prerelease)),
+ "allow-prereleased": strconv.FormatBool(proptools.BoolDefault(p.properties.Prerelease, defaultAllowPrerelease)),
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
},
})
@@ -915,6 +916,15 @@
return false
}
+func (a *ApexSet) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return android.Paths{a.outputApex}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+}
+
// prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex.
func apexSetFactory() android.Module {
module := &ApexSet{}
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 118a3a9..9feb82b 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -227,7 +227,7 @@
// - The function body should not be indented outside of its own scope.
func (g getApexInfoType) StarlarkFunctionBody() string {
return `
-info = providers(target).get("//build/bazel/rules/apex:apex.bzl%ApexInfo")
+info = providers(target).get("//build/bazel/rules/apex:apex_info.bzl%ApexInfo")
if not info:
fail("%s did not provide ApexInfo" % id_string)
bundle_key_info = info.bundle_key_info
diff --git a/bazel/properties.go b/bazel/properties.go
index ee9609a..6921984 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -1207,6 +1207,11 @@
// The configured attribute label list Values. Optional
// a map of independent configurability axes
ConfigurableValues configurableStringLists
+
+ // If a property has struct tag "variant_prepend", this value should
+ // be set to True, so that when bp2build generates BUILD.bazel, variant
+ // properties(select ...) come before general properties.
+ Prepend bool
}
// IsEmpty returns true if the attribute has no values under any configuration.
@@ -1273,6 +1278,9 @@
// Append appends all values, including os and arch specific ones, from another
// StringListAttribute to this StringListAttribute
func (sla *StringListAttribute) Append(other StringListAttribute) *StringListAttribute {
+ if sla.Prepend != other.Prepend {
+ panic(fmt.Errorf("StringListAttribute could not be appended because it has different prepend value"))
+ }
sla.Value = append(sla.Value, other.Value...)
if sla.ConfigurableValues == nil {
sla.ConfigurableValues = make(configurableStringLists)
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 7c9af1a..2e01789 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -51,6 +51,7 @@
"cc_prebuilt_library_conversion_test.go",
"cc_prebuilt_library_shared_test.go",
"cc_prebuilt_library_static_test.go",
+ "cc_prebuilt_object_conversion_test.go",
"cc_test_conversion_test.go",
"cc_yasm_conversion_test.go",
"conversion_test.go",
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index a1e83d8..ee6e5b8 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -3603,6 +3603,89 @@
})
}
+func TestCcLibraryWithAfdoEnabled(t *testing.T) {
+ bp := `
+cc_library {
+ name: "foo",
+ afdo: true,
+ include_build_directory: false,
+}`
+
+ // TODO(b/260714900): Add test case for arch-specific afdo profile
+ testCases := []struct {
+ description string
+ filesystem map[string]string
+ expectedBazelTargets []string
+ }{
+ {
+ description: "cc_library with afdo enabled and existing profile",
+ filesystem: map[string]string{
+ "vendor/google_data/pgo_profile/sampling/BUILD": "",
+ "vendor/google_data/pgo_profile/sampling/foo.afdo": "",
+ },
+ expectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "fdo_profile": `"//vendor/google_data/pgo_profile/sampling:foo"`,
+ }),
+ },
+ },
+ {
+ description: "cc_library with afdo enabled and existing profile in AOSP",
+ filesystem: map[string]string{
+ "toolchain/pgo-profiles/sampling/BUILD": "",
+ "toolchain/pgo-profiles/sampling/foo.afdo": "",
+ },
+ expectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "fdo_profile": `"//toolchain/pgo-profiles/sampling:foo"`,
+ }),
+ },
+ },
+ {
+ description: "cc_library with afdo enabled but profile filename doesn't match with module name",
+ filesystem: map[string]string{
+ "toolchain/pgo-profiles/sampling/BUILD": "",
+ "toolchain/pgo-profiles/sampling/bar.afdo": "",
+ },
+ expectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{}),
+ },
+ },
+ {
+ description: "cc_library with afdo enabled but profile doesn't exist",
+ expectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{}),
+ },
+ },
+ {
+ description: "cc_library with afdo enabled and existing profile but BUILD file doesn't exist",
+ filesystem: map[string]string{
+ "vendor/google_data/pgo_profile/sampling/foo.afdo": "",
+ },
+ expectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{}),
+ },
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.description, func(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ ExpectedBazelTargets: testCase.expectedBazelTargets,
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Description: testCase.description,
+ Blueprint: binaryReplacer.Replace(bp),
+ Filesystem: testCase.filesystem,
+ })
+ })
+ }
+}
+
func TestCcLibraryHeaderAbiChecker(t *testing.T) {
runCcLibraryTestCase(t, Bp2buildTestCase{
Description: "cc_library with header abi checker",
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 7d9db6f..686c9d5 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -107,15 +107,15 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
- "export_includes": `[
- "dir-1",
- "dir-2",
- ] + select({
+ "export_includes": `select({
"//build/bazel/platforms/arch:arm64": ["arch_arm64_exported_include_dir"],
"//build/bazel/platforms/arch:x86": ["arch_x86_exported_include_dir"],
"//build/bazel/platforms/arch:x86_64": ["arch_x86_64_exported_include_dir"],
"//conditions:default": [],
- })`,
+ }) + [
+ "dir-1",
+ "dir-2",
+ ]`,
"sdk_version": `"current"`,
"min_sdk_version": `"29"`,
}),
@@ -340,16 +340,16 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
- "export_system_includes": `["shared_include_dir"] + select({
- "//build/bazel/platforms/arch:arm": ["arm_include_dir"],
- "//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
- "//conditions:default": [],
- }) + select({
+ "export_system_includes": `select({
"//build/bazel/platforms/os:android": ["android_include_dir"],
"//build/bazel/platforms/os:darwin": ["darwin_include_dir"],
"//build/bazel/platforms/os:linux": ["linux_include_dir"],
"//conditions:default": [],
- })`,
+ }) + select({
+ "//build/bazel/platforms/arch:arm": ["arm_include_dir"],
+ "//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
+ "//conditions:default": [],
+ }) + ["shared_include_dir"]`,
}),
},
})
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index b8dc690..1377c6b 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -24,6 +24,7 @@
func registerCcObjectModuleTypes(ctx android.RegistrationContext) {
// Always register cc_defaults module factory
ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
+ ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
}
func runCcObjectTestCase(t *testing.T, tc Bp2buildTestCase) {
@@ -147,7 +148,7 @@
"system_dynamic_deps": `[]`,
}), MakeBazelTarget("cc_object", "foo", AttrNameToString{
"copts": `["-fno-addrsig"]`,
- "deps": `[":bar"]`,
+ "objs": `[":bar"]`,
"srcs": `["a/b/c.c"]`,
"system_dynamic_deps": `[]`,
}),
@@ -362,7 +363,7 @@
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_object", "foo", AttrNameToString{
"copts": `["-fno-addrsig"]`,
- "deps": `select({
+ "objs": `select({
"//build/bazel/platforms/arch:arm": [":arm_obj"],
"//build/bazel/platforms/arch:x86": [":x86_obj"],
"//build/bazel/platforms/arch:x86_64": [":x86_64_obj"],
@@ -422,3 +423,56 @@
},
})
}
+
+func TestCcObjectHeaderLib(t *testing.T) {
+ runCcObjectTestCase(t, Bp2buildTestCase{
+ Description: "simple cc_object generates cc_object with include header dep",
+ Filesystem: map[string]string{
+ "a/b/foo.h": "",
+ "a/b/bar.h": "",
+ "a/b/exclude.c": "",
+ "a/b/c.c": "",
+ },
+ Blueprint: `cc_object {
+ name: "foo",
+ header_libs: ["libheaders"],
+ system_shared_libs: [],
+ cflags: [
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ],
+ srcs: [
+ "a/b/*.c"
+ ],
+ exclude_srcs: ["a/b/exclude.c"],
+ sdk_version: "current",
+ min_sdk_version: "29",
+}
+
+cc_library_headers {
+ name: "libheaders",
+ export_include_dirs: ["include"],
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_object", "foo", AttrNameToString{
+ "copts": `[
+ "-fno-addrsig",
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ]`,
+ "deps": `[":libheaders"]`,
+ "local_includes": `["."]`,
+ "srcs": `["a/b/c.c"]`,
+ "system_dynamic_deps": `[]`,
+ "sdk_version": `"current"`,
+ "min_sdk_version": `"29"`,
+ }),
+ MakeBazelTarget("cc_library_headers", "libheaders", AttrNameToString{
+ "export_includes": `["include"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_prebuilt_object_conversion_test.go b/bp2build/cc_prebuilt_object_conversion_test.go
new file mode 100644
index 0000000..903c816
--- /dev/null
+++ b/bp2build/cc_prebuilt_object_conversion_test.go
@@ -0,0 +1,101 @@
+// Copyright 2022 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 bp2build
+
+import (
+ "fmt"
+ "testing"
+
+ "android/soong/cc"
+)
+
+func runCcPrebuiltObjectTestCase(t *testing.T, testCase Bp2buildTestCase) {
+ t.Helper()
+ description := fmt.Sprintf("cc_prebuilt_object: %s", testCase.Description)
+ testCase.ModuleTypeUnderTest = "cc_prebuilt_object"
+ testCase.ModuleTypeUnderTestFactory = cc.PrebuiltObjectFactory
+ testCase.Description = description
+ t.Run(description, func(t *testing.T) {
+ t.Helper()
+ RunBp2BuildTestCaseSimple(t, testCase)
+ })
+}
+
+func TestPrebuiltObject(t *testing.T) {
+ runCcPrebuiltObjectTestCase(t,
+ Bp2buildTestCase{
+ Description: "simple",
+ Filesystem: map[string]string{
+ "obj.o": "",
+ },
+ Blueprint: `
+cc_prebuilt_object {
+ name: "objtest",
+ srcs: ["obj.o"],
+ bazel_module: { bp2build_available: true },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_prebuilt_object", "objtest", AttrNameToString{
+ "src": `"obj.o"`,
+ })},
+ })
+}
+
+func TestPrebuiltObjectWithArchVariance(t *testing.T) {
+ runCcPrebuiltObjectTestCase(t,
+ Bp2buildTestCase{
+ Description: "with arch variance",
+ Filesystem: map[string]string{
+ "obja.o": "",
+ "objb.o": "",
+ },
+ Blueprint: `
+cc_prebuilt_object {
+ name: "objtest",
+ arch: {
+ arm64: { srcs: ["obja.o"], },
+ arm: { srcs: ["objb.o"], },
+ },
+ bazel_module: { bp2build_available: true },
+}`, ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_prebuilt_object", "objtest", AttrNameToString{
+ "src": `select({
+ "//build/bazel/platforms/arch:arm": "objb.o",
+ "//build/bazel/platforms/arch:arm64": "obja.o",
+ "//conditions:default": None,
+ })`,
+ }),
+ },
+ })
+}
+
+func TestPrebuiltObjectMultipleSrcsFails(t *testing.T) {
+ runCcPrebuiltObjectTestCase(t,
+ Bp2buildTestCase{
+ Description: "fails because multiple sources",
+ Filesystem: map[string]string{
+ "obja": "",
+ "objb": "",
+ },
+ Blueprint: `
+cc_prebuilt_object {
+ name: "objtest",
+ srcs: ["obja.o", "objb.o"],
+ bazel_module: { bp2build_available: true },
+}`,
+ ExpectedErr: fmt.Errorf("Expected at most one source file"),
+ })
+}
+
+// TODO: nosrcs test
diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go
index 8c2d30d..b20f6ff 100644
--- a/bp2build/cc_test_conversion_test.go
+++ b/bp2build/cc_test_conversion_test.go
@@ -26,6 +26,7 @@
type ccTestBp2buildTestCase struct {
description string
blueprint string
+ filesystem map[string]string
targets []testBazelTarget
}
@@ -41,12 +42,12 @@
func runCcTestTestCase(t *testing.T, testCase ccTestBp2buildTestCase) {
t.Helper()
moduleTypeUnderTest := "cc_test"
-
description := fmt.Sprintf("%s %s", moduleTypeUnderTest, testCase.description)
t.Run(description, func(t *testing.T) {
t.Helper()
RunBp2BuildTestCase(t, registerCcTestModuleTypes, Bp2buildTestCase{
ExpectedBazelTargets: generateBazelTargetsForTest(testCase.targets, android.HostAndDeviceSupported),
+ Filesystem: testCase.filesystem,
ModuleTypeUnderTest: moduleTypeUnderTest,
ModuleTypeUnderTestFactory: cc.TestFactory,
Description: description,
@@ -172,3 +173,90 @@
},
})
}
+
+func TestCcTest_TestConfig(t *testing.T) {
+ runCcTestTestCase(t, ccTestBp2buildTestCase{
+ description: "cc test that sets a test_config",
+ filesystem: map[string]string{
+ "test_config.xml": "",
+ },
+ blueprint: `
+cc_test {
+ name: "mytest",
+ srcs: ["test.cpp"],
+ test_config: "test_config.xml",
+}
+`,
+ targets: []testBazelTarget{
+ {"cc_test", "mytest", AttrNameToString{
+ "gtest": "True",
+ "isolated": "True",
+ "local_includes": `["."]`,
+ "srcs": `["test.cpp"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ "test_config": `"test_config.xml"`,
+ },
+ },
+ },
+ })
+}
+
+func TestCcTest_TestConfigAndroidTestXML(t *testing.T) {
+ runCcTestTestCase(t, ccTestBp2buildTestCase{
+ description: "cc test that defaults to test config AndroidTest.xml",
+ filesystem: map[string]string{
+ "AndroidTest.xml": "",
+ },
+ blueprint: `
+cc_test {
+ name: "mytest",
+ srcs: ["test.cpp"],
+}
+`,
+ targets: []testBazelTarget{
+ {"cc_test", "mytest", AttrNameToString{
+ "gtest": "True",
+ "isolated": "True",
+ "local_includes": `["."]`,
+ "srcs": `["test.cpp"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ "test_config": `"AndroidTest.xml"`,
+ },
+ },
+ },
+ })
+}
+
+func TestCcTest_TestConfigTemplateOptions(t *testing.T) {
+ runCcTestTestCase(t, ccTestBp2buildTestCase{
+ description: "cc test that sets test config template attributes",
+ filesystem: map[string]string{
+ "test_config_template.xml": "",
+ },
+ blueprint: `
+cc_test {
+ name: "mytest",
+ srcs: ["test.cpp"],
+ test_config_template: "test_config_template.xml",
+ auto_gen_config: true,
+}
+`,
+ targets: []testBazelTarget{
+ {"cc_test", "mytest", AttrNameToString{
+ "auto_generate_test_config": "True",
+ "gtest": "True",
+ "isolated": "True",
+ "local_includes": `["."]`,
+ "srcs": `["test.cpp"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ "template_configs": `[
+ "'<target_preparer class=\"com.android.tradefed.targetprep.RootTargetPreparer\">\\n <option name=\"force-root\" value=\"false\" />\\n </target_preparer>'",
+ "'<option name=\"not-shardable\" value=\"true\" />'",
+ ]`,
+ "template_install_base": `"/data/local/tmp"`,
+ "template_test_config": `"test_config_template.xml"`,
+ },
+ },
+ },
+ })
+}
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index 9398d12..112755b 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -37,10 +37,11 @@
return value, []selects{ret}
}
-func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects) {
+func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects, bool) {
value := reflect.ValueOf(list.Value)
+ prepend := reflect.ValueOf(list.Prepend).Bool()
if !list.HasConfigurableValues() {
- return value, []selects{}
+ return value, []selects{}, prepend
}
var ret []selects
@@ -56,7 +57,7 @@
}
}
- return value, ret
+ return value, ret, prepend
}
func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
@@ -156,6 +157,7 @@
func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
var value reflect.Value
var configurableAttrs []selects
+ var prepend bool
var defaultSelectValue *string
var emitZeroValues bool
// If true, print the default attribute value, even if the attribute is zero.
@@ -168,7 +170,7 @@
value, configurableAttrs = getStringValue(list)
defaultSelectValue = &bazelNone
case bazel.StringListAttribute:
- value, configurableAttrs = getStringListValues(list)
+ value, configurableAttrs, prepend = getStringListValues(list)
defaultSelectValue = &emptyBazelList
case bazel.LabelListAttribute:
value, configurableAttrs = getLabelListValues(list)
@@ -203,22 +205,28 @@
ret += s
}
- // Convenience function to append selects components to an attribute value.
- appendSelects := func(selectsData selects, defaultValue *string, s string) (string, error) {
+ // Convenience function to prepend/append selects components to an attribute value.
+ concatenateSelects := func(selectsData selects, defaultValue *string, s string, prepend bool) (string, error) {
selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent, emitZeroValues)
if err != nil {
return "", err
}
- if s != "" && selectMap != "" {
- s += " + "
+ var left, right string
+ if prepend {
+ left, right = selectMap, s
+ } else {
+ left, right = s, selectMap
}
- s += selectMap
+ if left != "" && right != "" {
+ left += " + "
+ }
+ left += right
- return s, nil
+ return left, nil
}
for _, configurableAttr := range configurableAttrs {
- ret, err = appendSelects(configurableAttr, defaultSelectValue, ret)
+ ret, err = concatenateSelects(configurableAttr, defaultSelectValue, ret, prepend)
if err != nil {
return "", err
}
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 6eb93bc..e15dd59 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -55,6 +55,10 @@
files = append(files, newFile("api_levels", "api_levels.json", string(apiLevelsContent)))
files = append(files, newFile("api_levels", "api_levels.bzl", android.StarlarkApiLevelConfigs(cfg)))
+ // TODO(b/262781701): Create an alternate soong_build entrypoint for writing out these files only when requested
+ files = append(files, newFile("allowlists", "mixed_build_prod_allowlist.txt", strings.Join(android.GetBazelEnabledModules(android.BazelProdMode), "\n")+"\n"))
+ files = append(files, newFile("allowlists", "mixed_build_staging_allowlist.txt", strings.Join(android.GetBazelEnabledModules(android.BazelStagingMode), "\n")+"\n"))
+
return files
}
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index 8de2f83..dfc7f0b 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -147,6 +147,14 @@
dir: "api_levels",
basename: "api_levels.bzl",
},
+ {
+ dir: "allowlists",
+ basename: "mixed_build_prod_allowlist.txt",
+ },
+ {
+ dir: "allowlists",
+ basename: "mixed_build_staging_allowlist.txt",
+ },
}
if len(files) != len(expectedFilePaths) {
diff --git a/bpf/bpf.go b/bpf/bpf.go
index d91180b..45009c1 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -240,7 +240,7 @@
fmt.Fprintln(w, "include $(CLEAR_VARS)", " # bpf.bpf")
fmt.Fprintln(w, "LOCAL_MODULE := ", name)
data.Entries.WriteLicenseVariables(w)
- fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(names, " "))
+ android.AndroidMkEmitAssignList(w, "LOCAL_REQUIRED_MODULES", names)
fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
},
}
diff --git a/cc/afdo_test.go b/cc/afdo_test.go
index fe3392a..f5d27ff 100644
--- a/cc/afdo_test.go
+++ b/cc/afdo_test.go
@@ -150,3 +150,31 @@
}
}
+
+func TestAfdoEnabledWithRuntimeDepNoAfdo(t *testing.T) {
+ bp := `
+ cc_library {
+ name: "libTest",
+ srcs: ["foo.c"],
+ runtime_libs: ["libFoo"],
+ afdo: true,
+ }
+
+ cc_library {
+ name: "libFoo",
+ }
+ `
+ prepareForAfdoTest := android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libTest.afdo", "TEST")
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ prepareForAfdoTest,
+ ).RunTestWithBp(t, bp)
+
+ libFooVariants := result.ModuleVariantsForTests("libFoo")
+ for _, v := range libFooVariants {
+ if strings.Contains(v, "afdo-") {
+ t.Errorf("Expected no afdo variant of 'foo', got %q", v)
+ }
+ }
+}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 6caa854..510ecee 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -337,6 +337,19 @@
}
}
+func bp2BuildParsePrebuiltObjectProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
+ var srcLabelAttribute bazel.LabelAttribute
+ bp2BuildPropParseHelper(ctx, module, &prebuiltObjectProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
+ if props, ok := props.(*prebuiltObjectProperties); ok {
+ parseSrc(ctx, &srcLabelAttribute, axis, config, props.Srcs)
+ }
+ })
+
+ return prebuiltAttributes{
+ Src: srcLabelAttribute,
+ }
+}
+
type baseAttributes struct {
compilerAttributes
linkerAttributes
@@ -393,6 +406,8 @@
features bazel.StringListAttribute
suffix bazel.StringAttribute
+
+ fdoProfile bazel.LabelAttribute
}
type filterOutFn func(string) bool
@@ -777,6 +792,13 @@
(&compilerAttrs).srcs.Add(&convertedLSrcs.srcName)
(&compilerAttrs).cSrcs.Add(&convertedLSrcs.cSrcName)
+ if module.afdo != nil && module.afdo.Properties.Afdo {
+ fdoProfileDep := bp2buildFdoProfile(ctx, module)
+ if fdoProfileDep != nil {
+ (&compilerAttrs).fdoProfile.SetValue(*fdoProfileDep)
+ }
+ }
+
if !compilerAttrs.syspropSrcs.IsEmpty() {
(&linkerAttrs).wholeArchiveDeps.Add(bp2buildCcSysprop(ctx, module.Name(), module.Properties.Min_sdk_version, compilerAttrs.syspropSrcs))
}
@@ -793,6 +815,41 @@
}
}
+type fdoProfileAttributes struct {
+ Absolute_path_profile string
+}
+
+func bp2buildFdoProfile(
+ ctx android.Bp2buildMutatorContext,
+ m *Module,
+) *bazel.Label {
+ for _, project := range globalAfdoProfileProjects {
+ // Ensure handcrafted BUILD file exists in the project
+ BUILDPath := android.ExistentPathForSource(ctx, project, "BUILD")
+ if BUILDPath.Valid() {
+ // We handcraft a BUILD file with fdo_profile targets that use the existing profiles in the project
+ // This implementation is assuming that every afdo profile in globalAfdoProfileProjects already has
+ // an associated fdo_profile target declared in the same package.
+ // TODO(b/260714900): Handle arch-specific afdo profiles (e.g. `<module-name>-arm<64>.afdo`)
+ path := android.ExistentPathForSource(ctx, project, m.Name()+".afdo")
+ if path.Valid() {
+ // FIXME: Some profiles only exist internally and are not released to AOSP.
+ // When generated BUILD files are checked in, we'll run into merge conflict.
+ // The cc_library_shared target in AOSP won't have reference to an fdo_profile target because
+ // the profile doesn't exist. Internally, the same cc_library_shared target will
+ // have reference to the fdo_profile.
+ // For more context, see b/258682955#comment2
+ fdoProfileLabel := "//" + strings.TrimSuffix(project, "/") + ":" + m.Name()
+ return &bazel.Label{
+ Label: fdoProfileLabel,
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
func bp2buildCcAidlLibrary(
ctx android.Bp2buildMutatorContext,
m *Module,
@@ -1257,6 +1314,13 @@
} else {
exported = BazelIncludes{}
}
+
+ // cc library Export_include_dirs and Export_system_include_dirs are marked
+ // "variant_prepend" in struct tag, set their prepend property to true to make
+ // sure bp2build generates correct result.
+ exported.Includes.Prepend = true
+ exported.SystemIncludes.Prepend = true
+
bp2BuildPropParseHelper(ctx, module, &FlagExporterProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
if len(flagExporterProperties.Export_include_dirs) > 0 {
diff --git a/cc/cc.go b/cc/cc.go
index 2ff5bba..632bdca 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1440,7 +1440,7 @@
func isBionic(name string) bool {
switch name {
- case "libc", "libm", "libdl", "libdl_android", "linker", "linkerconfig":
+ case "libc", "libm", "libdl", "libdl_android", "linker":
return true
}
return false
@@ -3775,7 +3775,9 @@
testBinaryBp2build(ctx, c)
}
case object:
- if !prebuilt {
+ if prebuilt {
+ prebuiltObjectBp2Build(ctx, c)
+ } else {
objectBp2Build(ctx, c)
}
case fullLibrary:
diff --git a/cc/config/global.go b/cc/config/global.go
index 61151d1..a4e2975 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -278,8 +278,6 @@
// http://b/145211477
"-Wno-pointer-compare",
// http://b/145211022
- "-Wno-xor-used-as-pow",
- // http://b/145211022
"-Wno-final-dtor-non-final-class",
// http://b/165945989
@@ -311,8 +309,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r475365"
- ClangDefaultShortVersion = "16.0.1"
+ ClangDefaultVersion = "clang-r475365b"
+ ClangDefaultShortVersion = "16.0.2"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index e2b0f06..9f093bb 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -41,6 +41,12 @@
"broadwell": []string{
"-march=broadwell",
},
+ "goldmont": []string{
+ "-march=goldmont",
+ },
+ "goldmont-plus": []string{
+ "-march=goldmont-plus",
+ },
"haswell": []string{
"-march=core-avx2",
},
@@ -59,6 +65,9 @@
"stoneyridge": []string{
"-march=bdver4",
},
+ "tremont": []string{
+ "-march=tremont",
+ },
}
x86_64ArchFeatureCflags = map[string][]string{
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index 3001ab4..c826d3c 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -50,6 +50,12 @@
"broadwell": []string{
"-march=broadwell",
},
+ "goldmont": []string{
+ "-march=goldmont",
+ },
+ "goldmont-plus": []string{
+ "-march=goldmont-plus",
+ },
"haswell": []string{
"-march=core-avx2",
},
@@ -68,6 +74,9 @@
"stoneyridge": []string{
"-march=bdver4",
},
+ "tremont": []string{
+ "-march=tremont",
+ },
}
x86ArchFeatureCflags = map[string][]string{
diff --git a/cc/library.go b/cc/library.go
index d1d1945..ed0ed01 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -120,6 +120,9 @@
// Extra flags passed to header-abi-diff
Diff_flags []string
+
+ // Opt-in reference dump directories
+ Ref_dump_dirs []string
}
// Inject boringssl hash into the shared library. This is only intended for use by external/boringssl.
@@ -414,6 +417,8 @@
Strip: stripAttrsFromLinkerAttrs(&linkerAttrs),
Features: baseAttributes.features,
bazelCcHeaderAbiCheckerAttributes: bp2buildParseAbiCheckerProps(ctx, m),
+
+ Fdo_profile: compilerAttrs.fdoProfile,
}
if compilerAttrs.stubsSymbolFile != nil && len(compilerAttrs.stubsVersions.Value) > 0 {
@@ -1911,6 +1916,16 @@
isLlndkOrNdk, allowExtensions, "current", errorMessage)
}
+func (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+ baseName, nameExt string, isLlndkOrNdk bool, refDumpDir string) {
+
+ libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
+ errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName + " -ref-dump-dir $$ANDROID_BUILD_TOP/" + refDumpDir
+
+ library.sourceAbiDiff(ctx, referenceDump, baseName, nameExt,
+ isLlndkOrNdk, /* allowExtensions */ false, "current", errorMessage)
+}
+
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
if library.sabi.shouldCreateSourceAbiDump() {
exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
@@ -1955,6 +1970,19 @@
library.sameVersionAbiDiff(ctx, currDumpFile.Path(),
fileName, isLlndk || isNdk, ctx.IsVndkExt())
}
+ // Check against the opt-in reference dumps.
+ for i, optInDumpDir := range library.Properties.Header_abi_checker.Ref_dump_dirs {
+ optInDumpDirPath := android.PathForModuleSrc(ctx, optInDumpDir)
+ // Ref_dump_dirs are not versioned.
+ // They do not contain subdir for binder bitness because 64-bit binder has been mandatory.
+ optInDumpFile := getRefAbiDumpFile(ctx, optInDumpDirPath.String(), fileName)
+ if !optInDumpFile.Valid() {
+ continue
+ }
+ library.optInAbiDiff(ctx, optInDumpFile.Path(),
+ fileName, "opt"+strconv.Itoa(i), isLlndk || isNdk,
+ optInDumpDirPath.String())
+ }
}
}
@@ -2904,6 +2932,8 @@
Suffix: compilerAttrs.suffix,
bazelCcHeaderAbiCheckerAttributes: bp2buildParseAbiCheckerProps(ctx, module),
+
+ Fdo_profile: compilerAttrs.fdoProfile,
}
if compilerAttrs.stubsSymbolFile != nil && len(compilerAttrs.stubsVersions.Value) > 0 {
hasStubs := true
@@ -2994,6 +3024,8 @@
Suffix bazel.StringAttribute
bazelCcHeaderAbiCheckerAttributes
+
+ Fdo_profile bazel.LabelAttribute
}
type bazelCcStubSuiteAttributes struct {
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 1c4f354..4d38068 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -145,7 +145,12 @@
Bzl_load_location: "//build/bazel/rules/cc:cc_library_headers.bzl",
}
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
+ tags := android.ApexAvailableTags(module)
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+ Name: module.Name(),
+ Tags: tags,
+ }, attrs)
}
// Append .contribution suffix to input labels
diff --git a/cc/library_stub.go b/cc/library_stub.go
index c61e2d1..d21df51 100644
--- a/cc/library_stub.go
+++ b/cc/library_stub.go
@@ -148,8 +148,9 @@
var in android.Path
+ // src might not exist during the beginning of soong analysis in Multi-tree
if src := String(d.properties.Src); src != "" {
- in = android.PathForModuleSrc(ctx, src)
+ in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src)
}
// LLNDK variant
diff --git a/cc/linker.go b/cc/linker.go
index 76a60ca..625d89c 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -221,7 +221,7 @@
// Generate compact dynamic relocation table, default true.
Pack_relocations *bool `android:"arch_variant"`
- // local file name to pass to the linker as --version_script
+ // local file name to pass to the linker as --version-script
Version_script *string `android:"path,arch_variant"`
// local file name to pass to the linker as --dynamic-list
diff --git a/cc/object.go b/cc/object.go
index 1a96b72..c3a198d 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -133,6 +133,7 @@
Srcs bazel.LabelListAttribute
Srcs_as bazel.LabelListAttribute
Hdrs bazel.LabelListAttribute
+ Objs bazel.LabelListAttribute
Deps bazel.LabelListAttribute
System_dynamic_deps bazel.LabelListAttribute
Copts bazel.StringListAttribute
@@ -155,6 +156,7 @@
// Set arch-specific configurable attributes
baseAttributes := bp2BuildParseBaseProps(ctx, m)
compilerAttrs := baseAttributes.compilerAttributes
+ var objs bazel.LabelListAttribute
var deps bazel.LabelListAttribute
systemDynamicDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
@@ -167,16 +169,19 @@
label := android.BazelLabelForModuleSrcSingle(ctx, *objectLinkerProps.Linker_script)
linkerScript.SetSelectValue(axis, config, label)
}
- deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
+ objs.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
systemSharedLibs := objectLinkerProps.System_shared_libs
if len(systemSharedLibs) > 0 {
systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
}
systemDynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
+ deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Static_libs))
+ deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Shared_libs))
+ deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Header_libs))
}
}
}
- deps.ResolveExcludes()
+ objs.ResolveExcludes()
// Don't split cc_object srcs across languages. Doing so would add complexity,
// and this isn't typically done for cc_object.
@@ -192,6 +197,7 @@
attrs := &bazelObjectAttributes{
Srcs: srcs,
Srcs_as: compilerAttrs.asSrcs,
+ Objs: objs,
Deps: deps,
System_dynamic_deps: systemDynamicDeps,
Copts: compilerAttrs.copts,
@@ -208,7 +214,12 @@
Bzl_load_location: "//build/bazel/rules/cc:cc_object.bzl",
}
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+ tags := android.ApexAvailableTags(m)
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+ Name: m.Name(),
+ Tags: tags,
+ }, attrs)
}
func (object *objectLinker) appendLdflags(flags []string) {
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 9fbf879..45af303 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -32,7 +32,7 @@
ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory)
- ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory)
+ ctx.RegisterModuleType("cc_prebuilt_object", PrebuiltObjectFactory)
ctx.RegisterModuleType("cc_prebuilt_binary", PrebuiltBinaryFactory)
}
@@ -572,6 +572,8 @@
func NewPrebuiltObject(hod android.HostOrDeviceSupported) *Module {
module := newObject(hod)
+ module.bazelHandler = &prebuiltObjectBazelHandler{module: module}
+ module.bazelable = true
prebuilt := &prebuiltObjectLinker{
objectLinker: objectLinker{
baseLinker: NewBaseLinker(nil),
@@ -584,7 +586,55 @@
return module
}
-func prebuiltObjectFactory() android.Module {
+type prebuiltObjectBazelHandler struct {
+ module *Module
+}
+
+var _ BazelHandler = (*prebuiltObjectBazelHandler)(nil)
+
+func (h *prebuiltObjectBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
+ bazelCtx := ctx.Config().BazelContext
+ bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKey(ctx))
+}
+
+func (h *prebuiltObjectBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
+ bazelCtx := ctx.Config().BazelContext
+ outputs, err := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
+ if err != nil {
+ ctx.ModuleErrorf(err.Error())
+ return
+ }
+ if len(outputs) != 1 {
+ ctx.ModuleErrorf("Expected a single output for `%s`, but got:\n%v", label, outputs)
+ return
+ }
+ out := android.PathForBazelOut(ctx, outputs[0])
+ h.module.outputFile = android.OptionalPathForPath(out)
+ h.module.maybeUnhideFromMake()
+}
+
+type bazelPrebuiltObjectAttributes struct {
+ Src bazel.LabelAttribute
+}
+
+func prebuiltObjectBp2Build(ctx android.TopDownMutatorContext, module *Module) {
+ prebuiltAttrs := bp2BuildParsePrebuiltObjectProps(ctx, module)
+
+ attrs := &bazelPrebuiltObjectAttributes{
+ Src: prebuiltAttrs.Src,
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_prebuilt_object",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_object.bzl",
+ }
+
+ name := android.RemoveOptionalPrebuiltPrefix(module.Name())
+ tags := android.ApexAvailableTags(module)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name, Tags: tags}, attrs)
+}
+
+func PrebuiltObjectFactory() android.Module {
module := NewPrebuiltObject(android.HostAndDeviceSupported)
return module.Init()
}
diff --git a/cc/proto.go b/cc/proto.go
index 27f37cb..97470e5 100644
--- a/cc/proto.go
+++ b/cc/proto.go
@@ -165,7 +165,8 @@
}
type protoAttributes struct {
- Deps bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Min_sdk_version *string
}
type bp2buildProtoDeps struct {
@@ -203,6 +204,7 @@
var protoAttrs protoAttributes
protoAttrs.Deps.SetValue(protoInfo.Proto_libs)
+ protoAttrs.Min_sdk_version = m.Properties.Min_sdk_version
name := m.Name() + suffix
tags := android.ApexAvailableTags(m)
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index b102d33..143602a 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -572,7 +572,7 @@
}
cc_binary {
- name: "bin_depends_ubsan",
+ name: "bin_depends_ubsan_static",
host_supported: true,
shared_libs: [
"libshared",
@@ -585,6 +585,14 @@
}
cc_binary {
+ name: "bin_depends_ubsan_shared",
+ host_supported: true,
+ shared_libs: [
+ "libsharedubsan",
+ ],
+ }
+
+ cc_binary {
name: "bin_no_ubsan",
host_supported: true,
shared_libs: [
@@ -607,6 +615,14 @@
host_supported: true,
}
+ cc_library_shared {
+ name: "libsharedubsan",
+ host_supported: true,
+ sanitize: {
+ undefined: true,
+ }
+ }
+
cc_library_static {
name: "libubsan",
host_supported: true,
@@ -632,22 +648,33 @@
check := func(t *testing.T, result *android.TestResult, variant string) {
staticVariant := variant + "_static"
+ sharedVariant := variant + "_shared"
minimalRuntime := result.ModuleForTests("libclang_rt.ubsan_minimal", staticVariant)
// The binaries, one with ubsan and one without
binWithUbsan := result.ModuleForTests("bin_with_ubsan", variant)
- binDependsUbsan := result.ModuleForTests("bin_depends_ubsan", variant)
+ binDependsUbsan := result.ModuleForTests("bin_depends_ubsan_static", variant)
+ libSharedUbsan := result.ModuleForTests("libsharedubsan", sharedVariant)
+ binDependsUbsanShared := result.ModuleForTests("bin_depends_ubsan_shared", variant)
binNoUbsan := result.ModuleForTests("bin_no_ubsan", variant)
android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_with_ubsan static libs",
strings.Split(binWithUbsan.Rule("ld").Args["libFlags"], " "),
minimalRuntime.OutputFiles(t, "")[0].String())
- android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_depends_ubsan static libs",
+ android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_depends_ubsan_static static libs",
strings.Split(binDependsUbsan.Rule("ld").Args["libFlags"], " "),
minimalRuntime.OutputFiles(t, "")[0].String())
+ android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in libsharedubsan static libs",
+ strings.Split(libSharedUbsan.Rule("ld").Args["libFlags"], " "),
+ minimalRuntime.OutputFiles(t, "")[0].String())
+
+ android.AssertStringListDoesNotContain(t, "unexpected libclang_rt.ubsan_minimal in bin_depends_ubsan_shared static libs",
+ strings.Split(binDependsUbsanShared.Rule("ld").Args["libFlags"], " "),
+ minimalRuntime.OutputFiles(t, "")[0].String())
+
android.AssertStringListDoesNotContain(t, "unexpected libclang_rt.ubsan_minimal in bin_no_ubsan static libs",
strings.Split(binNoUbsan.Rule("ld").Args["libFlags"], " "),
minimalRuntime.OutputFiles(t, "")[0].String())
@@ -656,10 +683,18 @@
strings.Split(binWithUbsan.Rule("ld").Args["ldFlags"], " "),
"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
- android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in bin_depends_ubsan static libs",
+ android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in bin_depends_ubsan_static static libs",
strings.Split(binDependsUbsan.Rule("ld").Args["ldFlags"], " "),
"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+ android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in libsharedubsan static libs",
+ strings.Split(libSharedUbsan.Rule("ld").Args["ldFlags"], " "),
+ "-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+
+ android.AssertStringListDoesNotContain(t, "unexpected -Wl,--exclude-libs for minimal runtime in bin_depends_ubsan_shared static libs",
+ strings.Split(binDependsUbsanShared.Rule("ld").Args["ldFlags"], " "),
+ "-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+
android.AssertStringListDoesNotContain(t, "unexpected -Wl,--exclude-libs for minimal runtime in bin_no_ubsan static libs",
strings.Split(binNoUbsan.Rule("ld").Args["ldFlags"], " "),
"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
diff --git a/cc/test.go b/cc/test.go
index 536210b..dee6ed6 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -378,12 +378,6 @@
}
func (test *testBinary) install(ctx ModuleContext, file android.Path) {
- // TODO: (b/167308193) Switch to /data/local/tests/unrestricted as the default install base.
- testInstallBase := "/data/local/tmp"
- if ctx.inVendor() || ctx.useVndk() {
- testInstallBase = "/data/local/tests/vendor"
- }
-
dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
for _, dataSrcPath := range dataSrcPaths {
@@ -415,52 +409,20 @@
}
})
- var configs []tradefed.Config
- for _, module := range test.Properties.Test_mainline_modules {
- configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
- }
- if Bool(test.Properties.Require_root) {
- configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
- } else {
- var options []tradefed.Option
- options = append(options, tradefed.Option{Name: "force-root", Value: "false"})
- configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
- }
- if Bool(test.Properties.Disable_framework) {
- var options []tradefed.Option
- configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options})
- }
- if test.isolated(ctx) {
- configs = append(configs, tradefed.Option{Name: "not-shardable", Value: "true"})
- }
- if test.Properties.Test_options.Run_test_as != nil {
- configs = append(configs, tradefed.Option{Name: "run-test-as", Value: String(test.Properties.Test_options.Run_test_as)})
- }
- for _, tag := range test.Properties.Test_options.Test_suite_tag {
- configs = append(configs, tradefed.Option{Name: "test-suite-tag", Value: tag})
- }
- if test.Properties.Test_options.Min_shipping_api_level != nil {
- if test.Properties.Test_options.Vsr_min_shipping_api_level != nil {
- ctx.PropertyErrorf("test_options.min_shipping_api_level", "must not be set at the same time as 'vsr_min_shipping_api_level'.")
- }
- var options []tradefed.Option
- options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Min_shipping_api_level), 10)})
- configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
- }
- if test.Properties.Test_options.Vsr_min_shipping_api_level != nil {
- var options []tradefed.Option
- options = append(options, tradefed.Option{Name: "vsr-min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Vsr_min_shipping_api_level), 10)})
- configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
- }
- if test.Properties.Test_options.Min_vndk_version != nil {
- var options []tradefed.Option
- options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Min_vndk_version), 10)})
- options = append(options, tradefed.Option{Name: "api-level-prop", Value: "ro.vndk.version"})
- configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.MinApiLevelModuleController", options})
- }
+ useVendor := ctx.inVendor() || ctx.useVndk()
+ testInstallBase := getTestInstallBase(useVendor)
+ configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx))
- test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config,
- test.Properties.Test_config_template, test.testDecorator.InstallerProperties.Test_suites, configs, test.Properties.Auto_gen_config, testInstallBase)
+ test.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(test.Properties.Test_config).
+ SetTestTemplateConfigProp(test.Properties.Test_config_template).
+ SetTestSuites(test.testDecorator.InstallerProperties.Test_suites).
+ SetConfig(configs).
+ SetAutoGenConfig(test.Properties.Auto_gen_config).
+ SetTestInstallBase(testInstallBase).
+ SetDeviceTemplate("${NativeTestConfigTemplate}").
+ SetHostTemplate("${NativeHostTestConfigTemplate}").
+ Build()
test.extraTestConfigs = android.PathsForModuleSrc(ctx, test.Properties.Test_options.Extra_test_configs)
@@ -479,6 +441,63 @@
test.binaryDecorator.baseInstaller.install(ctx, file)
}
+func getTestInstallBase(useVendor bool) string {
+ // TODO: (b/167308193) Switch to /data/local/tests/unrestricted as the default install base.
+ testInstallBase := "/data/local/tmp"
+ if useVendor {
+ testInstallBase = "/data/local/tests/vendor"
+ }
+ return testInstallBase
+}
+
+func getTradefedConfigOptions(ctx android.EarlyModuleContext, properties *TestBinaryProperties, isolated bool) []tradefed.Config {
+ var configs []tradefed.Config
+
+ for _, module := range properties.Test_mainline_modules {
+ configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
+ }
+ if Bool(properties.Require_root) {
+ configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
+ } else {
+ var options []tradefed.Option
+ options = append(options, tradefed.Option{Name: "force-root", Value: "false"})
+ configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
+ }
+ if Bool(properties.Disable_framework) {
+ var options []tradefed.Option
+ configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options})
+ }
+ if isolated {
+ configs = append(configs, tradefed.Option{Name: "not-shardable", Value: "true"})
+ }
+ if properties.Test_options.Run_test_as != nil {
+ configs = append(configs, tradefed.Option{Name: "run-test-as", Value: String(properties.Test_options.Run_test_as)})
+ }
+ for _, tag := range properties.Test_options.Test_suite_tag {
+ configs = append(configs, tradefed.Option{Name: "test-suite-tag", Value: tag})
+ }
+ if properties.Test_options.Min_shipping_api_level != nil {
+ if properties.Test_options.Vsr_min_shipping_api_level != nil {
+ ctx.PropertyErrorf("test_options.min_shipping_api_level", "must not be set at the same time as 'vsr_min_shipping_api_level'.")
+ }
+ var options []tradefed.Option
+ options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*properties.Test_options.Min_shipping_api_level), 10)})
+ configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
+ }
+ if properties.Test_options.Vsr_min_shipping_api_level != nil {
+ var options []tradefed.Option
+ options = append(options, tradefed.Option{Name: "vsr-min-api-level", Value: strconv.FormatInt(int64(*properties.Test_options.Vsr_min_shipping_api_level), 10)})
+ configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
+ }
+ if properties.Test_options.Min_vndk_version != nil {
+ var options []tradefed.Option
+ options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*properties.Test_options.Min_vndk_version), 10)})
+ options = append(options, tradefed.Option{Name: "api-level-prop", Value: "ro.vndk.version"})
+ configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.MinApiLevelModuleController", options})
+ }
+ return configs
+}
+
func NewTest(hod android.HostOrDeviceSupported, bazelable bool) *Module {
module, binary := newBinary(hod, bazelable)
module.multilib = android.MultilibBoth
@@ -616,8 +635,15 @@
if Bool(benchmark.Properties.Require_root) {
configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
}
- benchmark.testConfig = tradefed.AutoGenNativeBenchmarkTestConfig(ctx, benchmark.Properties.Test_config,
- benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites, configs, benchmark.Properties.Auto_gen_config)
+ benchmark.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(benchmark.Properties.Test_config).
+ SetTestTemplateConfigProp(benchmark.Properties.Test_config_template).
+ SetTestSuites(benchmark.Properties.Test_suites).
+ SetConfig(configs).
+ SetAutoGenConfig(benchmark.Properties.Auto_gen_config).
+ SetDeviceTemplate("${NativeBenchmarkTestConfigTemplate}").
+ SetHostTemplate("${NativeBenchmarkTestConfigTemplate}").
+ Build()
benchmark.binaryDecorator.baseInstaller.dir = filepath.Join("benchmarktest", ctx.ModuleName())
benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName())
@@ -645,6 +671,7 @@
Isolated bool
tidyAttributes
+ tradefed.TestConfigAttributes
}
// testBinaryBp2build is the bp2build converter for cc_test modules. A cc_test's
@@ -655,7 +682,6 @@
// TODO(b/244432609): handle `isolated` property.
// TODO(b/244432134): handle custom runpaths for tests that assume runfile layouts not
// default to bazel. (see linkerInit function)
-// TODO(b/244432500): handle test.testConfig generation (see install function)
func testBinaryBp2build(ctx android.TopDownMutatorContext, m *Module) {
var testBinaryAttrs testBinaryAttributes
testBinaryAttrs.binaryAttributes = binaryBp2buildAttrs(ctx, m)
@@ -688,6 +714,25 @@
}
}
+ for _, testProps := range m.GetProperties() {
+ if p, ok := testProps.(*TestBinaryProperties); ok {
+ useVendor := false // TODO Bug: 262914724
+ testInstallBase := getTestInstallBase(useVendor)
+ testConfigAttributes := tradefed.GetTestConfigAttributes(
+ ctx,
+ p.Test_config,
+ p.Test_options.Extra_test_configs,
+ p.Auto_gen_config,
+ p.Test_options.Test_suite_tag,
+ p.Test_config_template,
+ getTradefedConfigOptions(ctx, p, testBinaryAttrs.Isolated),
+ &testInstallBase,
+ )
+ testBinaryAttrs.TestConfigAttributes = testConfigAttributes
+ }
+ }
+
+ // TODO (b/262914724): convert to tradefed_cc_test and tradefed_cc_test_host
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "cc_test",
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index f4a63a4..744a10c 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -18,7 +18,6 @@
"bytes"
"flag"
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -38,38 +37,26 @@
var (
topDir string
- outDir string
- soongOutDir string
availableEnvFile string
usedEnvFile string
- runGoTests bool
-
globFile string
globListDir string
delveListen string
delvePath string
- moduleGraphFile string
- moduleActionsFile string
- docFile string
- bazelQueryViewDir string
- bazelApiBp2buildDir string
- bp2buildMarker string
- symlinkForestMarker string
-
- cmdlineArgs bootstrap.Args
+ cmdlineArgs android.CmdArgs
)
func init() {
// Flags that make sense in every mode
flag.StringVar(&topDir, "top", "", "Top directory of the Android source tree")
- flag.StringVar(&soongOutDir, "soong_out", "", "Soong output directory (usually $TOP/out/soong)")
+ flag.StringVar(&cmdlineArgs.SoongOutDir, "soong_out", "", "Soong output directory (usually $TOP/out/soong)")
flag.StringVar(&availableEnvFile, "available_env", "", "File containing available environment variables")
flag.StringVar(&usedEnvFile, "used_env", "", "File containing used environment variables")
flag.StringVar(&globFile, "globFile", "build-globs.ninja", "the Ninja file of globs to output")
flag.StringVar(&globListDir, "globListDir", "", "the directory containing the glob list files")
- flag.StringVar(&outDir, "out", "", "the ninja builddir directory")
+ flag.StringVar(&cmdlineArgs.OutDir, "out", "", "the ninja builddir directory")
flag.StringVar(&cmdlineArgs.ModuleListFile, "l", "", "file that lists filepaths to parse")
// Debug flags
@@ -81,13 +68,13 @@
flag.BoolVar(&cmdlineArgs.NoGC, "nogc", false, "turn off GC for debugging")
// Flags representing various modes soong_build can run in
- flag.StringVar(&moduleGraphFile, "module_graph_file", "", "JSON module graph file to output")
- flag.StringVar(&moduleActionsFile, "module_actions_file", "", "JSON file to output inputs/outputs of actions of modules")
- flag.StringVar(&docFile, "soong_docs", "", "build documentation file to output")
- flag.StringVar(&bazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory relative to --top")
- flag.StringVar(&bazelApiBp2buildDir, "bazel_api_bp2build_dir", "", "path to the bazel api_bp2build directory relative to --top")
- flag.StringVar(&bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
- flag.StringVar(&symlinkForestMarker, "symlink_forest_marker", "", "If set, create the bp2build symlink forest, touch the specified marker file, then exit")
+ flag.StringVar(&cmdlineArgs.ModuleGraphFile, "module_graph_file", "", "JSON module graph file to output")
+ flag.StringVar(&cmdlineArgs.ModuleActionsFile, "module_actions_file", "", "JSON file to output inputs/outputs of actions of modules")
+ flag.StringVar(&cmdlineArgs.DocFile, "soong_docs", "", "build documentation file to output")
+ flag.StringVar(&cmdlineArgs.BazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory relative to --top")
+ flag.StringVar(&cmdlineArgs.BazelApiBp2buildDir, "bazel_api_bp2build_dir", "", "path to the bazel api_bp2build directory relative to --top")
+ flag.StringVar(&cmdlineArgs.Bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
+ flag.StringVar(&cmdlineArgs.SymlinkForestMarker, "symlink_forest_marker", "", "If set, create the bp2build symlink forest, touch the specified marker file, then exit")
flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
flag.StringVar(&cmdlineArgs.BazelForceEnabledModules, "bazel-force-enabled-modules", "", "additional modules to build with Bazel. Comma-delimited")
flag.BoolVar(&cmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
@@ -95,9 +82,9 @@
flag.BoolVar(&cmdlineArgs.BazelModeStaging, "bazel-mode-staging", false, "use bazel for analysis of certain near-ready modules")
flag.BoolVar(&cmdlineArgs.BazelModeDev, "bazel-mode-dev", false, "use bazel for analysis of a large number of modules (less stable)")
- // Flags that probably shouldn't be flags of soong_build but we haven't found
+ // Flags that probably shouldn't be flags of soong_build, but we haven't found
// the time to remove them yet
- flag.BoolVar(&runGoTests, "t", false, "build and run go tests during bootstrap")
+ flag.BoolVar(&cmdlineArgs.RunGoTests, "t", false, "build and run go tests during bootstrap")
// Disable deterministic randomization in the protobuf package, so incremental
// builds with unrelated Soong changes don't trigger large rebuilds (since we
@@ -118,87 +105,44 @@
return ctx
}
-func newConfig(availableEnv map[string]string) android.Config {
- var buildMode android.SoongBuildMode
- var bazelForceEnabledModules []string
- if len(cmdlineArgs.BazelForceEnabledModules) > 0 {
- bazelForceEnabledModules = strings.Split(cmdlineArgs.BazelForceEnabledModules, ",")
- }
-
- if symlinkForestMarker != "" {
- buildMode = android.SymlinkForest
- } else if bp2buildMarker != "" {
- buildMode = android.Bp2build
- } else if bazelQueryViewDir != "" {
- buildMode = android.GenerateQueryView
- } else if bazelApiBp2buildDir != "" {
- buildMode = android.ApiBp2build
- } else if moduleGraphFile != "" {
- buildMode = android.GenerateModuleGraph
- } else if docFile != "" {
- buildMode = android.GenerateDocFile
- } else if cmdlineArgs.BazelModeDev {
- buildMode = android.BazelDevMode
- } else if cmdlineArgs.BazelMode {
- buildMode = android.BazelProdMode
- } else if cmdlineArgs.BazelModeStaging {
- buildMode = android.BazelStagingMode
- } else {
- buildMode = android.AnalysisNoBazel
- }
-
- configuration, err := android.NewConfig(cmdlineArgs.ModuleListFile, buildMode, runGoTests, outDir, soongOutDir, availableEnv, bazelForceEnabledModules)
- if err != nil {
- fmt.Fprintf(os.Stderr, "%s", err)
- os.Exit(1)
- }
- return configuration
-}
-
// Bazel-enabled mode. Attaches a mutator to queue Bazel requests, adds a
// BeforePrepareBuildActionsHook to invoke Bazel, and then uses Bazel metadata
// for modules that should be handled by Bazel.
-func runMixedModeBuild(configuration android.Config, ctx *android.Context, extraNinjaDeps []string) string {
+func runMixedModeBuild(ctx *android.Context, extraNinjaDeps []string) string {
ctx.EventHandler.Begin("mixed_build")
defer ctx.EventHandler.End("mixed_build")
bazelHook := func() error {
- return configuration.BazelContext.InvokeBazel(configuration, ctx)
+ return ctx.Config().BazelContext.InvokeBazel(ctx.Config(), ctx)
}
ctx.SetBeforePrepareBuildActionsHook(bazelHook)
- ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs, bootstrap.DoEverything, ctx.Context, configuration)
+ ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs.Args, bootstrap.DoEverything, ctx.Context, ctx.Config())
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
- bazelPaths, err := readBazelPaths(configuration)
+ bazelPaths, err := readFileLines(ctx.Config().Getenv("BAZEL_DEPS_FILE"))
if err != nil {
panic("Bazel deps file not found: " + err.Error())
}
ninjaDeps = append(ninjaDeps, bazelPaths...)
-
- globListFiles := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
- ninjaDeps = append(ninjaDeps, globListFiles...)
+ ninjaDeps = append(ninjaDeps, writeBuildGlobsNinjaFile(ctx)...)
writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps)
return cmdlineArgs.OutFile
}
// Run the code-generation phase to convert BazelTargetModules to BUILD files.
-func runQueryView(queryviewDir, queryviewMarker string, configuration android.Config, ctx *android.Context) {
+func runQueryView(queryviewDir, queryviewMarker string, ctx *android.Context) {
ctx.EventHandler.Begin("queryview")
defer ctx.EventHandler.End("queryview")
- codegenContext := bp2build.NewCodegenContext(configuration, ctx, bp2build.QueryView)
- absoluteQueryViewDir := shared.JoinPath(topDir, queryviewDir)
- if err := createBazelWorkspace(codegenContext, absoluteQueryViewDir); err != nil {
- fmt.Fprintf(os.Stderr, "%s", err)
- os.Exit(1)
- }
-
+ codegenContext := bp2build.NewCodegenContext(ctx.Config(), ctx, bp2build.QueryView)
+ err := createBazelWorkspace(codegenContext, shared.JoinPath(topDir, queryviewDir))
+ maybeQuit(err, "")
touch(shared.JoinPath(topDir, queryviewMarker))
}
// Run the code-generation phase to convert API contributions to BUILD files.
// Return marker file for the new synthetic workspace
-func runApiBp2build(configuration android.Config, ctx *android.Context, extraNinjaDeps []string) string {
+func runApiBp2build(ctx *android.Context, extraNinjaDeps []string) string {
ctx.EventHandler.Begin("api_bp2build")
defer ctx.EventHandler.End("api_bp2build")
// Do not allow missing dependencies.
@@ -215,50 +159,42 @@
}
// Run the loading and analysis phase
- ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs,
+ ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs.Args,
bootstrap.StopBeforePrepareBuildActions,
ctx.Context,
- configuration)
+ ctx.Config())
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
// Add the globbed dependencies
- globs := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
- ninjaDeps = append(ninjaDeps, globs...)
+ ninjaDeps = append(ninjaDeps, writeBuildGlobsNinjaFile(ctx)...)
// Run codegen to generate BUILD files
- codegenContext := bp2build.NewCodegenContext(configuration, ctx, bp2build.ApiBp2build)
- absoluteApiBp2buildDir := shared.JoinPath(topDir, bazelApiBp2buildDir)
- if err := createBazelWorkspace(codegenContext, absoluteApiBp2buildDir); err != nil {
- fmt.Fprintf(os.Stderr, "%s", err)
- os.Exit(1)
- }
+ codegenContext := bp2build.NewCodegenContext(ctx.Config(), ctx, bp2build.ApiBp2build)
+ absoluteApiBp2buildDir := shared.JoinPath(topDir, cmdlineArgs.BazelApiBp2buildDir)
+ err := createBazelWorkspace(codegenContext, absoluteApiBp2buildDir)
+ maybeQuit(err, "")
ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
// Create soong_injection repository
- soongInjectionFiles := bp2build.CreateSoongInjectionFiles(configuration, bp2build.CreateCodegenMetrics())
- absoluteSoongInjectionDir := shared.JoinPath(topDir, configuration.SoongOutDir(), bazel.SoongInjectionDirName)
+ soongInjectionFiles := bp2build.CreateSoongInjectionFiles(ctx.Config(), bp2build.CreateCodegenMetrics())
+ absoluteSoongInjectionDir := shared.JoinPath(topDir, ctx.Config().SoongOutDir(), bazel.SoongInjectionDirName)
for _, file := range soongInjectionFiles {
- writeReadOnlyFile(absoluteSoongInjectionDir, file)
+ // The API targets in api_bp2build workspace do not have any dependency on api_bp2build.
+ // But we need to create these files to prevent errors during Bazel analysis.
+ // These need to be created in Read-Write mode.
+ // This is because the subsequent step (bp2build in api domain analysis) creates them in Read-Write mode
+ // to allow users to edit/experiment in the synthetic workspace.
+ writeReadWriteFile(absoluteSoongInjectionDir, file)
}
- workspace := shared.JoinPath(configuration.SoongOutDir(), "api_bp2build")
-
- excludes := bazelArtifacts()
- // Exclude all src BUILD files
- excludes = append(excludes, apiBuildFileExcludes()...)
-
- // Android.bp files for api surfaces are mounted to out/, but out/ should not be a
- // dep for api_bp2build.
- // Otherwise api_bp2build will be run every single time
- excludes = append(excludes, configuration.OutDir())
-
+ workspace := shared.JoinPath(ctx.Config().SoongOutDir(), "api_bp2build")
// Create the symlink forest
symlinkDeps := bp2build.PlantSymlinkForest(
- configuration.IsEnvTrue("BP2BUILD_VERBOSE"),
+ ctx.Config().IsEnvTrue("BP2BUILD_VERBOSE"),
topDir,
workspace,
- bazelApiBp2buildDir,
- excludes)
+ cmdlineArgs.BazelApiBp2buildDir,
+ apiBuildFileExcludes(ctx))
ninjaDeps = append(ninjaDeps, symlinkDeps...)
workspaceMarkerFile := workspace + ".marker"
@@ -269,15 +205,12 @@
// With some exceptions, api_bp2build does not have any dependencies on the checked-in BUILD files
// Exclude them from the generated workspace to prevent unrelated errors during the loading phase
-func apiBuildFileExcludes() []string {
- ret := make([]string, 0)
-
+func apiBuildFileExcludes(ctx *android.Context) []string {
+ ret := bazelArtifacts()
srcs, err := getExistingBazelRelatedFiles(topDir)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error determining existing Bazel-related files: %s\n", err)
- os.Exit(1)
- }
+ maybeQuit(err, "Error determining existing Bazel-related files")
for _, src := range srcs {
+ // Exclude all src BUILD files
if src != "WORKSPACE" &&
src != "BUILD" &&
src != "BUILD.bazel" &&
@@ -287,6 +220,9 @@
ret = append(ret, src)
}
}
+ // Android.bp files for api surfaces are mounted to out/, but out/ should not be a
+ // dep for api_bp2build. Otherwise, api_bp2build will be run every single time
+ ret = append(ret, ctx.Config().OutDir())
return ret
}
@@ -297,36 +233,30 @@
}
metricsFile := filepath.Join(metricsDir, "soong_build_metrics.pb")
err := android.WriteMetrics(configuration, eventHandler, metricsFile)
- if err != nil {
- fmt.Fprintf(os.Stderr, "error writing soong_build metrics %s: %s", metricsFile, err)
- os.Exit(1)
- }
+ maybeQuit(err, "error writing soong_build metrics %s", metricsFile)
}
-func writeJsonModuleGraphAndActions(ctx *android.Context, graphPath string, actionsPath string) {
- graphFile, graphErr := os.Create(shared.JoinPath(topDir, graphPath))
- actionsFile, actionsErr := os.Create(shared.JoinPath(topDir, actionsPath))
- if graphErr != nil || actionsErr != nil {
- fmt.Fprintf(os.Stderr, "Graph err: %s, actions err: %s", graphErr, actionsErr)
- os.Exit(1)
- }
-
+func writeJsonModuleGraphAndActions(ctx *android.Context, cmdArgs android.CmdArgs) {
+ graphFile, graphErr := os.Create(shared.JoinPath(topDir, cmdArgs.ModuleGraphFile))
+ maybeQuit(graphErr, "graph err")
defer graphFile.Close()
+ actionsFile, actionsErr := os.Create(shared.JoinPath(topDir, cmdArgs.ModuleActionsFile))
+ maybeQuit(actionsErr, "actions err")
defer actionsFile.Close()
ctx.Context.PrintJSONGraphAndActions(graphFile, actionsFile)
}
-func writeBuildGlobsNinjaFile(ctx *android.Context, buildDir string, config interface{}) []string {
+func writeBuildGlobsNinjaFile(ctx *android.Context) []string {
ctx.EventHandler.Begin("globs_ninja_file")
defer ctx.EventHandler.End("globs_ninja_file")
- globDir := bootstrap.GlobDirectory(buildDir, globListDir)
+ globDir := bootstrap.GlobDirectory(ctx.Config().SoongOutDir(), globListDir)
bootstrap.WriteBuildGlobsNinjaFile(&bootstrap.GlobSingleton{
GlobLister: ctx.Globs,
GlobFile: globFile,
GlobDir: globDir,
SrcDir: ctx.SrcDir(),
- }, config)
+ }, ctx.Config())
return bootstrap.GlobFileListFiles(globDir)
}
@@ -335,83 +265,50 @@
defer eventHandler.End("ninja_deps")
depFile := shared.JoinPath(topDir, outputFile+".d")
err := deptools.WriteDepFile(depFile, outputFile, ninjaDeps)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error writing depfile '%s': %s\n", depFile, err)
- os.Exit(1)
- }
-}
-
-// doChosenActivity runs Soong for a specific activity, like bp2build, queryview
-// or the actual Soong build for the build.ninja file. Returns the top level
-// output file of the specific activity.
-func doChosenActivity(ctx *android.Context, configuration android.Config, extraNinjaDeps []string, metricsDir string) string {
- if configuration.BuildMode == android.SymlinkForest {
- return runSymlinkForestCreation(configuration, ctx, extraNinjaDeps, metricsDir)
- } else if configuration.BuildMode == android.Bp2build {
- // Run the alternate pipeline of bp2build mutators and singleton to convert
- // Blueprint to BUILD files before everything else.
- return runBp2Build(configuration, ctx, extraNinjaDeps, metricsDir)
- } else if configuration.BuildMode == android.ApiBp2build {
- outputFile := runApiBp2build(configuration, ctx, extraNinjaDeps)
- writeMetrics(configuration, ctx.EventHandler, metricsDir)
- return outputFile
- } else {
- ctx.Register()
-
- var outputFile string
- if configuration.IsMixedBuildsEnabled() {
- outputFile = runMixedModeBuild(configuration, ctx, extraNinjaDeps)
- } else {
- outputFile = runSoongOnlyBuild(configuration, ctx, extraNinjaDeps)
- }
-
- writeMetrics(configuration, ctx.EventHandler, metricsDir)
-
- return outputFile
- }
+ maybeQuit(err, "error writing depfile '%s'", depFile)
}
// runSoongOnlyBuild runs the standard Soong build in a number of different modes.
-func runSoongOnlyBuild(configuration android.Config, ctx *android.Context, extraNinjaDeps []string) string {
+func runSoongOnlyBuild(ctx *android.Context, extraNinjaDeps []string) string {
ctx.EventHandler.Begin("soong_build")
defer ctx.EventHandler.End("soong_build")
var stopBefore bootstrap.StopBefore
- if configuration.BuildMode == android.GenerateModuleGraph {
+ switch ctx.Config().BuildMode {
+ case android.GenerateModuleGraph:
stopBefore = bootstrap.StopBeforeWriteNinja
- } else if configuration.BuildMode == android.GenerateQueryView || configuration.BuildMode == android.GenerateDocFile {
+ case android.GenerateQueryView | android.GenerateDocFile:
stopBefore = bootstrap.StopBeforePrepareBuildActions
- } else {
+ default:
stopBefore = bootstrap.DoEverything
}
- ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs, stopBefore, ctx.Context, configuration)
+ ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs.Args, stopBefore, ctx.Context, ctx.Config())
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
- globListFiles := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
+ globListFiles := writeBuildGlobsNinjaFile(ctx)
ninjaDeps = append(ninjaDeps, globListFiles...)
// Convert the Soong module graph into Bazel BUILD files.
- if configuration.BuildMode == android.GenerateQueryView {
- queryviewMarkerFile := bazelQueryViewDir + ".marker"
- runQueryView(bazelQueryViewDir, queryviewMarkerFile, configuration, ctx)
+ switch ctx.Config().BuildMode {
+ case android.GenerateQueryView:
+ queryviewMarkerFile := cmdlineArgs.BazelQueryViewDir + ".marker"
+ runQueryView(cmdlineArgs.BazelQueryViewDir, queryviewMarkerFile, ctx)
writeDepFile(queryviewMarkerFile, ctx.EventHandler, ninjaDeps)
return queryviewMarkerFile
- } else if configuration.BuildMode == android.GenerateModuleGraph {
- writeJsonModuleGraphAndActions(ctx, moduleGraphFile, moduleActionsFile)
- writeDepFile(moduleGraphFile, ctx.EventHandler, ninjaDeps)
- return moduleGraphFile
- } else if configuration.BuildMode == android.GenerateDocFile {
+ case android.GenerateModuleGraph:
+ writeJsonModuleGraphAndActions(ctx, cmdlineArgs)
+ writeDepFile(cmdlineArgs.ModuleGraphFile, ctx.EventHandler, ninjaDeps)
+ return cmdlineArgs.ModuleGraphFile
+ case android.GenerateDocFile:
// TODO: we could make writeDocs() return the list of documentation files
// written and add them to the .d file. Then soong_docs would be re-run
// whenever one is deleted.
- if err := writeDocs(ctx, shared.JoinPath(topDir, docFile)); err != nil {
- fmt.Fprintf(os.Stderr, "error building Soong documentation: %s\n", err)
- os.Exit(1)
- }
- writeDepFile(docFile, ctx.EventHandler, ninjaDeps)
- return docFile
- } else {
+ err := writeDocs(ctx, shared.JoinPath(topDir, cmdlineArgs.DocFile))
+ maybeQuit(err, "error building Soong documentation")
+ writeDepFile(cmdlineArgs.DocFile, ctx.EventHandler, ninjaDeps)
+ return cmdlineArgs.DocFile
+ default:
// The actual output (build.ninja) was written in the RunBlueprint() call
// above
writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps)
@@ -437,13 +334,8 @@
fmt.Fprintf(os.Stderr, "--available_env not set\n")
os.Exit(1)
}
-
result, err := shared.EnvFromFile(shared.JoinPath(topDir, availableEnvFile))
- if err != nil {
- fmt.Fprintf(os.Stderr, "error reading available environment file '%s': %s\n", availableEnvFile, err)
- os.Exit(1)
- }
-
+ maybeQuit(err, "error reading available environment file '%s'", availableEnvFile)
return result
}
@@ -454,17 +346,13 @@
android.InitSandbox(topDir)
availableEnv := parseAvailableEnv()
-
- configuration := newConfig(availableEnv)
- extraNinjaDeps := []string{
- configuration.ProductVariablesFileName,
- usedEnvFile,
- }
-
+ configuration, err := android.NewConfig(cmdlineArgs, availableEnv)
+ maybeQuit(err, "")
if configuration.Getenv("ALLOW_MISSING_DEPENDENCIES") == "true" {
configuration.SetAllowMissingDependencies()
}
+ extraNinjaDeps := []string{configuration.ProductVariablesFileName, usedEnvFile}
if shared.IsDebugging() {
// Add a non-existent file to the dependencies so that soong_build will rerun when the debugger is
// enabled even if it completed successfully.
@@ -473,12 +361,33 @@
// Bypass configuration.Getenv, as LOG_DIR does not need to be dependency tracked. By definition, it will
// change between every CI build, so tracking it would require re-running Soong for every build.
- logDir := availableEnv["LOG_DIR"]
+ metricsDir := availableEnv["LOG_DIR"]
ctx := newContext(configuration)
- finalOutputFile := doChosenActivity(ctx, configuration, extraNinjaDeps, logDir)
+ var finalOutputFile string
+ // Run Soong for a specific activity, like bp2build, queryview
+ // or the actual Soong build for the build.ninja file.
+ switch configuration.BuildMode {
+ case android.SymlinkForest:
+ finalOutputFile = runSymlinkForestCreation(ctx, extraNinjaDeps, metricsDir)
+ case android.Bp2build:
+ // Run the alternate pipeline of bp2build mutators and singleton to convert
+ // Blueprint to BUILD files before everything else.
+ finalOutputFile = runBp2Build(ctx, extraNinjaDeps, metricsDir)
+ case android.ApiBp2build:
+ finalOutputFile = runApiBp2build(ctx, extraNinjaDeps)
+ writeMetrics(configuration, ctx.EventHandler, metricsDir)
+ default:
+ ctx.Register()
+ if configuration.IsMixedBuildsEnabled() {
+ finalOutputFile = runMixedModeBuild(ctx, extraNinjaDeps)
+ } else {
+ finalOutputFile = runSoongOnlyBuild(ctx, extraNinjaDeps)
+ }
+ writeMetrics(configuration, ctx.EventHandler, metricsDir)
+ }
writeUsedEnvironmentFile(configuration, finalOutputFile)
}
@@ -489,24 +398,19 @@
path := shared.JoinPath(topDir, usedEnvFile)
data, err := shared.EnvFileContents(configuration.EnvDeps())
- if err != nil {
- fmt.Fprintf(os.Stderr, "error writing used environment file '%s': %s\n", usedEnvFile, err)
- os.Exit(1)
- }
+ maybeQuit(err, "error writing used environment file '%s'\n", usedEnvFile)
if preexistingData, err := os.ReadFile(path); err != nil {
if !os.IsNotExist(err) {
- fmt.Fprintf(os.Stderr, "error reading used environment file '%s': %s\n", usedEnvFile, err)
- os.Exit(1)
+ maybeQuit(err, "error reading used environment file '%s'", usedEnvFile)
}
} else if bytes.Equal(preexistingData, data) {
// used environment file is unchanged
return
}
- if err = os.WriteFile(path, data, 0666); err != nil {
- fmt.Fprintf(os.Stderr, "error writing used environment file '%s': %s\n", usedEnvFile, err)
- os.Exit(1)
- }
+ err = os.WriteFile(path, data, 0666)
+ maybeQuit(err, "error writing used environment file '%s'", usedEnvFile)
+
// Touch the output file so that it's not older than the file we just
// wrote. We can't write the environment file earlier because one an access
// new environment variables while writing it.
@@ -515,88 +419,13 @@
func touch(path string) {
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error touching '%s': %s\n", path, err)
- os.Exit(1)
- }
-
+ maybeQuit(err, "Error touching '%s'", path)
err = f.Close()
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error touching '%s': %s\n", path, err)
- os.Exit(1)
- }
+ maybeQuit(err, "Error touching '%s'", path)
currentTime := time.Now().Local()
err = os.Chtimes(path, currentTime, currentTime)
- if err != nil {
- fmt.Fprintf(os.Stderr, "error touching '%s': %s\n", path, err)
- os.Exit(1)
- }
-}
-
-// Find BUILD files in the srcDir which are not in the allowlist
-// (android.Bp2BuildConversionAllowlist#ShouldKeepExistingBuildFileForDir)
-// and return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
-func getPathsToIgnoredBuildFiles(config android.Bp2BuildConversionAllowlist, topDir string, srcDirBazelFiles []string, verbose bool) []string {
- paths := make([]string, 0)
-
- for _, srcDirBazelFileRelativePath := range srcDirBazelFiles {
- srcDirBazelFileFullPath := shared.JoinPath(topDir, srcDirBazelFileRelativePath)
- fileInfo, err := os.Stat(srcDirBazelFileFullPath)
- if err != nil {
- // Warn about error, but continue trying to check files
- fmt.Fprintf(os.Stderr, "WARNING: Error accessing path '%s', err: %s\n", srcDirBazelFileFullPath, err)
- continue
- }
- if fileInfo.IsDir() {
- // Don't ignore entire directories
- continue
- }
- if fileInfo.Name() != "BUILD" && fileInfo.Name() != "BUILD.bazel" {
- // Don't ignore this file - it is not a build file
- continue
- }
- if config.ShouldKeepExistingBuildFileForDir(filepath.Dir(srcDirBazelFileRelativePath)) {
- // Don't ignore this existing build file
- continue
- }
- if verbose {
- fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", srcDirBazelFileRelativePath)
- }
- paths = append(paths, srcDirBazelFileRelativePath)
- }
-
- return paths
-}
-
-// Returns temporary symlink forest excludes necessary for bazel build //external/... (and bazel build //frameworks/...) to work
-func getTemporaryExcludes() []string {
- excludes := make([]string, 0)
-
- // FIXME: 'autotest_lib' is a symlink back to external/autotest, and this causes an infinite symlink expansion error for Bazel
- excludes = append(excludes, "external/autotest/venv/autotest_lib")
- excludes = append(excludes, "external/autotest/autotest_lib")
- excludes = append(excludes, "external/autotest/client/autotest_lib/client")
-
- // FIXME: The external/google-fruit/extras/bazel_root/third_party/fruit dir is poison
- // It contains several symlinks back to real source dirs, and those source dirs contain BUILD files we want to ignore
- excludes = append(excludes, "external/google-fruit/extras/bazel_root/third_party/fruit")
-
- // FIXME: 'frameworks/compile/slang' has a filegroup error due to an escaping issue
- excludes = append(excludes, "frameworks/compile/slang")
-
- // FIXME(b/260809113): 'prebuilts/clang/host/linux-x86/clang-dev' is a tool-generated symlink directory that contains a BUILD file.
- // The bazel files finder code doesn't traverse into symlink dirs, and hence is not aware of this BUILD file and exclude it accordingly
- // during symlink forest generation when checking against keepExistingBuildFiles allowlist.
- //
- // This is necessary because globs in //prebuilts/clang/host/linux-x86/BUILD
- // currently assume no subpackages (keepExistingBuildFile is not recursive for that directory).
- //
- // This is a bandaid until we the symlink forest logic can intelligently exclude BUILD files found in source symlink dirs according
- // to the keepExistingBuildFile allowlist.
- excludes = append(excludes, "prebuilts/clang/host/linux-x86/clang-dev")
-
- return excludes
+ maybeQuit(err, "error touching '%s'", path)
}
// Read the bazel.list file that the Soong Finder already dumped earlier (hopefully)
@@ -607,12 +436,7 @@
// Assume this was a relative path under topDir
bazelFinderFile = filepath.Join(topDir, bazelFinderFile)
}
- data, err := ioutil.ReadFile(bazelFinderFile)
- if err != nil {
- return nil, err
- }
- files := strings.Split(strings.TrimSpace(string(data)), "\n")
- return files, nil
+ return readFileLines(bazelFinderFile)
}
func bazelArtifacts() []string {
@@ -634,41 +458,25 @@
// Ideally, bp2build would write a file that contains instructions to the
// symlink tree creation binary. Then the latter would not need to depend on
// the very heavy-weight machinery of soong_build .
-func runSymlinkForestCreation(configuration android.Config, ctx *android.Context, extraNinjaDeps []string, metricsDir string) string {
+func runSymlinkForestCreation(ctx *android.Context, extraNinjaDeps []string, metricsDir string) string {
ctx.EventHandler.Do("symlink_forest", func() {
var ninjaDeps []string
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
-
- generatedRoot := shared.JoinPath(configuration.SoongOutDir(), "bp2build")
- workspaceRoot := shared.JoinPath(configuration.SoongOutDir(), "workspace")
-
- excludes := bazelArtifacts()
-
- if outDir[0] != '/' {
- excludes = append(excludes, outDir)
- }
-
- existingBazelRelatedFiles, err := getExistingBazelRelatedFiles(topDir)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error determining existing Bazel-related files: %s\n", err)
- os.Exit(1)
- }
-
- pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(configuration.Bp2buildPackageConfig, topDir, existingBazelRelatedFiles, configuration.IsEnvTrue("BP2BUILD_VERBOSE"))
- excludes = append(excludes, pathsToIgnoredBuildFiles...)
- excludes = append(excludes, getTemporaryExcludes()...)
+ verbose := ctx.Config().IsEnvTrue("BP2BUILD_VERBOSE")
// PlantSymlinkForest() returns all the directories that were readdir()'ed.
// Such a directory SHOULD be added to `ninjaDeps` so that a child directory
// or file created/deleted under it would trigger an update of the symlink forest.
+ generatedRoot := shared.JoinPath(ctx.Config().SoongOutDir(), "bp2build")
+ workspaceRoot := shared.JoinPath(ctx.Config().SoongOutDir(), "workspace")
ctx.EventHandler.Do("plant", func() {
symlinkForestDeps := bp2build.PlantSymlinkForest(
- configuration.IsEnvTrue("BP2BUILD_VERBOSE"), topDir, workspaceRoot, generatedRoot, excludes)
+ verbose, topDir, workspaceRoot, generatedRoot, excludedFromSymlinkForest(ctx, verbose))
ninjaDeps = append(ninjaDeps, symlinkForestDeps...)
})
- writeDepFile(symlinkForestMarker, ctx.EventHandler, ninjaDeps)
- touch(shared.JoinPath(topDir, symlinkForestMarker))
+ writeDepFile(cmdlineArgs.SymlinkForestMarker, ctx.EventHandler, ninjaDeps)
+ touch(shared.JoinPath(topDir, cmdlineArgs.SymlinkForestMarker))
})
codegenMetrics := bp2build.ReadCodegenMetrics(metricsDir)
if codegenMetrics == nil {
@@ -679,21 +487,84 @@
//invocation of codegen. We should simply use a separate .pb file
}
writeBp2BuildMetrics(codegenMetrics, ctx.EventHandler, metricsDir)
+ return cmdlineArgs.SymlinkForestMarker
+}
- return symlinkForestMarker
+func excludedFromSymlinkForest(ctx *android.Context, verbose bool) []string {
+ excluded := bazelArtifacts()
+ if cmdlineArgs.OutDir[0] != '/' {
+ excluded = append(excluded, cmdlineArgs.OutDir)
+ }
+
+ // Find BUILD files in the srcDir which are not in the allowlist
+ // (android.Bp2BuildConversionAllowlist#ShouldKeepExistingBuildFileForDir)
+ // and return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
+ existingBazelFiles, err := getExistingBazelRelatedFiles(topDir)
+ maybeQuit(err, "Error determining existing Bazel-related files")
+
+ for _, path := range existingBazelFiles {
+ fullPath := shared.JoinPath(topDir, path)
+ fileInfo, err2 := os.Stat(fullPath)
+ if err2 != nil {
+ // Warn about error, but continue trying to check files
+ fmt.Fprintf(os.Stderr, "WARNING: Error accessing path '%s', err: %s\n", fullPath, err2)
+ continue
+ }
+ // Exclude only files named 'BUILD' or 'BUILD.bazel' and unless forcibly kept
+ if fileInfo.IsDir() ||
+ (fileInfo.Name() != "BUILD" && fileInfo.Name() != "BUILD.bazel") ||
+ ctx.Config().Bp2buildPackageConfig.ShouldKeepExistingBuildFileForDir(filepath.Dir(path)) {
+ // Don't ignore this existing build file
+ continue
+ }
+ if verbose {
+ fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", path)
+ }
+ excluded = append(excluded, path)
+ }
+
+ // Temporarily exclude stuff to make `bazel build //external/...` (and `bazel build //frameworks/...`) work
+ excluded = append(excluded,
+ // FIXME: 'autotest_lib' is a symlink back to external/autotest, and this causes an infinite
+ // symlink expansion error for Bazel
+ "external/autotest/venv/autotest_lib",
+ "external/autotest/autotest_lib",
+ "external/autotest/client/autotest_lib/client",
+
+ // FIXME: The external/google-fruit/extras/bazel_root/third_party/fruit dir is poison
+ // It contains several symlinks back to real source dirs, and those source dirs contain
+ // BUILD files we want to ignore
+ "external/google-fruit/extras/bazel_root/third_party/fruit",
+
+ // FIXME: 'frameworks/compile/slang' has a filegroup error due to an escaping issue
+ "frameworks/compile/slang",
+
+ // FIXME(b/260809113): 'prebuilts/clang/host/linux-x86/clang-dev' is a tool-generated symlink
+ // directory that contains a BUILD file. The bazel files finder code doesn't traverse into symlink dirs,
+ // and hence is not aware of this BUILD file and exclude it accordingly during symlink forest generation
+ // when checking against keepExistingBuildFiles allowlist.
+ //
+ // This is necessary because globs in //prebuilts/clang/host/linux-x86/BUILD
+ // currently assume no subpackages (keepExistingBuildFile is not recursive for that directory).
+ //
+ // This is a bandaid until we the symlink forest logic can intelligently exclude BUILD files found in
+ // source symlink dirs according to the keepExistingBuildFile allowlist.
+ "prebuilts/clang/host/linux-x86/clang-dev",
+ )
+ return excluded
}
// Run Soong in the bp2build mode. This creates a standalone context that registers
// an alternate pipeline of mutators and singletons specifically for generating
// Bazel BUILD files instead of Ninja files.
-func runBp2Build(configuration android.Config, ctx *android.Context, extraNinjaDeps []string, metricsDir string) string {
+func runBp2Build(ctx *android.Context, extraNinjaDeps []string, metricsDir string) string {
var codegenMetrics *bp2build.CodegenMetrics
ctx.EventHandler.Do("bp2build", func() {
// Propagate "allow misssing dependencies" bit. This is normally set in
// newContext(), but we create ctx without calling that method.
- ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
- ctx.SetNameInterface(newNameResolver(configuration))
+ ctx.SetAllowMissingDependencies(ctx.Config().AllowMissingDependencies())
+ ctx.SetNameInterface(newNameResolver(ctx.Config()))
ctx.RegisterForBazelConversion()
ctx.SetModuleListFile(cmdlineArgs.ModuleListFile)
@@ -705,34 +576,35 @@
// from the regular Modules.
ctx.EventHandler.Do("bootstrap", func() {
blueprintArgs := cmdlineArgs
- bootstrapDeps := bootstrap.RunBlueprint(blueprintArgs, bootstrap.StopBeforePrepareBuildActions, ctx.Context, configuration)
+ bootstrapDeps := bootstrap.RunBlueprint(blueprintArgs.Args,
+ bootstrap.StopBeforePrepareBuildActions, ctx.Context, ctx.Config())
ninjaDeps = append(ninjaDeps, bootstrapDeps...)
})
- globListFiles := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
+ globListFiles := writeBuildGlobsNinjaFile(ctx)
ninjaDeps = append(ninjaDeps, globListFiles...)
// Run the code-generation phase to convert BazelTargetModules to BUILD files
// and print conversion codegenMetrics to the user.
- codegenContext := bp2build.NewCodegenContext(configuration, ctx, bp2build.Bp2Build)
+ codegenContext := bp2build.NewCodegenContext(ctx.Config(), ctx, bp2build.Bp2Build)
ctx.EventHandler.Do("codegen", func() {
codegenMetrics = bp2build.Codegen(codegenContext)
})
ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
- writeDepFile(bp2buildMarker, ctx.EventHandler, ninjaDeps)
- touch(shared.JoinPath(topDir, bp2buildMarker))
+ writeDepFile(cmdlineArgs.Bp2buildMarker, ctx.EventHandler, ninjaDeps)
+ touch(shared.JoinPath(topDir, cmdlineArgs.Bp2buildMarker))
})
// Only report metrics when in bp2build mode. The metrics aren't relevant
// for queryview, since that's a total repo-wide conversion and there's a
// 1:1 mapping for each module.
- if configuration.IsEnvTrue("BP2BUILD_VERBOSE") {
+ if ctx.Config().IsEnvTrue("BP2BUILD_VERBOSE") {
codegenMetrics.Print()
}
writeBp2BuildMetrics(codegenMetrics, ctx.EventHandler, metricsDir)
- return bp2buildMarker
+ return cmdlineArgs.Bp2buildMarker
}
// Write Bp2Build metrics into $LOG_DIR
@@ -751,13 +623,22 @@
codegenMetrics.Write(metricsDir)
}
-func readBazelPaths(configuration android.Config) ([]string, error) {
- depsPath := configuration.Getenv("BAZEL_DEPS_FILE")
-
- data, err := os.ReadFile(depsPath)
- if err != nil {
- return nil, err
+func readFileLines(path string) ([]string, error) {
+ data, err := os.ReadFile(path)
+ if err == nil {
+ return strings.Split(strings.TrimSpace(string(data)), "\n"), nil
}
- paths := strings.Split(strings.TrimSpace(string(data)), "\n")
- return paths, nil
+ return nil, err
+
+}
+func maybeQuit(err error, format string, args ...interface{}) {
+ if err == nil {
+ return
+ }
+ if format != "" {
+ fmt.Fprintln(os.Stderr, fmt.Sprintf(format, args...)+": "+err.Error())
+ } else {
+ fmt.Fprintln(os.Stderr, err)
+ }
+ os.Exit(1)
}
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index a876522..45b451c 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -91,6 +91,19 @@
return err
}
+func writeReadWriteFile(dir string, f bp2build.BazelFile) error {
+ dir = filepath.Join(dir, f.Dir)
+ if err := createDirectoryIfNonexistent(dir); err != nil {
+ return err
+ }
+ pathToFile := filepath.Join(dir, f.Basename)
+
+ // 0644 is read-write
+ err := ioutil.WriteFile(pathToFile, []byte(f.Contents), 0644)
+
+ return err
+}
+
func createDirectoryIfNonexistent(dir string) error {
if _, err := os.Stat(dir); os.IsNotExist(err) {
return os.MkdirAll(dir, os.ModePerm)
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index f7689b9..928ae17 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -117,6 +117,7 @@
// Command is the type of soong_ui execution. Only one type of
// execution is specified. The args are specific to the command.
func main() {
+ //TODO(juu): Add logic to soong_ui to delete a hardcoded list of metrics files
shared.ReexecWithDelveMaybe(os.Getenv("SOONG_UI_DELVE"), shared.ResolveDelveBinary())
buildStarted := time.Now()
@@ -184,6 +185,7 @@
rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
soongMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_metrics")
bp2buildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"bp2build_metrics.pb")
+ soongBuildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_build_metrics.pb")
build.PrintOutDirWarning(buildCtx, config)
@@ -211,11 +213,15 @@
files := []string{
buildErrorFile, // build error strings
rbeMetricsFile, // high level metrics related to remote build execution.
+ soongBuildMetricsFile, // high level metrics related to soong build(except bp2build).
bp2buildMetricsFile, // high level metrics related to bp2build.
soongMetricsFile, // high level metrics related to this build system.
config.BazelMetricsDir(), // directory that contains a set of bazel metrics.
}
- defer build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, files...)
+
+ if !config.SkipMetricsUpload() {
+ defer build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, files...)
+ }
defer met.Dump(soongMetricsFile)
defer build.CheckProdCreds(buildCtx, config)
}
diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go
index 1ee0edc..2ee420c 100644
--- a/filesystem/avb_add_hash_footer.go
+++ b/filesystem/avb_add_hash_footer.go
@@ -149,7 +149,7 @@
cmd.FlagWithArg("--prop ", proptools.ShellEscape(fmt.Sprintf("%s:%s", name, value)))
} else {
p := android.PathForModuleSrc(ctx, file)
- cmd.Input(p)
+ cmd.Implicit(p)
cmd.FlagWithArg("--prop_from_file ", proptools.ShellEscape(fmt.Sprintf("%s:%s", name, cmd.PathForInput(p))))
}
}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 14895c9..f5da50e 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -940,6 +940,8 @@
}
}
+ tags := android.ApexAvailableTags(m)
+
if ctx.ModuleType() == "gensrcs" {
// The Output_extension prop is not in an immediately accessible field
// in the Module struct, so use GetProperties and cast it
@@ -961,7 +963,10 @@
Cmd: cmd,
Tools: tools,
}
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+ Name: m.Name(),
+ Tags: tags,
+ }, attrs)
} else {
// The Out prop is not in an immediately accessible field
// in the Module struct, so use GetProperties and cast it
@@ -982,7 +987,10 @@
props := bazel.BazelTargetModuleProperties{
Rule_class: "genrule",
}
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+ Name: m.Name(),
+ Tags: tags,
+ }, attrs)
}
}
diff --git a/java/builder.go b/java/builder.go
index b1b9a4a..6f8eec9 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -231,7 +231,7 @@
jetifier = pctx.AndroidStaticRule("jetifier",
blueprint.RuleParams{
- Command: "${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.JetifierJar} -l error -o $out -i $in",
+ Command: "${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.JetifierJar} -l error -o $out -i $in -t epoch",
CommandDeps: []string{"${config.JavaCmd}", "${config.JetifierJar}"},
},
)
diff --git a/java/java.go b/java/java.go
index e37a77e..dd24376 100644
--- a/java/java.go
+++ b/java/java.go
@@ -888,6 +888,10 @@
// a list of extra test configuration files that should be installed with the module.
Extra_test_configs []string `android:"path,arch_variant"`
+
+ // Extra <option> tags to add to the auto generated test xml file. The "key"
+ // is optional in each of these.
+ Tradefed_options []tradefed.Option
}
type testProperties struct {
@@ -1166,8 +1170,18 @@
j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest)
}
- j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
- j.testProperties.Test_suites, configs, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test)
+ j.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(j.testProperties.Test_config).
+ SetTestTemplateConfigProp(j.testProperties.Test_config_template).
+ SetTestSuites(j.testProperties.Test_suites).
+ SetConfig(configs).
+ SetOptionsForAutogenerated(j.testProperties.Test_options.Tradefed_options).
+ SetAutoGenConfig(j.testProperties.Auto_gen_config).
+ SetUnitTest(j.testProperties.Test_options.Unit_test).
+ SetDeviceTemplate("${JavaTestConfigTemplate}").
+ SetHostTemplate("${JavaHostTestConfigTemplate}").
+ SetHostUnitTestTemplate("${JavaHostUnitTestConfigTemplate}").
+ Build()
j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
@@ -1212,8 +1226,13 @@
}
func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil,
- j.prebuiltTestProperties.Test_suites, nil, nil, nil)
+ j.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(j.prebuiltTestProperties.Test_config).
+ SetTestSuites(j.prebuiltTestProperties.Test_suites).
+ SetDeviceTemplate("${JavaTestConfigTemplate}").
+ SetHostTemplate("${JavaHostTestConfigTemplate}").
+ SetHostUnitTestTemplate("${JavaHostUnitTestConfigTemplate}").
+ Build()
j.Import.GenerateAndroidBuildActions(ctx)
}
@@ -1567,8 +1586,14 @@
Api_surface *string
// list of Java API contribution modules that consists this API surface
+ // This is a list of Soong modules
Api_contributions []string
+ // list of api.txt files relative to this directory that contribute to the
+ // API surface.
+ // This is a list of relative paths
+ Api_files []string
+
// List of flags to be passed to the javac compiler to generate jar file
Javacflags []string
}
@@ -1665,6 +1690,13 @@
srcFiles = append(srcFiles, android.PathForSource(ctx, provider.ApiFile.String()))
})
+ // Add the api_files inputs
+ for _, api := range al.properties.Api_files {
+ // Use MaybeExistentPathForSource since the api file might not exist during analysis.
+ // This will be provided by the orchestrator in the combined execution.
+ srcFiles = append(srcFiles, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), api))
+ }
+
cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
al.stubsFlags(ctx, cmd, stubsDir)
diff --git a/java/java_test.go b/java/java_test.go
index ff15783..62a372c 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1863,6 +1863,7 @@
name: "bar2",
api_surface: "system",
api_contributions: ["foo1", "foo2"],
+ api_files: ["api1/current.txt", "api2/current.txt"]
}
`,
map[string][]byte{
@@ -1880,7 +1881,7 @@
},
{
moduleName: "bar2",
- sourceTextFileDirs: []string{"a/foo1.txt", "b/foo2.txt"},
+ sourceTextFileDirs: []string{"a/foo1.txt", "b/foo2.txt", "api1/current.txt", "api2/current.txt"},
},
}
for _, c := range testcases {
@@ -1944,3 +1945,25 @@
}
}
}
+
+func TestTradefedOptions(t *testing.T) {
+ result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
+java_test_host {
+ name: "foo",
+ test_options: {
+ tradefed_options: [
+ {
+ name: "exclude-path",
+ value: "org/apache"
+ }
+ ]
+ }
+}
+`)
+ args := result.ModuleForTests("foo", "linux_glibc_common").
+ Output("out/soong/.intermediates/foo/linux_glibc_common/foo.config").Args
+ expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />")
+ if args["extraConfigs"] != expected {
+ t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"])
+ }
+}
diff --git a/java/lint.go b/java/lint.go
index 7a6e5d9..07b9629 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -366,6 +366,9 @@
}
}
+ l.extraLintCheckJars = append(l.extraLintCheckJars, android.PathForSource(ctx,
+ "prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar"))
+
rule := android.NewRuleBuilder(pctx, ctx).
Sbox(android.PathForModuleOut(ctx, "lint"),
android.PathForModuleOut(ctx, "lint.sbox.textproto")).
diff --git a/java/robolectric.go b/java/robolectric.go
index 1d56708..63e05d8 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -131,9 +131,14 @@
r.forceOSType = ctx.Config().BuildOS
r.forceArchType = ctx.Config().BuildArch
- r.testConfig = tradefed.AutoGenRobolectricTestConfig(ctx, r.testProperties.Test_config,
- r.testProperties.Test_config_template, r.testProperties.Test_suites,
- r.testProperties.Auto_gen_config)
+ r.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(r.testProperties.Test_config).
+ SetTestTemplateConfigProp(r.testProperties.Test_config_template).
+ SetTestSuites(r.testProperties.Test_suites).
+ SetAutoGenConfig(r.testProperties.Auto_gen_config).
+ SetDeviceTemplate("${RobolectricTestConfigTemplate}").
+ SetHostTemplate("${RobolectricTestConfigTemplate}").
+ Build()
r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
roboTestConfig := android.PathForModuleGen(ctx, "robolectric").
@@ -296,6 +301,7 @@
entries.ExtraEntries = append(entries.ExtraEntries,
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+ entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", "robolectric-tests")
})
entries.ExtraFooters = []android.AndroidMkExtraFootersFunc{
@@ -329,11 +335,10 @@
fmt.Fprintln(w, "")
fmt.Fprintln(w, "include $(CLEAR_VARS)", " # java.robolectricTest")
fmt.Fprintln(w, "LOCAL_MODULE :=", name)
- fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES :=", module)
- fmt.Fprintln(w, "LOCAL_JAVA_LIBRARIES += ", strings.Join(r.libs, " "))
+ android.AndroidMkEmitAssignList(w, "LOCAL_JAVA_LIBRARIES", []string{module}, r.libs)
fmt.Fprintln(w, "LOCAL_TEST_PACKAGE :=", String(r.robolectricProperties.Instrumentation_for))
fmt.Fprintln(w, "LOCAL_INSTRUMENT_SRCJARS :=", r.roboSrcJar.String())
- fmt.Fprintln(w, "LOCAL_ROBOTEST_FILES :=", strings.Join(tests, " "))
+ android.AndroidMkEmitAssignList(w, "LOCAL_ROBOTEST_FILES", tests)
if t := r.robolectricProperties.Test_options.Timeout; t != nil {
fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
}
diff --git a/java/testing.go b/java/testing.go
index ccbb638..e6f76e1 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -56,6 +56,8 @@
"build/make/target/product/security": nil,
// Required to generate Java used-by API coverage
"build/soong/scripts/gen_java_usedby_apex.sh": nil,
+ // Needed for the global lint checks provided from frameworks/base
+ "prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar": nil,
}.AddToFixture(),
)
diff --git a/licenses/Android.bp b/licenses/Android.bp
index eabc303..7267cf3 100644
--- a/licenses/Android.bp
+++ b/licenses/Android.bp
@@ -921,6 +921,14 @@
}
license_kind {
+ name: "SPDX-license-identifier-Linux-syscall-note",
+ // expanding visibility requires approval from an OSPO lawyer or pcounsel
+ visibility: ["//external/libbpf:__subpackages__"],
+ conditions: ["permissive"],
+ url: "https://spdx.org/licenses/Linux-syscall-note.html",
+}
+
+license_kind {
name: "SPDX-license-identifier-LPL-1.02",
conditions: ["notice"],
url: "https://spdx.org/licenses/LPL-1.02.html",
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index aa48e63..705eac3 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -77,6 +77,8 @@
"add-to-product-copy-files-if-exists": &simpleCallParser{name: baseName + ".copy_if_exists", returnType: starlarkTypeList},
"addprefix": &simpleCallParser{name: baseName + ".addprefix", returnType: starlarkTypeList},
"addsuffix": &simpleCallParser{name: baseName + ".addsuffix", returnType: starlarkTypeList},
+ "and": &andOrParser{isAnd: true},
+ "clear-var-list": &simpleCallParser{name: baseName + ".clear_var_list", returnType: starlarkTypeVoid, addGlobals: true, addHandle: true},
"copy-files": &simpleCallParser{name: baseName + ".copy_files", returnType: starlarkTypeList},
"dir": &simpleCallParser{name: baseName + ".dir", returnType: starlarkTypeString},
"dist-for-goals": &simpleCallParser{name: baseName + ".mkdist_for_goals", returnType: starlarkTypeVoid, addGlobals: true},
@@ -105,6 +107,7 @@
"math_gt": &mathComparisonCallParser{op: ">"},
"math_lt": &mathComparisonCallParser{op: "<"},
"my-dir": &myDirCallParser{},
+ "or": &andOrParser{isAnd: false},
"patsubst": &substCallParser{fname: "patsubst"},
"product-copy-files-by-pattern": &simpleCallParser{name: baseName + ".product_copy_files_by_pattern", returnType: starlarkTypeList},
"require-artifacts-in-path": &simpleCallParser{name: baseName + ".require_artifacts_in_path", returnType: starlarkTypeVoid, addHandle: true},
@@ -114,6 +117,8 @@
"sort": &simpleCallParser{name: baseName + ".mksort", returnType: starlarkTypeList},
"strip": &simpleCallParser{name: baseName + ".mkstrip", returnType: starlarkTypeString},
"subst": &substCallParser{fname: "subst"},
+ "to-lower": &lowerUpperParser{isUpper: false},
+ "to-upper": &lowerUpperParser{isUpper: true},
"warning": &makeControlFuncParser{name: baseName + ".mkwarning"},
"word": &wordCallParser{},
"words": &wordsCallParser{},
@@ -1430,6 +1435,51 @@
return &stringLiteralExpr{literal: filepath.Dir(ctx.script.mkFile)}
}
+type andOrParser struct {
+ isAnd bool
+}
+
+func (p *andOrParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
+ if args.Empty() {
+ return ctx.newBadExpr(node, "and/or function must have at least 1 argument")
+ }
+ op := "or"
+ if p.isAnd {
+ op = "and"
+ }
+
+ argsParsed := make([]starlarkExpr, 0)
+
+ for _, arg := range args.Split(",") {
+ arg.TrimLeftSpaces()
+ arg.TrimRightSpaces()
+ x := ctx.parseMakeString(node, arg)
+ if xBad, ok := x.(*badExpr); ok {
+ return xBad
+ }
+ argsParsed = append(argsParsed, x)
+ }
+ typ := starlarkTypeUnknown
+ for _, arg := range argsParsed {
+ if typ != arg.typ() && arg.typ() != starlarkTypeUnknown && typ != starlarkTypeUnknown {
+ return ctx.newBadExpr(node, "Expected all arguments to $(or) or $(and) to have the same type, found %q and %q", typ.String(), arg.typ().String())
+ }
+ if arg.typ() != starlarkTypeUnknown {
+ typ = arg.typ()
+ }
+ }
+ result := argsParsed[0]
+ for _, arg := range argsParsed[1:] {
+ result = &binaryOpExpr{
+ left: result,
+ right: arg,
+ op: op,
+ returnType: typ,
+ }
+ }
+ return result
+}
+
type isProductInListCallParser struct{}
func (p *isProductInListCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
@@ -1848,6 +1898,24 @@
return []starlarkNode{ctx.newBadNode(node, "Eval expression too complex; only assignments, comments, includes, and inherit-products are supported")}
}
+type lowerUpperParser struct {
+ isUpper bool
+}
+
+func (p *lowerUpperParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
+ fn := "lower"
+ if p.isUpper {
+ fn = "upper"
+ }
+ arg := ctx.parseMakeString(node, args)
+
+ return &callExpr{
+ object: arg,
+ name: fn,
+ returnType: starlarkTypeString,
+ }
+}
+
func (ctx *parseContext) parseMakeString(node mkparser.Node, mk *mkparser.MakeString) starlarkExpr {
if mk.Const() {
return &stringLiteralExpr{mk.Dump()}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 31555d3..65a3be7 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -1629,6 +1629,58 @@
g["MY_VAR_5"] = rblf.mk2rbc_error("product.mk:6", "reference is too complex: $(MY_VAR_2) bar")
`,
},
+ {
+ desc: "Conditional functions",
+ mkname: "product.mk",
+ in: `
+B := foo
+X := $(or $(A))
+X := $(or $(A),$(B))
+X := $(or $(A),$(B),$(C))
+X := $(and $(A))
+X := $(and $(A),$(B))
+X := $(and $(A),$(B),$(C))
+X := $(or $(A),$(B)) Y
+
+D := $(wildcard *.mk)
+X := $(or $(B),$(D))
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["B"] = "foo"
+ g["X"] = g.get("A", "")
+ g["X"] = g.get("A", "") or g["B"]
+ g["X"] = g.get("A", "") or g["B"] or g.get("C", "")
+ g["X"] = g.get("A", "")
+ g["X"] = g.get("A", "") and g["B"]
+ g["X"] = g.get("A", "") and g["B"] and g.get("C", "")
+ g["X"] = "%s Y" % g.get("A", "") or g["B"]
+ g["D"] = rblf.expand_wildcard("*.mk")
+ g["X"] = rblf.mk2rbc_error("product.mk:12", "Expected all arguments to $(or) or $(and) to have the same type, found \"string\" and \"list\"")
+`,
+ },
+ {
+
+ desc: "is-lower/is-upper",
+ mkname: "product.mk",
+ in: `
+X := $(call to-lower,aBc)
+X := $(call to-upper,aBc)
+X := $(call to-lower,$(VAR))
+X := $(call to-upper,$(VAR))
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["X"] = ("aBc").lower()
+ g["X"] = ("aBc").upper()
+ g["X"] = (g.get("VAR", "")).lower()
+ g["X"] = (g.get("VAR", "")).upper()
+`,
+ },
}
var known_variables = []struct {
diff --git a/mk2rbc/types.go b/mk2rbc/types.go
index 46c6aa9..ac32507 100644
--- a/mk2rbc/types.go
+++ b/mk2rbc/types.go
@@ -14,6 +14,8 @@
package mk2rbc
+import "fmt"
+
// Starlark expression types we use
type starlarkType int
@@ -31,6 +33,25 @@
starlarkTypeVoid starlarkType = iota
)
+func (t starlarkType) String() string {
+ switch t {
+ case starlarkTypeList:
+ return "list"
+ case starlarkTypeString:
+ return "string"
+ case starlarkTypeInt:
+ return "int"
+ case starlarkTypeBool:
+ return "bool"
+ case starlarkTypeVoid:
+ return "void"
+ case starlarkTypeUnknown:
+ return "unknown"
+ default:
+ panic(fmt.Sprintf("Unknown starlark type %d", t))
+ }
+}
+
type hiddenArgType int
const (
diff --git a/python/test.go b/python/test.go
index b9b3465..5781df7 100644
--- a/python/test.go
+++ b/python/test.go
@@ -67,9 +67,14 @@
}
func (test *testDecorator) install(ctx android.ModuleContext, file android.Path) {
- test.testConfig = tradefed.AutoGenPythonBinaryHostTestConfig(ctx, test.testProperties.Test_config,
- test.testProperties.Test_config_template, test.binaryDecorator.binaryProperties.Test_suites,
- test.binaryDecorator.binaryProperties.Auto_gen_config)
+ test.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(test.testProperties.Test_config).
+ SetTestTemplateConfigProp(test.testProperties.Test_config_template).
+ SetTestSuites(test.binaryDecorator.binaryProperties.Test_suites).
+ SetAutoGenConfig(test.binaryDecorator.binaryProperties.Auto_gen_config).
+ SetDeviceTemplate("${PythonBinaryHostTestConfigTemplate}").
+ SetHostTemplate("${PythonBinaryHostTestConfigTemplate}").
+ Build()
test.binaryDecorator.pythonInstaller.dir = "nativetest"
test.binaryDecorator.pythonInstaller.dir64 = "nativetest64"
diff --git a/rust/benchmark.go b/rust/benchmark.go
index 0e84243..b417a2d 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -112,12 +112,14 @@
}
func (benchmark *benchmarkDecorator) install(ctx ModuleContext) {
- benchmark.testConfig = tradefed.AutoGenRustBenchmarkConfig(ctx,
- benchmark.Properties.Test_config,
- benchmark.Properties.Test_config_template,
- benchmark.Properties.Test_suites,
- nil,
- benchmark.Properties.Auto_gen_config)
+ benchmark.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(benchmark.Properties.Test_config).
+ SetTestTemplateConfigProp(benchmark.Properties.Test_config_template).
+ SetTestSuites(benchmark.Properties.Test_suites).
+ SetAutoGenConfig(benchmark.Properties.Auto_gen_config).
+ SetDeviceTemplate("${RustDeviceBenchmarkConfigTemplate}").
+ SetHostTemplate("${RustHostBenchmarkConfigTemplate}").
+ Build()
// default relative install path is module name
if !Bool(benchmark.Properties.No_named_install_directory) {
diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go
index 94b719f..3458ec9 100644
--- a/rust/config/x86_64_device.go
+++ b/rust/config/x86_64_device.go
@@ -26,15 +26,18 @@
x86_64LinkFlags = []string{}
x86_64ArchVariantRustFlags = map[string][]string{
- "": []string{},
- "broadwell": []string{"-C target-cpu=broadwell"},
- "haswell": []string{"-C target-cpu=haswell"},
- "ivybridge": []string{"-C target-cpu=ivybridge"},
- "sandybridge": []string{"-C target-cpu=sandybridge"},
- "silvermont": []string{"-C target-cpu=silvermont"},
- "skylake": []string{"-C target-cpu=skylake"},
+ "": []string{},
+ "broadwell": []string{"-C target-cpu=broadwell"},
+ "goldmont": []string{"-C target-cpu=goldmont"},
+ "goldmont-plus": []string{"-C target-cpu=goldmont-plus"},
+ "haswell": []string{"-C target-cpu=haswell"},
+ "ivybridge": []string{"-C target-cpu=ivybridge"},
+ "sandybridge": []string{"-C target-cpu=sandybridge"},
+ "silvermont": []string{"-C target-cpu=silvermont"},
+ "skylake": []string{"-C target-cpu=skylake"},
//TODO: Add target-cpu=stoneyridge when rustc supports it.
"stoneyridge": []string{""},
+ "tremont": []string{"-C target-cpu=tremont"},
}
)
diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go
index 5ae30e7..43f7340 100644
--- a/rust/config/x86_device.go
+++ b/rust/config/x86_device.go
@@ -26,16 +26,19 @@
x86LinkFlags = []string{}
x86ArchVariantRustFlags = map[string][]string{
- "": []string{},
- "atom": []string{"-C target-cpu=atom"},
- "broadwell": []string{"-C target-cpu=broadwell"},
- "haswell": []string{"-C target-cpu=haswell"},
- "ivybridge": []string{"-C target-cpu=ivybridge"},
- "sandybridge": []string{"-C target-cpu=sandybridge"},
- "silvermont": []string{"-C target-cpu=silvermont"},
- "skylake": []string{"-C target-cpu=skylake"},
+ "": []string{},
+ "atom": []string{"-C target-cpu=atom"},
+ "broadwell": []string{"-C target-cpu=broadwell"},
+ "goldmont": []string{"-C target-cpu=goldmont"},
+ "goldmont-plus": []string{"-C target-cpu=goldmont-plus"},
+ "haswell": []string{"-C target-cpu=haswell"},
+ "ivybridge": []string{"-C target-cpu=ivybridge"},
+ "sandybridge": []string{"-C target-cpu=sandybridge"},
+ "silvermont": []string{"-C target-cpu=silvermont"},
+ "skylake": []string{"-C target-cpu=skylake"},
//TODO: Add target-cpu=stoneyridge when rustc supports it.
"stoneyridge": []string{""},
+ "tremont": []string{"-C target-cpu=tremont"},
// use prescott for x86_64, like cc/config/x86_device.go
"x86_64": []string{"-C target-cpu=prescott"},
}
diff --git a/rust/test.go b/rust/test.go
index 0cc3bca..ecc7d5d 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -130,13 +130,16 @@
configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
}
- test.testConfig = tradefed.AutoGenRustTestConfig(ctx,
- test.Properties.Test_config,
- test.Properties.Test_config_template,
- test.Properties.Test_suites,
- configs,
- test.Properties.Auto_gen_config,
- testInstallBase)
+ test.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(test.Properties.Test_config).
+ SetTestTemplateConfigProp(test.Properties.Test_config_template).
+ SetTestSuites(test.Properties.Test_suites).
+ SetConfig(configs).
+ SetAutoGenConfig(test.Properties.Auto_gen_config).
+ SetTestInstallBase(testInstallBase).
+ SetDeviceTemplate("${RustDeviceTestConfigTemplate}").
+ SetHostTemplate("${RustHostTestConfigTemplate}").
+ Build()
dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
diff --git a/scripts/unpack-prebuilt-apex.sh b/scripts/unpack-prebuilt-apex.sh
index f34a480..b244f79 100755
--- a/scripts/unpack-prebuilt-apex.sh
+++ b/scripts/unpack-prebuilt-apex.sh
@@ -17,23 +17,28 @@
# limitations under the License.
# Tool to unpack an apex file and verify that the required files were extracted.
-if [ $# -lt 5 ]; then
- echo "usage: $0 <deapaxer_path> <debugfs_path> <apex file> <output_dir> <required_files>+" >&2
+if [ $# -lt 7 ]; then
+ echo "usage: $0 <deapaxer_path> <debugfs_path> <blkid_path> <fsck.erofs_path> <apex file> <output_dir> <required_files>+" >&2
exit 1
fi
DEAPEXER_PATH=$1
DEBUGFS_PATH=$2
-APEX_FILE=$3
-OUTPUT_DIR=$4
-shift 4
+BLKID_PATH=$3
+FSCK_EROFS_PATH=$4
+APEX_FILE=$5
+OUTPUT_DIR=$6
+shift 6
REQUIRED_PATHS=$@
rm -fr $OUTPUT_DIR
mkdir -p $OUTPUT_DIR
# Unpack the apex file contents.
-$DEAPEXER_PATH --debugfs_path $DEBUGFS_PATH extract $APEX_FILE $OUTPUT_DIR
+$DEAPEXER_PATH --debugfs_path $DEBUGFS_PATH \
+ --blkid_path $BLKID_PATH \
+ --fsckerofs_path $FSCK_EROFS_PATH \
+ extract $APEX_FILE $OUTPUT_DIR
# Verify that the files that the build expects to be in the .apex file actually
# exist, and make sure they have a fresh mtime to not confuse ninja.
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 9627329..4eae397 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -379,8 +379,16 @@
}
configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.PushFilePreparer", options})
}
- s.testConfig = tradefed.AutoGenShellTestConfig(ctx, s.testProperties.Test_config,
- s.testProperties.Test_config_template, s.testProperties.Test_suites, configs, s.testProperties.Auto_gen_config, s.outputFilePath.Base())
+ s.testConfig = tradefed.NewMaybeAutoGenTestConfigBuilder(ctx).
+ SetTestConfigProp(s.testProperties.Test_config).
+ SetTestTemplateConfigProp(s.testProperties.Test_config_template).
+ SetTestSuites(s.testProperties.Test_suites).
+ SetConfig(configs).
+ SetAutoGenConfig(s.testProperties.Auto_gen_config).
+ SetOutputFileName(s.outputFilePath.Base()).
+ SetDeviceTemplate("${ShellTestConfigTemplate}").
+ SetHostTemplate("${ShellTestConfigTemplate}").
+ Build()
s.dataModules = make(map[string]android.Path)
ctx.VisitDirectDeps(func(dep android.Module) {
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
index 5fbbd0f..d579429 100755
--- a/tests/apex_comparison_tests.sh
+++ b/tests/apex_comparison_tests.sh
@@ -29,10 +29,13 @@
# Test Setup
############
-OUTPUT_DIR="$(mktemp -d)"
+OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
SOONG_OUTPUT_DIR="$OUTPUT_DIR/soong"
BAZEL_OUTPUT_DIR="$OUTPUT_DIR/bazel"
+export TARGET_PRODUCT="module_arm"
+[ "$#" -eq 1 ] && export TARGET_PRODUCT="$1"
+
function call_bazel() {
build/bazel/bin/bazel --output_base="$BAZEL_OUTPUT_DIR" $@
}
@@ -50,7 +53,7 @@
export UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true # don't rely on prebuilts
export TARGET_BUILD_APPS="com.android.adbd com.android.tzdata build.bazel.examples.apex.minimal"
packages/modules/common/build/build_unbundled_mainline_module.sh \
- --product module_arm \
+ --product "$TARGET_PRODUCT" \
--dist_dir "$SOONG_OUTPUT_DIR"
######################
@@ -60,22 +63,15 @@
BAZEL_OUT="$(call_bazel info --config=bp2build output_path)"
-export TARGET_PRODUCT="module_arm"
call_bazel build --config=bp2build --config=ci --config=android \
//packages/modules/adb/apex:com.android.adbd \
//system/timezone/apex:com.android.tzdata \
//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex
-# Build debugfs separately, as it's not a dep of apexer, but needs to be an explicit arg.
-call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs
-DEBUGFS_PATH="$BAZEL_OUT/linux_x86_64-fastbuild/bin/external/e2fsprogs/debugfs/debugfs"
-
-function run_deapexer() {
- call_bazel run --config=bp2build --config=linux_x86_64 //system/apex/tools:deapexer \
- -- \
- --debugfs_path="$DEBUGFS_PATH" \
- $@
-}
+# # Build debugfs separately, as it's not a dep of apexer, but needs to be an explicit arg.
+call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs //system/apex/tools:deapexer
+DEBUGFS_PATH="$BAZEL_OUT/linux_x86_64-opt/bin/external/e2fsprogs/debugfs/debugfs"
+DEAPEXER="$BAZEL_OUT/linux_x86_64-opt/bin/system/apex/tools/deapexer --debugfs_path=$DEBUGFS_PATH"
#######
# Tests
@@ -87,13 +83,13 @@
# Compare the outputs of `deapexer list`, which lists the contents of the apex filesystem image.
local SOONG_APEX="$SOONG_OUTPUT_DIR/$APEX"
- local BAZEL_APEX="$BAZEL_OUT/android_target-fastbuild/bin/$APEX_DIR/$APEX"
+ local BAZEL_APEX="$BAZEL_OUT/android_target-opt/bin/$APEX_DIR/$APEX"
local SOONG_LIST="$OUTPUT_DIR/soong.list"
local BAZEL_LIST="$OUTPUT_DIR/bazel.list"
- run_deapexer list "$SOONG_APEX" > "$SOONG_LIST"
- run_deapexer list "$BAZEL_APEX" > "$BAZEL_LIST"
+ $DEAPEXER list "$SOONG_APEX" > "$SOONG_LIST"
+ $DEAPEXER list "$BAZEL_APEX" > "$BAZEL_LIST"
if cmp -s "$SOONG_LIST" "$BAZEL_LIST"
then
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index d89e6b7..17b4419 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -17,11 +17,11 @@
function test_null_build() {
setup
run_soong
- local bootstrap_mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
- local output_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r bootstrap_mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
+ local -r output_mtime1=$(stat -c "%y" out/soong/build.ninja)
run_soong
- local bootstrap_mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
- local output_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r bootstrap_mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
+ local -r output_mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$bootstrap_mtime1" == "$bootstrap_mtime2" ]]; then
# Bootstrapping is always done. It doesn't take a measurable amount of time.
@@ -36,12 +36,12 @@
function test_soong_build_rebuilt_if_blueprint_changes() {
setup
run_soong
- local mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
sed -i 's/pluginGenSrcCmd/pluginGenSrcCmd2/g' build/blueprint/bootstrap/bootstrap.go
run_soong
- local mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Bootstrap Ninja file did not change"
@@ -79,7 +79,7 @@
function test_add_android_bp() {
setup
run_soong
- local mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
mkdir -p a
cat > a/Android.bp <<'EOF'
@@ -91,7 +91,7 @@
touch a/my_little_binary_host.py
run_soong
- local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Output Ninja file did not change"
fi
@@ -142,7 +142,7 @@
EOF
touch a/my_little_binary_host.py
run_soong
- local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
local glob_deps_file=out/soong/globs/build/0.d
@@ -151,7 +151,7 @@
fi
run_soong
- local ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
# There is an ineffiencency in glob that requires bpglob to rerun once for each glob to update
# the entry in the .ninja_log. It doesn't update the output file, but we can detect the rerun
@@ -160,15 +160,15 @@
fail "Glob deps file missing after second build"
fi
- local glob_deps_mtime2=$(stat -c "%y" "$glob_deps_file")
+ local -r glob_deps_mtime2=$(stat -c "%y" "$glob_deps_file")
if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
fail "Ninja file rewritten on null incremental build"
fi
run_soong
- local ninja_mtime3=$(stat -c "%y" out/soong/build.ninja)
- local glob_deps_mtime3=$(stat -c "%y" "$glob_deps_file")
+ local -r ninja_mtime3=$(stat -c "%y" out/soong/build.ninja)
+ local -r glob_deps_mtime3=$(stat -c "%y" "$glob_deps_file")
if [[ "$ninja_mtime2" != "$ninja_mtime3" ]]; then
fail "Ninja file rewritten on null incremental build"
@@ -192,12 +192,12 @@
EOF
touch a/my_little_binary_host.py
run_soong
- local mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
touch a/my_little_library.py
run_soong
- local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Output Ninja file did not change"
fi
@@ -275,10 +275,10 @@
run_soong
grep -q "CHERRY IS RED" out/soong/build.ninja \
|| fail "second value of environment variable not used"
- local mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
run_soong
- local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$mtime1" != "$mtime2" ]]; then
fail "Output Ninja file changed when environment variable did not"
fi
@@ -288,7 +288,7 @@
function test_create_global_include_directory() {
setup
run_soong
- local mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
# Soong needs to know if top level directories like hardware/ exist for use
# as global include directories. Make sure that doesn't cause regens for
@@ -296,7 +296,7 @@
mkdir -p system/core
run_soong
- local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$mtime1" != "$mtime2" ]]; then
fail "Output Ninja file changed when top level directory changed"
fi
@@ -306,7 +306,7 @@
mkdir -p system/core/include
run_soong
- local mtime3=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime3=$(stat -c "%y" out/soong/build.ninja)
if [[ "$mtime2" = "$mtime3" ]]; then
fail "Output Ninja file did not change when global include directory created"
fi
@@ -317,7 +317,7 @@
function test_add_file_to_soong_build() {
setup
run_soong
- local mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
mkdir -p a
cat > a/Android.bp <<'EOF'
@@ -379,7 +379,7 @@
EOF
run_soong
- local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Output Ninja file did not change"
fi
@@ -457,7 +457,7 @@
EOF
run_soong
- local mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
grep -q "Make it so" out/soong/build.ninja || fail "Original action not present"
@@ -489,7 +489,7 @@
EOF
run_soong
- local mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Output Ninja file did not change"
fi
@@ -514,20 +514,20 @@
setup
run_soong
- local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
run_soong soong_docs
- local docs_mtime1=$(stat -c "%y" out/soong/docs/soong_build.html)
+ local -r docs_mtime1=$(stat -c "%y" out/soong/docs/soong_build.html)
run_soong soong_docs
- local docs_mtime2=$(stat -c "%y" out/soong/docs/soong_build.html)
+ local -r docs_mtime2=$(stat -c "%y" out/soong/docs/soong_build.html)
if [[ "$docs_mtime1" != "$docs_mtime2" ]]; then
fail "Output Ninja file changed on null build"
fi
run_soong
- local ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
fail "Output Ninja file changed on null build"
@@ -552,7 +552,7 @@
run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=false ${EXPECTED_OUT} &> /dev/null && \
fail "Write to source tree should not work in a ReadOnly source tree"
- if grep -q "${ERROR_MSG}" ${ERROR_LOG} && grep -q "${ERROR_HINT_PATTERN}" ${ERROR_LOG} ; then
+ if grep -q "${ERROR_MSG}" "${ERROR_LOG}" && grep -q "${ERROR_HINT_PATTERN}" "${ERROR_LOG}" ; then
echo Error message and error hint found in logs >/dev/null
else
fail "Did not find Read-only error AND error hint in error.log"
@@ -562,7 +562,7 @@
run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true ${EXPECTED_OUT} &> /dev/null || \
fail "Write to source tree did not succeed in a ReadWrite source tree"
- if grep -q "${ERROR_MSG}\|${ERROR_HINT_PATTERN}" ${ERROR_LOG} ; then
+ if grep -q "${ERROR_MSG}\|${ERROR_HINT_PATTERN}" "${ERROR_LOG}" ; then
fail "Found read-only error OR error hint in error.log"
fi
}
@@ -606,11 +606,11 @@
fail "BUILD file in symlink forest was not created";
fi
- local mtime1=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
+ local -r mtime1=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
touch a/irrelevant.txt
run_soong bp2build
- local mtime2=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
+ local -r mtime2=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
if [[ "$mtime1" != "$mtime2" ]]; then
fail "BUILD.bazel file was regenerated"
@@ -657,10 +657,10 @@
setup
run_soong bp2build
- local mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+ local -r mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
run_soong bp2build
- local mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+ local -r mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
if [[ "$mtime1" != "$mtime2" ]]; then
fail "Output Ninja file changed on null build"
@@ -717,19 +717,19 @@
setup
run_soong
- local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
run_soong json-module-graph
- local json_mtime1=$(stat -c "%y" out/soong/module-graph.json)
+ local -r json_mtime1=$(stat -c "%y" out/soong/module-graph.json)
run_soong
- local ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
fail "Output Ninja file changed after writing JSON module graph"
fi
run_soong json-module-graph
- local json_mtime2=$(stat -c "%y" out/soong/module-graph.json)
+ local -r json_mtime2=$(stat -c "%y" out/soong/module-graph.json)
if [[ "$json_mtime1" != "$json_mtime2" ]]; then
fail "JSON module graph file changed after writing Ninja file"
fi
@@ -837,19 +837,19 @@
setup
run_soong
- local output_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r output_mtime1=$(stat -c "%y" out/soong/build.ninja)
run_soong bp2build
- local output_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r output_mtime2=$(stat -c "%y" out/soong/build.ninja)
if [[ "$output_mtime1" != "$output_mtime2" ]]; then
fail "Output Ninja file changed when switching to bp2build"
fi
- local marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+ local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
run_soong
- local output_mtime3=$(stat -c "%y" out/soong/build.ninja)
- local marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+ local -r output_mtime3=$(stat -c "%y" out/soong/build.ninja)
+ local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
if [[ "$output_mtime1" != "$output_mtime3" ]]; then
fail "Output Ninja file changed when switching to regular build from bp2build"
fi
@@ -858,8 +858,8 @@
fi
run_soong bp2build
- local output_mtime4=$(stat -c "%y" out/soong/build.ninja)
- local marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+ local -r output_mtime4=$(stat -c "%y" out/soong/build.ninja)
+ local -r marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
if [[ "$output_mtime1" != "$output_mtime4" ]]; then
fail "Output Ninja file changed when switching back to bp2build"
fi
@@ -880,44 +880,14 @@
setup
run_soong queryview
- local output_mtime1=$(stat -c "%y" out/soong/queryview.marker)
+ local -r output_mtime1=$(stat -c "%y" out/soong/queryview.marker)
run_soong queryview
- local output_mtime2=$(stat -c "%y" out/soong/queryview.marker)
+ local -r output_mtime2=$(stat -c "%y" out/soong/queryview.marker)
if [[ "$output_mtime1" != "$output_mtime2" ]]; then
fail "Queryview marker file changed on null build"
fi
}
-test_smoke
-test_null_build
-test_soong_docs_smoke
-test_null_build_after_soong_docs
-test_soong_build_rebuilt_if_blueprint_changes
-test_glob_noop_incremental
-test_add_file_to_glob
-test_add_android_bp
-test_change_android_bp
-test_delete_android_bp
-test_add_file_to_soong_build
-test_glob_during_bootstrapping
-test_soong_build_rerun_iff_environment_changes
-test_create_global_include_directory
-test_multiple_soong_build_modes
-test_dump_json_module_graph
-test_json_module_graph_back_and_forth_null_build
-test_write_to_source_tree
-test_queryview_smoke
-test_queryview_null_build
-test_bp2build_smoke
-test_bp2build_generates_marker_file
-test_bp2build_null_build
-test_bp2build_back_and_forth_null_build
-test_bp2build_add_android_bp
-test_bp2build_add_irrelevant_file
-test_bp2build_add_to_glob
-test_bp2build_bazel_workspace_structure
-test_bp2build_bazel_workspace_add_file
-test_bp2build_build_file_precedence
-test_bp2build_reports_multiple_errors
+scan_and_run_tests
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index 679ac55..6a47e9f 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -8,7 +8,7 @@
readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
-function test_bp2build_null_build() {
+function test_bp2build_null_build {
setup
run_soong bp2build
local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
@@ -21,9 +21,7 @@
fi
}
-test_bp2build_null_build
-
-function test_bp2build_null_build_with_globs() {
+function test_bp2build_null_build_with_globs {
setup
mkdir -p foo/bar
@@ -46,8 +44,6 @@
fi
}
-test_bp2build_null_build_with_globs
-
function test_different_relative_outdir {
setup
@@ -65,11 +61,9 @@
outdir=out2
trap "rm -rf $outdir" EXIT
# Modify OUT_DIR in a subshell so it doesn't affect the top level one.
- (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build //a:g)
+ (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
}
-test_different_relative_outdir
-
function test_different_absolute_outdir {
setup
@@ -87,12 +81,10 @@
outdir=$(mktemp -t -d st.XXXXX)
trap 'rm -rf $outdir' EXIT
# Modify OUT_DIR in a subshell so it doesn't affect the top level one.
- (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build //a:g)
+ (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
}
-test_different_absolute_outdir
-
-function test_bp2build_generates_all_buildfiles {
+function _bp2build_generates_all_buildfiles {
setup
mkdir -p foo/convertible_soong_module
@@ -146,9 +138,9 @@
fi
# NOTE: We don't actually use the extra BUILD file for anything here
- run_bazel build --config=android --package_path=out/soong/workspace //foo/...
+ run_bazel build --config=android --config=bp2build --config=ci //foo/...
- local the_answer_file="bazel-out/android_target-fastbuild/bin/foo/convertible_soong_module/the_answer.txt"
+ local the_answer_file="bazel-out/android_target-opt/bin/foo/convertible_soong_module/the_answer.txt"
if [[ ! -f "${the_answer_file}" ]]; then
fail "Expected '${the_answer_file}' to be generated, but was missing"
fi
@@ -157,10 +149,12 @@
fi
}
-_save_trap=$(trap -p EXIT)
-trap '[[ $? -ne 0 ]] && echo Are you running this locally? Try changing --sandbox_tmpfs_path to something other than /tmp/ in build/bazel/linux.bazelrc.' EXIT
-test_bp2build_generates_all_buildfiles
-eval ${_save_trap}
+function test_bp2build_generates_all_buildfiles {
+ _save_trap=$(trap -p EXIT)
+ trap '[[ $? -ne 0 ]] && echo Are you running this locally? Try changing --sandbox_tmpfs_path to something other than /tmp/ in build/bazel/linux.bazelrc.' EXIT
+ _bp2build_generates_all_buildfiles
+ eval "${_save_trap}"
+}
function test_cc_correctness {
setup
@@ -191,10 +185,10 @@
run_soong bp2build
- run_bazel build --config=android --package_path=out/soong/workspace //a:qq
+ run_bazel build --config=android --config=bp2build --config=ci //a:qq
local -r output_mtime1=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
- run_bazel build --config=android --package_path=out/soong/workspace //a:qq
+ run_bazel build --config=android --config=bp2build --config=ci //a:qq
local -r output_mtime2=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
if [[ "$output_mtime1" != "$output_mtime2" ]]; then
@@ -205,7 +199,7 @@
#define QQ 2
EOF
- run_bazel build --config=android --package_path=out/soong/workspace //a:qq
+ run_bazel build --config=android --config=bp2build --config=ci //a:qq
local -r output_mtime3=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
if [[ "$output_mtime1" == "$output_mtime3" ]]; then
@@ -213,8 +207,6 @@
fi
}
-test_cc_correctness
-
# Regression test for the following failure during symlink forest creation:
#
# Cannot stat '/tmp/st.rr054/foo/bar/unresolved_symlink': stat /tmp/st.rr054/foo/bar/unresolved_symlink: no such file or directory
@@ -239,4 +231,4 @@
fi
}
-test_bp2build_null_build_with_unresolved_symlink_in_source
+scan_and_run_tests
diff --git a/tests/lib.sh b/tests/lib.sh
index e40f0ad..ae8875a 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -119,6 +119,7 @@
copy_directory build/bazel
copy_directory build/bazel_common_rules
+ symlink_directory packages/modules/common/build
symlink_directory prebuilts/bazel
symlink_directory prebuilts/clang
symlink_directory prebuilts/jdk
@@ -150,3 +151,16 @@
export ALLOW_MISSING_DEPENDENCIES=true
export ALLOW_BP_UNDER_SYMLINKS=true
warmup_mock_top
+
+function scan_and_run_tests {
+ # find all test_ functions
+ # NB "declare -F" output is sorted, hence test order is deterministic
+ readarray -t test_fns < <(declare -F | sed -n -e 's/^declare -f \(test_.*\)$/\1/p')
+ info "Found ${#test_fns[*]} tests"
+ if [[ ${#test_fns[*]} -eq 0 ]]; then
+ fail "No tests found"
+ fi
+ for f in ${test_fns[*]}; do
+ $f
+ done
+}
\ No newline at end of file
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index 1e07727..7a71b27 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -13,3 +13,4 @@
# The following tests build against the full source tree and don't rely on the
# mock client.
"$TOP/build/soong/tests/apex_comparison_tests.sh"
+"$TOP/build/soong/tests/apex_comparison_tests.sh" "module_arm64only"
diff --git a/tradefed/Android.bp b/tradefed/Android.bp
index f0336a3..a161108 100644
--- a/tradefed/Android.bp
+++ b/tradefed/Android.bp
@@ -11,6 +11,7 @@
],
srcs: [
"autogen.go",
+ "autogen_bazel.go",
"config.go",
"makevars.go",
],
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index c2429ab..236e559 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -107,15 +107,134 @@
}
-func autogenTemplate(ctx android.ModuleContext, output android.WritablePath, template string, configs []Config, testInstallBase string) {
- autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), output, template, configs, "", testInstallBase)
+// MaybeAutoGenTestConfigBuilder provides a Build() method that will either
+// generate a AndroidTest.xml file, or use an existing user-supplied one.
+// It used to be a bunch of separate functions for each language, but was
+// converted to this builder pattern to have one function that accepts many
+// optional arguments.
+type MaybeAutoGenTestConfigBuilder struct {
+ ctx android.ModuleContext
+ name string
+ outputFileName string
+ testConfigProp *string
+ testConfigTemplateProp *string
+ testSuites []string
+ config []Config
+ configsForAutogenerated []Config
+ autoGenConfig *bool
+ unitTest *bool
+ testInstallBase string
+ deviceTemplate string
+ hostTemplate string
+ hostUnitTestTemplate string
}
-func autogenTemplateWithName(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, testInstallBase string) {
- autogenTemplateWithNameAndOutputFile(ctx, name, output, template, configs, "", testInstallBase)
+func NewMaybeAutoGenTestConfigBuilder(ctx android.ModuleContext) *MaybeAutoGenTestConfigBuilder {
+ return &MaybeAutoGenTestConfigBuilder{
+ ctx: ctx,
+ name: ctx.ModuleName(),
+ }
}
-func autogenTemplateWithNameAndOutputFile(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string, testInstallBase string) {
+func (b *MaybeAutoGenTestConfigBuilder) SetName(name string) *MaybeAutoGenTestConfigBuilder {
+ b.name = name
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetOutputFileName(outputFileName string) *MaybeAutoGenTestConfigBuilder {
+ b.outputFileName = outputFileName
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetTestConfigProp(testConfigProp *string) *MaybeAutoGenTestConfigBuilder {
+ b.testConfigProp = testConfigProp
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetTestTemplateConfigProp(testConfigTemplateProp *string) *MaybeAutoGenTestConfigBuilder {
+ b.testConfigTemplateProp = testConfigTemplateProp
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetTestSuites(testSuites []string) *MaybeAutoGenTestConfigBuilder {
+ b.testSuites = testSuites
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetConfig(config []Config) *MaybeAutoGenTestConfigBuilder {
+ b.config = config
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetOptionsForAutogenerated(configsForAutogenerated []Option) *MaybeAutoGenTestConfigBuilder {
+ configs := make([]Config, 0, len(configsForAutogenerated))
+ for _, c := range configsForAutogenerated {
+ configs = append(configs, c)
+ }
+ b.configsForAutogenerated = configs
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetUnitTest(unitTest *bool) *MaybeAutoGenTestConfigBuilder {
+ b.unitTest = unitTest
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetAutoGenConfig(autoGenConfig *bool) *MaybeAutoGenTestConfigBuilder {
+ b.autoGenConfig = autoGenConfig
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetTestInstallBase(testInstallBase string) *MaybeAutoGenTestConfigBuilder {
+ b.testInstallBase = testInstallBase
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetDeviceTemplate(deviceTemplate string) *MaybeAutoGenTestConfigBuilder {
+ b.deviceTemplate = deviceTemplate
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetHostTemplate(hostTemplate string) *MaybeAutoGenTestConfigBuilder {
+ b.hostTemplate = hostTemplate
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) SetHostUnitTestTemplate(hostUnitTestTemplate string) *MaybeAutoGenTestConfigBuilder {
+ b.hostUnitTestTemplate = hostUnitTestTemplate
+ return b
+}
+
+func (b *MaybeAutoGenTestConfigBuilder) Build() android.Path {
+ config := append(b.config, b.configsForAutogenerated...)
+ path, autogenPath := testConfigPath(b.ctx, b.testConfigProp, b.testSuites, b.autoGenConfig, b.testConfigTemplateProp)
+ if autogenPath != nil {
+ templatePath := getTestConfigTemplate(b.ctx, b.testConfigTemplateProp)
+ if templatePath.Valid() {
+ autogenTemplate(b.ctx, b.name, autogenPath, templatePath.String(), config, b.outputFileName, b.testInstallBase)
+ } else {
+ if b.ctx.Device() {
+ autogenTemplate(b.ctx, b.name, autogenPath, b.deviceTemplate, config, b.outputFileName, b.testInstallBase)
+ } else {
+ if Bool(b.unitTest) {
+ autogenTemplate(b.ctx, b.name, autogenPath, b.hostUnitTestTemplate, config, b.outputFileName, b.testInstallBase)
+ } else {
+ autogenTemplate(b.ctx, b.name, autogenPath, b.hostTemplate, config, b.outputFileName, b.testInstallBase)
+ }
+ }
+ }
+ return autogenPath
+ }
+ if len(b.configsForAutogenerated) > 0 {
+ b.ctx.ModuleErrorf("Extra tradefed configurations were provided for an autogenerated xml file, but the autogenerated xml file was not used.")
+ }
+ return path
+}
+
+func autogenTemplate(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string, testInstallBase string) {
+ if template == "" {
+ ctx.ModuleErrorf("Empty template")
+ }
var configStrings []string
for _, config := range configs {
configStrings = append(configStrings, config.Config())
@@ -137,148 +256,6 @@
})
}
-func AutoGenNativeTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, testInstallBase string) android.Path {
-
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), config, testInstallBase)
- } else {
- if ctx.Device() {
- autogenTemplate(ctx, autogenPath, "${NativeTestConfigTemplate}", config, testInstallBase)
- } else {
- autogenTemplate(ctx, autogenPath, "${NativeHostTestConfigTemplate}", config, testInstallBase)
- }
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenShellTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, outputFileName string) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), autogenPath, templatePath.String(), config, outputFileName, "")
- } else {
- autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), autogenPath, "${ShellTestConfigTemplate}", config, outputFileName, "")
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenNativeBenchmarkTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, configs []Config, autoGenConfig *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), configs, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${NativeBenchmarkTestConfigTemplate}", configs, "")
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
- testSuites []string, config []Config, autoGenConfig *bool, unitTest *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), config, "")
- } else {
- if ctx.Device() {
- autogenTemplate(ctx, autogenPath, "${JavaTestConfigTemplate}", config, "")
- } else {
- if Bool(unitTest) {
- autogenTemplate(ctx, autogenPath, "${JavaHostUnitTestConfigTemplate}", config, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", config, "")
- }
- }
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenPythonBinaryHostTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, autoGenConfig *bool) android.Path {
-
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), nil, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${PythonBinaryHostTestConfigTemplate}", nil, "")
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenRustTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, testInstallBase string) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), config, testInstallBase)
- } else {
- if ctx.Device() {
- autogenTemplate(ctx, autogenPath, "${RustDeviceTestConfigTemplate}", config, testInstallBase)
- } else {
- autogenTemplate(ctx, autogenPath, "${RustHostTestConfigTemplate}", config, testInstallBase)
- }
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenRustBenchmarkConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), config, "")
- } else {
- if ctx.Device() {
- autogenTemplate(ctx, autogenPath, "${RustDeviceBenchmarkConfigTemplate}", config, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${RustHostBenchmarkConfigTemplate}", config, "")
- }
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenRobolectricTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
- testSuites []string, autoGenConfig *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), nil, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${RobolectricTestConfigTemplate}", nil, "")
- }
- return autogenPath
- }
- return path
-}
-
var autogenInstrumentationTest = pctx.StaticRule("autogenInstrumentationTest", blueprint.RuleParams{
Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template ${extraConfigs}",
CommandDeps: []string{
diff --git a/tradefed/autogen_bazel.go b/tradefed/autogen_bazel.go
new file mode 100644
index 0000000..d3109d9
--- /dev/null
+++ b/tradefed/autogen_bazel.go
@@ -0,0 +1,105 @@
+// Copyright 2022 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 tradefed
+
+import (
+ "android/soong/android"
+ "android/soong/bazel"
+
+ "github.com/google/blueprint/proptools"
+)
+
+const (
+ InstrumentationTestConfigTemplate = "build/make/core/instrumentation_test_config_template.xml"
+ JavaTestConfigTemplate = "build/make/core/java_test_config_template.xml"
+ JavaHostTestConfigTemplate = "build/make/core/java_host_test_config_template.xml"
+ JavaHostUnitTestConfigTemplate = "build/make/core/java_host_unit_test_config_template.xml"
+ NativeBenchmarkTestConfigTemplate = "build/make/core/native_benchmark_test_config_template.xml"
+ NativeHostTestConfigTemplate = "build/make/core/native_host_test_config_template.xml"
+ NativeTestConfigTemplate = "build/make/core/native_test_config_template.xml"
+ PythonBinaryHostTestConfigTemplate = "build/make/core/python_binary_host_test_config_template.xml"
+ RustDeviceTestConfigTemplate = "build/make/core/rust_device_test_config_template.xml"
+ RustHostTestConfigTemplate = "build/make/core/rust_host_test_config_template.xml"
+ RustDeviceBenchmarkConfigTemplate = "build/make/core/rust_device_benchmark_config_template.xml"
+ RustHostBenchmarkConfigTemplate = "build/make/core/rust_host_benchmark_config_template.xml"
+ RobolectricTestConfigTemplate = "build/make/core/robolectric_test_config_template.xml"
+ ShellTestConfigTemplate = "build/make/core/shell_test_config_template.xml"
+)
+
+type TestConfigAttributes struct {
+ Test_config *bazel.Label
+
+ Auto_generate_test_config *bool
+ Template_test_config *bazel.Label
+ Template_configs []string
+ Template_install_base *string
+}
+
+func GetTestConfigAttributes(
+ ctx android.TopDownMutatorContext,
+ testConfig *string,
+ extraTestConfigs []string,
+ autoGenConfig *bool,
+ testSuites []string,
+ template *string,
+ templateConfigs []Config,
+ templateInstallBase *string) TestConfigAttributes {
+
+ attrs := TestConfigAttributes{}
+ attrs.Test_config = GetTestConfig(ctx, testConfig)
+ // do not generate a test config if
+ // 1) test config already found
+ // 2) autoGenConfig == false
+ // 3) CTS tests and no template specified.
+ // CTS Modules can be used for test data, so test config files must be explicitly specified.
+ if (attrs.Template_test_config != nil) ||
+ proptools.Bool(autoGenConfig) == false ||
+ (template == nil && !android.InList("cts", testSuites)) {
+
+ return attrs
+ }
+
+ // Add properties for the bazel rule to generate a test config
+ // since a test config was not specified.
+ templateLabel := android.BazelLabelForModuleSrcSingle(ctx, *template)
+ attrs.Template_test_config = &templateLabel
+ attrs.Auto_generate_test_config = autoGenConfig
+ var configStrings []string
+ for _, c := range templateConfigs {
+ configString := proptools.NinjaAndShellEscape(c.Config())
+ configStrings = append(configStrings, configString)
+ }
+ attrs.Template_configs = configStrings
+ attrs.Template_install_base = templateInstallBase
+ return attrs
+}
+
+func GetTestConfig(
+ ctx android.TopDownMutatorContext,
+ testConfig *string,
+) *bazel.Label {
+
+ if testConfig != nil {
+ c, _ := android.BazelStringOrLabelFromProp(ctx, testConfig)
+ if c.Value != nil {
+ return c.Value
+ }
+ }
+
+ // check for default AndroidTest.xml
+ defaultTestConfigPath := ctx.ModuleDir() + "/AndroidTest.xml"
+ c, _ := android.BazelStringOrLabelFromProp(ctx, &defaultTestConfigPath)
+ return c.Value
+}
diff --git a/ui/build/config.go b/ui/build/config.go
index ef2e87e..a6bba15 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -65,24 +65,25 @@
buildDateTime string
// From the arguments
- parallel int
- keepGoing int
- verbose bool
- checkbuild bool
- dist bool
- jsonModuleGraph bool
- apiBp2build bool // Generate BUILD files for Soong modules that contribute APIs
- bp2build bool
- queryview bool
- reportMkMetrics bool // Collect and report mk2bp migration progress metrics.
- soongDocs bool
- skipConfig bool
- skipKati bool
- skipKatiNinja bool
- skipSoong bool
- skipNinja bool
- skipSoongTests bool
- searchApiDir bool // Scan the Android.bp files generated in out/api_surfaces
+ parallel int
+ keepGoing int
+ verbose bool
+ checkbuild bool
+ dist bool
+ jsonModuleGraph bool
+ apiBp2build bool // Generate BUILD files for Soong modules that contribute APIs
+ bp2build bool
+ queryview bool
+ reportMkMetrics bool // Collect and report mk2bp migration progress metrics.
+ soongDocs bool
+ skipConfig bool
+ skipKati bool
+ skipKatiNinja bool
+ skipSoong bool
+ skipNinja bool
+ skipSoongTests bool
+ searchApiDir bool // Scan the Android.bp files generated in out/api_surfaces
+ skipMetricsUpload bool
// From the product config
katiArgs []string
@@ -735,6 +736,8 @@
c.skipConfig = true
} else if arg == "--skip-soong-tests" {
c.skipSoongTests = true
+ } else if arg == "--skip-metrics-upload" {
+ c.skipMetricsUpload = true
} else if arg == "--mk-metrics" {
c.reportMkMetrics = true
} else if arg == "--bazel-mode" {
@@ -1512,6 +1515,10 @@
return c.bazelForceEnabledModules
}
+func (c *configImpl) SkipMetricsUpload() bool {
+ return c.skipMetricsUpload
+}
+
func GetMetricsUploader(topDir string, env *Environment) string {
if p, ok := env.Get("METRICS_UPLOADER"); ok {
metricsUploader := filepath.Join(topDir, p)
diff --git a/ui/build/rbe.go b/ui/build/rbe.go
index c3e52c6..3c844c1 100644
--- a/ui/build/rbe.go
+++ b/ui/build/rbe.go
@@ -148,7 +148,7 @@
}
if !config.StubbyExists() && prodCredsAuthType(config) {
fmt.Fprintln(ctx.Writer, "")
- fmt.Fprintln(ctx.Writer, fmt.Sprintf("\033[33mWARNING: %q binary not found in $PATH, follow go/build-fast#opting-out-of-loas-credentials instead for authenticating with RBE.\033[0m", "stubby"))
+ fmt.Fprintln(ctx.Writer, fmt.Sprintf("\033[33mWARNING: %q binary not found in $PATH, follow go/build-fast-without-stubby instead for authenticating with RBE.\033[0m", "stubby"))
fmt.Fprintln(ctx.Writer, "")
return
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index b89ca20..370b1bc 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -566,11 +566,12 @@
targets = append(targets, config.SoongNinjaFile())
}
+ // TODO(juu): Stop embedding soong_build_metrics in soong_metrics.
+ soongBuildMetricsFile := filepath.Join(config.LogsDir(), "soong_build_metrics.pb")
+ if err := os.Remove(soongBuildMetricsFile); err != nil && !os.IsNotExist(err) {
+ ctx.Verbosef("Failed to remove %s", soongBuildMetricsFile)
+ }
if shouldCollectBuildSoongMetrics(config) {
- soongBuildMetricsFile := filepath.Join(config.LogsDir(), "soong_build_metrics.pb")
- if err := os.Remove(soongBuildMetricsFile); err != nil && !os.IsNotExist(err) {
- ctx.Verbosef("Failed to remove %s", soongBuildMetricsFile)
- }
defer func() {
soongBuildMetrics := loadSoongBuildMetrics(ctx, soongBuildMetricsFile)
if soongBuildMetrics != nil {