Merge "Add external/musl to the bp2build allowlists"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 957d3ea..73021d7 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -732,8 +732,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",
@@ -1354,7 +1353,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",
}
@@ -1365,5 +1363,8 @@
// 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"}
+ StagingMixedBuildsEnabledList = []string{
+ "com.android.adbd",
+ "com.android.tzdata",
+ }
)
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/bazel_handler.go b/android/bazel_handler.go
index 122495f..908b2d6 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -16,7 +16,6 @@
import (
"bytes"
- "errors"
"fmt"
"os"
"os/exec"
@@ -376,107 +375,74 @@
}
func NewBazelContext(c *config) (BazelContext, error) {
- var modulesDefaultToBazel bool
disabledModules := map[string]bool{}
enabledModules := map[string]bool{}
+ addToStringSet := func(set map[string]bool, items []string) {
+ for _, item := range items {
+ set[item] = true
+ }
+ }
switch c.BuildMode {
case BazelProdMode:
- modulesDefaultToBazel = false
-
- for _, enabledProdModule := range allowlists.ProdMixedBuildsEnabledList {
- enabledModules[enabledProdModule] = true
- }
-
+ addToStringSet(enabledModules, allowlists.ProdMixedBuildsEnabledList)
for enabledAdHocModule := range c.BazelModulesForceEnabledByFlag() {
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
- }
-
+ addToStringSet(enabledModules, allowlists.ProdMixedBuildsEnabledList)
+ addToStringSet(enabledModules, allowlists.StagingMixedBuildsEnabledList)
for enabledAdHocModule := range c.BazelModulesForceEnabledByFlag() {
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:
return noopBazelContext{}, nil
}
- p, err := bazelPathsFromConfig(c)
- if err != nil {
- return nil, err
+ 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
}
diff --git a/android/register.go b/android/register.go
index 6cfc205..33e9ea3 100644
--- a/android/register.go
+++ b/android/register.go
@@ -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)
}
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..01e4f12 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) {
@@ -3078,31 +3087,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..1f2be35 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) {
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/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/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/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/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/bp2build.go b/cc/bp2build.go
index 6ed62fc..510ecee 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -406,6 +406,8 @@
features bazel.StringListAttribute
suffix bazel.StringAttribute
+
+ fdoProfile bazel.LabelAttribute
}
type filterOutFn func(string) bool
@@ -790,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))
}
@@ -806,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,
@@ -1270,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/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_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/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/cmd/soong_build/main.go b/cmd/soong_build/main.go
index f4a63a4..bea8df0 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -238,7 +238,12 @@
soongInjectionFiles := bp2build.CreateSoongInjectionFiles(configuration, bp2build.CreateCodegenMetrics())
absoluteSoongInjectionDir := shared.JoinPath(topDir, configuration.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")
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/java/java.go b/java/java.go
index e37a77e..9dd5850 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1567,8 +1567,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 +1671,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..dff1fd0 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 {
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..6e8d591 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -296,6 +296,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 +330,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..c3b192d 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -77,6 +77,7 @@
"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},
"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 +106,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 +116,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 +1434,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 +1897,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/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/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..07738b7 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
@@ -68,8 +64,6 @@
(export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build //a:g)
}
-test_different_relative_outdir
-
function test_different_absolute_outdir {
setup
@@ -90,9 +84,7 @@
(export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build //a:g)
}
-test_different_absolute_outdir
-
-function test_bp2build_generates_all_buildfiles {
+function _bp2build_generates_all_buildfiles {
setup
mkdir -p foo/convertible_soong_module
@@ -148,7 +140,7 @@
# NOTE: We don't actually use the extra BUILD file for anything here
run_bazel build --config=android --package_path=out/soong/workspace //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
@@ -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..f68199a 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -150,3 +150,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/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/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 {