Merge "Add support for privileged apps to androidmk"
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..caa2a95
--- /dev/null
+++ b/METADATA
@@ -0,0 +1 @@
+name: "Android"
diff --git a/android/arch.go b/android/arch.go
index 69d66e9..8aa8d40 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -22,6 +22,7 @@
"strings"
"android/soong/bazel"
+ "android/soong/starlark_fmt"
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
@@ -864,6 +865,10 @@
archVariant := variantReplacer.Replace(archVariant)
variants = append(variants, proptools.FieldNameForProperty(archVariant))
}
+ for _, cpuVariant := range cpuVariants[arch] {
+ cpuVariant := variantReplacer.Replace(cpuVariant)
+ variants = append(variants, proptools.FieldNameForProperty(cpuVariant))
+ }
for _, feature := range archFeatures[arch] {
feature := variantReplacer.Replace(feature)
variants = append(variants, proptools.FieldNameForProperty(feature))
@@ -1514,23 +1519,32 @@
targets := make(map[OsType][]Target)
var targetErr error
- addTarget := func(os OsType, archName string, archVariant, cpuVariant *string, abi []string,
- nativeBridgeEnabled NativeBridgeSupport, nativeBridgeHostArchName *string,
- nativeBridgeRelativePath *string) {
+ type targetConfig struct {
+ os OsType
+ archName string
+ archVariant *string
+ cpuVariant *string
+ abi []string
+ nativeBridgeEnabled NativeBridgeSupport
+ nativeBridgeHostArchName *string
+ nativeBridgeRelativePath *string
+ }
+
+ addTarget := func(target targetConfig) {
if targetErr != nil {
return
}
- arch, err := decodeArch(os, archName, archVariant, cpuVariant, abi)
+ arch, err := decodeArch(target.os, target.archName, target.archVariant, target.cpuVariant, target.abi)
if err != nil {
targetErr = err
return
}
- nativeBridgeRelativePathStr := String(nativeBridgeRelativePath)
- nativeBridgeHostArchNameStr := String(nativeBridgeHostArchName)
+ nativeBridgeRelativePathStr := String(target.nativeBridgeRelativePath)
+ nativeBridgeHostArchNameStr := String(target.nativeBridgeHostArchName)
// Use guest arch as relative install path by default
- if nativeBridgeEnabled && nativeBridgeRelativePathStr == "" {
+ if target.nativeBridgeEnabled && nativeBridgeRelativePathStr == "" {
nativeBridgeRelativePathStr = arch.ArchType.String()
}
@@ -1538,11 +1552,11 @@
// the currently configured build machine (either because the OS is different or because of
// the unsupported arch)
hostCross := false
- if os.Class == Host {
+ if target.os.Class == Host {
var osSupported bool
- if os == config.BuildOS {
+ if target.os == config.BuildOS {
osSupported = true
- } else if config.BuildOS.Linux() && os.Linux() {
+ } else if config.BuildOS.Linux() && target.os.Linux() {
// LinuxBionic and Linux are compatible
osSupported = true
} else {
@@ -1564,11 +1578,11 @@
}
}
- targets[os] = append(targets[os],
+ targets[target.os] = append(targets[target.os],
Target{
- Os: os,
+ Os: target.os,
Arch: arch,
- NativeBridge: nativeBridgeEnabled,
+ NativeBridge: target.nativeBridgeEnabled,
NativeBridgeHostArchName: nativeBridgeHostArchNameStr,
NativeBridgeRelativePath: nativeBridgeRelativePathStr,
HostCross: hostCross,
@@ -1580,11 +1594,11 @@
}
// The primary host target, which must always exist.
- addTarget(config.BuildOS, *variables.HostArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
+ addTarget(targetConfig{os: config.BuildOS, archName: *variables.HostArch, nativeBridgeEnabled: NativeBridgeDisabled})
// An optional secondary host target.
if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" {
- addTarget(config.BuildOS, *variables.HostSecondaryArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
+ addTarget(targetConfig{os: config.BuildOS, archName: *variables.HostSecondaryArch, nativeBridgeEnabled: NativeBridgeDisabled})
}
// Optional cross-compiled host targets, generally Windows.
@@ -1599,45 +1613,65 @@
}
// The primary cross-compiled host target.
- addTarget(crossHostOs, *variables.CrossHostArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
+ addTarget(targetConfig{os: crossHostOs, archName: *variables.CrossHostArch, nativeBridgeEnabled: NativeBridgeDisabled})
// An optional secondary cross-compiled host target.
if variables.CrossHostSecondaryArch != nil && *variables.CrossHostSecondaryArch != "" {
- addTarget(crossHostOs, *variables.CrossHostSecondaryArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
+ addTarget(targetConfig{os: crossHostOs, archName: *variables.CrossHostSecondaryArch, nativeBridgeEnabled: NativeBridgeDisabled})
}
}
// Optional device targets
if variables.DeviceArch != nil && *variables.DeviceArch != "" {
// The primary device target.
- addTarget(Android, *variables.DeviceArch, variables.DeviceArchVariant,
- variables.DeviceCpuVariant, variables.DeviceAbi, NativeBridgeDisabled, nil, nil)
+ addTarget(targetConfig{
+ os: Android,
+ archName: *variables.DeviceArch,
+ archVariant: variables.DeviceArchVariant,
+ cpuVariant: variables.DeviceCpuVariant,
+ abi: variables.DeviceAbi,
+ nativeBridgeEnabled: NativeBridgeDisabled,
+ })
// An optional secondary device target.
if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" {
- addTarget(Android, *variables.DeviceSecondaryArch,
- variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant,
- variables.DeviceSecondaryAbi, NativeBridgeDisabled, nil, nil)
+ addTarget(targetConfig{
+ os: Android,
+ archName: *variables.DeviceSecondaryArch,
+ archVariant: variables.DeviceSecondaryArchVariant,
+ cpuVariant: variables.DeviceSecondaryCpuVariant,
+ abi: variables.DeviceSecondaryAbi,
+ nativeBridgeEnabled: NativeBridgeDisabled,
+ })
}
// An optional NativeBridge device target.
if variables.NativeBridgeArch != nil && *variables.NativeBridgeArch != "" {
- addTarget(Android, *variables.NativeBridgeArch,
- variables.NativeBridgeArchVariant, variables.NativeBridgeCpuVariant,
- variables.NativeBridgeAbi, NativeBridgeEnabled, variables.DeviceArch,
- variables.NativeBridgeRelativePath)
+ addTarget(targetConfig{
+ os: Android,
+ archName: *variables.NativeBridgeArch,
+ archVariant: variables.NativeBridgeArchVariant,
+ cpuVariant: variables.NativeBridgeCpuVariant,
+ abi: variables.NativeBridgeAbi,
+ nativeBridgeEnabled: NativeBridgeEnabled,
+ nativeBridgeHostArchName: variables.DeviceArch,
+ nativeBridgeRelativePath: variables.NativeBridgeRelativePath,
+ })
}
// An optional secondary NativeBridge device target.
if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" &&
variables.NativeBridgeSecondaryArch != nil && *variables.NativeBridgeSecondaryArch != "" {
- addTarget(Android, *variables.NativeBridgeSecondaryArch,
- variables.NativeBridgeSecondaryArchVariant,
- variables.NativeBridgeSecondaryCpuVariant,
- variables.NativeBridgeSecondaryAbi,
- NativeBridgeEnabled,
- variables.DeviceSecondaryArch,
- variables.NativeBridgeSecondaryRelativePath)
+ addTarget(targetConfig{
+ os: Android,
+ archName: *variables.NativeBridgeSecondaryArch,
+ archVariant: variables.NativeBridgeSecondaryArchVariant,
+ cpuVariant: variables.NativeBridgeSecondaryCpuVariant,
+ abi: variables.NativeBridgeSecondaryAbi,
+ nativeBridgeEnabled: NativeBridgeEnabled,
+ nativeBridgeHostArchName: variables.DeviceSecondaryArch,
+ nativeBridgeRelativePath: variables.NativeBridgeSecondaryRelativePath,
+ })
}
}
@@ -1697,11 +1731,11 @@
}
// decodeArchSettings converts a list of archConfigs into a list of Targets for the given OsType.
-func decodeArchSettings(os OsType, archConfigs []archConfig) ([]Target, error) {
+func decodeAndroidArchSettings(archConfigs []archConfig) ([]Target, error) {
var ret []Target
for _, config := range archConfigs {
- arch, err := decodeArch(os, config.arch, &config.archVariant,
+ arch, err := decodeArch(Android, config.arch, &config.archVariant,
&config.cpuVariant, config.abi)
if err != nil {
return nil, err
@@ -1741,6 +1775,18 @@
a.CpuVariant = ""
}
+ if a.ArchVariant != "" {
+ if validArchVariants := archVariants[archType]; !InList(a.ArchVariant, validArchVariants) {
+ return Arch{}, fmt.Errorf("[%q] unknown arch variant %q, support variants: %q", archType, a.ArchVariant, validArchVariants)
+ }
+ }
+
+ if a.CpuVariant != "" {
+ if validCpuVariants := cpuVariants[archType]; !InList(a.CpuVariant, validCpuVariants) {
+ return Arch{}, fmt.Errorf("[%q] unknown cpu variant %q, support variants: %q", archType, a.CpuVariant, validCpuVariants)
+ }
+ }
+
// Filter empty ABIs out of the list.
for i := 0; i < len(a.Abi); i++ {
if a.Abi[i] == "" {
@@ -1749,14 +1795,9 @@
}
}
- if a.ArchVariant == "" {
- // Set ArchFeatures from the default arch features.
- if featureMap, ok := defaultArchFeatureMap[os]; ok {
- a.ArchFeatures = featureMap[archType]
- }
- } else {
- // Set ArchFeatures from the arch type.
- if featureMap, ok := archFeatureMap[archType]; ok {
+ // Set ArchFeatures from the arch type. for Android OS, other os-es do not specify features
+ if os == Android {
+ if featureMap, ok := androidArchFeatureMap[archType]; ok {
a.ArchFeatures = featureMap[a.ArchVariant]
}
}
@@ -2194,3 +2235,40 @@
return value
}
+
+func printArchTypeStarlarkDict(dict map[ArchType][]string) string {
+ valDict := make(map[string]string, len(dict))
+ for k, v := range dict {
+ valDict[k.String()] = starlark_fmt.PrintStringList(v, 1)
+ }
+ return starlark_fmt.PrintDict(valDict, 0)
+}
+
+func printArchTypeNestedStarlarkDict(dict map[ArchType]map[string][]string) string {
+ valDict := make(map[string]string, len(dict))
+ for k, v := range dict {
+ valDict[k.String()] = starlark_fmt.PrintStringListDict(v, 1)
+ }
+ return starlark_fmt.PrintDict(valDict, 0)
+}
+
+func StarlarkArchConfigurations() string {
+ return fmt.Sprintf(`
+_arch_to_variants = %s
+
+_arch_to_cpu_variants = %s
+
+_arch_to_features = %s
+
+_android_arch_feature_for_arch_variant = %s
+
+arch_to_variants = _arch_to_variants
+arch_to_cpu_variants = _arch_to_cpu_variants
+arch_to_features = _arch_to_features
+android_arch_feature_for_arch_variants = _android_arch_feature_for_arch_variant
+`, printArchTypeStarlarkDict(archVariants),
+ printArchTypeStarlarkDict(cpuVariants),
+ printArchTypeStarlarkDict(archFeatures),
+ printArchTypeNestedStarlarkDict(androidArchFeatureMap),
+ )
+}
diff --git a/android/arch_list.go b/android/arch_list.go
index d68a0d1..cbf8e7a 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -14,46 +14,18 @@
package android
-import "fmt"
-
var archVariants = map[ArchType][]string{
Arm: {
"armv7-a",
"armv7-a-neon",
"armv8-a",
"armv8-2a",
- "cortex-a7",
- "cortex-a8",
- "cortex-a9",
- "cortex-a15",
- "cortex-a53",
- "cortex-a53-a57",
- "cortex-a55",
- "cortex-a72",
- "cortex-a73",
- "cortex-a75",
- "cortex-a76",
- "krait",
- "kryo",
- "kryo385",
- "exynos-m1",
- "exynos-m2",
},
Arm64: {
- "armv8_a",
- "armv8_a_branchprot",
- "armv8_2a",
+ "armv8-a",
+ "armv8-a-branchprot",
+ "armv8-2a",
"armv8-2a-dotprod",
- "cortex-a53",
- "cortex-a55",
- "cortex-a72",
- "cortex-a73",
- "cortex-a75",
- "cortex-a76",
- "kryo",
- "kryo385",
- "exynos-m1",
- "exynos-m2",
},
X86: {
"amberlake",
@@ -87,6 +59,41 @@
},
}
+var cpuVariants = map[ArchType][]string{
+ Arm: {
+ "cortex-a7",
+ "cortex-a8",
+ "cortex-a9",
+ "cortex-a15",
+ "cortex-a53",
+ "cortex-a53.a57",
+ "cortex-a55",
+ "cortex-a72",
+ "cortex-a73",
+ "cortex-a75",
+ "cortex-a76",
+ "krait",
+ "kryo",
+ "kryo385",
+ "exynos-m1",
+ "exynos-m2",
+ },
+ Arm64: {
+ "cortex-a53",
+ "cortex-a55",
+ "cortex-a72",
+ "cortex-a73",
+ "cortex-a75",
+ "cortex-a76",
+ "kryo",
+ "kryo385",
+ "exynos-m1",
+ "exynos-m2",
+ },
+ X86: {},
+ X86_64: {},
+}
+
var archFeatures = map[ArchType][]string{
Arm: {
"neon",
@@ -119,7 +126,7 @@
},
}
-var archFeatureMap = map[ArchType]map[string][]string{
+var androidArchFeatureMap = map[ArchType]map[string][]string{
Arm: {
"armv7-a-neon": {
"neon",
@@ -270,6 +277,13 @@
},
},
X86_64: {
+ "" /*default */ : {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "popcnt",
+ },
"amberlake": {
"ssse3",
"sse4",
@@ -389,23 +403,3 @@
},
},
}
-
-var defaultArchFeatureMap = map[OsType]map[ArchType][]string{}
-
-// RegisterDefaultArchVariantFeatures is called by files that define Toolchains to specify the
-// arch features that are available for the default arch variant. It must be called from an
-// init() function.
-func RegisterDefaultArchVariantFeatures(os OsType, arch ArchType, features ...string) {
- checkCalledFromInit()
-
- for _, feature := range features {
- if !InList(feature, archFeatures[arch]) {
- panic(fmt.Errorf("Invalid feature %q for arch %q variant \"\"", feature, arch))
- }
- }
-
- if defaultArchFeatureMap[os] == nil {
- defaultArchFeatureMap[os] = make(map[ArchType][]string)
- }
- defaultArchFeatureMap[os][arch] = features
-}
diff --git a/android/arch_test.go b/android/arch_test.go
index a828321..7caf837 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -491,11 +491,9 @@
arch: {
arm: {
a: ["arm"],
- armv7_a_neon: { a: ["armv7_a_neon"] },
},
arm64: {
a: ["arm64"],
- armv8_a: { a: ["armv8_a"] },
},
x86: { a: ["x86"] },
x86_64: { a: ["x86_64"] },
@@ -552,12 +550,12 @@
{
module: "foo",
variant: "android_arm64_armv8-a",
- property: []string{"root", "linux", "bionic", "android", "android64", "arm64", "armv8_a", "lib64", "android_arm64"},
+ property: []string{"root", "linux", "bionic", "android", "android64", "arm64", "lib64", "android_arm64"},
},
{
module: "foo",
variant: "android_arm_armv7-a-neon",
- property: []string{"root", "linux", "bionic", "android", "android64", "arm", "armv7_a_neon", "lib32", "android_arm"},
+ property: []string{"root", "linux", "bionic", "android", "android64", "arm", "lib32", "android_arm"},
},
},
},
diff --git a/android/bazel.go b/android/bazel.go
index f4fc038..86339ab 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -208,6 +208,7 @@
"build/bazel/tests":/* recursive = */ true,
"build/bazel/platforms":/* recursive = */ true,
"build/bazel/product_variables":/* recursive = */ true,
+ "build/bazel/vendor/google":/* recursive = */ true,
"build/bazel_common_rules":/* recursive = */ true,
// build/make/tools/signapk BUILD file is generated, so build/make/tools is not recursive.
"build/make/tools":/* recursive = */ false,
@@ -225,8 +226,10 @@
"packages/apps/QuickSearchBox":/* recursive = */ true,
"packages/apps/WallpaperPicker":/* recursive = */ false,
+ "prebuilts/bundletool":/* recursive = */ true,
"prebuilts/gcc":/* recursive = */ true,
"prebuilts/build-tools":/* recursive = */ false,
+ "prebuilts/jdk/jdk11":/* recursive = */ false,
"prebuilts/sdk":/* recursive = */ false,
"prebuilts/sdk/current/extras/app-toolkit":/* recursive = */ false,
"prebuilts/sdk/current/support":/* recursive = */ false,
@@ -245,6 +248,7 @@
"build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively,
"build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
"build/make/tools/signapk": Bp2BuildDefaultTrue,
+ "build/make/target/product/security": Bp2BuildDefaultTrue,
"build/soong": Bp2BuildDefaultTrue,
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
"build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
@@ -295,6 +299,7 @@
"external/bouncycastle": Bp2BuildDefaultTrue,
"external/brotli": Bp2BuildDefaultTrue,
"external/conscrypt": Bp2BuildDefaultTrue,
+ "external/e2fsprogs/lib": Bp2BuildDefaultTrueRecursively,
"external/error_prone": Bp2BuildDefaultTrueRecursively,
"external/fmtlib": Bp2BuildDefaultTrueRecursively,
"external/google-benchmark": Bp2BuildDefaultTrueRecursively,
@@ -325,6 +330,7 @@
"external/zstd": Bp2BuildDefaultTrueRecursively,
"frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue,
"frameworks/base/startop/apps/test": Bp2BuildDefaultTrue,
+ "frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
"frameworks/native/opengl/tests/gl2_cameraeye": Bp2BuildDefaultTrue,
"frameworks/native/opengl/tests/gl2_java": Bp2BuildDefaultTrue,
@@ -379,6 +385,39 @@
"tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively,
}
+ // Per-module allowlist to always opt modules in of both bp2build and mixed builds.
+ // These modules are usually in directories with many other modules that are not ready for
+ // conversion.
+ //
+ // A module can either be in this list or its directory allowlisted entirely
+ // in bp2buildDefaultConfig, but not both at the same time.
+ bp2buildModuleAlwaysConvertList = []string{
+ "junit-params-assertj-core",
+
+ //external/avb
+ "avbtool",
+ "libavb",
+ "avb_headers",
+
+ //external/fec
+ "libfec_rs",
+
+ //system/core/libsparse
+ "libsparse",
+
+ //system/extras/ext4_utils
+ "libext4_utils",
+
+ //system/extras/libfec
+ "libfec",
+
+ //system/extras/squashfs_utils
+ "libsquashfs_utils",
+
+ //system/extras/verity/fec
+ "fec",
+ }
+
// Per-module denylist to always opt modules out of both bp2build and mixed builds.
bp2buildModuleDoNotConvertList = []string{
"libnativehelper_compat_libc", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99
@@ -494,10 +533,11 @@
// go deps:
"apex-protos", // depends on soong_zip, a go binary
"generated_android_icu4j_src_files", "generated_android_icu4j_test_files", "icu4c_test_data", // depends on unconverted modules: soong_zip
- "host_bionic_linker_asm", // depends on extract_linker, a go binary.
- "host_bionic_linker_script", // depends on extract_linker, a go binary.
- "robolectric-sqlite4java-native", // depends on soong_zip, a go binary
- "robolectric_tzdata", // depends on soong_zip, a go binary
+ "host_bionic_linker_asm", // depends on extract_linker, a go binary.
+ "host_bionic_linker_script", // depends on extract_linker, a go binary.
+ "robolectric-sqlite4java-native", // depends on soong_zip, a go binary
+ "robolectric_tzdata", // depends on soong_zip, a go binary
+ "libc_musl_sysroot_libc++_headers", "libc_musl_sysroot_libc++abi_headers", // depends on soong_zip, zip2zip
"android_icu4j_srcgen_binary", // Bazel build error: deps not allowed without srcs; move to runtime_deps
"core-icu4j-for-host", // Bazel build error: deps not allowed without srcs; move to runtime_deps
@@ -569,11 +609,16 @@
// Used for quicker lookups
bp2buildModuleDoNotConvert = map[string]bool{}
+ bp2buildModuleAlwaysConvert = map[string]bool{}
bp2buildCcLibraryStaticOnly = map[string]bool{}
mixedBuildsDisabled = map[string]bool{}
)
func init() {
+ for _, moduleName := range bp2buildModuleAlwaysConvertList {
+ bp2buildModuleAlwaysConvert[moduleName] = true
+ }
+
for _, moduleName := range bp2buildModuleDoNotConvertList {
bp2buildModuleDoNotConvert[moduleName] = true
}
@@ -649,7 +694,14 @@
}
func (b *BazelModuleBase) shouldConvertWithBp2build(ctx BazelConversionContext, module blueprint.Module) bool {
- if bp2buildModuleDoNotConvert[module.Name()] {
+ moduleNameNoPrefix := RemoveOptionalPrebuiltPrefix(module.Name())
+ alwaysConvert := bp2buildModuleAlwaysConvert[moduleNameNoPrefix]
+
+ if bp2buildModuleDoNotConvert[moduleNameNoPrefix] {
+ if alwaysConvert {
+ ctx.(BaseModuleContext).ModuleErrorf("a module cannot be in bp2buildModuleDoNotConvert" +
+ " and also be in bp2buildModuleAlwaysConvert")
+ }
return false
}
@@ -658,17 +710,29 @@
}
packagePath := ctx.OtherModuleDir(module)
- config := ctx.Config().bp2buildPackageConfig
+ if alwaysConvert && ShouldKeepExistingBuildFileForDir(packagePath) {
+ ctx.(BaseModuleContext).ModuleErrorf("A module cannot be in a directory listed in bp2buildKeepExistingBuildFile"+
+ " and also be in bp2buildModuleAlwaysConvert. Directory: '%s'", packagePath)
+ return false
+ }
+
+ config := ctx.Config().bp2buildPackageConfig
// This is a tristate value: true, false, or unset.
propValue := b.bazelProperties.Bazel_module.Bp2build_available
if bp2buildDefaultTrueRecursively(packagePath, config) {
+ if alwaysConvert {
+ ctx.(BaseModuleContext).ModuleErrorf("A module cannot be in a directory marked Bp2BuildDefaultTrue"+
+ " or Bp2BuildDefaultTrueRecursively and also be in bp2buildModuleAlwaysConvert. Directory: '%s'",
+ packagePath)
+ }
+
// Allow modules to explicitly opt-out.
return proptools.BoolDefault(propValue, true)
}
// Allow modules to explicitly opt-in.
- return proptools.BoolDefault(propValue, false)
+ return proptools.BoolDefault(propValue, alwaysConvert)
}
// bp2buildDefaultTrueRecursively checks that the package contains a prefix from the
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 804a5fb..3d6babc 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -664,7 +664,12 @@
if err != nil {
return err
}
-
+ if metricsDir := context.paths.BazelMetricsDir(); metricsDir != "" {
+ err = os.MkdirAll(metricsDir, 0777)
+ if err != nil {
+ return err
+ }
+ }
err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "WORKSPACE.bazel"), []byte{}, 0666)
if err != nil {
return err
@@ -716,9 +721,9 @@
}
}
- for val, _ := range context.requests {
+ for val := range context.requests {
if cqueryResult, ok := cqueryResults[getCqueryId(val)]; ok {
- context.results[val] = string(cqueryResult)
+ context.results[val] = cqueryResult
} else {
return fmt.Errorf("missing result for bazel target %s. query output: [%s], cquery err: [%s]",
getCqueryId(val), cqueryOutput, cqueryErr)
diff --git a/android/config.go b/android/config.go
index 4a7e0d9..3d8bc31 100644
--- a/android/config.go
+++ b/android/config.go
@@ -520,7 +520,7 @@
}
if archConfig != nil {
- androidTargets, err := decodeArchSettings(Android, archConfig)
+ androidTargets, err := decodeAndroidArchSettings(archConfig)
if err != nil {
return Config{}, err
}
@@ -1651,6 +1651,10 @@
return c.config.productVariables.BuildBrokenVendorPropertyNamespace
}
+func (c *deviceConfig) BuildBrokenInputDir(name string) bool {
+ return InList(name, c.config.productVariables.BuildBrokenInputDirModules)
+}
+
func (c *deviceConfig) RequiresInsecureExecmemForSwiftshader() bool {
return c.config.productVariables.RequiresInsecureExecmemForSwiftshader
}
diff --git a/android/filegroup.go b/android/filegroup.go
index c932ffa..d2ff97d 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -18,6 +18,8 @@
"strings"
"android/soong/bazel"
+
+ "github.com/google/blueprint"
)
func init() {
@@ -28,6 +30,11 @@
ctx.RegisterModuleType("filegroup", FileGroupFactory)
})
+// IsFilegroup checks that a module is a filegroup type
+func IsFilegroup(ctx bazel.OtherModuleContext, m blueprint.Module) bool {
+ return ctx.OtherModuleType(m) == "filegroup"
+}
+
// https://docs.bazel.build/versions/master/be/general.html#filegroup
type bazelFilegroupAttributes struct {
Srcs bazel.LabelListAttribute
diff --git a/android/licenses.go b/android/licenses.go
index b51a06b..e60c7a2 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -333,4 +333,6 @@
ctx.Strict("HTMLNOTICE", ctx.Config().HostToolPath(ctx, "htmlnotice").String())
ctx.Strict("XMLNOTICE", ctx.Config().HostToolPath(ctx, "xmlnotice").String())
ctx.Strict("TEXTNOTICE", ctx.Config().HostToolPath(ctx, "textnotice").String())
+ ctx.Strict("COMPLIANCENOTICE_BOM", ctx.Config().HostToolPath(ctx, "compliancenotice_bom").String())
+ ctx.Strict("COMPLIANCENOTICE_SHIPPEDLIBS", ctx.Config().HostToolPath(ctx, "compliancenotice_shippedlibs").String())
}
diff --git a/android/paths.go b/android/paths.go
index 4c69de7..05caebd 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -405,6 +405,13 @@
return PathsForModuleSrcExcludes(ctx, paths, nil)
}
+type SourceInput struct {
+ Context ModuleMissingDepsPathContext
+ Paths []string
+ ExcludePaths []string
+ IncludeDirs bool
+}
+
// PathsForModuleSrcExcludes returns a Paths{} containing the resolved references in paths, minus
// those listed in excludes. Elements of paths and excludes are resolved as:
// * filepath, relative to local module directory, resolves as a filepath relative to the local
@@ -423,12 +430,21 @@
// missing dependencies
// * otherwise, a ModuleError is thrown.
func PathsForModuleSrcExcludes(ctx ModuleMissingDepsPathContext, paths, excludes []string) Paths {
- ret, missingDeps := PathsAndMissingDepsForModuleSrcExcludes(ctx, paths, excludes)
- if ctx.Config().AllowMissingDependencies() {
- ctx.AddMissingDependencies(missingDeps)
+ return PathsRelativeToModuleSourceDir(SourceInput{
+ Context: ctx,
+ Paths: paths,
+ ExcludePaths: excludes,
+ IncludeDirs: true,
+ })
+}
+
+func PathsRelativeToModuleSourceDir(input SourceInput) Paths {
+ ret, missingDeps := PathsAndMissingDepsRelativeToModuleSourceDir(input)
+ if input.Context.Config().AllowMissingDependencies() {
+ input.Context.AddMissingDependencies(missingDeps)
} else {
for _, m := range missingDeps {
- ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
+ input.Context.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
}
}
return ret
@@ -543,23 +559,31 @@
// Properties passed as the paths argument must have been annotated with struct tag
// `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the
// path_deps mutator.
-func PathsAndMissingDepsForModuleSrcExcludes(ctx ModuleWithDepsPathContext, paths, excludes []string) (Paths, []string) {
- prefix := pathForModuleSrc(ctx).String()
+func PathsAndMissingDepsForModuleSrcExcludes(ctx ModuleMissingDepsPathContext, paths, excludes []string) (Paths, []string) {
+ return PathsAndMissingDepsRelativeToModuleSourceDir(SourceInput{
+ Context: ctx,
+ Paths: paths,
+ ExcludePaths: excludes,
+ IncludeDirs: true,
+ })
+}
+
+func PathsAndMissingDepsRelativeToModuleSourceDir(input SourceInput) (Paths, []string) {
+ prefix := pathForModuleSrc(input.Context).String()
var expandedExcludes []string
- if excludes != nil {
- expandedExcludes = make([]string, 0, len(excludes))
+ if input.ExcludePaths != nil {
+ expandedExcludes = make([]string, 0, len(input.ExcludePaths))
}
var missingExcludeDeps []string
-
- for _, e := range excludes {
+ for _, e := range input.ExcludePaths {
if m, t := SrcIsModuleWithTag(e); m != "" {
- modulePaths, err := getPathsFromModuleDep(ctx, e, m, t)
+ modulePaths, err := getPathsFromModuleDep(input.Context, e, m, t)
if m, ok := err.(missingDependencyError); ok {
missingExcludeDeps = append(missingExcludeDeps, m.missingDeps...)
} else if err != nil {
- reportPathError(ctx, err)
+ reportPathError(input.Context, err)
} else {
expandedExcludes = append(expandedExcludes, modulePaths.Strings()...)
}
@@ -568,19 +592,24 @@
}
}
- if paths == nil {
+ if input.Paths == nil {
return nil, missingExcludeDeps
}
var missingDeps []string
- expandedSrcFiles := make(Paths, 0, len(paths))
- for _, s := range paths {
- srcFiles, err := expandOneSrcPath(ctx, s, expandedExcludes)
+ expandedSrcFiles := make(Paths, 0, len(input.Paths))
+ for _, s := range input.Paths {
+ srcFiles, err := expandOneSrcPath(sourcePathInput{
+ context: input.Context,
+ path: s,
+ expandedExcludes: expandedExcludes,
+ includeDirs: input.IncludeDirs,
+ })
if depErr, ok := err.(missingDependencyError); ok {
missingDeps = append(missingDeps, depErr.missingDeps...)
} else if err != nil {
- reportPathError(ctx, err)
+ reportPathError(input.Context, err)
}
expandedSrcFiles = append(expandedSrcFiles, srcFiles...)
}
@@ -596,44 +625,59 @@
return "missing dependencies: " + strings.Join(e.missingDeps, ", ")
}
+type sourcePathInput struct {
+ context ModuleWithDepsPathContext
+ path string
+ expandedExcludes []string
+ includeDirs bool
+}
+
// Expands one path string to Paths rooted from the module's local source
// directory, excluding those listed in the expandedExcludes.
// Expands globs, references to SourceFileProducer or OutputFileProducer modules using the ":name" and ":name{.tag}" syntax.
-func expandOneSrcPath(ctx ModuleWithDepsPathContext, sPath string, expandedExcludes []string) (Paths, error) {
+func expandOneSrcPath(input sourcePathInput) (Paths, error) {
excludePaths := func(paths Paths) Paths {
- if len(expandedExcludes) == 0 {
+ if len(input.expandedExcludes) == 0 {
return paths
}
remainder := make(Paths, 0, len(paths))
for _, p := range paths {
- if !InList(p.String(), expandedExcludes) {
+ if !InList(p.String(), input.expandedExcludes) {
remainder = append(remainder, p)
}
}
return remainder
}
- if m, t := SrcIsModuleWithTag(sPath); m != "" {
- modulePaths, err := getPathsFromModuleDep(ctx, sPath, m, t)
+ if m, t := SrcIsModuleWithTag(input.path); m != "" {
+ modulePaths, err := getPathsFromModuleDep(input.context, input.path, m, t)
if err != nil {
return nil, err
} else {
return excludePaths(modulePaths), nil
}
- } else if pathtools.IsGlob(sPath) {
- paths := GlobFiles(ctx, pathForModuleSrc(ctx, sPath).String(), expandedExcludes)
- return PathsWithModuleSrcSubDir(ctx, paths, ""), nil
} else {
- p := pathForModuleSrc(ctx, sPath)
- if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
- ReportPathErrorf(ctx, "%s: %s", p, err.Error())
- } else if !exists && !ctx.Config().TestAllowNonExistentPaths {
- ReportPathErrorf(ctx, "module source path %q does not exist", p)
- }
+ p := pathForModuleSrc(input.context, input.path)
+ if pathtools.IsGlob(input.path) {
+ paths := GlobFiles(input.context, p.String(), input.expandedExcludes)
+ return PathsWithModuleSrcSubDir(input.context, paths, ""), nil
+ } else {
+ if exists, _, err := input.context.Config().fs.Exists(p.String()); err != nil {
+ ReportPathErrorf(input.context, "%s: %s", p, err.Error())
+ } else if !exists && !input.context.Config().TestAllowNonExistentPaths {
+ ReportPathErrorf(input.context, "module source path %q does not exist", p)
+ } else if !input.includeDirs {
+ if isDir, err := input.context.Config().fs.IsDir(p.String()); exists && err != nil {
+ ReportPathErrorf(input.context, "%s: %s", p, err.Error())
+ } else if isDir {
+ ReportPathErrorf(input.context, "module source path %q is a directory", p)
+ }
+ }
- if InList(p.String(), expandedExcludes) {
- return nil, nil
+ if InList(p.String(), input.expandedExcludes) {
+ return nil, nil
+ }
+ return Paths{p}, nil
}
- return Paths{p}, nil
}
}
@@ -1315,7 +1359,7 @@
// validatePath() will corrupt it, e.g. replace "//" with "/". If the path is not a module
// reference then it will be validated by expandOneSrcPath anyway when it calls expandOneSrcPath.
p := strings.Join(pathComponents, string(filepath.Separator))
- paths, err := expandOneSrcPath(ctx, p, nil)
+ paths, err := expandOneSrcPath(sourcePathInput{context: ctx, path: p, includeDirs: true})
if err != nil {
if depErr, ok := err.(missingDependencyError); ok {
if ctx.Config().AllowMissingDependencies() {
diff --git a/android/proto.go b/android/proto.go
index f466261..c3759f8 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -16,6 +16,7 @@
import (
"android/soong/bazel"
+ "regexp"
"strings"
"github.com/google/blueprint"
@@ -26,6 +27,14 @@
canonicalPathFromRootDefault = true
)
+var (
+ // ignoring case, checks for proto or protos as an independent word in the name, whether at the
+ // beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match
+ filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)")
+
+ ProtoSrcLabelPartition = bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup}
+)
+
// TODO(ccross): protos are often used to communicate between multiple modules. If the only
// way to convert a proto to source is to reference it as a source file, and external modules cannot
// reference source files in other modules, then every module that owns a proto file will need to
@@ -165,12 +174,11 @@
// Bp2buildProtoProperties converts proto properties, creating a proto_library and returning the
// information necessary for language-specific handling.
-func Bp2buildProtoProperties(ctx Bp2buildMutatorContext, module Module, srcs bazel.LabelListAttribute) (Bp2buildProtoInfo, bool) {
+func Bp2buildProtoProperties(ctx Bp2buildMutatorContext, m *ModuleBase, srcs bazel.LabelListAttribute) (Bp2buildProtoInfo, bool) {
var info Bp2buildProtoInfo
if srcs.IsEmpty() {
return info, false
}
- m := module.base()
info.Name = m.Name() + "_proto"
attrs := protoAttrs{
@@ -205,3 +213,13 @@
return info, true
}
+
+func isProtoFilegroup(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
+ m, exists := ctx.ModuleFromName(label.OriginalModuleName)
+ labelStr := label.Label
+ if !exists || !IsFilegroup(ctx, m) {
+ return labelStr, false
+ }
+ likelyProtos := filegroupLikelyProtoPattern.MatchString(label.OriginalModuleName)
+ return labelStr, likelyProtos
+}
diff --git a/android/variable.go b/android/variable.go
index 627d9bd..68f19b9 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -421,9 +421,10 @@
ShippingApiLevel *string `json:",omitempty"`
- BuildBrokenEnforceSyspropOwner bool `json:",omitempty"`
- BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"`
- BuildBrokenVendorPropertyNamespace bool `json:",omitempty"`
+ BuildBrokenEnforceSyspropOwner bool `json:",omitempty"`
+ BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"`
+ BuildBrokenVendorPropertyNamespace bool `json:",omitempty"`
+ BuildBrokenInputDirModules []string `json:",omitempty"`
BuildDebugfsRestrictionsEnabled bool `json:",omitempty"`
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 8cca137..8785ca0 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -309,7 +309,14 @@
return moduleNames
}
-func (a *apexBundle) writeRequiredModules(w io.Writer) {
+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
@@ -349,10 +356,7 @@
fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
fmt.Fprintln(w, "LOCAL_MODULE :=", name+a.suffix)
data.Entries.WriteLicenseVariables(w)
- if len(moduleNames) > 0 {
- fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(moduleNames, " "))
- }
- a.writeRequiredModules(w)
+ a.writeRequiredModules(w, moduleNames)
fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
} else {
@@ -388,13 +392,7 @@
if len(a.overridableProperties.Overrides) > 0 {
fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(a.overridableProperties.Overrides, " "))
}
- 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, " "))
- }
- a.writeRequiredModules(w)
+ a.writeRequiredModules(w, moduleNames)
if a.mergedNotices.Merged.Valid() {
fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", a.mergedNotices.Merged.Path().String())
diff --git a/apex/apex.go b/apex/apex.go
index d12a786..9031a4e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -108,15 +108,6 @@
Multilib apexMultilibProperties
- // List of bootclasspath fragments that are embedded inside this APEX bundle.
- Bootclasspath_fragments []string
-
- // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
- Systemserverclasspath_fragments []string
-
- // List of java libraries that are embedded inside this APEX bundle.
- Java_libs []string
-
// List of sh binaries that are embedded inside this APEX bundle.
Sh_binaries []string
@@ -316,6 +307,15 @@
// List of BPF programs inside this APEX bundle.
Bpfs []string
+ // List of bootclasspath fragments that are embedded inside this APEX bundle.
+ Bootclasspath_fragments []string
+
+ // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
+ Systemserverclasspath_fragments []string
+
+ // List of java libraries that are embedded inside this APEX bundle.
+ Java_libs []string
+
// Names of modules to be overridden. Listed modules can only be other binaries (in Make or
// Soong). This does not completely prevent installation of the overridden binaries, but if
// both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
@@ -416,8 +416,12 @@
mergedNotices android.NoticeOutputs
// The built APEX file. This is the main product.
+ // Could be .apex or .capex
outputFile android.WritablePath
+ // The built uncompressed .apex file.
+ outputApexFile android.WritablePath
+
// The built APEX file in app bundle format. This file is not directly installed to the
// device. For an APEX, multiple app bundles are created each of which is for a specific ABI
// like arm, arm64, x86, etc. Then they are processed again (outside of the Android build
@@ -783,9 +787,6 @@
// Common-arch dependencies come next
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
- ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
- ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments...)
- ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
@@ -813,6 +814,9 @@
ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
+ ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
+ ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
+ ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
// regardless of the TARGET_PREFER_* setting. See b/144532908
@@ -1284,6 +1288,12 @@
case "", android.DefaultDistTag:
// This is the default dist path.
return android.Paths{a.outputFile}, nil
+ case imageApexSuffix:
+ // uncompressed one
+ if a.outputApexFile != nil {
+ return android.Paths{a.outputApexFile}, nil
+ }
+ fallthrough
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -1745,6 +1755,7 @@
fi := apexFileForRustLibrary(ctx, r)
fi.isJniLib = isJniLib
filesInfo = append(filesInfo, fi)
+ return true // track transitive dependencies
} else {
propertyName := "native_shared_libs"
if isJniLib {
@@ -2584,9 +2595,9 @@
// Collect information for opening IDE project files in java/jdeps.go.
func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
- dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
- dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
- dpInfo.Deps = append(dpInfo.Deps, a.properties.Systemserverclasspath_fragments...)
+ dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
+ dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
+ dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 6d77b06..1c36c75 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -971,6 +971,9 @@
rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
+
+ apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
+ ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so")
}
func TestApexCanUsePrivateApis(t *testing.T) {
@@ -6088,6 +6091,9 @@
apps: ["app"],
bpfs: ["bpf"],
prebuilts: ["myetc"],
+ bootclasspath_fragments: ["mybootclasspath_fragment"],
+ systemserverclasspath_fragments: ["mysystemserverclasspath_fragment"],
+ java_libs: ["myjava_library"],
overrides: ["oldapex"],
updatable: false,
}
@@ -6098,6 +6104,9 @@
apps: ["override_app"],
bpfs: ["override_bpf"],
prebuilts: ["override_myetc"],
+ bootclasspath_fragments: ["override_bootclasspath_fragment"],
+ systemserverclasspath_fragments: ["override_systemserverclasspath_fragment"],
+ java_libs: ["override_java_library"],
overrides: ["unknownapex"],
logging_parent: "com.foo.bar",
package_name: "test.overridden.package",
@@ -6156,6 +6165,72 @@
name: "override_myetc",
src: "override_myprebuilt",
}
+
+ java_library {
+ name: "bcplib",
+ srcs: ["a.java"],
+ compile_dex: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["bcp.lib"],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspath_fragment",
+ contents: ["bcplib"],
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "override_bcplib",
+ srcs: ["a.java"],
+ compile_dex: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["override.bcp.lib"],
+ }
+
+ bootclasspath_fragment {
+ name: "override_bootclasspath_fragment",
+ contents: ["override_bcplib"],
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "systemserverlib",
+ srcs: ["a.java"],
+ apex_available: ["myapex"],
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspath_fragment",
+ standalone_contents: ["systemserverlib"],
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "override_systemserverlib",
+ srcs: ["a.java"],
+ apex_available: ["myapex"],
+ }
+
+ systemserverclasspath_fragment {
+ name: "override_systemserverclasspath_fragment",
+ standalone_contents: ["override_systemserverlib"],
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "myjava_library",
+ srcs: ["a.java"],
+ compile_dex: true,
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "override_java_library",
+ srcs: ["a.java"],
+ compile_dex: true,
+ apex_available: ["myapex"],
+ }
`, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"}))
originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(android.OverridableModule)
@@ -6190,6 +6265,13 @@
t.Errorf("override_myapex should have logging parent (com.foo.bar), but was %q.", apexBundle.overridableProperties.Logging_parent)
}
+ android.AssertArrayString(t, "Bootclasspath_fragments does not match",
+ []string{"override_bootclasspath_fragment"}, apexBundle.overridableProperties.Bootclasspath_fragments)
+ android.AssertArrayString(t, "Systemserverclasspath_fragments does not match",
+ []string{"override_systemserverclasspath_fragment"}, apexBundle.overridableProperties.Systemserverclasspath_fragments)
+ android.AssertArrayString(t, "Java_libs does not match",
+ []string{"override_java_library"}, apexBundle.overridableProperties.Java_libs)
+
optFlags := apexRule.Args["opt_flags"]
ensureContains(t, optFlags, "--override_apk_package_name test.overridden.package")
ensureContains(t, optFlags, "--pubkey testkey2.avbpubkey")
@@ -6204,12 +6286,18 @@
ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE := override_bpf.o.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex")
+ ensureContains(t, androidMk, "LOCAL_MODULE := override_bcplib.override_myapex")
+ ensureContains(t, androidMk, "LOCAL_MODULE := override_systemserverlib.override_myapex")
+ ensureContains(t, androidMk, "LOCAL_MODULE := override_java_library.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex")
ensureContains(t, androidMk, "LOCAL_OVERRIDES_MODULES := unknownapex myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE := bpf.myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE := override_app.myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := override_bcplib.myapex")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := override_systemserverlib.myapex")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := override_java_library.pb.myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex")
}
@@ -6830,7 +6918,7 @@
apex {
name: "myapex",
key: "myapex.key",
- jni_libs: ["mylib"],
+ jni_libs: ["mylib", "libfoo.rust"],
updatable: false,
}
@@ -6856,15 +6944,41 @@
stl: "none",
apex_available: [ "myapex" ],
}
+
+ rust_ffi_shared {
+ name: "libfoo.rust",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ shared_libs: ["libfoo.shared_from_rust"],
+ prefer_rlib: true,
+ apex_available: ["myapex"],
+ }
+
+ cc_library_shared {
+ name: "libfoo.shared_from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: {
+ versions: ["10", "11", "12"],
+ },
+ }
+
`)
rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
// Notice mylib2.so (transitive dep) is not added as a jni_lib
- ensureEquals(t, rule.Args["opt"], "-a jniLibs mylib.so")
+ ensureEquals(t, rule.Args["opt"], "-a jniLibs libfoo.rust.so mylib.so")
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"lib64/mylib.so",
"lib64/mylib2.so",
+ "lib64/libfoo.rust.so",
+ "lib64/libc++.so", // auto-added to libfoo.rust by Soong
+ "lib64/liblog.so", // auto-added to libfoo.rust by Soong
})
+
+ // b/220397949
+ ensureListContains(t, names(rule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so")
}
func TestApexMutatorsDontRunIfDisabled(t *testing.T) {
@@ -8661,6 +8775,86 @@
ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherapex")
}
+func TestAndroidMk_RequiredDeps(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `)
+
+ bundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+ bundle.requiredDeps = append(bundle.requiredDeps, "foo")
+ data := android.AndroidMkDataForTest(t, ctx, bundle)
+ var builder strings.Builder
+ data.Custom(&builder, bundle.BaseModuleName(), "TARGET_", "", data)
+ androidMk := builder.String()
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += foo")
+
+ flattenedBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
+ flattenedBundle.requiredDeps = append(flattenedBundle.requiredDeps, "foo")
+ flattenedData := android.AndroidMkDataForTest(t, ctx, flattenedBundle)
+ var flattenedBuilder strings.Builder
+ flattenedData.Custom(&flattenedBuilder, flattenedBundle.BaseModuleName(), "TARGET_", "", flattenedData)
+ flattenedAndroidMk := flattenedBuilder.String()
+ ensureContains(t, flattenedAndroidMk, "LOCAL_REQUIRED_MODULES += foo")
+}
+
+func TestApexOutputFileProducer(t *testing.T) {
+ for _, tc := range []struct {
+ name string
+ ref string
+ expected_data []string
+ }{
+ {
+ name: "test_using_output",
+ ref: ":myapex",
+ expected_data: []string{"out/soong/.intermediates/myapex/android_common_myapex_image/myapex.capex:myapex.capex"},
+ },
+ {
+ name: "test_using_apex",
+ ref: ":myapex{.apex}",
+ expected_data: []string{"out/soong/.intermediates/myapex/android_common_myapex_image/myapex.apex:myapex.apex"},
+ },
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ compressible: true,
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_test {
+ name: "`+tc.name+`",
+ srcs: ["a.java"],
+ data: ["`+tc.ref+`"],
+ }
+ `,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.CompressedApex = proptools.BoolPtr(true)
+ }))
+ javaTest := ctx.ModuleForTests(tc.name, "android_common").Module().(*java.Test)
+ data := android.AndroidMkEntriesForTest(t, ctx, javaTest)[0].EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
+ android.AssertStringPathsRelativeToTopEquals(t, "data", ctx.Config(), tc.expected_data, data)
+ })
+ }
+}
+
func TestSdkLibraryCanHaveHigherMinSdkVersion(t *testing.T) {
preparer := android.GroupFixturePreparers(
PrepareForTestWithApexBuildComponents,
diff --git a/apex/builder.go b/apex/builder.go
index fc4bf8a..183c215 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -810,6 +810,9 @@
Implicits: implicits,
Args: args,
})
+ if suffix == imageApexSuffix {
+ a.outputApexFile = signedOutputFile
+ }
a.outputFile = signedOutputFile
if ctx.ModuleDir() != "system/apex/apexd/apexd_testdata" && a.testOnlyShouldForceCompression() {
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 96c12d3..3ab846b 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -28,6 +28,8 @@
files = append(files, newFile("product_config", "soong_config_variables.bzl", cfg.Bp2buildSoongConfigDefinitions.String()))
+ files = append(files, newFile("product_config", "arch_configuration.bzl", android.StarlarkArchConfigurations()))
+
apiLevelsContent, err := json.Marshal(android.GetApiLevelsMap(cfg))
if err != nil {
panic(err)
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index 629ca9b..c94a923 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -103,6 +103,10 @@
basename: "soong_config_variables.bzl",
},
{
+ dir: "product_config",
+ basename: "arch_configuration.bzl",
+ },
+ {
dir: "api_levels",
basename: GeneratedBuildFileName,
},
diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go
new file mode 100644
index 0000000..93b0677
--- /dev/null
+++ b/bp2build/java_proto_conversion_test.go
@@ -0,0 +1,124 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package bp2build
+
+import (
+ "fmt"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/java"
+)
+
+func runJavaProtoTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ (&tc).moduleTypeUnderTest = "java_library_static"
+ (&tc).moduleTypeUnderTestFactory = java.LibraryFactory
+ runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
+}
+
+func TestJavaProto(t *testing.T) {
+ testCases := []struct {
+ protoType string
+ javaLibraryType string
+ javaLibraryNameExtension string
+ }{
+ {
+ protoType: "nano",
+ javaLibraryType: "java_nano_proto_library",
+ javaLibraryNameExtension: "java_proto_nano",
+ },
+ {
+ protoType: "micro",
+ javaLibraryType: "java_micro_proto_library",
+ javaLibraryNameExtension: "java_proto_micro",
+ },
+ {
+ protoType: "lite",
+ javaLibraryType: "java_lite_proto_library",
+ javaLibraryNameExtension: "java_proto_lite",
+ },
+ {
+ protoType: "stream",
+ javaLibraryType: "java_stream_proto_library",
+ javaLibraryNameExtension: "java_proto_stream",
+ },
+ {
+ protoType: "full",
+ javaLibraryType: "java_proto_library",
+ javaLibraryNameExtension: "java_proto",
+ },
+ }
+
+ bp := `java_library_static {
+ name: "java-protos",
+ proto: {
+ type: "%s",
+ },
+ srcs: ["a.proto"],
+}`
+
+ protoLibrary := makeBazelTarget("proto_library", "java-protos_proto", attrNameToString{
+ "srcs": `["a.proto"]`,
+ "strip_import_prefix": `""`,
+ })
+
+ for _, tc := range testCases {
+ javaLibraryName := fmt.Sprintf("java-protos_%s", tc.javaLibraryNameExtension)
+
+ runJavaProtoTestCase(t, bp2buildTestCase{
+ description: fmt.Sprintf("java_proto %s", tc.protoType),
+ blueprint: fmt.Sprintf(bp, tc.protoType),
+ expectedBazelTargets: []string{
+ protoLibrary,
+ makeBazelTarget(
+ tc.javaLibraryType,
+ javaLibraryName,
+ attrNameToString{
+ "deps": `[":java-protos_proto"]`,
+ }),
+ makeBazelTarget("java_library", "java-protos", attrNameToString{
+ "deps": fmt.Sprintf(`[":%s"]`, javaLibraryName),
+ }),
+ },
+ })
+ }
+}
+
+func TestJavaProtoDefault(t *testing.T) {
+ runJavaProtoTestCase(t, bp2buildTestCase{
+ description: "java_proto",
+ blueprint: `java_library_static {
+ name: "java-protos",
+ srcs: ["a.proto"],
+}
+`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "java-protos_proto", attrNameToString{
+ "srcs": `["a.proto"]`,
+ "strip_import_prefix": `""`,
+ }),
+ makeBazelTarget(
+ "java_lite_proto_library",
+ "java-protos_java_proto_lite",
+ attrNameToString{
+ "deps": `[":java-protos_proto"]`,
+ }),
+ makeBazelTarget("java_library", "java-protos", attrNameToString{
+ "deps": `[":java-protos_java_proto_lite"]`,
+ }),
+ },
+ })
+}
diff --git a/build_test.bash b/build_test.bash
index b6d00e2..1dc6660 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -25,7 +25,9 @@
# Products that are broken or otherwise don't work with multiproduct_kati
SKIPPED_PRODUCTS=(
+ # Both of these products are for soong-only builds, and will fail the kati stage.
mainline_sdk
+ ndk
)
# To track how long we took to startup. %N isn't supported on Darwin, but
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 9290272..318cd7c 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -560,10 +560,6 @@
func (c *snapshotBinaryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
entries.Class = "EXECUTABLES"
entries.SubName = c.baseProperties.Androidmk_suffix
-
- entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.AddStrings("LOCAL_MODULE_SYMLINKS", c.Properties.Symlinks...)
- })
}
func (c *snapshotObjectLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
diff --git a/cc/binary.go b/cc/binary.go
index 6c7d581..0fe4490 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -441,6 +441,16 @@
// Need to determine symlinks early since some targets (ie APEX) need this
// information but will not call 'install'
+ binary.setSymlinkList(ctx)
+
+ return ret
+}
+
+func (binary *binaryDecorator) unstrippedOutputFilePath() android.Path {
+ return binary.unstrippedOutputFile
+}
+
+func (binary *binaryDecorator) setSymlinkList(ctx ModuleContext) {
for _, symlink := range binary.Properties.Symlinks {
binary.symlinks = append(binary.symlinks,
symlink+String(binary.Properties.Suffix)+ctx.toolchain().ExecutableSuffix())
@@ -457,12 +467,6 @@
binary.preferredArchSymlink = symlinkName
}
}
-
- return ret
-}
-
-func (binary *binaryDecorator) unstrippedOutputFilePath() android.Path {
- return binary.unstrippedOutputFile
}
func (binary *binaryDecorator) symlinkList() []string {
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 42fc0e4..379d6f2 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -16,7 +16,6 @@
import (
"fmt"
"path/filepath"
- "regexp"
"strings"
"android/soong/android"
@@ -34,12 +33,6 @@
protoSrcPartition = "proto"
)
-var (
- // ignoring case, checks for proto or protos as an independent word in the name, whether at the
- // beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match
- filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)")
-)
-
// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
// properties which apply to either the shared or static version of a cc_library module.
type staticOrSharedAttributes struct {
@@ -61,46 +54,32 @@
Enabled bazel.BoolAttribute
}
+// groupSrcsByExtension partitions `srcs` into groups based on file extension.
func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
- // Check that a module is a filegroup type
- isFilegroup := func(m blueprint.Module) bool {
- return ctx.OtherModuleType(m) == "filegroup"
- }
-
// Convert filegroup dependencies into extension-specific filegroups filtered in the filegroup.bzl
// macro.
addSuffixForFilegroup := func(suffix string) bazel.LabelMapper {
return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
m, exists := ctx.ModuleFromName(label.OriginalModuleName)
labelStr := label.Label
- if !exists || !isFilegroup(m) {
+ if !exists || !android.IsFilegroup(ctx, m) {
return labelStr, false
}
return labelStr + suffix, true
}
}
- isProtoFilegroup := func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
- m, exists := ctx.ModuleFromName(label.OriginalModuleName)
- labelStr := label.Label
- if !exists || !isFilegroup(m) {
- return labelStr, false
- }
- likelyProtos := filegroupLikelyProtoPattern.MatchString(label.OriginalModuleName)
- return labelStr, likelyProtos
- }
-
// TODO(b/190006308): Handle language detection of sources in a Bazel rule.
- partitioned := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{
- protoSrcPartition: bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup},
+ labels := bazel.LabelPartitions{
+ protoSrcPartition: android.ProtoSrcLabelPartition,
cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
// C++ is the "catch-all" group, and comprises generated sources because we don't
// know the language of these sources until the genrule is executed.
cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
- })
+ }
- return partitioned
+ return bazel.PartitionLabelListAttribute(ctx, &srcs, labels)
}
// bp2BuildParseLibProps returns the attributes for a variant of a cc_library.
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 979c825..4d0ae1a 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -104,19 +104,22 @@
exportStringListStaticVariable("Arm64Cflags", arm64Cflags)
exportStringListStaticVariable("Arm64Cppflags", arm64Cppflags)
- exportedStringListDictVars.Set("Arm64ArchVariantCflags", arm64ArchVariantCflags)
- exportedStringListDictVars.Set("Arm64CpuVariantCflags", arm64CpuVariantCflags)
+ exportedVariableReferenceDictVars.Set("Arm64ArchVariantCflags", arm64ArchVariantCflagsVar)
+ exportedVariableReferenceDictVars.Set("Arm64CpuVariantCflags", arm64CpuVariantCflagsVar)
+ exportedVariableReferenceDictVars.Set("Arm64CpuVariantLdflags", arm64CpuVariantLdflags)
- pctx.StaticVariable("Arm64Armv8ACflags", strings.Join(arm64ArchVariantCflags["armv8-a"], " "))
- pctx.StaticVariable("Arm64Armv8ABranchProtCflags", strings.Join(arm64ArchVariantCflags["armv8-a-branchprot"], " "))
- pctx.StaticVariable("Arm64Armv82ACflags", strings.Join(arm64ArchVariantCflags["armv8-2a"], " "))
- pctx.StaticVariable("Arm64Armv82ADotprodCflags", strings.Join(arm64ArchVariantCflags["armv8-2a-dotprod"], " "))
+ exportStringListStaticVariable("Arm64Armv8ACflags", arm64ArchVariantCflags["armv8-a"])
+ exportStringListStaticVariable("Arm64Armv8ABranchProtCflags", arm64ArchVariantCflags["armv8-a-branchprot"])
+ exportStringListStaticVariable("Arm64Armv82ACflags", arm64ArchVariantCflags["armv8-2a"])
+ exportStringListStaticVariable("Arm64Armv82ADotprodCflags", arm64ArchVariantCflags["armv8-2a-dotprod"])
- pctx.StaticVariable("Arm64CortexA53Cflags", strings.Join(arm64CpuVariantCflags["cortex-a53"], " "))
- pctx.StaticVariable("Arm64CortexA55Cflags", strings.Join(arm64CpuVariantCflags["cortex-a55"], " "))
- pctx.StaticVariable("Arm64KryoCflags", strings.Join(arm64CpuVariantCflags["kryo"], " "))
- pctx.StaticVariable("Arm64ExynosM1Cflags", strings.Join(arm64CpuVariantCflags["exynos-m1"], " "))
- pctx.StaticVariable("Arm64ExynosM2Cflags", strings.Join(arm64CpuVariantCflags["exynos-m2"], " "))
+ exportStringListStaticVariable("Arm64CortexA53Cflags", arm64CpuVariantCflags["cortex-a53"])
+ exportStringListStaticVariable("Arm64CortexA55Cflags", arm64CpuVariantCflags["cortex-a55"])
+ exportStringListStaticVariable("Arm64KryoCflags", arm64CpuVariantCflags["kryo"])
+ exportStringListStaticVariable("Arm64ExynosM1Cflags", arm64CpuVariantCflags["exynos-m1"])
+ exportStringListStaticVariable("Arm64ExynosM2Cflags", arm64CpuVariantCflags["exynos-m2"])
+
+ exportStringListStaticVariable("Arm64FixCortexA53Ldflags", []string{"-Wl,--fix-cortex-a53-843419"})
}
var (
@@ -128,7 +131,6 @@
}
arm64CpuVariantCflagsVar = map[string]string{
- "": "",
"cortex-a53": "${config.Arm64CortexA53Cflags}",
"cortex-a55": "${config.Arm64CortexA55Cflags}",
"cortex-a72": "${config.Arm64CortexA53Cflags}",
@@ -140,6 +142,15 @@
"exynos-m1": "${config.Arm64ExynosM1Cflags}",
"exynos-m2": "${config.Arm64ExynosM2Cflags}",
}
+
+ arm64CpuVariantLdflags = map[string]string{
+ "cortex-a53": "${config.Arm64FixCortexA53Ldflags}",
+ "cortex-a72": "${config.Arm64FixCortexA53Ldflags}",
+ "cortex-a73": "${config.Arm64FixCortexA53Ldflags}",
+ "kryo": "${config.Arm64FixCortexA53Ldflags}",
+ "exynos-m1": "${config.Arm64FixCortexA53Ldflags}",
+ "exynos-m2": "${config.Arm64FixCortexA53Ldflags}",
+ }
)
type toolchainArm64 struct {
@@ -214,12 +225,7 @@
toolchainCflags = append(toolchainCflags,
variantOrDefault(arm64CpuVariantCflagsVar, arch.CpuVariant))
- var extraLdflags string
- switch arch.CpuVariant {
- case "cortex-a53", "cortex-a72", "cortex-a73", "kryo", "exynos-m1", "exynos-m2":
- extraLdflags = "-Wl,--fix-cortex-a53-843419"
- }
-
+ extraLdflags := variantOrDefault(arm64CpuVariantLdflags, arch.CpuVariant)
return &toolchainArm64{
ldflags: strings.Join([]string{
"${config.Arm64Ldflags}",
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 0fe5e68..4466632 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -39,6 +39,10 @@
armLldflags = armLdflags
+ armFixCortexA8LdFlags = []string{"-Wl,--fix-cortex-a8"}
+
+ armNoFixCortexA8LdFlags = []string{"-Wl,--no-fix-cortex-a8"}
+
armArmCflags = []string{
"-fstrict-aliasing",
}
@@ -179,6 +183,9 @@
exportStringListStaticVariable("ArmLdflags", armLdflags)
exportStringListStaticVariable("ArmLldflags", armLldflags)
+ exportStringListStaticVariable("ArmFixCortexA8LdFlags", armFixCortexA8LdFlags)
+ exportStringListStaticVariable("ArmNoFixCortexA8LdFlags", armNoFixCortexA8LdFlags)
+
// Clang cflags
exportStringListStaticVariable("ArmToolchainCflags", armToolchainCflags)
exportStringListStaticVariable("ArmCflags", armCflags)
@@ -188,8 +195,8 @@
exportStringListStaticVariable("ArmArmCflags", armArmCflags)
exportStringListStaticVariable("ArmThumbCflags", armThumbCflags)
- exportedStringListDictVars.Set("ArmArchVariantCflags", armArchVariantCflags)
- exportedStringListDictVars.Set("ArmCpuVariantCflags", armCpuVariantCflags)
+ exportedVariableReferenceDictVars.Set("ArmArchVariantCflags", armArchVariantCflagsVar)
+ exportedVariableReferenceDictVars.Set("ArmCpuVariantCflags", armCpuVariantCflagsVar)
// Clang arch variant cflags
exportStringListStaticVariable("ArmArmv7ACflags", armArchVariantCflags["armv7-a"])
@@ -324,12 +331,12 @@
switch arch.CpuVariant {
case "cortex-a8", "":
// Generic ARM might be a Cortex A8 -- better safe than sorry
- fixCortexA8 = "-Wl,--fix-cortex-a8"
+ fixCortexA8 = "${config.ArmFixCortexA8LdFlags}"
default:
- fixCortexA8 = "-Wl,--no-fix-cortex-a8"
+ fixCortexA8 = "${config.ArmNoFixCortexA8LdFlags}"
}
case "armv7-a":
- fixCortexA8 = "-Wl,--fix-cortex-a8"
+ fixCortexA8 = "${config.ArmFixCortexA8LdFlags}"
case "armv8-a", "armv8-2a":
// Nothing extra for armv8-a/armv8-2a
default:
diff --git a/cc/config/bp2build.go b/cc/config/bp2build.go
index eca5161..73f65f5 100644
--- a/cc/config/bp2build.go
+++ b/cc/config/bp2build.go
@@ -38,6 +38,8 @@
exportedStringListVars = exportedStringListVariables{}
exportedStringVars = exportedStringVariables{}
exportedStringListDictVars = exportedStringListDictVariables{}
+ // Note: these can only contain references to other variables and must be printed last
+ exportedVariableReferenceDictVars = exportedVariableReferenceDictVariables{}
/// Maps containing variables that are dependent on the build config.
exportedConfigDependingVars = exportedConfigDependingVariables{}
@@ -62,6 +64,7 @@
type bazelConstant struct {
variableName string
internalDefinition string
+ sortLast bool
}
type exportedStringVariables map[string]string
@@ -168,6 +171,36 @@
return ret
}
+type exportedVariableReferenceDictVariables map[string]map[string]string
+
+func (m exportedVariableReferenceDictVariables) Set(k string, v map[string]string) {
+ m[k] = v
+}
+
+func (m exportedVariableReferenceDictVariables) asBazel(_ android.Config, _ exportedStringVariables,
+ _ exportedStringListVariables, _ exportedConfigDependingVariables) []bazelConstant {
+ ret := make([]bazelConstant, 0, len(m))
+ for n, dict := range m {
+ for k, v := range dict {
+ matches, err := variableReference(v)
+ if err != nil {
+ panic(err)
+ } else if !matches.matches {
+ panic(fmt.Errorf("Expected a variable reference, got %q", v))
+ } else if len(matches.fullVariableReference) != len(v) {
+ panic(fmt.Errorf("Expected only a variable reference, got %q", v))
+ }
+ dict[k] = "_" + matches.variable
+ }
+ ret = append(ret, bazelConstant{
+ variableName: n,
+ internalDefinition: starlark_fmt.PrintDict(dict, 0),
+ sortLast: true,
+ })
+ }
+ return ret
+}
+
// BazelCcToolchainVars generates bzl file content containing variables for
// Bazel's cc_toolchain configuration.
func BazelCcToolchainVars(config android.Config) string {
@@ -175,7 +208,8 @@
config,
exportedStringListDictVars,
exportedStringListVars,
- exportedStringVars)
+ exportedStringVars,
+ exportedVariableReferenceDictVars)
}
func bazelToolchainVars(config android.Config, vars ...bazelVarExporter) string {
@@ -186,7 +220,12 @@
results = append(results, v.asBazel(config, exportedStringVars, exportedStringListVars, exportedConfigDependingVars)...)
}
- sort.Slice(results, func(i, j int) bool { return results[i].variableName < results[j].variableName })
+ sort.Slice(results, func(i, j int) bool {
+ if results[i].sortLast != results[j].sortLast {
+ return !results[i].sortLast
+ }
+ return results[i].variableName < results[j].variableName
+ })
definitions := make([]string, 0, len(results))
constants := make([]string, 0, len(results))
@@ -207,6 +246,32 @@
return ret
}
+type match struct {
+ matches bool
+ fullVariableReference string
+ variable string
+}
+
+func variableReference(input string) (match, error) {
+ // e.g. "${ExternalCflags}"
+ r := regexp.MustCompile(`\${(?:config\.)?([a-zA-Z0-9_]+)}`)
+
+ matches := r.FindStringSubmatch(input)
+ if len(matches) == 0 {
+ return match{}, nil
+ }
+ if len(matches) != 2 {
+ return match{}, fmt.Errorf("Expected to only match 1 subexpression in %s, got %d", input, len(matches)-1)
+ }
+ return match{
+ matches: true,
+ fullVariableReference: matches[0],
+ // Index 1 of FindStringSubmatch contains the subexpression match
+ // (variable name) of the capture group.
+ variable: matches[1],
+ }, nil
+}
+
// expandVar recursively expand interpolated variables in the exportedVars scope.
//
// We're using a string slice to track the seen variables to avoid
@@ -216,8 +281,6 @@
// interpolation stacks are deep (n > 1).
func expandVar(config android.Config, toExpand string, stringScope exportedStringVariables,
stringListScope exportedStringListVariables, exportedVars exportedConfigDependingVariables) ([]string, error) {
- // e.g. "${ExternalCflags}"
- r := regexp.MustCompile(`\${([a-zA-Z0-9_]+)}`)
// Internal recursive function.
var expandVarInternal func(string, map[string]bool) (string, error)
@@ -225,20 +288,18 @@
var ret string
remainingString := toExpand
for len(remainingString) > 0 {
- matches := r.FindStringSubmatch(remainingString)
- if len(matches) == 0 {
+ matches, err := variableReference(remainingString)
+ if err != nil {
+ panic(err)
+ }
+ if !matches.matches {
return ret + remainingString, nil
}
- if len(matches) != 2 {
- panic(fmt.Errorf("Expected to only match 1 subexpression in %s, got %d", remainingString, len(matches)-1))
- }
- matchIndex := strings.Index(remainingString, matches[0])
+ matchIndex := strings.Index(remainingString, matches.fullVariableReference)
ret += remainingString[:matchIndex]
- remainingString = remainingString[matchIndex+len(matches[0]):]
+ remainingString = remainingString[matchIndex+len(matches.fullVariableReference):]
- // Index 1 of FindStringSubmatch contains the subexpression match
- // (variable name) of the capture group.
- variable := matches[1]
+ variable := matches.variable
// toExpand contains a variable.
if _, ok := seenVars[variable]; ok {
return ret, fmt.Errorf(
diff --git a/cc/config/bp2build_test.go b/cc/config/bp2build_test.go
index 4cbf0c6..9a8178a 100644
--- a/cc/config/bp2build_test.go
+++ b/cc/config/bp2build_test.go
@@ -48,6 +48,14 @@
expectedValues: []string{"bar"},
},
{
+ description: "single level expansion with short-name for string var",
+ stringScope: exportedStringVariables{
+ "foo": "bar",
+ },
+ toExpand: "${config.foo}",
+ expectedValues: []string{"bar"},
+ },
+ {
description: "single level expansion string list var",
stringListScope: exportedStringListVariables{
"foo": []string{"bar"},
@@ -224,7 +232,30 @@
)`,
},
{
- name: "sorts across types",
+ name: "exports dict with var refs",
+ vars: []bazelVarExporter{
+ exportedVariableReferenceDictVariables{
+ "a": map[string]string{"b1": "${b2}"},
+ "c": map[string]string{"d1": "${config.d2}"},
+ },
+ },
+ expectedOut: `# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.
+
+_a = {
+ "b1": _b2,
+}
+
+_c = {
+ "d1": _d2,
+}
+
+constants = struct(
+ a = _a,
+ c = _c,
+)`,
+ },
+ {
+ name: "sorts across types with variable references last",
vars: []bazelVarExporter{
exportedStringVariables{
"b": "b-val",
@@ -238,6 +269,10 @@
"a": map[string][]string{"a1": []string{"a2"}},
"f": map[string][]string{"f1": []string{"f2"}},
},
+ exportedVariableReferenceDictVariables{
+ "aa": map[string]string{"b1": "${b}"},
+ "cc": map[string]string{"d1": "${config.d}"},
+ },
},
expectedOut: `# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.
@@ -257,6 +292,14 @@
"f1": ["f2"],
}
+_aa = {
+ "b1": _b,
+}
+
+_cc = {
+ "d1": _d,
+}
+
constants = struct(
a = _a,
b = _b,
@@ -264,6 +307,8 @@
d = _d,
e = _e,
f = _f,
+ aa = _aa,
+ cc = _cc,
)`,
},
}
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index d789cde..164e7a6 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -37,10 +37,10 @@
"": []string{
"-march=x86-64",
},
+
"broadwell": []string{
"-march=broadwell",
},
-
"haswell": []string{
"-march=core-avx2",
},
@@ -78,14 +78,6 @@
"popcnt": []string{"-mpopcnt"},
"aes_ni": []string{"-maes"},
}
-
- x86_64DefaultArchVariantFeatures = []string{
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "popcnt",
- }
)
const (
@@ -93,8 +85,6 @@
)
func init() {
- android.RegisterDefaultArchVariantFeatures(android.Android, android.X86_64, x86_64DefaultArchVariantFeatures...)
- exportedStringListVars.Set("X86_64DefaultArchVariantFeatures", x86_64DefaultArchVariantFeatures)
pctx.StaticVariable("x86_64GccVersion", x86_64GccVersion)
diff --git a/cc/proto.go b/cc/proto.go
index 3cf1453..8e6d5ed 100644
--- a/cc/proto.go
+++ b/cc/proto.go
@@ -177,7 +177,7 @@
func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) bp2buildProtoDeps {
var ret bp2buildProtoDeps
- protoInfo, ok := android.Bp2buildProtoProperties(ctx, m, protoSrcs)
+ protoInfo, ok := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, protoSrcs)
if !ok {
return ret
}
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index 753d74c..9d40ad0 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -680,6 +680,9 @@
Input: in,
})
+ // binary snapshots need symlinking
+ p.setSymlinkList(ctx)
+
return outputFile
}
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
index 645b2cc..2bb43ab 100644
--- a/cc/vendor_snapshot_test.go
+++ b/cc/vendor_snapshot_test.go
@@ -741,6 +741,7 @@
src: "bin",
},
},
+ symlinks: ["binfoo", "binbar"],
}
vendor_snapshot_binary {
@@ -920,7 +921,21 @@
ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so")
// bin is installed by bin.vendor_binary.31.arm64
- ctx.ModuleForTests("bin.vendor_binary.31.arm64", binaryVariant).Output("bin")
+ bin64Module := ctx.ModuleForTests("bin.vendor_binary.31.arm64", binaryVariant)
+ bin64Module.Output("bin")
+
+ // also test symlinks
+ bin64MkEntries := android.AndroidMkEntriesForTest(t, ctx, bin64Module.Module())
+ bin64KatiSymlinks := bin64MkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"]
+
+ // Either AndroidMk entries contain symlinks, or symlinks should be installed by Soong
+ for _, symlink := range []string{"binfoo", "binbar"} {
+ if inList(symlink, bin64KatiSymlinks) {
+ continue
+ }
+
+ bin64Module.Output(symlink)
+ }
// bin32 is installed by bin32.vendor_binary.31.arm64
ctx.ModuleForTests("bin32.vendor_binary.31.arm64", binary32Variant).Output("bin32")
diff --git a/cmd/extract_linker/main.go b/cmd/extract_linker/main.go
index 5603b41..aaca1dd 100644
--- a/cmd/extract_linker/main.go
+++ b/cmd/extract_linker/main.go
@@ -116,7 +116,7 @@
// Discard the PT_INTERP section so that the linker doesn't need to be passed the
// --no-dynamic-linker flag.
- fmt.Println(script, " /DISCARD/ : { *(.interp) }")
+ fmt.Fprintln(script, " /DISCARD/ : { *(.interp) }")
fmt.Fprintln(script, "}")
fmt.Fprintln(script, "INSERT BEFORE .note.android.embedded_linker;")
diff --git a/docs/rbe.json b/docs/rbe.json
new file mode 100644
index 0000000..f6ff107
--- /dev/null
+++ b/docs/rbe.json
@@ -0,0 +1,24 @@
+{
+ "env": {
+ "USE_RBE": "1",
+
+ "RBE_R8_EXEC_STRATEGY": "remote_local_fallback",
+ "RBE_CXX_EXEC_STRATEGY": "remote_local_fallback",
+ "RBE_D8_EXEC_STRATEGY": "remote_local_fallback",
+ "RBE_JAVAC_EXEC_STRATEGY": "remote_local_fallback",
+ "RBE_JAVAC": "1",
+ "RBE_R8": "1",
+ "RBE_D8": "1",
+
+ "RBE_instance": "[replace with your RBE instance]",
+ "RBE_service": "[replace with your RBE service endpoint]",
+
+ "RBE_DIR": "prebuilts/remoteexecution-client/live",
+
+ "RBE_use_application_default_credentials": "true",
+
+ "RBE_log_dir": "/tmp",
+ "RBE_output_dir": "/tmp",
+ "RBE_proxy_log_dir": "/tmp"
+ }
+}
diff --git a/docs/rbe.md b/docs/rbe.md
new file mode 100644
index 0000000..cfe86d7
--- /dev/null
+++ b/docs/rbe.md
@@ -0,0 +1,70 @@
+# Build Android Platform on Remote Build Execution
+
+Soong is integrated with Google's Remote Build Execution(RBE) service, which
+implements the
+[Remote Executaion API](https://github.com/bazelbuild/remote-apis).
+
+With RBE enabled, it can speed up the Android Platform builds by distributing
+build actions through a worker pool sharing a central cache of build results.
+
+## Configuration
+
+To enable RBE, you need to set several environment variables before triggering
+the build. You can set them through a
+[environment variables config file](https://android.googlesource.com/platform/build/soong/+/master/README.md#environment-variables-config-file).
+As an example, [build/soong/docs/rbe.json](rbe.json) is a config that enables
+RBE in the build. Once the config file is created, you need to let Soong load
+the config file by specifying `ANDROID_BUILD_ENVIRONMENT_CONFIG_DIR` environment
+variable and `ANDROID_BUILD_ENVIRONMENT_CONFIG` environment variable. The
+following command starts Soong with [build/soong/docs/rbe.json](rbe.json)
+loaded:
+
+```shell
+ANDROID_BUILD_ENVIRONMENT_CONFIG=rbe \
+ANDROID_BUILD_ENVIRONMENT_CONFIG_DIR=build/soong/doc \
+ build/soong/soong_ui.bash
+```
+
+### Configuration Explanation
+
+Below a brief explanation of each field in
+[build/soong/docs/rbe.json](rbe.json):
+
+##### USE\_RBE:
+If set to 1, enable RBE for the build.
+
+##### RBE\_CXX\_EXEC\_STRATEGY / RBE\_JAVAC\_EXEC\_STRATEGY / RBE\_R8\_EXEC\_STRATEGY / RBE\_D8\_EXEC\_STRATEGY:
+
+Sets strategies for C++/javac/r8/d8 action types. Available options are
+(**Note**: all options will update the remote cache if the right permissions to
+update cache are given to the user.):
+
+* **local**: Only execute locally.
+* **remote**: Only execute remotely.
+* **remote_local_fallback**: Try executing remotely and fall back to local
+ execution if failed.
+* **racing**: Race remote execution and local execution and use the earlier
+ result.
+
+##### RBE\_JAVAC / RBE\_R8 / RBE\_D8
+
+If set to 1, enable javac/r8/d8 support. C++ compilation is enabled by default.
+
+##### RBE\_service / RBE\_instance
+
+The remote execution service endpoint and instance ID to target when calling
+remote execution via gRPC to execute actions.
+
+##### RBE\_DIR
+
+Where to find remote client binaries (rewrapper, reproxy)
+
+##### RBE\_use\_application\_default\_credentials
+
+reclient uses
+[application default credentials](https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login)
+for autentication, as generated by `gcloud auth application-default login`
+
+##### RBE\_log\_dir/RBE\_proxy\_log\_dir/RBE\_output\_dir
+
+Logs generated by rewrapper and reproxy will go here.
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 8282426..c52ddee 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -382,9 +382,12 @@
addLocationLabel(toolFile, toolLocation{paths})
}
+ includeDirInPaths := ctx.DeviceConfig().BuildBrokenInputDir(g.Name())
var srcFiles android.Paths
for _, in := range g.properties.Srcs {
- paths, missingDeps := android.PathsAndMissingDepsForModuleSrcExcludes(ctx, []string{in}, g.properties.Exclude_srcs)
+ paths, missingDeps := android.PathsAndMissingDepsRelativeToModuleSourceDir(android.SourceInput{
+ Context: ctx, Paths: []string{in}, ExcludePaths: g.properties.Exclude_srcs, IncludeDirs: includeDirInPaths,
+ })
if len(missingDeps) > 0 {
if !ctx.Config().AllowMissingDependencies() {
panic(fmt.Errorf("should never get here, the missing dependencies %q should have been reported in DepsMutator",
@@ -496,7 +499,7 @@
}
return paths[0], nil
} else {
- return reportError("unknown location label %q", label)
+ return reportError("unknown location label %q is not in srcs, out, tools or tool_files.", label)
}
} else if strings.HasPrefix(name, "locations ") {
label := strings.TrimSpace(strings.TrimPrefix(name, "locations "))
@@ -507,7 +510,7 @@
}
return strings.Join(paths, " "), nil
} else {
- return reportError("unknown locations label %q", label)
+ return reportError("unknown locations label %q is not in srcs, out, tools or tool_files.", label)
}
} else {
return reportError("unknown variable '$(%s)'", name)
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index 04c97fd..1b5cef2 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -341,7 +341,7 @@
out: ["out"],
cmd: "echo foo > $(location missing)",
`,
- err: `unknown location label "missing"`,
+ err: `unknown location label "missing" is not in srcs, out, tools or tool_files.`,
},
{
name: "error locations",
@@ -349,7 +349,7 @@
out: ["out"],
cmd: "echo foo > $(locations missing)",
`,
- err: `unknown locations label "missing"`,
+ err: `unknown locations label "missing" is not in srcs, out, tools or tool_files`,
},
{
name: "error location no files",
diff --git a/java/app.go b/java/app.go
index e4432ff..96fd61a 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1443,7 +1443,7 @@
props := bazel.BazelTargetModuleProperties{
Rule_class: "android_app_certificate",
- Bzl_load_location: "//build/bazel/rules:android_app_certificate.bzl",
+ Bzl_load_location: "//build/bazel/rules/android:android_app_certificate.bzl",
}
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
@@ -1451,9 +1451,11 @@
type bazelAndroidAppAttributes struct {
*javaLibraryAttributes
- Manifest bazel.Label
- Custom_package *string
- Resource_files bazel.LabelListAttribute
+ Manifest bazel.Label
+ Custom_package *string
+ Resource_files bazel.LabelListAttribute
+ Certificate *bazel.Label
+ Certificate_name *string
}
// ConvertWithBp2build is used to convert android_app to Bazel.
@@ -1470,15 +1472,30 @@
resourceFiles.Includes = append(resourceFiles.Includes, files...)
}
+ var certificate *bazel.Label
+ certificateNamePtr := a.overridableAppProperties.Certificate
+ certificateName := proptools.StringDefault(certificateNamePtr, "")
+ certModule := android.SrcIsModule(certificateName)
+ if certModule != "" {
+ c := android.BazelLabelForModuleDepSingle(ctx, certificateName)
+ certificate = &c
+ certificateNamePtr = nil
+ }
+
attrs := &bazelAndroidAppAttributes{
libAttrs,
android.BazelLabelForModuleSrcSingle(ctx, manifest),
// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
a.overridableAppProperties.Package_name,
bazel.MakeLabelListAttribute(resourceFiles),
+ certificate,
+ certificateNamePtr,
}
- props := bazel.BazelTargetModuleProperties{Rule_class: "android_binary",
- Bzl_load_location: "@rules_android//rules:rules.bzl"}
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "android_binary",
+ Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
+ }
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs)
diff --git a/java/base.go b/java/base.go
index 42d7733..8747039 100644
--- a/java/base.go
+++ b/java/base.go
@@ -227,6 +227,12 @@
// whether to generate Binder#GetTransaction name method.
Generate_get_transaction_name *bool
+ // whether all interfaces should be annotated with required permissions.
+ Enforce_permissions *bool
+
+ // allowlist for interfaces that (temporarily) do not require annotation for permissions.
+ Enforce_permissions_exceptions []string `android:"path"`
+
// list of flags that will be passed to the AIDL compiler
Flags []string
}
@@ -418,7 +424,8 @@
outputFile android.Path
extraOutputFiles android.Paths
- exportAidlIncludeDirs android.Paths
+ exportAidlIncludeDirs android.Paths
+ ignoredAidlPermissionList android.Paths
logtagsSrcs android.Paths
@@ -772,6 +779,17 @@
return hasSrcExt(j.properties.Srcs, ext)
}
+func (j *Module) individualAidlFlags(ctx android.ModuleContext, aidlFile android.Path) string {
+ var flags string
+
+ if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
+ if !android.InList(aidlFile.String(), j.ignoredAidlPermissionList.Strings()) {
+ flags = "-Wmissing-permission-annotation -Werror"
+ }
+ }
+ return flags
+}
+
func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
aidlIncludeDirs android.Paths) (string, android.Paths) {
@@ -814,6 +832,11 @@
flags = append(flags, "--transaction_names")
}
+ if Bool(j.deviceProperties.Aidl.Enforce_permissions) {
+ exceptions := j.deviceProperties.Aidl.Enforce_permissions_exceptions
+ j.ignoredAidlPermissionList = android.PathsForModuleSrcExcludes(ctx, exceptions, nil)
+ }
+
aidlMinSdkVersion := j.MinSdkVersion(ctx).ApiLevel.String()
flags = append(flags, "--min_sdk_version="+aidlMinSdkVersion)
@@ -839,7 +862,7 @@
}
errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)
- flags.errorProneExtraJavacFlags = "${config.ErrorProneFlags} " +
+ flags.errorProneExtraJavacFlags = "${config.ErrorProneHeapFlags} ${config.ErrorProneFlags} " +
"'" + strings.Join(errorProneFlags, " ") + "'"
flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
}
diff --git a/java/config/config.go b/java/config/config.go
index ea2f934..05dfde6 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -68,6 +68,12 @@
pctx.StaticVariable("JavacHeapSize", "2048M")
pctx.StaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
+
+ // ErrorProne can use significantly more memory than javac alone, give it a higher heap
+ // size (b/221480398).
+ pctx.StaticVariable("ErrorProneHeapSize", "4096M")
+ pctx.StaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
+
pctx.StaticVariable("DexFlags", "-JXX:OnError='cat hs_err_pid%p.log' -JXX:CICompilerCount=6 -JXX:+UseDynamicNumberOfGCThreads")
pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
@@ -99,7 +105,12 @@
if override := ctx.Config().Getenv("OVERRIDE_JLINK_VERSION_NUMBER"); override != "" {
return override
}
- return "11"
+ switch ctx.Config().Getenv("EXPERIMENTAL_USE_OPENJDK17_TOOLCHAIN") {
+ case "true":
+ return "17"
+ default:
+ return "11"
+ }
})
pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin")
diff --git a/java/droiddoc.go b/java/droiddoc.go
index c84a15c..023d619 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -330,7 +330,7 @@
// Process all aidl files together to support sharding them into one or more rules that produce srcjars.
if len(aidlSrcs) > 0 {
- srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
+ srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, nil, flags.aidlDeps)
outSrcFiles = append(outSrcFiles, srcJarFiles...)
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 7ad316f..421737b 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -334,7 +334,9 @@
// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
FlagWithArg("--hide ", "SuperfluousPrefix").
- FlagWithArg("--hide ", "AnnotationExtraction")
+ FlagWithArg("--hide ", "AnnotationExtraction").
+ // b/222738070
+ FlagWithArg("--hide ", "BannedThrow")
}
}
@@ -472,7 +474,8 @@
Flag("--quiet").
Flag("--format=v2").
FlagWithArg("--repeat-errors-max ", "10").
- FlagWithArg("--hide ", "UnresolvedImport")
+ FlagWithArg("--hide ", "UnresolvedImport").
+ FlagWithArg("--hide ", "InvalidNullability")
return cmd
}
diff --git a/java/gen.go b/java/gen.go
index 445a2d8..1572bf0 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -44,7 +44,7 @@
})
)
-func genAidl(ctx android.ModuleContext, aidlFiles android.Paths, aidlFlags string, deps android.Paths) android.Paths {
+func genAidl(ctx android.ModuleContext, aidlFiles android.Paths, aidlGlobalFlags string, aidlIndividualFlags map[string]string, deps android.Paths) android.Paths {
// Shard aidl files into groups of 50 to avoid having to recompile all of them if one changes and to avoid
// hitting command line length limits.
shards := android.ShardPaths(aidlFiles, 50)
@@ -61,15 +61,17 @@
rule.Command().Text("rm -rf").Flag(outDir.String())
rule.Command().Text("mkdir -p").Flag(outDir.String())
- rule.Command().Text("FLAGS=' " + aidlFlags + "'")
+ rule.Command().Text("FLAGS=' " + aidlGlobalFlags + "'")
for _, aidlFile := range shard {
+ localFlag := aidlIndividualFlags[aidlFile.String()]
depFile := srcJarFile.InSameDir(ctx, aidlFile.String()+".d")
javaFile := outDir.Join(ctx, pathtools.ReplaceExtension(aidlFile.String(), "java"))
rule.Command().
Tool(ctx.Config().HostToolPath(ctx, "aidl")).
FlagWithDepFile("-d", depFile).
Flag("$FLAGS").
+ Flag(localFlag).
Input(aidlFile).
Output(javaFile).
Implicits(deps)
@@ -159,7 +161,14 @@
// Process all aidl files together to support sharding them into one or more rules that produce srcjars.
if len(aidlSrcs) > 0 {
- srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
+ individualFlags := make(map[string]string)
+ for _, aidlSrc := range aidlSrcs {
+ flags := j.individualAidlFlags(ctx, aidlSrc)
+ if flags != "" {
+ individualFlags[aidlSrc.String()] = flags
+ }
+ }
+ srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, individualFlags, flags.aidlDeps)
outSrcFiles = append(outSrcFiles, srcJarFiles...)
}
diff --git a/java/java.go b/java/java.go
index e55f045..d0f0abc 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2013,8 +2013,16 @@
func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) *javaLibraryAttributes {
//TODO(b/209577426): Support multiple arch variants
srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs))
+
+ javaSrcPartition := "java"
+ protoSrcPartition := "proto"
+ srcPartitions := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{
+ javaSrcPartition: bazel.LabelPartition{Extensions: []string{".java"}, Keep_remainder: true},
+ protoSrcPartition: android.ProtoSrcLabelPartition,
+ })
+
attrs := &javaLibraryAttributes{
- Srcs: srcs,
+ Srcs: srcPartitions[javaSrcPartition],
}
if m.properties.Javacflags != nil {
@@ -2029,6 +2037,12 @@
//TODO(b/217236083) handle static libs similarly to Soong
deps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Static_libs))
}
+
+ protoDeps := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition])
+ if protoDeps != nil {
+ deps.Add(protoDeps)
+ }
+
attrs.Deps = bazel.MakeLabelListAttribute(deps)
return attrs
diff --git a/java/java_test.go b/java/java_test.go
index 21c76b6..f095c5e 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1333,6 +1333,42 @@
}
}
+func TestAidlEnforcePermissions(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["aidl/foo/IFoo.aidl"],
+ aidl: { enforce_permissions: true },
+ }
+ `)
+
+ aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ expectedAidlFlag := "-Wmissing-permission-annotation -Werror"
+ if !strings.Contains(aidlCommand, expectedAidlFlag) {
+ t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
+ }
+}
+
+func TestAidlEnforcePermissionsException(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["aidl/foo/IFoo.aidl", "aidl/foo/IFoo2.aidl"],
+ aidl: { enforce_permissions: true, enforce_permissions_exceptions: ["aidl/foo/IFoo2.aidl"] },
+ }
+ `)
+
+ aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ expectedAidlFlag := "$$FLAGS -Wmissing-permission-annotation -Werror aidl/foo/IFoo.aidl"
+ if !strings.Contains(aidlCommand, expectedAidlFlag) {
+ t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
+ }
+ expectedAidlFlag = "$$FLAGS aidl/foo/IFoo2.aidl"
+ if !strings.Contains(aidlCommand, expectedAidlFlag) {
+ t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
+ }
+}
+
func TestDataNativeBinaries(t *testing.T) {
ctx, _ := testJava(t, `
java_test_host {
diff --git a/java/proto.go b/java/proto.go
index 8d23803..5ba486f 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -19,6 +19,13 @@
"strconv"
"android/soong/android"
+ "android/soong/bazel"
+
+ "github.com/google/blueprint/proptools"
+)
+
+const (
+ protoTypeDefault = "lite"
)
func genProto(ctx android.ModuleContext, protoFiles android.Paths, flags android.ProtoFlags) android.Paths {
@@ -134,3 +141,52 @@
return flags
}
+
+type protoAttributes struct {
+ Deps bazel.LabelListAttribute
+}
+
+func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) *bazel.Label {
+ protoInfo, ok := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, protoSrcs)
+ if !ok {
+ return nil
+ }
+
+ typ := proptools.StringDefault(protoInfo.Type, protoTypeDefault)
+ var rule_class string
+ suffix := "_java_proto"
+ switch typ {
+ case "nano":
+ suffix += "_nano"
+ rule_class = "java_nano_proto_library"
+ case "micro":
+ suffix += "_micro"
+ rule_class = "java_micro_proto_library"
+ case "lite":
+ suffix += "_lite"
+ rule_class = "java_lite_proto_library"
+ case "stream":
+ suffix += "_stream"
+ rule_class = "java_stream_proto_library"
+ case "full":
+ rule_class = "java_proto_library"
+ default:
+ ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
+ }
+
+ protoLabel := bazel.Label{Label: ":" + m.Name() + "_proto"}
+ var protoAttrs protoAttributes
+ protoAttrs.Deps.SetValue(bazel.LabelList{Includes: []bazel.Label{protoLabel}})
+
+ name := m.Name() + suffix
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: rule_class,
+ Bzl_load_location: "//build/bazel/rules/java:proto.bzl",
+ },
+ android.CommonAttributes{Name: name},
+ &protoAttrs)
+
+ return &bazel.Label{Label: ":" + name}
+}
diff --git a/mk2rbc/expr.go b/mk2rbc/expr.go
index 07f7ca1..dc16d1d 100644
--- a/mk2rbc/expr.go
+++ b/mk2rbc/expr.go
@@ -595,6 +595,7 @@
for i, arg := range cx.args {
argsCopy[i] = arg.transform(transformer)
}
+ cx.args = argsCopy
if replacement := transformer(cx); replacement != nil {
return replacement
} else {
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index cb50a50..74053fe 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -69,54 +69,55 @@
var knownFunctions = map[string]interface {
parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr
}{
- "abspath": &simpleCallParser{name: baseName + ".abspath", returnType: starlarkTypeString, addGlobals: false},
- "add_soong_config_namespace": &simpleCallParser{name: baseName + ".soong_config_namespace", returnType: starlarkTypeVoid, addGlobals: true},
- "add_soong_config_var_value": &simpleCallParser{name: baseName + ".soong_config_set", returnType: starlarkTypeVoid, addGlobals: true},
- soongConfigAssign: &simpleCallParser{name: baseName + ".soong_config_set", returnType: starlarkTypeVoid, addGlobals: true},
- soongConfigAppend: &simpleCallParser{name: baseName + ".soong_config_append", returnType: starlarkTypeVoid, addGlobals: true},
- "soong_config_get": &simpleCallParser{name: baseName + ".soong_config_get", returnType: starlarkTypeString, addGlobals: true},
- "add-to-product-copy-files-if-exists": &simpleCallParser{name: baseName + ".copy_if_exists", returnType: starlarkTypeList, addGlobals: false},
- "addprefix": &simpleCallParser{name: baseName + ".addprefix", returnType: starlarkTypeList, addGlobals: false},
- "addsuffix": &simpleCallParser{name: baseName + ".addsuffix", returnType: starlarkTypeList, addGlobals: false},
- "copy-files": &simpleCallParser{name: baseName + ".copy_files", returnType: starlarkTypeList, addGlobals: false},
- "dir": &simpleCallParser{name: baseName + ".dir", returnType: starlarkTypeList, addGlobals: false},
- "dist-for-goals": &simpleCallParser{name: baseName + ".mkdist_for_goals", returnType: starlarkTypeVoid, addGlobals: true},
- "enforce-product-packages-exist": &simpleCallParser{name: baseName + ".enforce_product_packages_exist", returnType: starlarkTypeVoid, addGlobals: false},
- "error": &makeControlFuncParser{name: baseName + ".mkerror"},
- "findstring": &simpleCallParser{name: baseName + ".findstring", returnType: starlarkTypeInt, addGlobals: false},
- "find-copy-subdir-files": &simpleCallParser{name: baseName + ".find_and_copy", returnType: starlarkTypeList, addGlobals: false},
- "filter": &simpleCallParser{name: baseName + ".filter", returnType: starlarkTypeList, addGlobals: false},
- "filter-out": &simpleCallParser{name: baseName + ".filter_out", returnType: starlarkTypeList, addGlobals: false},
- "firstword": &firstOrLastwordCallParser{isLastWord: false},
- "foreach": &foreachCallPaser{},
- "if": &ifCallParser{},
- "info": &makeControlFuncParser{name: baseName + ".mkinfo"},
- "is-board-platform": &simpleCallParser{name: baseName + ".board_platform_is", returnType: starlarkTypeBool, addGlobals: true},
- "is-board-platform2": &simpleCallParser{name: baseName + ".board_platform_is", returnType: starlarkTypeBool, addGlobals: true},
- "is-board-platform-in-list": &simpleCallParser{name: baseName + ".board_platform_in", returnType: starlarkTypeBool, addGlobals: true},
- "is-board-platform-in-list2": &simpleCallParser{name: baseName + ".board_platform_in", returnType: starlarkTypeBool, addGlobals: true},
- "is-product-in-list": &isProductInListCallParser{},
- "is-vendor-board-platform": &isVendorBoardPlatformCallParser{},
- "is-vendor-board-qcom": &isVendorBoardQcomCallParser{},
- "lastword": &firstOrLastwordCallParser{isLastWord: true},
- "notdir": &simpleCallParser{name: baseName + ".notdir", returnType: starlarkTypeString, addGlobals: false},
- "math_max": &mathMaxOrMinCallParser{function: "max"},
- "math_min": &mathMaxOrMinCallParser{function: "min"},
- "math_gt_or_eq": &mathComparisonCallParser{op: ">="},
- "math_gt": &mathComparisonCallParser{op: ">"},
- "math_lt": &mathComparisonCallParser{op: "<"},
- "my-dir": &myDirCallParser{},
- "patsubst": &substCallParser{fname: "patsubst"},
- "product-copy-files-by-pattern": &simpleCallParser{name: baseName + ".product_copy_files_by_pattern", returnType: starlarkTypeList, addGlobals: false},
- "require-artifacts-in-path": &simpleCallParser{name: baseName + ".require_artifacts_in_path", returnType: starlarkTypeVoid, addGlobals: false},
- "require-artifacts-in-path-relaxed": &simpleCallParser{name: baseName + ".require_artifacts_in_path_relaxed", returnType: starlarkTypeVoid, addGlobals: false},
+ "abspath": &simpleCallParser{name: baseName + ".abspath", returnType: starlarkTypeString},
+ "add-product-dex-preopt-module-config": &simpleCallParser{name: baseName + ".add_product_dex_preopt_module_config", returnType: starlarkTypeString, addHandle: true},
+ "add_soong_config_namespace": &simpleCallParser{name: baseName + ".soong_config_namespace", returnType: starlarkTypeVoid, addGlobals: true},
+ "add_soong_config_var_value": &simpleCallParser{name: baseName + ".soong_config_set", returnType: starlarkTypeVoid, addGlobals: true},
+ soongConfigAssign: &simpleCallParser{name: baseName + ".soong_config_set", returnType: starlarkTypeVoid, addGlobals: true},
+ soongConfigAppend: &simpleCallParser{name: baseName + ".soong_config_append", returnType: starlarkTypeVoid, addGlobals: true},
+ "soong_config_get": &simpleCallParser{name: baseName + ".soong_config_get", returnType: starlarkTypeString, addGlobals: true},
+ "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},
+ "copy-files": &simpleCallParser{name: baseName + ".copy_files", returnType: starlarkTypeList},
+ "dir": &simpleCallParser{name: baseName + ".dir", returnType: starlarkTypeList},
+ "dist-for-goals": &simpleCallParser{name: baseName + ".mkdist_for_goals", returnType: starlarkTypeVoid, addGlobals: true},
+ "enforce-product-packages-exist": &simpleCallParser{name: baseName + ".enforce_product_packages_exist", returnType: starlarkTypeVoid},
+ "error": &makeControlFuncParser{name: baseName + ".mkerror"},
+ "findstring": &simpleCallParser{name: baseName + ".findstring", returnType: starlarkTypeInt},
+ "find-copy-subdir-files": &simpleCallParser{name: baseName + ".find_and_copy", returnType: starlarkTypeList},
+ "filter": &simpleCallParser{name: baseName + ".filter", returnType: starlarkTypeList},
+ "filter-out": &simpleCallParser{name: baseName + ".filter_out", returnType: starlarkTypeList},
+ "firstword": &firstOrLastwordCallParser{isLastWord: false},
+ "foreach": &foreachCallPaser{},
+ "if": &ifCallParser{},
+ "info": &makeControlFuncParser{name: baseName + ".mkinfo"},
+ "is-board-platform": &simpleCallParser{name: baseName + ".board_platform_is", returnType: starlarkTypeBool, addGlobals: true},
+ "is-board-platform2": &simpleCallParser{name: baseName + ".board_platform_is", returnType: starlarkTypeBool, addGlobals: true},
+ "is-board-platform-in-list": &simpleCallParser{name: baseName + ".board_platform_in", returnType: starlarkTypeBool, addGlobals: true},
+ "is-board-platform-in-list2": &simpleCallParser{name: baseName + ".board_platform_in", returnType: starlarkTypeBool, addGlobals: true},
+ "is-product-in-list": &isProductInListCallParser{},
+ "is-vendor-board-platform": &isVendorBoardPlatformCallParser{},
+ "is-vendor-board-qcom": &isVendorBoardQcomCallParser{},
+ "lastword": &firstOrLastwordCallParser{isLastWord: true},
+ "notdir": &simpleCallParser{name: baseName + ".notdir", returnType: starlarkTypeString},
+ "math_max": &mathMaxOrMinCallParser{function: "max"},
+ "math_min": &mathMaxOrMinCallParser{function: "min"},
+ "math_gt_or_eq": &mathComparisonCallParser{op: ">="},
+ "math_gt": &mathComparisonCallParser{op: ">"},
+ "math_lt": &mathComparisonCallParser{op: "<"},
+ "my-dir": &myDirCallParser{},
+ "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},
+ "require-artifacts-in-path-relaxed": &simpleCallParser{name: baseName + ".require_artifacts_in_path_relaxed", returnType: starlarkTypeVoid},
// TODO(asmundak): remove it once all calls are removed from configuration makefiles. see b/183161002
"shell": &shellCallParser{},
- "strip": &simpleCallParser{name: baseName + ".mkstrip", returnType: starlarkTypeString, addGlobals: false},
+ "strip": &simpleCallParser{name: baseName + ".mkstrip", returnType: starlarkTypeString},
"subst": &substCallParser{fname: "subst"},
"warning": &makeControlFuncParser{name: baseName + ".mkwarning"},
"word": &wordCallParser{},
- "wildcard": &simpleCallParser{name: baseName + ".expand_wildcard", returnType: starlarkTypeList, addGlobals: false},
+ "wildcard": &simpleCallParser{name: baseName + ".expand_wildcard", returnType: starlarkTypeList},
}
// These are functions that we don't implement conversions for, but
@@ -430,7 +431,6 @@
{"TARGET_COPY_OUT_RECOVERY", "recovery"},
{"TARGET_COPY_OUT_VENDOR_RAMDISK", "vendor_ramdisk"},
// TODO(asmundak): to process internal config files, we need the following variables:
- // BOARD_CONFIG_VENDOR_PATH
// TARGET_VENDOR
// target_base_product
//
@@ -807,20 +807,16 @@
if len(matchingPaths) > maxMatchingFiles {
return []starlarkNode{ctx.newBadNode(v, "there are >%d files matching the pattern, please rewrite it", maxMatchingFiles)}
}
- if len(matchingPaths) == 1 {
- res := inheritedStaticModule{ctx.newDependentModule(matchingPaths[0], loadAlways && ctx.ifNestLevel == 0), loadAlways}
- return []starlarkNode{processModule(res)}
- } else {
- needsWarning := pathPattern[0] == "" && len(ctx.includeTops) == 0
- res := inheritedDynamicModule{*varPath, []*moduleInfo{}, loadAlways, ctx.errorLocation(v), needsWarning}
- for _, p := range matchingPaths {
- // A product configuration files discovered dynamically may attempt to inherit
- // from another one which does not exist in this source tree. Prevent load errors
- // by always loading the dynamic files as optional.
- res.candidateModules = append(res.candidateModules, ctx.newDependentModule(p, true))
- }
- return []starlarkNode{processModule(res)}
+
+ needsWarning := pathPattern[0] == "" && len(ctx.includeTops) == 0
+ res := inheritedDynamicModule{*varPath, []*moduleInfo{}, loadAlways, ctx.errorLocation(v), needsWarning}
+ for _, p := range matchingPaths {
+ // A product configuration files discovered dynamically may attempt to inherit
+ // from another one which does not exist in this source tree. Prevent load errors
+ // by always loading the dynamic files as optional.
+ res.candidateModules = append(res.candidateModules, ctx.newDependentModule(p, true))
}
+ return []starlarkNode{processModule(res)}
}
func (ctx *parseContext) findMatchingPaths(pattern []string) []string {
@@ -1311,6 +1307,7 @@
name string
returnType starlarkType
addGlobals bool
+ addHandle bool
}
func (p *simpleCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
@@ -1318,6 +1315,9 @@
if p.addGlobals {
expr.args = append(expr.args, &globalsExpr{})
}
+ if p.addHandle {
+ expr.args = append(expr.args, &identifierExpr{name: "handle"})
+ }
for _, arg := range args.Split(",") {
arg.TrimLeftSpaces()
arg.TrimRightSpaces()
@@ -1871,9 +1871,7 @@
fmt.Fprintf(&buf, "load(%q, %q)\n", baseUri, baseName)
fmt.Fprintf(&buf, "load(%q, \"init\")\n", mainModuleUri)
fmt.Fprintf(&buf, "load(%q, input_variables_init = \"init\")\n", inputVariablesUri)
- fmt.Fprintf(&buf, "globals, cfg, globals_base = %s(init, input_variables_init)\n", cfnBoardMain)
- fmt.Fprintf(&buf, "# TODO: Some product config variables need to be printed, but most are readonly so we can't just print cfg here.\n")
- fmt.Fprintf(&buf, "%s((globals, cfg, globals_base))\n", cfnPrintVars)
+ fmt.Fprintf(&buf, "%s(%s(init, input_variables_init))\n", cfnPrintVars, cfnBoardMain)
return buf.String()
}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 447f658..55d48ff 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -739,6 +739,7 @@
$(call require-artifacts-in-path, foo, bar)
$(call require-artifacts-in-path-relaxed, foo, bar)
$(call dist-for-goals, goal, from:to)
+$(call add-product-dex-preopt-module-config,MyModule,disable)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -749,6 +750,7 @@
rblf.require_artifacts_in_path("foo", "bar")
rblf.require_artifacts_in_path_relaxed("foo", "bar")
rblf.mkdist_for_goals(g, "goal", "from:to")
+ rblf.add_product_dex_preopt_module_config(handle, "MyModule", "disable")
`,
},
{
@@ -1079,7 +1081,13 @@
def init(g, handle):
cfg = rblf.cfg(handle)
g["MY_PATH"] = "foo"
- rblf.inherit(handle, "vendor/foo1/cfg", _cfg_init)
+ _entry = {
+ "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init),
+ }.get("%s/cfg.mk" % g["MY_PATH"])
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
+ rblf.inherit(handle, _varmod, _varmod_init)
`,
},
{
@@ -1099,8 +1107,20 @@
def init(g, handle):
cfg = rblf.cfg(handle)
g["MY_PATH"] = "foo"
- rblf.inherit(handle, "vendor/foo1/cfg", _cfg_init)
- rblf.inherit(handle, "vendor/foo1/cfg", _cfg_init)
+ _entry = {
+ "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init),
+ }.get("%s/cfg.mk" % g["MY_PATH"])
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
+ rblf.inherit(handle, _varmod, _varmod_init)
+ _entry = {
+ "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init),
+ }.get("%s/cfg.mk" % g["MY_PATH"])
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
+ rblf.inherit(handle, _varmod, _varmod_init)
`,
},
{
@@ -1124,9 +1144,21 @@
def init(g, handle):
cfg = rblf.cfg(handle)
- rblf.inherit(handle, "foo/font", _font_init)
+ _entry = {
+ "foo/font.mk": ("foo/font", _font_init),
+ }.get("%s/font.mk" % g.get("MY_VAR", ""))
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("product.mk", "Cannot find %s" % ("%s/font.mk" % g.get("MY_VAR", "")))
+ rblf.inherit(handle, _varmod, _varmod_init)
# There's some space and even this comment between the include_top and the inherit-product
- rblf.inherit(handle, "foo/font", _font_init)
+ _entry = {
+ "foo/font.mk": ("foo/font", _font_init),
+ }.get("%s/font.mk" % g.get("MY_VAR", ""))
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("product.mk", "Cannot find %s" % ("%s/font.mk" % g.get("MY_VAR", "")))
+ rblf.inherit(handle, _varmod, _varmod_init)
rblf.mkwarning("product.mk:11", "Please avoid starting an include path with a variable. See https://source.android.com/setup/build/bazel/product_config/issues/includes for details.")
_entry = {
"foo/font.mk": ("foo/font", _font_init),
@@ -1228,6 +1260,9 @@
BOOT_KERNEL_MODULES_LIST += bar.ko
BOOT_KERNEL_MODULES_FILTER_2 := $(foreach m,$(BOOT_KERNEL_MODULES_LIST),%/$(m))
+FOREACH_WITH_IF := $(foreach module,\
+ $(BOOT_KERNEL_MODULES_LIST),\
+ $(if $(filter $(module),foo.ko),,$(error module "$(module)" has an error!)))
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -1238,6 +1273,7 @@
g["BOOT_KERNEL_MODULES_LIST"] = ["foo.ko"]
g["BOOT_KERNEL_MODULES_LIST"] += ["bar.ko"]
g["BOOT_KERNEL_MODULES_FILTER_2"] = ["%%/%s" % m for m in g["BOOT_KERNEL_MODULES_LIST"]]
+ g["FOREACH_WITH_IF"] = [("" if rblf.filter(module, "foo.ko") else rblf.mkerror("product.mk", "module \"%s\" has an error!" % module)) for module in g["BOOT_KERNEL_MODULES_LIST"]]
`,
},
{
diff --git a/rust/OWNERS b/rust/OWNERS
index d07ef7e..ddaebc5 100644
--- a/rust/OWNERS
+++ b/rust/OWNERS
@@ -1,5 +1,5 @@
# Additional owner/reviewers for rust rules, including parent directory owners.
-per-file * = chh@google.com, ivanlozano@google.com, jeffv@google.com, mmaurer@google.com, srhines@google.com
+per-file * = chiw@google.com, chriswailes@google.com, ivanlozano@google.com, jeffv@google.com, mmaurer@google.com, srhines@google.com
# Limited owners/reviewers of the allowed list.
-per-file allowed_list.go = chh@google.com, ivanlozano@google.com, jeffv@google.com, mmaurer@google.com, srhines@google.com
+per-file allowed_list.go = chiw@google.com, chriswailes@google.com, ivanlozano@google.com, jeffv@google.com, mmaurer@google.com, srhines@google.com
diff --git a/rust/bindgen.go b/rust/bindgen.go
index f4c337d..c2b0512 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -30,7 +30,7 @@
defaultBindgenFlags = []string{""}
// bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
- bindgenClangVersion = "clang-r437112b"
+ bindgenClangVersion = "clang-r445002"
_ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" {
diff --git a/rust/config/global.go b/rust/config/global.go
index c1ce13f..1cf773e 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
var pctx = android.NewPackageContext("android/soong/rust/config")
var (
- RustDefaultVersion = "1.58.1"
+ RustDefaultVersion = "1.59.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
@@ -49,7 +49,7 @@
"-C overflow-checks=on",
"-C force-unwind-tables=yes",
// Use v0 mangling to distinguish from C++ symbols
- "-Z symbol-mangling-version=v0",
+ "-C symbol-mangling-version=v0",
}
deviceGlobalRustFlags = []string{
diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go
index 98be7c2..865665e 100644
--- a/rust/fuzz_test.go
+++ b/rust/fuzz_test.go
@@ -47,17 +47,17 @@
// Check that compiler flags are set appropriately .
fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
if !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-Z sanitizer=hwaddress") ||
- !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-C passes='sancov'") ||
+ !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-C passes='sancov-module'") ||
!strings.Contains(fuzz_libtest.Args["rustcFlags"], "--cfg fuzzing") {
- t.Errorf("rust_fuzz module does not contain the expected flags (sancov, cfg fuzzing, hwaddress sanitizer).")
+ t.Errorf("rust_fuzz module does not contain the expected flags (sancov-module, cfg fuzzing, hwaddress sanitizer).")
}
// Check that dependencies have 'fuzzer' variants produced for them as well.
libtest_fuzzer := ctx.ModuleForTests("libtest_fuzzing", "android_arm64_armv8-a_rlib_rlib-std_fuzzer").Output("libtest_fuzzing.rlib")
if !strings.Contains(libtest_fuzzer.Args["rustcFlags"], "-Z sanitizer=hwaddress") ||
- !strings.Contains(libtest_fuzzer.Args["rustcFlags"], "-C passes='sancov'") ||
+ !strings.Contains(libtest_fuzzer.Args["rustcFlags"], "-C passes='sancov-module'") ||
!strings.Contains(libtest_fuzzer.Args["rustcFlags"], "--cfg fuzzing") {
- t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov, cfg fuzzing, hwaddress sanitizer).")
+ t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov-module, cfg fuzzing, hwaddress sanitizer).")
}
}
diff --git a/rust/sanitize.go b/rust/sanitize.go
index be9dc42..39aaf33 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -57,7 +57,7 @@
}
var fuzzerFlags = []string{
- "-C passes='sancov'",
+ "-C passes='sancov-module'",
"--cfg fuzzing",
"-C llvm-args=-sanitizer-coverage-level=3",
@@ -70,7 +70,7 @@
"-C link-dead-code",
// Sancov breaks with lto
- // TODO: Remove when https://bugs.llvm.org/show_bug.cgi?id=41734 is resolved and sancov works with LTO
+ // TODO: Remove when https://bugs.llvm.org/show_bug.cgi?id=41734 is resolved and sancov-module works with LTO
"-C lto=no",
}
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index 1574587..b57963b 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -19,56 +19,9 @@
exit 1
fi
-TOP=$(pwd)
-
-source build/envsetup.sh
-PLATFORM_SDK_VERSION=$(get_build_var PLATFORM_SDK_VERSION)
-PLATFORM_BASE_SDK_EXTENSION_VERSION=$(get_build_var PLATFORM_BASE_SDK_EXTENSION_VERSION)
-PLATFORM_VERSION_ALL_CODENAMES=$(get_build_var PLATFORM_VERSION_ALL_CODENAMES)
-
-# PLATFORM_VERSION_ALL_CODENAMES is a comma separated list like O,P. We need to
-# turn this into ["O","P"].
-PLATFORM_VERSION_ALL_CODENAMES=${PLATFORM_VERSION_ALL_CODENAMES/,/'","'}
-PLATFORM_VERSION_ALL_CODENAMES="[\"${PLATFORM_VERSION_ALL_CODENAMES}\"]"
-
-# Get the list of missing <uses-library> modules and convert it to a JSON array
-# (quote module names, add comma separator and wrap in brackets).
-MISSING_USES_LIBRARIES="$(get_build_var INTERNAL_PLATFORM_MISSING_USES_LIBRARIES)"
-MISSING_USES_LIBRARIES="[$(echo $MISSING_USES_LIBRARIES | sed -e 's/\([^ ]\+\)/\"\1\"/g' -e 's/[ ]\+/, /g')]"
-
-SOONG_OUT=${OUT_DIR}/soong
-SOONG_NDK_OUT=${OUT_DIR}/soong/ndk
-rm -rf ${SOONG_OUT}
-mkdir -p ${SOONG_OUT}
-
-# We only really need to set some of these variables, but soong won't merge this
-# with the defaults, so we need to write out all the defaults with our values
-# added.
-cat > ${SOONG_OUT}/soong.variables << EOF
-{
- "Platform_sdk_version": ${PLATFORM_SDK_VERSION},
- "Platform_base_sdk_extension_version": ${PLATFORM_BASE_SDK_EXTENSION_VERSION},
- "Platform_version_active_codenames": ${PLATFORM_VERSION_ALL_CODENAMES},
-
- "DeviceName": "generic_arm64",
- "HostArch": "x86_64",
- "Malloc_not_svelte": false,
- "Safestack": false,
-
- "Ndk_abis": true,
-
- "VendorVars": {
- "art_module": {
- "source_build": "true"
- }
- },
-
- "MissingUsesLibraries": ${MISSING_USES_LIBRARIES}
-}
-EOF
-m --soong-only --skip-config ${SOONG_OUT}/ndk.timestamp
+TARGET_PRODUCT=ndk build/soong/soong_ui.bash --make-mode --soong-only ${OUT_DIR}/soong/ndk.timestamp
if [ -n "${DIST_DIR}" ]; then
mkdir -p ${DIST_DIR} || true
- tar cjf ${DIST_DIR}/ndk_platform.tar.bz2 -C ${SOONG_OUT} ndk
+ tar cjf ${DIST_DIR}/ndk_platform.tar.bz2 -C ${OUT_DIR}/soong ndk
fi
diff --git a/ui/build/config.go b/ui/build/config.go
index 1dd948c..01fe8fa 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -35,10 +35,10 @@
)
const (
- envConfigDir = "vendor/google/tools/soong_config"
- jsonSuffix = "json"
+ envConfigDir = "vendor/google/tools/soong_config"
+ jsonSuffix = "json"
- configFetcher = "vendor/google/tools/soong/expconfigfetcher"
+ configFetcher = "vendor/google/tools/soong/expconfigfetcher"
envConfigFetchTimeout = 10 * time.Second
)
@@ -62,6 +62,7 @@
jsonModuleGraph bool
bp2build bool
queryview bool
+ reportMkMetrics bool // Collect and report mk2bp migration progress metrics.
soongDocs bool
skipConfig bool
skipKati bool
@@ -155,7 +156,7 @@
}
configExists := false
- outConfigFilePath := filepath.Join(config.OutDir(), envConfigName + jsonSuffix)
+ outConfigFilePath := filepath.Join(config.OutDir(), envConfigName+jsonSuffix)
if _, err := os.Stat(outConfigFilePath); err == nil {
configExists = true
}
@@ -367,10 +368,14 @@
java8Home := filepath.Join("prebuilts/jdk/jdk8", ret.HostPrebuiltTag())
java9Home := filepath.Join("prebuilts/jdk/jdk9", ret.HostPrebuiltTag())
java11Home := filepath.Join("prebuilts/jdk/jdk11", ret.HostPrebuiltTag())
+ java17Home := filepath.Join("prebuilts/jdk/jdk17", ret.HostPrebuiltTag())
javaHome := func() string {
if override, ok := ret.environ.Get("OVERRIDE_ANDROID_JAVA_HOME"); ok {
return override
}
+ if ret.environ.IsEnvTrue("EXPERIMENTAL_USE_OPENJDK17_TOOLCHAIN") {
+ return java17Home
+ }
if toolchain11, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK11_TOOLCHAIN"); ok && toolchain11 != "true" {
ctx.Fatalln("The environment variable EXPERIMENTAL_USE_OPENJDK11_TOOLCHAIN is no longer supported. An OpenJDK 11 toolchain is now the global default.")
}
@@ -711,6 +716,8 @@
c.skipConfig = true
} else if arg == "--skip-soong-tests" {
c.skipSoongTests = true
+ } else if arg == "--mk-metrics" {
+ c.reportMkMetrics = true
} else if len(arg) > 0 && arg[0] == '-' {
parseArgNum := func(def int) int {
if len(arg) > 2 {
@@ -1381,6 +1388,11 @@
return filepath.Join(c.LogsDir(), "bazel_metrics")
}
+// MkFileMetrics returns the file path for make-related metrics.
+func (c *configImpl) MkMetrics() string {
+ return filepath.Join(c.LogsDir(), "mk_metrics.pb")
+}
+
func (c *configImpl) SetEmptyNinjaFile(v bool) {
c.emptyNinjaFile = v
}
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 68efe21..262de3d 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -138,6 +138,17 @@
ctx.Fatalf("Could not export module list: %v", err)
}
+ // Gate collecting/reporting mk metrics on builds that specifically request
+ // it, as identifying the total number of mk files adds 4-5ms onto null
+ // builds.
+ if config.reportMkMetrics {
+ androidMksTotal := f.FindNamedAt(".", "Android.mk")
+
+ ctx.Metrics.SetToplevelMakefiles(len(androidMks))
+ ctx.Metrics.SetTotalMakefiles(len(androidMksTotal))
+ ctx.Metrics.DumpMkMetrics(config.MkMetrics())
+ }
+
// Stop searching a subdirectory recursively after finding a CleanSpec.mk.
cleanSpecs := f.FindFirstNamedAt(".", "CleanSpec.mk")
err = dumpListToFile(ctx, config, cleanSpecs, filepath.Join(dumpDir, "CleanSpec.mk.list"))
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 81c500d..831a80f 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -91,6 +91,7 @@
"pstree": Allowed,
"rsync": Allowed,
"sh": Allowed,
+ "stubby": Allowed,
"tr": Allowed,
"unzip": Allowed,
"zip": Allowed,
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 117a2a5..1b993e1 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -507,6 +507,9 @@
if shouldCollectBuildSoongMetrics(config) && ctx.Metrics != nil {
ctx.Metrics.SetSoongBuildMetrics(soongBuildMetrics)
}
+ if config.JsonModuleGraph() {
+ distGzipFile(ctx, config, config.ModuleGraphFile(), "soong")
+ }
}
func runMicrofactory(ctx Context, config Config, name string, pkg string, mapping map[string]string) {
diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp
index 3ba3907..05db1d7 100644
--- a/ui/metrics/Android.bp
+++ b/ui/metrics/Android.bp
@@ -21,9 +21,10 @@
pkgPath: "android/soong/ui/metrics",
deps: [
"golang-protobuf-proto",
+ "soong-ui-bp2build_metrics_proto",
"soong-ui-metrics_upload_proto",
"soong-ui-metrics_proto",
- "soong-ui-bp2build_metrics_proto",
+ "soong-ui-mk_metrics_proto",
"soong-ui-tracer",
"soong-shared",
],
@@ -71,3 +72,15 @@
"bp2build_metrics_proto/bp2build_metrics.pb.go",
],
}
+
+bootstrap_go_package {
+ name: "soong-ui-mk_metrics_proto",
+ pkgPath: "android/soong/ui/metrics/mk_metrics_proto",
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
+ srcs: [
+ "mk_metrics_proto/mk_metrics.pb.go",
+ ],
+}
diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go
index 80f8c1a..6f1ed60 100644
--- a/ui/metrics/metrics.go
+++ b/ui/metrics/metrics.go
@@ -41,6 +41,7 @@
"google.golang.org/protobuf/proto"
soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
+ mk_metrics_proto "android/soong/ui/metrics/mk_metrics_proto"
)
const (
@@ -62,14 +63,22 @@
Total = "total"
)
-// Metrics is a struct that stores collected metrics during the course
-// of a build which later is dumped to a MetricsBase protobuf file.
-// See ui/metrics/metrics_proto/metrics.proto for further details
-// on what information is collected.
+// Metrics is a struct that stores collected metrics during the course of a
+// build. It is later dumped to protobuf files. See underlying metrics protos
+// for further details on what information is collected.
type Metrics struct {
- // The protobuf message that is later written to the file.
+ // Protobuf containing various top-level build metrics. These include:
+ // 1. Build identifiers (ex: branch ID, requested product, hostname,
+ // originating command)
+ // 2. Per-subprocess top-level metrics (ex: ninja process IO and runtime).
+ // Note that, since these metrics are reported by soong_ui, there is little
+ // insight that can be provided into performance breakdowns of individual
+ // subprocesses.
metrics soong_metrics_proto.MetricsBase
+ // Protobuf containing metrics pertaining to number of makefiles in a build.
+ mkMetrics mk_metrics_proto.MkMetrics
+
// A list of pending build events.
EventTracer *EventTracer
}
@@ -78,11 +87,24 @@
func New() (metrics *Metrics) {
m := &Metrics{
metrics: soong_metrics_proto.MetricsBase{},
+ mkMetrics: mk_metrics_proto.MkMetrics{},
EventTracer: &EventTracer{},
}
return m
}
+func (m *Metrics) SetTotalMakefiles(total int) {
+ m.mkMetrics.TotalMakefiles = uint32(total)
+}
+
+func (m *Metrics) SetToplevelMakefiles(total int) {
+ m.mkMetrics.ToplevelMakefiles = uint32(total)
+}
+
+func (m *Metrics) DumpMkMetrics(outPath string) {
+ shared.Save(&m.mkMetrics, outPath)
+}
+
// SetTimeMetrics stores performance information from an executed block of
// code.
func (m *Metrics) SetTimeMetrics(perf soong_metrics_proto.PerfInfo) {
diff --git a/ui/metrics/mk_metrics_proto/mk_metrics.pb.go b/ui/metrics/mk_metrics_proto/mk_metrics.pb.go
new file mode 100644
index 0000000..32e136a
--- /dev/null
+++ b/ui/metrics/mk_metrics_proto/mk_metrics.pb.go
@@ -0,0 +1,177 @@
+// 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.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.27.1
+// protoc v3.9.1
+// source: mk_metrics.proto
+
+package mk_metrics_proto
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// Contains metrics pertaining to makefiles.
+type MkMetrics struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Total number of mk files present in the workspace.
+ TotalMakefiles uint32 `protobuf:"varint,1,opt,name=totalMakefiles,proto3" json:"totalMakefiles,omitempty"`
+ // Number of top-level mk files present in the workspace.
+ // A mk file is "top level" if there are no mk files in its parent
+ // direrctories.
+ // This value is equivalent to the number of entries in Android.mk.list.
+ ToplevelMakefiles uint32 `protobuf:"varint,2,opt,name=toplevelMakefiles,proto3" json:"toplevelMakefiles,omitempty"`
+}
+
+func (x *MkMetrics) Reset() {
+ *x = MkMetrics{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_mk_metrics_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MkMetrics) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MkMetrics) ProtoMessage() {}
+
+func (x *MkMetrics) ProtoReflect() protoreflect.Message {
+ mi := &file_mk_metrics_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MkMetrics.ProtoReflect.Descriptor instead.
+func (*MkMetrics) Descriptor() ([]byte, []int) {
+ return file_mk_metrics_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *MkMetrics) GetTotalMakefiles() uint32 {
+ if x != nil {
+ return x.TotalMakefiles
+ }
+ return 0
+}
+
+func (x *MkMetrics) GetToplevelMakefiles() uint32 {
+ if x != nil {
+ return x.ToplevelMakefiles
+ }
+ return 0
+}
+
+var File_mk_metrics_proto protoreflect.FileDescriptor
+
+var file_mk_metrics_proto_rawDesc = []byte{
+ 0x0a, 0x10, 0x6d, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x12, 0x16, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
+ 0x6d, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x61, 0x0a, 0x09, 0x4d, 0x6b,
+ 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+ 0x4d, 0x61, 0x6b, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x6b, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12,
+ 0x2c, 0x0a, 0x11, 0x74, 0x6f, 0x70, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x61, 0x6b, 0x65, 0x66,
+ 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x74, 0x6f, 0x70, 0x6c,
+ 0x65, 0x76, 0x65, 0x6c, 0x4d, 0x61, 0x6b, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x42, 0x2b, 0x5a,
+ 0x29, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75,
+ 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x6d, 0x6b, 0x5f, 0x6d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x33,
+}
+
+var (
+ file_mk_metrics_proto_rawDescOnce sync.Once
+ file_mk_metrics_proto_rawDescData = file_mk_metrics_proto_rawDesc
+)
+
+func file_mk_metrics_proto_rawDescGZIP() []byte {
+ file_mk_metrics_proto_rawDescOnce.Do(func() {
+ file_mk_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_mk_metrics_proto_rawDescData)
+ })
+ return file_mk_metrics_proto_rawDescData
+}
+
+var file_mk_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_mk_metrics_proto_goTypes = []interface{}{
+ (*MkMetrics)(nil), // 0: soong_build_mk_metrics.MkMetrics
+}
+var file_mk_metrics_proto_depIdxs = []int32{
+ 0, // [0:0] is the sub-list for method output_type
+ 0, // [0:0] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_mk_metrics_proto_init() }
+func file_mk_metrics_proto_init() {
+ if File_mk_metrics_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_mk_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MkMetrics); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_mk_metrics_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_mk_metrics_proto_goTypes,
+ DependencyIndexes: file_mk_metrics_proto_depIdxs,
+ MessageInfos: file_mk_metrics_proto_msgTypes,
+ }.Build()
+ File_mk_metrics_proto = out.File
+ file_mk_metrics_proto_rawDesc = nil
+ file_mk_metrics_proto_goTypes = nil
+ file_mk_metrics_proto_depIdxs = nil
+}
diff --git a/ui/metrics/mk_metrics_proto/mk_metrics.proto b/ui/metrics/mk_metrics_proto/mk_metrics.proto
new file mode 100644
index 0000000..df7bca3
--- /dev/null
+++ b/ui/metrics/mk_metrics_proto/mk_metrics.proto
@@ -0,0 +1,30 @@
+// 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.
+
+syntax = "proto3";
+
+package soong_build_mk_metrics;
+option go_package = "android/soong/ui/metrics/mk_metrics_proto";
+
+// Contains metrics pertaining to makefiles.
+message MkMetrics {
+ // Total number of mk files present in the workspace.
+ uint32 totalMakefiles = 1;
+
+ // Number of top-level mk files present in the workspace.
+ // A mk file is "top level" if there are no mk files in its parent
+ // direrctories.
+ // This value is equivalent to the number of entries in Android.mk.list.
+ uint32 toplevelMakefiles = 2;
+}
diff --git a/ui/metrics/mk_metrics_proto/regen.sh b/ui/metrics/mk_metrics_proto/regen.sh
new file mode 100755
index 0000000..64018d4
--- /dev/null
+++ b/ui/metrics/mk_metrics_proto/regen.sh
@@ -0,0 +1,29 @@
+#!/bin/bash -e
+
+# 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.
+
+# Generates the golang source file of the mk_metrics.proto protobuf file.
+
+function die() { echo "ERROR: $1" >&2; exit 1; }
+
+readonly error_msg="Maybe you need to run 'lunch aosp_arm-eng && m aprotoc blueprint_tools'?"
+
+if ! hash aprotoc &>/dev/null; then
+ die "could not find aprotoc. ${error_msg}"
+fi
+
+if ! aprotoc --go_out=paths=source_relative:. mk_metrics.proto; then
+ die "build failed. ${error_msg}"
+fi