Merge "Add support for prepending text from a file"
diff --git a/android/Android.bp b/android/Android.bp
index f58a472..e0ad58f 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -38,7 +38,9 @@
"bazel_paths.go",
"buildinfo_prop.go",
"config.go",
+ "test_config.go",
"config_bp2build.go",
+ "configured_jars.go",
"csuite_config.go",
"deapexer.go",
"defaults.go",
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index e606cb1..692e554 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -215,6 +215,10 @@
"system/libartpalette": Bp2BuildDefaultTrueRecursively,
"system/libbase": Bp2BuildDefaultTrueRecursively,
"system/libfmq": Bp2BuildDefaultTrue,
+ "system/libhidl/transport/base/1.0": Bp2BuildDefaultTrue,
+ "system/libhidl/transport/manager/1.0": Bp2BuildDefaultTrue,
+ "system/libhidl/transport/manager/1.1": Bp2BuildDefaultTrue,
+ "system/libhidl/transport/manager/1.2": Bp2BuildDefaultTrue,
"system/libhwbinder": Bp2BuildDefaultTrueRecursively,
"system/libprocinfo": Bp2BuildDefaultTrue,
"system/libziparchive": Bp2BuildDefaultTrueRecursively,
@@ -258,6 +262,7 @@
// build/make/tools/signapk BUILD file is generated, so build/make/tools is not recursive.
"build/make/tools":/* recursive = */ false,
"build/pesto":/* recursive = */ true,
+ "build/soong/ui/metrics/bp2build_progress_metrics_proto":/* recursive = */ true,
// external/bazelbuild-rules_android/... is needed by mixed builds, otherwise mixed builds analysis fails
// e.g. ERROR: Analysis of target '@soong_injection//mixed_builds:buildroot' failed
@@ -382,6 +387,10 @@
"car-ui-androidx-core-common-nodeps",
"car-ui-androidx-lifecycle-common-nodeps",
"car-ui-androidx-constraintlayout-solver-nodeps",
+
+ //system/libhidl
+ // needed by cc_hidl_library
+ "libhidlbase",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -566,5 +575,12 @@
"prebuilt_android-support-annotations-nodeps",
"prebuilt_android-arch-paging-common-nodeps",
"prebuilt_android-arch-room-common-nodeps",
+
+ // Disabled pending the investigation of b/242220039
+ "libhidlbase",
+ "android.hidl.base@1.0",
+ "android.hidl.manager@1.0",
+ "android.hidl.manager@1.1",
+ "android.hidl.manager@1.2",
}
)
diff --git a/android/arch.go b/android/arch.go
index 6acc8ad..b5bd2f0 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -393,54 +393,6 @@
}
}
-func registerBp2buildArchPathDepsMutator(ctx RegisterMutatorsContext) {
- ctx.BottomUp("bp2build-arch-pathdeps", bp2buildArchPathDepsMutator).Parallel()
-}
-
-// add dependencies for architecture specific properties tagged with `android:"path"`
-func bp2buildArchPathDepsMutator(ctx BottomUpMutatorContext) {
- var module Module
- module = ctx.Module()
-
- m := module.base()
- if !m.ArchSpecific() {
- return
- }
-
- // addPathDepsForProps does not descend into sub structs, so we need to descend into the
- // arch-specific properties ourselves
- var properties []interface{}
- for _, archProperties := range m.archProperties {
- for _, archProps := range archProperties {
- archPropValues := reflect.ValueOf(archProps).Elem()
- // there are three "arch" variations, descend into each
- for _, variant := range []string{"Arch", "Multilib", "Target"} {
- // The properties are an interface, get the value (a pointer) that it points to
- archProps := archPropValues.FieldByName(variant).Elem()
- if archProps.IsNil() {
- continue
- }
- // And then a pointer to a struct
- archProps = archProps.Elem()
- for i := 0; i < archProps.NumField(); i += 1 {
- f := archProps.Field(i)
- // If the value of the field is a struct (as opposed to a pointer to a struct) then step
- // into the BlueprintEmbed field.
- if f.Kind() == reflect.Struct {
- f = f.FieldByName("BlueprintEmbed")
- }
- if f.IsZero() {
- continue
- }
- props := f.Interface().(interface{})
- properties = append(properties, props)
- }
- }
- }
- }
- addPathDepsForProps(ctx, properties)
-}
-
// osMutator splits an arch-specific module into a variant for each OS that is enabled for the
// module. It uses the HostOrDevice value passed to InitAndroidArchModule and the
// device_supported and host_supported properties to determine which OsTypes are enabled for this
@@ -998,19 +950,13 @@
if string(field.Tag) != `android:"`+strings.Join(values, ",")+`"` {
panic(fmt.Errorf("unexpected tag format %q", field.Tag))
}
- // don't delete path tag as it is needed for bp2build
// these tags don't need to be present in the runtime generated struct type.
- values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend"})
- if len(values) > 0 && values[0] != "path" {
+ values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend", "path"})
+ if len(values) > 0 {
panic(fmt.Errorf("unknown tags %q in field %q", values, prefix+field.Name))
- } else if len(values) == 1 {
- // FIXME(b/200678898): This assumes that the only tag type when there's
- // `android:"arch_variant"` is `android` itself and thus clobbers others
- field.Tag = reflect.StructTag(`android:"` + strings.Join(values, ",") + `"`)
- } else {
- field.Tag = ``
}
+ field.Tag = ``
return true, field
}
return false, field
diff --git a/android/arch_test.go b/android/arch_test.go
index dd0b115..ad2076d 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -66,9 +66,9 @@
}{},
out: &struct {
A *string
- B *string `android:"path"`
- C *string `android:"path"`
- D *string `android:"path"`
+ B *string
+ C *string
+ D *string
}{},
filtered: true,
},
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 5804a46..a5fa043 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -29,6 +29,7 @@
"android/soong/bazel/cquery"
"android/soong/shared"
+
"github.com/google/blueprint"
"android/soong/bazel"
@@ -54,7 +55,7 @@
}
func RegisterMixedBuildsMutator(ctx RegistrationContext) {
- ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
+ ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
})
}
@@ -766,9 +767,9 @@
cqueryOutput, cqueryErr, err := context.issueBazelCommand(context.paths, bazel.CqueryBuildRootRunName, cqueryCmd,
"--output=starlark", "--starlark:file="+absolutePath(cqueryFileRelpath))
if err != nil {
- _ = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"), []byte(cqueryOutput), 0666)
+ return err
}
- if err != nil {
+ if err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"), []byte(cqueryOutput), 0666); err != nil {
return err
}
diff --git a/android/config.go b/android/config.go
index 84c17de..d3f8ab4 100644
--- a/android/config.go
+++ b/android/config.go
@@ -20,7 +20,6 @@
import (
"bytes"
"encoding/json"
- "errors"
"fmt"
"io/ioutil"
"os"
@@ -345,123 +344,6 @@
}
}
-// TestConfig returns a Config object for testing.
-func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
- envCopy := make(map[string]string)
- for k, v := range env {
- envCopy[k] = v
- }
-
- // Copy the real PATH value to the test environment, it's needed by
- // NonHermeticHostSystemTool() used in x86_darwin_host.go
- envCopy["PATH"] = os.Getenv("PATH")
-
- config := &config{
- productVariables: productVariables{
- DeviceName: stringPtr("test_device"),
- DeviceProduct: stringPtr("test_product"),
- Platform_sdk_version: intPtr(30),
- Platform_sdk_codename: stringPtr("S"),
- Platform_base_sdk_extension_version: intPtr(1),
- Platform_version_active_codenames: []string{"S", "Tiramisu"},
- DeviceSystemSdkVersions: []string{"14", "15"},
- Platform_systemsdk_versions: []string{"29", "30"},
- AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
- AAPTPreferredConfig: stringPtr("xhdpi"),
- AAPTCharacteristics: stringPtr("nosdcard"),
- AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
- UncompressPrivAppDex: boolPtr(true),
- ShippingApiLevel: stringPtr("30"),
- },
-
- outDir: buildDir,
- soongOutDir: filepath.Join(buildDir, "soong"),
- captureBuild: true,
- env: envCopy,
-
- // Set testAllowNonExistentPaths so that test contexts don't need to specify every path
- // passed to PathForSource or PathForModuleSrc.
- TestAllowNonExistentPaths: true,
-
- BazelContext: noopBazelContext{},
- mixedBuildDisabledModules: make(map[string]struct{}),
- mixedBuildEnabledModules: make(map[string]struct{}),
- }
- config.deviceConfig = &deviceConfig{
- config: config,
- }
- config.TestProductVariables = &config.productVariables
-
- config.mockFileSystem(bp, fs)
-
- determineBuildOS(config)
-
- return Config{config}
-}
-
-func modifyTestConfigToSupportArchMutator(testConfig Config) {
- config := testConfig.config
-
- config.Targets = map[OsType][]Target{
- Android: []Target{
- {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
- {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false},
- },
- config.BuildOS: []Target{
- {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
- {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
- },
- }
-
- if runtime.GOOS == "darwin" {
- config.Targets[config.BuildOS] = config.Targets[config.BuildOS][:1]
- }
-
- config.BuildOSTarget = config.Targets[config.BuildOS][0]
- config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
- config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
- config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
- config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
- config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a")
- config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm")
- config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon")
-}
-
-func modifyTestConfigForMusl(config Config) {
- delete(config.Targets, config.BuildOS)
- config.productVariables.HostMusl = boolPtr(true)
- determineBuildOS(config.config)
- config.Targets[config.BuildOS] = []Target{
- {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
- {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
- }
-
- config.BuildOSTarget = config.Targets[config.BuildOS][0]
- config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
-}
-
-// TestArchConfig returns a Config object suitable for using for tests that
-// need to run the arch mutator.
-func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
- testConfig := TestConfig(buildDir, env, bp, fs)
- modifyTestConfigToSupportArchMutator(testConfig)
- return testConfig
-}
-
-// ConfigForAdditionalRun is a config object which is "reset" for another
-// bootstrap run. Only per-run data is reset. Data which needs to persist across
-// multiple runs in the same program execution is carried over (such as Bazel
-// context or environment deps).
-func ConfigForAdditionalRun(c Config) (Config, error) {
- newConfig, err := NewConfig(c.moduleListFile, c.runGoTests, c.outDir, c.soongOutDir, c.env)
- if err != nil {
- return Config{}, err
- }
- newConfig.BazelContext = c.BazelContext
- newConfig.envDeps = c.envDeps
- return newConfig, nil
-}
-
// 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, runGoTests bool, outDir, soongOutDir string, availableEnv map[string]string) (Config, error) {
@@ -744,7 +626,8 @@
// these per device type.
//
// NOTE: Do not base conditional logic on this value. It may break product
-// inheritance.
+//
+// inheritance.
func (c *config) DeviceProduct() string {
return *c.productVariables.DeviceProduct
}
@@ -915,6 +798,15 @@
return PathForSource(ctx, filepath.Dir(defaultCert))
}
+// Certificate for the NetworkStack sepolicy context
+func (c *config) MainlineSepolicyDevCertificatesDir(ctx ModuleContext) SourcePath {
+ cert := String(c.productVariables.MainlineSepolicyDevCertificates)
+ if cert != "" {
+ return PathForSource(ctx, cert)
+ }
+ return c.DefaultAppCertificateDir(ctx)
+}
+
// AllowMissingDependencies configures Blueprint/Soong to not fail when modules
// are configured to depend on non-existent modules. Note that this does not
// affect missing input dependencies at the Ninja level.
@@ -1737,316 +1629,6 @@
return c.productVariables.IgnorePrefer32OnDevice
}
-// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
-// Such lists are used in the build system for things like bootclasspath jars or system server jars.
-// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
-// module name. The pairs come from Make product variables as a list of colon-separated strings.
-//
-// Examples:
-// - "com.android.art:core-oj"
-// - "platform:framework"
-// - "system_ext:foo"
-//
-type ConfiguredJarList struct {
- // A list of apex components, which can be an apex name,
- // or special names like "platform" or "system_ext".
- apexes []string
-
- // A list of jar module name components.
- jars []string
-}
-
-// Len returns the length of the list of jars.
-func (l *ConfiguredJarList) Len() int {
- return len(l.jars)
-}
-
-// Jar returns the idx-th jar component of (apex, jar) pairs.
-func (l *ConfiguredJarList) Jar(idx int) string {
- return l.jars[idx]
-}
-
-// Apex returns the idx-th apex component of (apex, jar) pairs.
-func (l *ConfiguredJarList) Apex(idx int) string {
- return l.apexes[idx]
-}
-
-// ContainsJar returns true if the (apex, jar) pairs contains a pair with the
-// given jar module name.
-func (l *ConfiguredJarList) ContainsJar(jar string) bool {
- return InList(jar, l.jars)
-}
-
-// If the list contains the given (apex, jar) pair.
-func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool {
- for i := 0; i < l.Len(); i++ {
- if apex == l.apexes[i] && jar == l.jars[i] {
- return true
- }
- }
- return false
-}
-
-// ApexOfJar returns the apex component of the first pair with the given jar name on the list, or
-// an empty string if not found.
-func (l *ConfiguredJarList) ApexOfJar(jar string) string {
- if idx := IndexList(jar, l.jars); idx != -1 {
- return l.Apex(IndexList(jar, l.jars))
- }
- return ""
-}
-
-// IndexOfJar returns the first pair with the given jar name on the list, or -1
-// if not found.
-func (l *ConfiguredJarList) IndexOfJar(jar string) int {
- return IndexList(jar, l.jars)
-}
-
-func copyAndAppend(list []string, item string) []string {
- // Create the result list to be 1 longer than the input.
- result := make([]string, len(list)+1)
-
- // Copy the whole input list into the result.
- count := copy(result, list)
-
- // Insert the extra item at the end.
- result[count] = item
-
- return result
-}
-
-// Append an (apex, jar) pair to the list.
-func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
- // Create a copy of the backing arrays before appending to avoid sharing backing
- // arrays that are mutated across instances.
- apexes := copyAndAppend(l.apexes, apex)
- jars := copyAndAppend(l.jars, jar)
-
- return ConfiguredJarList{apexes, jars}
-}
-
-// Append a list of (apex, jar) pairs to the list.
-func (l *ConfiguredJarList) AppendList(other *ConfiguredJarList) ConfiguredJarList {
- apexes := make([]string, 0, l.Len()+other.Len())
- jars := make([]string, 0, l.Len()+other.Len())
-
- apexes = append(apexes, l.apexes...)
- jars = append(jars, l.jars...)
-
- apexes = append(apexes, other.apexes...)
- jars = append(jars, other.jars...)
-
- return ConfiguredJarList{apexes, jars}
-}
-
-// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs.
-func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
- apexes := make([]string, 0, l.Len())
- jars := make([]string, 0, l.Len())
-
- for i, jar := range l.jars {
- apex := l.apexes[i]
- if !list.containsApexJarPair(apex, jar) {
- apexes = append(apexes, apex)
- jars = append(jars, jar)
- }
- }
-
- return ConfiguredJarList{apexes, jars}
-}
-
-// Filter keeps the entries if a jar appears in the given list of jars to keep. Returns a new list
-// and any remaining jars that are not on this list.
-func (l *ConfiguredJarList) Filter(jarsToKeep []string) (ConfiguredJarList, []string) {
- var apexes []string
- var jars []string
-
- for i, jar := range l.jars {
- if InList(jar, jarsToKeep) {
- apexes = append(apexes, l.apexes[i])
- jars = append(jars, jar)
- }
- }
-
- return ConfiguredJarList{apexes, jars}, RemoveListFromList(jarsToKeep, jars)
-}
-
-// CopyOfJars returns a copy of the list of strings containing jar module name
-// components.
-func (l *ConfiguredJarList) CopyOfJars() []string {
- return CopyOf(l.jars)
-}
-
-// CopyOfApexJarPairs returns a copy of the list of strings with colon-separated
-// (apex, jar) pairs.
-func (l *ConfiguredJarList) CopyOfApexJarPairs() []string {
- pairs := make([]string, 0, l.Len())
-
- for i, jar := range l.jars {
- apex := l.apexes[i]
- pairs = append(pairs, apex+":"+jar)
- }
-
- return pairs
-}
-
-// BuildPaths returns a list of build paths based on the given directory prefix.
-func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths {
- paths := make(WritablePaths, l.Len())
- for i, jar := range l.jars {
- paths[i] = dir.Join(ctx, ModuleStem(jar)+".jar")
- }
- return paths
-}
-
-// BuildPathsByModule returns a map from module name to build paths based on the given directory
-// prefix.
-func (l *ConfiguredJarList) BuildPathsByModule(ctx PathContext, dir OutputPath) map[string]WritablePath {
- paths := map[string]WritablePath{}
- for _, jar := range l.jars {
- paths[jar] = dir.Join(ctx, ModuleStem(jar)+".jar")
- }
- return paths
-}
-
-// UnmarshalJSON converts JSON configuration from raw bytes into a
-// ConfiguredJarList structure.
-func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error {
- // Try and unmarshal into a []string each item of which contains a pair
- // <apex>:<jar>.
- var list []string
- err := json.Unmarshal(b, &list)
- if err != nil {
- // Did not work so return
- return err
- }
-
- apexes, jars, err := splitListOfPairsIntoPairOfLists(list)
- if err != nil {
- return err
- }
- l.apexes = apexes
- l.jars = jars
- return nil
-}
-
-func (l *ConfiguredJarList) MarshalJSON() ([]byte, error) {
- if len(l.apexes) != len(l.jars) {
- return nil, errors.New(fmt.Sprintf("Inconsistent ConfiguredJarList: apexes: %q, jars: %q", l.apexes, l.jars))
- }
-
- list := make([]string, 0, len(l.apexes))
-
- for i := 0; i < len(l.apexes); i++ {
- list = append(list, l.apexes[i]+":"+l.jars[i])
- }
-
- return json.Marshal(list)
-}
-
-// ModuleStem hardcodes the stem of framework-minus-apex to return "framework".
-//
-// TODO(b/139391334): hard coded until we find a good way to query the stem of a
-// module before any other mutators are run.
-func ModuleStem(module string) string {
- if module == "framework-minus-apex" {
- return "framework"
- }
- return module
-}
-
-// DevicePaths computes the on-device paths for the list of (apex, jar) pairs,
-// based on the operating system.
-func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string {
- paths := make([]string, l.Len())
- for i, jar := range l.jars {
- apex := l.apexes[i]
- name := ModuleStem(jar) + ".jar"
-
- var subdir string
- if apex == "platform" {
- subdir = "system/framework"
- } else if apex == "system_ext" {
- subdir = "system_ext/framework"
- } else {
- subdir = filepath.Join("apex", apex, "javalib")
- }
-
- if ostype.Class == Host {
- paths[i] = filepath.Join(cfg.Getenv("OUT_DIR"), "host", cfg.PrebuiltOS(), subdir, name)
- } else {
- paths[i] = filepath.Join("/", subdir, name)
- }
- }
- return paths
-}
-
-func (l *ConfiguredJarList) String() string {
- var pairs []string
- for i := 0; i < l.Len(); i++ {
- pairs = append(pairs, l.apexes[i]+":"+l.jars[i])
- }
- return strings.Join(pairs, ",")
-}
-
-func splitListOfPairsIntoPairOfLists(list []string) ([]string, []string, error) {
- // Now we need to populate this list by splitting each item in the slice of
- // pairs and appending them to the appropriate list of apexes or jars.
- apexes := make([]string, len(list))
- jars := make([]string, len(list))
-
- for i, apexjar := range list {
- apex, jar, err := splitConfiguredJarPair(apexjar)
- if err != nil {
- return nil, nil, err
- }
- apexes[i] = apex
- jars[i] = jar
- }
-
- return apexes, jars, nil
-}
-
-// Expected format for apexJarValue = <apex name>:<jar name>
-func splitConfiguredJarPair(str string) (string, string, error) {
- pair := strings.SplitN(str, ":", 2)
- if len(pair) == 2 {
- apex := pair[0]
- jar := pair[1]
- if apex == "" {
- return apex, jar, fmt.Errorf("invalid apex '%s' in <apex>:<jar> pair '%s', expected format: <apex>:<jar>", apex, str)
- }
- return apex, jar, nil
- } else {
- return "error-apex", "error-jar", fmt.Errorf("malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
- }
-}
-
-// CreateTestConfiguredJarList is a function to create ConfiguredJarList for tests.
-func CreateTestConfiguredJarList(list []string) ConfiguredJarList {
- // Create the ConfiguredJarList in as similar way as it is created at runtime by marshalling to
- // a json list of strings and then unmarshalling into a ConfiguredJarList instance.
- b, err := json.Marshal(list)
- if err != nil {
- panic(err)
- }
-
- var jarList ConfiguredJarList
- err = json.Unmarshal(b, &jarList)
- if err != nil {
- panic(err)
- }
-
- return jarList
-}
-
-// EmptyConfiguredJarList returns an empty jar list.
-func EmptyConfiguredJarList() ConfiguredJarList {
- return ConfiguredJarList{}
-}
-
-var earlyBootJarsKey = NewOnceKey("earlyBootJars")
-
func (c *config) BootJars() []string {
return c.Once(earlyBootJarsKey, func() interface{} {
list := c.productVariables.BootJars.CopyOfJars()
diff --git a/android/configured_jars.go b/android/configured_jars.go
new file mode 100644
index 0000000..53fef05
--- /dev/null
+++ b/android/configured_jars.go
@@ -0,0 +1,314 @@
+// 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 android
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "path/filepath"
+ "strings"
+)
+
+// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
+// Such lists are used in the build system for things like bootclasspath jars or system server jars.
+// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
+// module name. The pairs come from Make product variables as a list of colon-separated strings.
+//
+// Examples:
+// - "com.android.art:core-oj"
+// - "platform:framework"
+// - "system_ext:foo"
+type ConfiguredJarList struct {
+ // A list of apex components, which can be an apex name,
+ // or special names like "platform" or "system_ext".
+ apexes []string
+
+ // A list of jar module name components.
+ jars []string
+}
+
+// Len returns the length of the list of jars.
+func (l *ConfiguredJarList) Len() int {
+ return len(l.jars)
+}
+
+// Jar returns the idx-th jar component of (apex, jar) pairs.
+func (l *ConfiguredJarList) Jar(idx int) string {
+ return l.jars[idx]
+}
+
+// Apex returns the idx-th apex component of (apex, jar) pairs.
+func (l *ConfiguredJarList) Apex(idx int) string {
+ return l.apexes[idx]
+}
+
+// ContainsJar returns true if the (apex, jar) pairs contains a pair with the
+// given jar module name.
+func (l *ConfiguredJarList) ContainsJar(jar string) bool {
+ return InList(jar, l.jars)
+}
+
+// If the list contains the given (apex, jar) pair.
+func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool {
+ for i := 0; i < l.Len(); i++ {
+ if apex == l.apexes[i] && jar == l.jars[i] {
+ return true
+ }
+ }
+ return false
+}
+
+// ApexOfJar returns the apex component of the first pair with the given jar name on the list, or
+// an empty string if not found.
+func (l *ConfiguredJarList) ApexOfJar(jar string) string {
+ if idx := IndexList(jar, l.jars); idx != -1 {
+ return l.Apex(IndexList(jar, l.jars))
+ }
+ return ""
+}
+
+// IndexOfJar returns the first pair with the given jar name on the list, or -1
+// if not found.
+func (l *ConfiguredJarList) IndexOfJar(jar string) int {
+ return IndexList(jar, l.jars)
+}
+
+func copyAndAppend(list []string, item string) []string {
+ // Create the result list to be 1 longer than the input.
+ result := make([]string, len(list)+1)
+
+ // Copy the whole input list into the result.
+ count := copy(result, list)
+
+ // Insert the extra item at the end.
+ result[count] = item
+
+ return result
+}
+
+// Append an (apex, jar) pair to the list.
+func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
+ // Create a copy of the backing arrays before appending to avoid sharing backing
+ // arrays that are mutated across instances.
+ apexes := copyAndAppend(l.apexes, apex)
+ jars := copyAndAppend(l.jars, jar)
+
+ return ConfiguredJarList{apexes, jars}
+}
+
+// Append a list of (apex, jar) pairs to the list.
+func (l *ConfiguredJarList) AppendList(other *ConfiguredJarList) ConfiguredJarList {
+ apexes := make([]string, 0, l.Len()+other.Len())
+ jars := make([]string, 0, l.Len()+other.Len())
+
+ apexes = append(apexes, l.apexes...)
+ jars = append(jars, l.jars...)
+
+ apexes = append(apexes, other.apexes...)
+ jars = append(jars, other.jars...)
+
+ return ConfiguredJarList{apexes, jars}
+}
+
+// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs.
+func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
+ apexes := make([]string, 0, l.Len())
+ jars := make([]string, 0, l.Len())
+
+ for i, jar := range l.jars {
+ apex := l.apexes[i]
+ if !list.containsApexJarPair(apex, jar) {
+ apexes = append(apexes, apex)
+ jars = append(jars, jar)
+ }
+ }
+
+ return ConfiguredJarList{apexes, jars}
+}
+
+// Filter keeps the entries if a jar appears in the given list of jars to keep. Returns a new list
+// and any remaining jars that are not on this list.
+func (l *ConfiguredJarList) Filter(jarsToKeep []string) (ConfiguredJarList, []string) {
+ var apexes []string
+ var jars []string
+
+ for i, jar := range l.jars {
+ if InList(jar, jarsToKeep) {
+ apexes = append(apexes, l.apexes[i])
+ jars = append(jars, jar)
+ }
+ }
+
+ return ConfiguredJarList{apexes, jars}, RemoveListFromList(jarsToKeep, jars)
+}
+
+// CopyOfJars returns a copy of the list of strings containing jar module name
+// components.
+func (l *ConfiguredJarList) CopyOfJars() []string {
+ return CopyOf(l.jars)
+}
+
+// CopyOfApexJarPairs returns a copy of the list of strings with colon-separated
+// (apex, jar) pairs.
+func (l *ConfiguredJarList) CopyOfApexJarPairs() []string {
+ pairs := make([]string, 0, l.Len())
+
+ for i, jar := range l.jars {
+ apex := l.apexes[i]
+ pairs = append(pairs, apex+":"+jar)
+ }
+
+ return pairs
+}
+
+// BuildPaths returns a list of build paths based on the given directory prefix.
+func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths {
+ paths := make(WritablePaths, l.Len())
+ for i, jar := range l.jars {
+ paths[i] = dir.Join(ctx, ModuleStem(jar)+".jar")
+ }
+ return paths
+}
+
+// BuildPathsByModule returns a map from module name to build paths based on the given directory
+// prefix.
+func (l *ConfiguredJarList) BuildPathsByModule(ctx PathContext, dir OutputPath) map[string]WritablePath {
+ paths := map[string]WritablePath{}
+ for _, jar := range l.jars {
+ paths[jar] = dir.Join(ctx, ModuleStem(jar)+".jar")
+ }
+ return paths
+}
+
+// UnmarshalJSON converts JSON configuration from raw bytes into a
+// ConfiguredJarList structure.
+func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error {
+ // Try and unmarshal into a []string each item of which contains a pair
+ // <apex>:<jar>.
+ var list []string
+ err := json.Unmarshal(b, &list)
+ if err != nil {
+ // Did not work so return
+ return err
+ }
+
+ apexes, jars, err := splitListOfPairsIntoPairOfLists(list)
+ if err != nil {
+ return err
+ }
+ l.apexes = apexes
+ l.jars = jars
+ return nil
+}
+
+func (l *ConfiguredJarList) MarshalJSON() ([]byte, error) {
+ if len(l.apexes) != len(l.jars) {
+ return nil, errors.New(fmt.Sprintf("Inconsistent ConfiguredJarList: apexes: %q, jars: %q", l.apexes, l.jars))
+ }
+
+ list := make([]string, 0, len(l.apexes))
+
+ for i := 0; i < len(l.apexes); i++ {
+ list = append(list, l.apexes[i]+":"+l.jars[i])
+ }
+
+ return json.Marshal(list)
+}
+
+// ModuleStem hardcodes the stem of framework-minus-apex to return "framework".
+//
+// TODO(b/139391334): hard coded until we find a good way to query the stem of a
+// module before any other mutators are run.
+func ModuleStem(module string) string {
+ if module == "framework-minus-apex" {
+ return "framework"
+ }
+ return module
+}
+
+// DevicePaths computes the on-device paths for the list of (apex, jar) pairs,
+// based on the operating system.
+func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string {
+ paths := make([]string, l.Len())
+ for i, jar := range l.jars {
+ apex := l.apexes[i]
+ name := ModuleStem(jar) + ".jar"
+
+ var subdir string
+ if apex == "platform" {
+ subdir = "system/framework"
+ } else if apex == "system_ext" {
+ subdir = "system_ext/framework"
+ } else {
+ subdir = filepath.Join("apex", apex, "javalib")
+ }
+
+ if ostype.Class == Host {
+ paths[i] = filepath.Join(cfg.Getenv("OUT_DIR"), "host", cfg.PrebuiltOS(), subdir, name)
+ } else {
+ paths[i] = filepath.Join("/", subdir, name)
+ }
+ }
+ return paths
+}
+
+func (l *ConfiguredJarList) String() string {
+ var pairs []string
+ for i := 0; i < l.Len(); i++ {
+ pairs = append(pairs, l.apexes[i]+":"+l.jars[i])
+ }
+ return strings.Join(pairs, ",")
+}
+
+func splitListOfPairsIntoPairOfLists(list []string) ([]string, []string, error) {
+ // Now we need to populate this list by splitting each item in the slice of
+ // pairs and appending them to the appropriate list of apexes or jars.
+ apexes := make([]string, len(list))
+ jars := make([]string, len(list))
+
+ for i, apexjar := range list {
+ apex, jar, err := splitConfiguredJarPair(apexjar)
+ if err != nil {
+ return nil, nil, err
+ }
+ apexes[i] = apex
+ jars[i] = jar
+ }
+
+ return apexes, jars, nil
+}
+
+// Expected format for apexJarValue = <apex name>:<jar name>
+func splitConfiguredJarPair(str string) (string, string, error) {
+ pair := strings.SplitN(str, ":", 2)
+ if len(pair) == 2 {
+ apex := pair[0]
+ jar := pair[1]
+ if apex == "" {
+ return apex, jar, fmt.Errorf("invalid apex '%s' in <apex>:<jar> pair '%s', expected format: <apex>:<jar>", apex, str)
+ }
+ return apex, jar, nil
+ } else {
+ return "error-apex", "error-jar", fmt.Errorf("malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
+ }
+}
+
+// EmptyConfiguredJarList returns an empty jar list.
+func EmptyConfiguredJarList() ConfiguredJarList {
+ return ConfiguredJarList{}
+}
+
+var earlyBootJarsKey = NewOnceKey("earlyBootJars")
diff --git a/android/defs.go b/android/defs.go
index 362b382..2a28e98 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -68,7 +68,7 @@
CpExecutable = pctx.AndroidStaticRule("CpExecutable",
blueprint.RuleParams{
- Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out && chmod +x $out$extraCmds",
+ Command: "rm -f $out && cp $cpFlags $in $out && chmod +x $out$extraCmds",
Description: "cp $out",
},
"cpFlags", "extraCmds")
diff --git a/android/test_config.go b/android/test_config.go
new file mode 100644
index 0000000..f36e8ba
--- /dev/null
+++ b/android/test_config.go
@@ -0,0 +1,145 @@
+// 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 android
+
+import (
+ "encoding/json"
+ "os"
+ "path/filepath"
+ "runtime"
+
+ "github.com/google/blueprint/proptools"
+)
+
+// TestConfig returns a Config object for testing.
+func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
+ envCopy := make(map[string]string)
+ for k, v := range env {
+ envCopy[k] = v
+ }
+
+ // Copy the real PATH value to the test environment, it's needed by
+ // NonHermeticHostSystemTool() used in x86_darwin_host.go
+ envCopy["PATH"] = os.Getenv("PATH")
+
+ config := &config{
+ productVariables: productVariables{
+ DeviceName: stringPtr("test_device"),
+ DeviceProduct: stringPtr("test_product"),
+ Platform_sdk_version: intPtr(30),
+ Platform_sdk_codename: stringPtr("S"),
+ Platform_base_sdk_extension_version: intPtr(1),
+ Platform_version_active_codenames: []string{"S", "Tiramisu"},
+ DeviceSystemSdkVersions: []string{"14", "15"},
+ Platform_systemsdk_versions: []string{"29", "30"},
+ AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
+ AAPTPreferredConfig: stringPtr("xhdpi"),
+ AAPTCharacteristics: stringPtr("nosdcard"),
+ AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
+ UncompressPrivAppDex: boolPtr(true),
+ ShippingApiLevel: stringPtr("30"),
+ },
+
+ outDir: buildDir,
+ soongOutDir: filepath.Join(buildDir, "soong"),
+ captureBuild: true,
+ env: envCopy,
+
+ // Set testAllowNonExistentPaths so that test contexts don't need to specify every path
+ // passed to PathForSource or PathForModuleSrc.
+ TestAllowNonExistentPaths: true,
+
+ BazelContext: noopBazelContext{},
+ mixedBuildDisabledModules: make(map[string]struct{}),
+ mixedBuildEnabledModules: make(map[string]struct{}),
+ }
+ config.deviceConfig = &deviceConfig{
+ config: config,
+ }
+ config.TestProductVariables = &config.productVariables
+
+ config.mockFileSystem(bp, fs)
+
+ determineBuildOS(config)
+
+ return Config{config}
+}
+
+func modifyTestConfigToSupportArchMutator(testConfig Config) {
+ config := testConfig.config
+
+ config.Targets = map[OsType][]Target{
+ Android: []Target{
+ {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
+ {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false},
+ },
+ config.BuildOS: []Target{
+ {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
+ {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
+ },
+ }
+
+ if runtime.GOOS == "darwin" {
+ config.Targets[config.BuildOS] = config.Targets[config.BuildOS][:1]
+ }
+
+ config.BuildOSTarget = config.Targets[config.BuildOS][0]
+ config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
+ config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
+ config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
+ config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
+ config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a")
+ config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm")
+ config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon")
+}
+
+func modifyTestConfigForMusl(config Config) {
+ delete(config.Targets, config.BuildOS)
+ config.productVariables.HostMusl = boolPtr(true)
+ determineBuildOS(config.config)
+ config.Targets[config.BuildOS] = []Target{
+ {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
+ {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
+ }
+
+ config.BuildOSTarget = config.Targets[config.BuildOS][0]
+ config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
+}
+
+// TestArchConfig returns a Config object suitable for using for tests that
+// need to run the arch mutator.
+func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
+ testConfig := TestConfig(buildDir, env, bp, fs)
+ modifyTestConfigToSupportArchMutator(testConfig)
+ return testConfig
+}
+
+// CreateTestConfiguredJarList is a function to create ConfiguredJarList for tests.
+func CreateTestConfiguredJarList(list []string) ConfiguredJarList {
+ // Create the ConfiguredJarList in as similar way as it is created at runtime by marshalling to
+ // a json list of strings and then unmarshalling into a ConfiguredJarList instance.
+ b, err := json.Marshal(list)
+ if err != nil {
+ panic(err)
+ }
+
+ var jarList ConfiguredJarList
+ err = json.Unmarshal(b, &jarList)
+ if err != nil {
+ panic(err)
+ }
+
+ return jarList
+}
diff --git a/android/variable.go b/android/variable.go
index 874b69d..86b8c8f 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -249,7 +249,8 @@
AAPTPreferredConfig *string `json:",omitempty"`
AAPTPrebuiltDPI []string `json:",omitempty"`
- DefaultAppCertificate *string `json:",omitempty"`
+ DefaultAppCertificate *string `json:",omitempty"`
+ MainlineSepolicyDevCertificates *string `json:",omitempty"`
AppsDefaultVersionName *string `json:",omitempty"`
diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go
index 280dae8..f646742 100644
--- a/android_sdk/sdk_repo_host.go
+++ b/android_sdk/sdk_repo_host.go
@@ -166,9 +166,10 @@
}
} else {
llvmStrip := config.ClangPath(ctx, "bin/llvm-strip")
- llvmLib := config.ClangPath(ctx, "lib64/libc++.so.1")
+ llvmLib64 := config.ClangPath(ctx, "lib64/libc++.so.1")
+ llvmLib := config.ClangPath(ctx, "lib/libc++.so.1")
for _, strip := range s.properties.Strip_files {
- cmd := builder.Command().Tool(llvmStrip).ImplicitTool(llvmLib)
+ cmd := builder.Command().Tool(llvmStrip).ImplicitTool(llvmLib64).ImplicitTool(llvmLib)
if !ctx.Windows() {
cmd.Flag("-x")
}
diff --git a/bazel/properties.go b/bazel/properties.go
index aba97c6..bffd97b 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -960,6 +960,146 @@
return ret
}
+// StringAttribute corresponds to the string Bazel attribute type with
+// support for additional metadata, like configurations.
+type StringAttribute struct {
+ // The base value of the string attribute.
+ Value *string
+
+ // The configured attribute label list Values. Optional
+ // a map of independent configurability axes
+ ConfigurableValues configurableStrings
+}
+
+type configurableStrings map[ConfigurationAxis]stringSelectValues
+
+func (cs configurableStrings) setValueForAxis(axis ConfigurationAxis, config string, str *string) {
+ if cs[axis] == nil {
+ cs[axis] = make(stringSelectValues)
+ }
+ var v = ""
+ if str != nil {
+ v = *str
+ }
+ cs[axis][config] = v
+}
+
+type stringSelectValues map[string]string
+
+// HasConfigurableValues returns true if the attribute contains axis-specific string values.
+func (sa StringAttribute) HasConfigurableValues() bool {
+ for _, selectValues := range sa.ConfigurableValues {
+ if len(selectValues) > 0 {
+ return true
+ }
+ }
+ return false
+}
+
+// SetSelectValue set a value for a bazel select for the given axis, config and value.
+func (sa *StringAttribute) SetSelectValue(axis ConfigurationAxis, config string, str *string) {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ sa.Value = str
+ case arch, os, osArch, productVariables:
+ if sa.ConfigurableValues == nil {
+ sa.ConfigurableValues = make(configurableStrings)
+ }
+ sa.ConfigurableValues.setValueForAxis(axis, config, str)
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SelectValue gets a value for a bazel select for the given axis and config.
+func (sa *StringAttribute) SelectValue(axis ConfigurationAxis, config string) *string {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ return sa.Value
+ case arch, os, osArch, productVariables:
+ if v, ok := sa.ConfigurableValues[axis][config]; ok {
+ return &v
+ } else {
+ return nil
+ }
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
+func (sa *StringAttribute) SortedConfigurationAxes() []ConfigurationAxis {
+ keys := make([]ConfigurationAxis, 0, len(sa.ConfigurableValues))
+ for k := range sa.ConfigurableValues {
+ keys = append(keys, k)
+ }
+
+ sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
+ return keys
+}
+
+// Collapse reduces the configurable axes of the string attribute to a single axis.
+// This is necessary for final writing to bp2build, as a configurable string
+// attribute can only be comprised by a single select.
+func (sa *StringAttribute) Collapse() error {
+ axisTypes := sa.axisTypes()
+ _, containsOs := axisTypes[os]
+ _, containsArch := axisTypes[arch]
+ _, containsOsArch := axisTypes[osArch]
+ _, containsProductVariables := axisTypes[productVariables]
+ if containsProductVariables {
+ if containsOs || containsArch || containsOsArch {
+ return fmt.Errorf("boolean attribute could not be collapsed as it has two or more unrelated axes")
+ }
+ }
+ if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
+ // If a bool attribute has both os and arch configuration axes, the only
+ // way to successfully union their values is to increase the granularity
+ // of the configuration criteria to os_arch.
+ for osType, supportedArchs := range osToArchMap {
+ for _, supportedArch := range supportedArchs {
+ osArch := osArchString(osType, supportedArch)
+ if archOsVal := sa.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
+ // Do nothing, as the arch_os is explicitly defined already.
+ } else {
+ archVal := sa.SelectValue(ArchConfigurationAxis, supportedArch)
+ osVal := sa.SelectValue(OsConfigurationAxis, osType)
+ if osVal != nil && archVal != nil {
+ // In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
+ // runs after os mutator.
+ sa.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
+ } else if osVal != nil && archVal == nil {
+ sa.SetSelectValue(OsArchConfigurationAxis, osArch, osVal)
+ } else if osVal == nil && archVal != nil {
+ sa.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
+ }
+ }
+ }
+ }
+ // All os_arch values are now set. Clear os and arch axes.
+ delete(sa.ConfigurableValues, ArchConfigurationAxis)
+ delete(sa.ConfigurableValues, OsConfigurationAxis)
+ // Verify post-condition; this should never fail, provided no additional
+ // axes are introduced.
+ if len(sa.ConfigurableValues) > 1 {
+ panic(fmt.Errorf("error in collapsing attribute: %#v", sa))
+ }
+ }
+ return nil
+}
+
+func (sa *StringAttribute) axisTypes() map[configurationType]bool {
+ types := map[configurationType]bool{}
+ for k := range sa.ConfigurableValues {
+ if strs := sa.ConfigurableValues[k]; len(strs) > 0 {
+ types[k.configurationType] = true
+ }
+ }
+ return types
+}
+
// StringListAttribute corresponds to the string_list Bazel attribute type with
// support for additional metadata, like configurations.
type StringListAttribute struct {
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 1fabfaa..cb25627 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -15,6 +15,7 @@
"conversion.go",
"metrics.go",
"symlink_forest.go",
+ "testing.go",
],
deps: [
"soong-android",
@@ -68,7 +69,6 @@
"python_library_conversion_test.go",
"sh_conversion_test.go",
"soong_config_module_type_conversion_test.go",
- "testing.go",
],
pluginFor: [
"soong_build",
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index c5644ed..1ac7518 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -231,6 +231,52 @@
func TestGenerateBazelTargetModules(t *testing.T) {
testCases := []Bp2buildTestCase{
{
+ Description: "string prop empty",
+ Blueprint: `custom {
+ name: "foo",
+ string_literal_prop: "",
+ bazel_module: { bp2build_available: true },
+}`,
+ ExpectedBazelTargets: []string{
+ makeBazelTarget("custom", "foo", AttrNameToString{
+ "string_literal_prop": `""`,
+ }),
+ },
+ },
+ {
+ Description: `string prop "PROP"`,
+ Blueprint: `custom {
+ name: "foo",
+ string_literal_prop: "PROP",
+ bazel_module: { bp2build_available: true },
+}`,
+ ExpectedBazelTargets: []string{
+ makeBazelTarget("custom", "foo", AttrNameToString{
+ "string_literal_prop": `"PROP"`,
+ }),
+ },
+ },
+ {
+ Description: `string prop arch variant`,
+ Blueprint: `custom {
+ name: "foo",
+ arch: {
+ arm: { string_literal_prop: "ARM" },
+ arm64: { string_literal_prop: "ARM64" },
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ ExpectedBazelTargets: []string{
+ makeBazelTarget("custom", "foo", AttrNameToString{
+ "string_literal_prop": `select({
+ "//build/bazel/platforms/arch:arm": "ARM",
+ "//build/bazel/platforms/arch:arm64": "ARM64",
+ "//conditions:default": None,
+ })`,
+ }),
+ },
+ },
+ {
Description: "string ptr props",
Blueprint: `custom {
name: "foo",
@@ -244,7 +290,7 @@
},
},
{
- Description: "string props",
+ Description: "string list props",
Blueprint: `custom {
name: "foo",
string_list_prop: ["a", "b"],
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 6cb9509..28d2c75 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -15,11 +15,12 @@
package bp2build
import (
- "android/soong/android"
"io/ioutil"
"os"
"strings"
"testing"
+
+ "android/soong/android"
)
func setUp() {
@@ -103,6 +104,7 @@
"one_to_many_prop": attr.bool(),
"other_embedded_prop": attr.string(),
"string_list_prop": attr.string_list(),
+ "string_literal_prop": attr.string(),
"string_prop": attr.string(),
"string_ptr_prop": attr.string(),
},
@@ -132,6 +134,7 @@
"one_to_many_prop": attr.bool(),
"other_embedded_prop": attr.string(),
"string_list_prop": attr.string_list(),
+ "string_literal_prop": attr.string(),
"string_prop": attr.string(),
"string_ptr_prop": attr.string(),
},
@@ -161,6 +164,7 @@
"one_to_many_prop": attr.bool(),
"other_embedded_prop": attr.string(),
"string_list_prop": attr.string_list(),
+ "string_literal_prop": attr.string(),
"string_prop": attr.string(),
"string_ptr_prop": attr.string(),
# test_prop start
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index d37a523..9398d12 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -13,6 +13,30 @@
type selects map[string]reflect.Value
+func getStringValue(str bazel.StringAttribute) (reflect.Value, []selects) {
+ value := reflect.ValueOf(str.Value)
+
+ if !str.HasConfigurableValues() {
+ return value, []selects{}
+ }
+
+ ret := selects{}
+ for _, axis := range str.SortedConfigurationAxes() {
+ configToStrs := str.ConfigurableValues[axis]
+ for config, strs := range configToStrs {
+ selectKey := axis.SelectKey(config)
+ ret[selectKey] = reflect.ValueOf(strs)
+ }
+ }
+ // if there is a select, use the base value as the conditions default value
+ if len(ret) > 0 {
+ ret[bazel.ConditionsDefaultSelectKey] = value
+ value = reflect.Zero(value.Type())
+ }
+
+ return value, []selects{ret}
+}
+
func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(list.Value)
if !list.HasConfigurableValues() {
@@ -137,6 +161,12 @@
// If true, print the default attribute value, even if the attribute is zero.
shouldPrintDefault := false
switch list := v.(type) {
+ case bazel.StringAttribute:
+ if err := list.Collapse(); err != nil {
+ return "", err
+ }
+ value, configurableAttrs = getStringValue(list)
+ defaultSelectValue = &bazelNone
case bazel.StringListAttribute:
value, configurableAttrs = getStringListValues(list)
defaultSelectValue = &emptyBazelList
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 3ee5096..0f321de 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -173,11 +173,12 @@
Bool_prop bool
Bool_ptr_prop *bool
// Ensure that properties tagged `blueprint:mutated` are omitted
- Int_prop int `blueprint:"mutated"`
- Int64_ptr_prop *int64
- String_prop string
- String_ptr_prop *string
- String_list_prop []string
+ Int_prop int `blueprint:"mutated"`
+ Int64_ptr_prop *int64
+ String_prop string
+ String_literal_prop *string `android:"arch_variant"`
+ String_ptr_prop *string
+ String_list_prop []string
Nested_props nestedProps
Nested_props_ptr *nestedProps
@@ -305,23 +306,29 @@
type customBazelModuleAttributes struct {
EmbeddedAttr
*OtherEmbeddedAttr
- String_ptr_prop *string
- String_list_prop []string
- Arch_paths bazel.LabelListAttribute
+ String_literal_prop bazel.StringAttribute
+ String_ptr_prop *string
+ String_list_prop []string
+ Arch_paths bazel.LabelListAttribute
}
func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- paths := bazel.LabelListAttribute{}
-
if p := m.props.One_to_many_prop; p != nil && *p {
customBp2buildOneToMany(ctx, m)
return
}
+ paths := bazel.LabelListAttribute{}
+ strAttr := bazel.StringAttribute{}
for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
for config, props := range configToProps {
- if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
- paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, archProps.Arch_paths, archProps.Arch_paths_exclude))
+ if custProps, ok := props.(*customProps); ok {
+ if custProps.Arch_paths != nil {
+ paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, custProps.Arch_paths, custProps.Arch_paths_exclude))
+ }
+ if custProps.String_literal_prop != nil {
+ strAttr.SetSelectValue(axis, config, custProps.String_literal_prop)
+ }
}
}
}
@@ -329,10 +336,12 @@
paths.ResolveExcludes()
attrs := &customBazelModuleAttributes{
- String_ptr_prop: m.props.String_ptr_prop,
- String_list_prop: m.props.String_list_prop,
- Arch_paths: paths,
+ String_literal_prop: strAttr,
+ String_ptr_prop: m.props.String_ptr_prop,
+ String_list_prop: m.props.String_list_prop,
+ Arch_paths: paths,
}
+
attrs.Embedded_attr = m.props.Embedded_prop
if m.props.OtherEmbeddedProps != nil {
attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop}
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 5d2533f..e89cc4e 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -69,12 +69,23 @@
}
type BpfProperties struct {
- Srcs []string `android:"path"`
- Cflags []string
+ // source paths to the files.
+ Srcs []string `android:"path"`
+
+ // additional cflags that should be used to build the bpf variant of
+ // the C/C++ module.
+ Cflags []string
+
+ // directories (relative to the root of the source tree) that will
+ // be added to the include paths using -I.
Include_dirs []string
- Sub_dir string
- // If set to true, generate BTF debug info for maps & programs
- Btf *bool
+
+ // optional subdirectory under which this module is installed into.
+ Sub_dir string
+
+ // if set to true, generate BTF debug info for maps & programs.
+ Btf *bool
+
Vendor *bool
VendorInternal bool `blueprint:"mutated"`
diff --git a/cc/androidmk.go b/cc/androidmk.go
index ff5ba45..47fb919 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -226,17 +226,27 @@
}
}
-func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkEntries) {
- if library.sAbiDiff.Valid() && !library.static() {
- entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", library.sAbiDiff.String())
+func (library *libraryDecorator) getAbiDiffsForAndroidMkDeps() []string {
+ if library.static() {
+ return nil
}
+ var abiDiffs []string
+ if library.sAbiDiff.Valid() {
+ abiDiffs = append(abiDiffs, library.sAbiDiff.String())
+ }
+ if library.prevSAbiDiff.Valid() {
+ abiDiffs = append(abiDiffs, library.prevSAbiDiff.String())
+ }
+ return abiDiffs
+}
+
+func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkEntries) {
+ entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", library.getAbiDiffsForAndroidMkDeps()...)
}
// TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries
func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
- if library.sAbiDiff.Valid() && !library.static() {
- fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", library.sAbiDiff.String())
- }
+ fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.getAbiDiffsForAndroidMkDeps(), " "))
}
func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
diff --git a/cc/builder.go b/cc/builder.go
index ab2b80a..f3faca8 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -920,10 +920,15 @@
// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump).
func sourceAbiDiff(ctx android.ModuleContext, inputDump android.Path, referenceDump android.Path,
- baseName, exportedHeaderFlags string, diffFlags []string,
- checkAllApis, isLlndk, isNdk, isVndkExt bool) android.OptionalPath {
+ baseName, prevVersion, exportedHeaderFlags string, diffFlags []string,
+ checkAllApis, isLlndk, isNdk, isVndkExt, previousVersionDiff bool) android.OptionalPath {
- outputFile := android.PathForModuleOut(ctx, baseName+".abidiff")
+ var outputFile android.ModuleOutPath
+ if prevVersion == "" {
+ outputFile = android.PathForModuleOut(ctx, baseName+".abidiff")
+ } else {
+ outputFile = android.PathForModuleOut(ctx, baseName+"."+prevVersion+".abidiff")
+ }
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
var extraFlags []string
@@ -935,10 +940,15 @@
"-allow-unreferenced-elf-symbol-changes")
}
+ // TODO(b/241496591): Remove -advice-only after b/239792343 and b/239790286 are reolved.
+ if previousVersionDiff {
+ extraFlags = append(extraFlags, "-advice-only")
+ }
+
if isLlndk || isNdk {
extraFlags = append(extraFlags, "-consider-opaque-types-different")
}
- if isVndkExt {
+ if isVndkExt || previousVersionDiff {
extraFlags = append(extraFlags, "-allow-extensions")
}
// TODO(b/232891473): Simplify the above logic with diffFlags.
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index 674edad..232e686 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -37,16 +37,22 @@
// http://b/216364337 - TODO: Follow-up after compiler update to
// disable or fix individual instances.
"-cert-err33-c",
+ // http://b/241125373
+ "-bugprone-unchecked-optional-access",
}
// Some clang-tidy checks are included in some tidy_checks_as_errors lists,
// but not all warnings are fixed/suppressed yet. These checks are not
// disabled in the TidyGlobalNoChecks list, so we can see them and fix/suppress them.
globalNoErrorCheckList = []string{
- // http://b/155034563
- "-bugprone-signed-char-misuse",
+ // http://b/241997913
+ "-bugprone-assignment-in-if-condition",
// http://b/155034972
"-bugprone-branch-clone",
+ // http://b/155034563
+ "-bugprone-signed-char-misuse",
+ // http://b/241819232
+ "-misc-const-correctness",
}
)
@@ -80,8 +86,10 @@
"misc-*",
"performance-*",
"portability-*",
+ "-bugprone-assignment-in-if-condition",
"-bugprone-easily-swappable-parameters",
"-bugprone-narrowing-conversions",
+ "-misc-const-correctness",
"-misc-no-recursion",
"-misc-non-private-member-variables-in-classes",
"-misc-unused-parameters",
diff --git a/cc/library.go b/cc/library.go
index 546982b..897b572 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -613,6 +613,9 @@
// Source Abi Diff
sAbiDiff android.OptionalPath
+ // Source Abi Diff against previous SDK version
+ prevSAbiDiff android.OptionalPath
+
// Location of the static library in the sysroot. Empty if the library is
// not included in the NDK.
ndkSysrootPath android.Path
@@ -771,6 +774,12 @@
if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
continue
}
+
+ // Filter out the generated headers from bazel.
+ if strings.HasPrefix(dir, android.PathForBazelOut(ctx, "bazel-out").String()) {
+ continue
+ }
+
// libeigen wrongly exports the root directory "external/eigen". But only two
// subdirectories "Eigen" and "unsupported" contain exported header files. Even worse
// some of them have no extension. So we need special treatment for libeigen in order
@@ -1614,9 +1623,39 @@
return nil
}
+func prevDumpRefVersion(ctx ModuleContext) string {
+ sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt()
+ sdkVersionStr := ctx.Config().PlatformSdkVersion().String()
+
+ if ctx.Config().PlatformSdkFinal() {
+ return strconv.Itoa(sdkVersionInt - 1)
+ } else {
+ var dirName string
+
+ isNdk := ctx.isNdk(ctx.Config())
+ if isNdk {
+ dirName = "ndk"
+ } else {
+ dirName = "platform"
+ }
+
+ // The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't
+ // been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version.
+ // This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory.
+ refDumpDir := android.ExistentPathForSource(ctx, "prebuilts", "abi-dumps", dirName, sdkVersionStr)
+ if refDumpDir.Valid() {
+ return sdkVersionStr
+ } else {
+ return strconv.Itoa(sdkVersionInt - 1)
+ }
+ }
+}
+
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
if library.sabi.shouldCreateSourceAbiDump() {
var version string
+ var prevVersion string
+
if ctx.useVndk() {
// For modules linking against vndk, follow its vndk version
version = ctx.Module().(*Module).VndkVersion()
@@ -1628,6 +1667,7 @@
} else {
version = "current"
}
+ prevVersion = prevDumpRefVersion(ctx)
}
exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
@@ -1646,13 +1686,24 @@
addLsdumpPath(classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String())
+ if prevVersion != "" {
+ prevRefAbiDumpFile := getRefAbiDumpFile(ctx, prevVersion, fileName)
+ if prevRefAbiDumpFile != nil {
+ library.prevSAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
+ prevRefAbiDumpFile, fileName, prevVersion, exportedHeaderFlags,
+ library.Properties.Header_abi_checker.Diff_flags,
+ Bool(library.Properties.Header_abi_checker.Check_all_apis),
+ ctx.IsLlndk(), ctx.isNdk(ctx.Config()), ctx.IsVndkExt(), true)
+ }
+ }
+
refAbiDumpFile := getRefAbiDumpFile(ctx, version, fileName)
if refAbiDumpFile != nil {
library.sAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
- refAbiDumpFile, fileName, exportedHeaderFlags,
+ refAbiDumpFile, fileName, "", exportedHeaderFlags,
library.Properties.Header_abi_checker.Diff_flags,
Bool(library.Properties.Header_abi_checker.Check_all_apis),
- ctx.IsLlndk(), ctx.isNdk(ctx.Config()), ctx.IsVndkExt())
+ ctx.IsLlndk(), ctx.isNdk(ctx.Config()), ctx.IsVndkExt(), false)
}
}
}
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 3d18849..cb85634 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -268,6 +268,8 @@
func dumpVar(ctx build.Context, config build.Config, args []string, _ string) {
flags := flag.NewFlagSet("dumpvar", flag.ExitOnError)
+ flags.SetOutput(ctx.Writer)
+
flags.Usage = func() {
fmt.Fprintf(ctx.Writer, "usage: %s --dumpvar-mode [--abs] <VAR>\n\n", os.Args[0])
fmt.Fprintln(ctx.Writer, "In dumpvar mode, print the value of the legacy make variable VAR to stdout")
@@ -318,6 +320,8 @@
func dumpVars(ctx build.Context, config build.Config, args []string, _ string) {
flags := flag.NewFlagSet("dumpvars", flag.ExitOnError)
+ flags.SetOutput(ctx.Writer)
+
flags.Usage = func() {
fmt.Fprintf(ctx.Writer, "usage: %s --dumpvars-mode [--vars=\"VAR VAR ...\"]\n\n", os.Args[0])
fmt.Fprintln(ctx.Writer, "In dumpvars mode, dump the values of one or more legacy make variables, in")
@@ -401,6 +405,8 @@
func buildActionConfig(ctx build.Context, args ...string) build.Config {
flags := flag.NewFlagSet("build-mode", flag.ContinueOnError)
+ flags.SetOutput(ctx.Writer)
+
flags.Usage = func() {
fmt.Fprintf(ctx.Writer, "usage: %s --build-mode --dir=<path> <build action> [<build arg 1> <build arg 2> ...]\n\n", os.Args[0])
fmt.Fprintln(ctx.Writer, "In build mode, build the set of modules based on the specified build")
@@ -453,21 +459,32 @@
const numBuildActionFlags = 2
if len(args) < numBuildActionFlags {
flags.Usage()
- ctx.Fatalln("Improper build action arguments.")
+ ctx.Fatalln("Improper build action arguments: too few arguments")
}
- flags.Parse(args[0:numBuildActionFlags])
+ parseError := flags.Parse(args[0:numBuildActionFlags])
// The next block of code is to validate that exactly one build action is set and the dir flag
// is specified.
- buildActionCount := 0
+ buildActionFound := false
var buildAction build.BuildAction
- for _, flag := range buildActionFlags {
- if flag.set {
- buildActionCount++
- buildAction = flag.action
+ for _, f := range buildActionFlags {
+ if f.set {
+ if buildActionFound {
+ if parseError == nil {
+ //otherwise Parse() already called Usage()
+ flags.Usage()
+ }
+ ctx.Fatalf("Build action already specified, omit: --%s\n", f.name)
+ }
+ buildActionFound = true
+ buildAction = f.action
}
}
- if buildActionCount != 1 {
+ if !buildActionFound {
+ if parseError == nil {
+ //otherwise Parse() already called Usage()
+ flags.Usage()
+ }
ctx.Fatalln("Build action not defined.")
}
if *dir == "" {
@@ -509,8 +526,16 @@
// getCommand finds the appropriate command based on args[1] flag. args[0]
// is the soong_ui filename.
func getCommand(args []string) (*command, []string, error) {
+ listFlags := func() []string {
+ flags := make([]string, len(commands))
+ for i, c := range commands {
+ flags[i] = c.flag
+ }
+ return flags
+ }
+
if len(args) < 2 {
- return nil, nil, fmt.Errorf("Too few arguments: %q", args)
+ return nil, nil, fmt.Errorf("Too few arguments: %q\nUse one of these: %q", args, listFlags())
}
for _, c := range commands {
@@ -518,13 +543,7 @@
return &c, args[2:], nil
}
}
-
- // command not found
- flags := make([]string, len(commands))
- for i, c := range commands {
- flags[i] = c.flag
- }
- return nil, nil, fmt.Errorf("Command not found: %q\nDid you mean one of these: %q", args, flags)
+ return nil, nil, fmt.Errorf("Command not found: %q\nDid you mean one of these: %q", args[1], listFlags())
}
// For Bazel support, this moves files and directories from e.g. out/dist/$f to DIST_DIR/$f if necessary.
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index e99cb05..01e7e6e 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -101,7 +101,6 @@
--warning_check WrongViewCast # 1 occurences in 1 modules
--warning_check CoarseFineLocation
---warning_check ExtraText
--warning_check IntentFilterExportedReceiver
--warning_check MissingInflatedId
--warning_check NotificationPermission
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 72cc894..0199d3a 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -299,7 +299,15 @@
ClangProperties: cc.RustBindgenClangProperties{},
}
- module := NewSourceProviderModule(hod, bindgen, false)
+ module := NewSourceProviderModule(hod, bindgen, false, true)
+
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ type stub_props struct {
+ Visibility []string
+ }
+ props := &stub_props{[]string{":__subpackages__"}}
+ ctx.PrependProperties(props)
+ })
return module, bindgen
}
diff --git a/rust/protobuf.go b/rust/protobuf.go
index 9fe27c4c..88e80fe 100644
--- a/rust/protobuf.go
+++ b/rust/protobuf.go
@@ -238,7 +238,7 @@
Properties: ProtobufProperties{},
}
- module := NewSourceProviderModule(hod, protobuf, false)
+ module := NewSourceProviderModule(hod, protobuf, false, false)
return module, protobuf
}
diff --git a/rust/source_provider.go b/rust/source_provider.go
index 7719611..4f8d22b 100644
--- a/rust/source_provider.go
+++ b/rust/source_provider.go
@@ -65,9 +65,12 @@
}
}
-func NewSourceProviderModule(hod android.HostOrDeviceSupported, sourceProvider SourceProvider, enableLints bool) *Module {
+func NewSourceProviderModule(hod android.HostOrDeviceSupported, sourceProvider SourceProvider, enableLints bool, rlibOnly bool) *Module {
_, library := NewRustLibrary(hod)
library.BuildOnlyRust()
+ if rlibOnly {
+ library.BuildOnlyRlib()
+ }
library.sourceProvider = sourceProvider
module := newModule(hod, android.MultilibBoth)
diff --git a/tests/lib.sh b/tests/lib.sh
index 69ad201..6210e77 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -111,7 +111,7 @@
# shellcheck disable=SC2120
function run_soong {
- build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
+ USE_RBE=false build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
}
function create_mock_bazel {
diff --git a/ui/build/build.go b/ui/build/build.go
index 5b80b4d..f7a2d7b 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -201,7 +201,20 @@
buildLock := BecomeSingletonOrFail(ctx, config)
defer buildLock.Unlock()
+ logArgsOtherThan := func(specialTargets ...string) {
+ var ignored []string
+ for _, a := range config.Arguments() {
+ if !inList(a, specialTargets) {
+ ignored = append(ignored, a)
+ }
+ }
+ if len(ignored) > 0 {
+ ctx.Printf("ignoring arguments %q", ignored)
+ }
+ }
+
if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
+ logArgsOtherThan("clean", "clobber")
clean(ctx, config)
return
}
@@ -279,6 +292,7 @@
if inList("installclean", config.Arguments()) ||
inList("install-clean", config.Arguments()) {
+ logArgsOtherThan("installclean", "install-clean")
installClean(ctx, config)
ctx.Println("Deleted images and staging directories.")
return
@@ -286,6 +300,7 @@
if inList("dataclean", config.Arguments()) ||
inList("data-clean", config.Arguments()) {
+ logArgsOtherThan("dataclean", "data-clean")
dataClean(ctx, config)
ctx.Println("Deleted data files.")
return
diff --git a/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel b/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel
new file mode 100644
index 0000000..356b188
--- /dev/null
+++ b/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel
@@ -0,0 +1,27 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("//build/bazel/rules/python:py_proto.bzl", "py_proto_library")
+
+proto_library(
+ name = "bp2build_proto",
+ srcs = ["bp2build.proto"],
+ strip_import_prefix = "",
+)
+
+py_proto_library(
+ name = "bp2build_py_proto",
+ deps = [":bp2build_proto"],
+ visibility = ["//build/bazel/scripts/bp2build-progress:__pkg__"],
+)
diff --git a/ui/metrics/bp2build_progress_metrics_proto/bp2build.proto b/ui/metrics/bp2build_progress_metrics_proto/bp2build.proto
new file mode 100644
index 0000000..4aee88b
--- /dev/null
+++ b/ui/metrics/bp2build_progress_metrics_proto/bp2build.proto
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto3";
+
+package bp2build_proto;
+
+
+// Conversion progress report for root_modules .
+message Bp2buildConversionProgress {
+
+ // Soong module identifying information.
+ message Module {
+ // Name of the Soong module.
+ string name = 1;
+
+ // Directory that the Soong module is in.
+ string directory = 2;
+
+ // Module type of this module.
+ string type = 3;
+
+ // All unconverted transitive dependencies.
+ repeated string unconverted_deps = 4;
+
+ // Total number of transitive dependencies.
+ int32 num_deps = 5;
+ }
+
+ // Modules that the transitive dependencies were identified for.
+ repeated string root_modules = 1;
+
+ // Names of all dependencies of the root_modules.
+ int32 num_deps = 2;
+
+ // Module with all its unconverted transitive dependencies.
+ repeated Module unconverted = 3;
+}