Merge "Add support for java streaming proto"
diff --git a/Android.bp b/Android.bp
index d6260b4..0e8d86d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -62,6 +62,7 @@
},
},
notice: ":mingw-libwinpthread-notice",
+ licenses: ["winpthreads_license"],
}
kernel_headers {
@@ -126,3 +127,7 @@
srcs: ["cc/config/global.go"],
out: ["clang-prebuilts-version.txt"],
}
+
+dexpreopt_systemserver_check {
+ name: "dexpreopt_systemserver_check",
+}
diff --git a/android/androidmk.go b/android/androidmk.go
index 967c550..f5a9f87 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -29,6 +29,7 @@
"os"
"path/filepath"
"reflect"
+ "runtime"
"sort"
"strings"
@@ -477,8 +478,9 @@
func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
a.EntryMap = make(map[string][]string)
- amod := mod.(Module).base()
- name := amod.BaseModuleName()
+ amod := mod.(Module)
+ base := amod.base()
+ name := base.BaseModuleName()
if a.OverrideName != "" {
name = a.OverrideName
}
@@ -486,9 +488,9 @@
if a.Include == "" {
a.Include = "$(BUILD_PREBUILT)"
}
- a.Required = append(a.Required, mod.(Module).RequiredModuleNames()...)
- a.Host_required = append(a.Host_required, mod.(Module).HostRequiredModuleNames()...)
- a.Target_required = append(a.Target_required, mod.(Module).TargetRequiredModuleNames()...)
+ a.Required = append(a.Required, amod.RequiredModuleNames()...)
+ a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
+ a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
for _, distString := range a.GetDistForGoals(mod) {
fmt.Fprintf(&a.header, distString)
@@ -499,14 +501,14 @@
// Collect make variable assignment entries.
a.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
a.SetString("LOCAL_MODULE", name+a.SubName)
- a.AddStrings("LOCAL_LICENSE_KINDS", amod.commonProperties.Effective_license_kinds...)
- a.AddStrings("LOCAL_LICENSE_CONDITIONS", amod.commonProperties.Effective_license_conditions...)
- a.AddStrings("LOCAL_NOTICE_FILE", amod.commonProperties.Effective_license_text.Strings()...)
+ a.AddStrings("LOCAL_LICENSE_KINDS", base.commonProperties.Effective_license_kinds...)
+ a.AddStrings("LOCAL_LICENSE_CONDITIONS", base.commonProperties.Effective_license_conditions...)
+ a.AddStrings("LOCAL_NOTICE_FILE", base.commonProperties.Effective_license_text.Strings()...)
// TODO(b/151177513): Does this code need to set LOCAL_MODULE_IS_CONTAINER ?
- if amod.commonProperties.Effective_package_name != nil {
- a.SetString("LOCAL_LICENSE_PACKAGE_NAME", *amod.commonProperties.Effective_package_name)
- } else if len(amod.commonProperties.Effective_licenses) > 0 {
- a.SetString("LOCAL_LICENSE_PACKAGE_NAME", strings.Join(amod.commonProperties.Effective_licenses, " "))
+ if base.commonProperties.Effective_package_name != nil {
+ a.SetString("LOCAL_LICENSE_PACKAGE_NAME", *base.commonProperties.Effective_package_name)
+ } else if len(base.commonProperties.Effective_licenses) > 0 {
+ a.SetString("LOCAL_LICENSE_PACKAGE_NAME", strings.Join(base.commonProperties.Effective_licenses, " "))
}
a.SetString("LOCAL_MODULE_CLASS", a.Class)
a.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
@@ -518,27 +520,27 @@
a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
}
- archStr := amod.Arch().ArchType.String()
+ archStr := base.Arch().ArchType.String()
host := false
- switch amod.Os().Class {
+ switch base.Os().Class {
case Host:
- if amod.Target().HostCross {
+ if base.Target().HostCross {
// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
- if amod.Arch().ArchType != Common {
+ if base.Arch().ArchType != Common {
a.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
}
} else {
// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
- if amod.Arch().ArchType != Common {
+ if base.Arch().ArchType != Common {
a.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
}
}
host = true
case Device:
// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
- if amod.Arch().ArchType != Common {
- if amod.Target().NativeBridge {
- hostArchStr := amod.Target().NativeBridgeHostArchName
+ if base.Arch().ArchType != Common {
+ if base.Target().NativeBridge {
+ hostArchStr := base.Target().NativeBridgeHostArchName
if hostArchStr != "" {
a.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
}
@@ -547,31 +549,31 @@
}
}
- if !amod.InRamdisk() && !amod.InVendorRamdisk() {
- a.AddPaths("LOCAL_FULL_INIT_RC", amod.initRcPaths)
+ if !base.InRamdisk() && !base.InVendorRamdisk() {
+ a.AddPaths("LOCAL_FULL_INIT_RC", base.initRcPaths)
}
- if len(amod.vintfFragmentsPaths) > 0 {
- a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", amod.vintfFragmentsPaths)
+ if len(base.vintfFragmentsPaths) > 0 {
+ a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", base.vintfFragmentsPaths)
}
- a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(amod.commonProperties.Proprietary))
- if Bool(amod.commonProperties.Vendor) || Bool(amod.commonProperties.Soc_specific) {
+ a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
+ if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
a.SetString("LOCAL_VENDOR_MODULE", "true")
}
- a.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(amod.commonProperties.Device_specific))
- a.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(amod.commonProperties.Product_specific))
- a.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(amod.commonProperties.System_ext_specific))
- if amod.commonProperties.Owner != nil {
- a.SetString("LOCAL_MODULE_OWNER", *amod.commonProperties.Owner)
+ a.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
+ a.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
+ a.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
+ if base.commonProperties.Owner != nil {
+ a.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
}
}
- if len(amod.noticeFiles) > 0 {
- a.SetString("LOCAL_NOTICE_FILE", strings.Join(amod.noticeFiles.Strings(), " "))
+ if len(base.noticeFiles) > 0 {
+ a.SetString("LOCAL_NOTICE_FILE", strings.Join(base.noticeFiles.Strings(), " "))
}
if host {
- makeOs := amod.Os().String()
- if amod.Os() == Linux || amod.Os() == LinuxBionic || amod.Os() == LinuxMusl {
+ makeOs := base.Os().String()
+ if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
makeOs = "linux"
}
a.SetString("LOCAL_MODULE_HOST_OS", makeOs)
@@ -579,10 +581,10 @@
}
prefix := ""
- if amod.ArchSpecific() {
- switch amod.Os().Class {
+ if base.ArchSpecific() {
+ switch base.Os().Class {
case Host:
- if amod.Target().HostCross {
+ if base.Target().HostCross {
prefix = "HOST_CROSS_"
} else {
prefix = "HOST_"
@@ -592,7 +594,7 @@
}
- if amod.Arch().ArchType != ctx.Config().Targets[amod.Os()][0].Arch.ArchType {
+ if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType {
prefix = "2ND_" + prefix
}
}
@@ -836,6 +838,7 @@
case "*aidl.aidlApi": // writes non-custom before adding .phony
case "*aidl.aidlMapping": // writes non-custom before adding .phony
case "*android.customModule": // appears in tests only
+ case "*android_sdk.sdkRepoHost": // doesn't go through base_rules
case "*apex.apexBundle": // license properties written
case "*bpf.bpf": // license properties written (both for module and objs)
case "*genrule.Module": // writes non-custom before adding .phony
@@ -901,6 +904,13 @@
return true
}
+ // On Mac, only expose host darwin modules to Make, as that's all we claim to support.
+ // In reality, some of them depend on device-built (Java) modules, so we can't disable all
+ // device modules in Soong, but we can hide them from Make (and thus the build user interface)
+ if runtime.GOOS == "darwin" && module.Os() != Darwin {
+ return true
+ }
+
return !module.Enabled() ||
module.commonProperties.HideFromMake ||
// Make does not understand LinuxBionic
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 8eda9b2..ecfb008 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -18,6 +18,7 @@
"fmt"
"io"
"reflect"
+ "runtime"
"strings"
"testing"
@@ -155,6 +156,11 @@
}
func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testing.T) {
+ if runtime.GOOS == "darwin" {
+ // Device modules are not exported on Mac, so this test doesn't work.
+ t.SkipNow()
+ }
+
bp := `
custom {
name: "foo",
diff --git a/android/api_levels.go b/android/api_levels.go
index 84ab27c..93583bc 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -289,6 +289,7 @@
"P": 28,
"Q": 29,
"R": 30,
+ "S": 31,
}
// TODO: Differentiate "current" and "future".
@@ -331,6 +332,7 @@
"P": 28,
"Q": 29,
"R": 30,
+ "S": 31,
}
for i, codename := range config.PlatformVersionActiveCodenames() {
apiLevelsMap[codename] = previewAPILevelBase + i
diff --git a/android/arch.go b/android/arch.go
index 6add1b1..5e3e920 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1587,10 +1587,12 @@
return PrefixInList(arch.Abi, "arm")
}
-// hasArmArch returns true if targets has at least non-native_bridge arm Android arch
+// hasArmAndroidArch returns true if targets has at least
+// one arm Android arch (possibly native bridged)
func hasArmAndroidArch(targets []Target) bool {
for _, target := range targets {
- if target.Os == Android && target.Arch.ArchType == Arm {
+ if target.Os == Android &&
+ (target.Arch.ArchType == Arm || target.Arch.ArchType == Arm64) {
return true
}
}
@@ -1999,38 +2001,80 @@
// Create a new instance of the requested property set
value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
- // Merge all the structs together
- for _, propertyStruct := range propertyStructs {
- mergePropertyStruct(ctx, value, propertyStruct)
- }
-
- archToProp[arch.Name] = value
+ archToProp[arch.Name] = mergeStructs(ctx, propertyStructs, value)
}
axisToProps[bazel.ArchConfigurationAxis] = archToProp
osToProp := ArchVariantProperties{}
archOsToProp := ArchVariantProperties{}
+
+ linuxStructs := getTargetStructs(ctx, archProperties, "Linux")
+ bionicStructs := getTargetStructs(ctx, archProperties, "Bionic")
+ hostStructs := getTargetStructs(ctx, archProperties, "Host")
+ hostNotWindowsStructs := getTargetStructs(ctx, archProperties, "Not_windows")
+
// For android, linux, ...
for _, os := range osTypeList {
if os == CommonOS {
// It looks like this OS value is not used in Blueprint files
continue
}
- osToProp[os.Name] = getTargetStruct(ctx, propertySet, archProperties, os.Field)
+ osStructs := make([]reflect.Value, 0)
+
+ osSpecificStructs := getTargetStructs(ctx, archProperties, os.Field)
+ if os.Class == Host {
+ osStructs = append(osStructs, hostStructs...)
+ }
+ if os.Linux() {
+ osStructs = append(osStructs, linuxStructs...)
+ }
+ if os.Bionic() {
+ osStructs = append(osStructs, bionicStructs...)
+ }
+
+ if os == LinuxMusl {
+ osStructs = append(osStructs, getTargetStructs(ctx, archProperties, "Musl")...)
+ }
+ if os == Linux {
+ osStructs = append(osStructs, getTargetStructs(ctx, archProperties, "Glibc")...)
+ }
+
+ osStructs = append(osStructs, osSpecificStructs...)
+
+ if os.Class == Host && os != Windows {
+ osStructs = append(osStructs, hostNotWindowsStructs...)
+ }
+ osToProp[os.Name] = mergeStructs(ctx, osStructs, propertySet)
+
// For arm, x86, ...
for _, arch := range osArchTypeMap[os] {
+ osArchStructs := make([]reflect.Value, 0)
+
+ // Auto-combine with Linux_ and Bionic_ targets. This potentially results in
+ // repetition and select() bloat, but use of Linux_* and Bionic_* targets is rare.
+ // TODO(b/201423152): Look into cleanup.
+ if os.Linux() {
+ targetField := "Linux_" + arch.Name
+ targetStructs := getTargetStructs(ctx, archProperties, targetField)
+ osArchStructs = append(osArchStructs, targetStructs...)
+ }
+ if os.Bionic() {
+ targetField := "Bionic_" + arch.Name
+ targetStructs := getTargetStructs(ctx, archProperties, targetField)
+ osArchStructs = append(osArchStructs, targetStructs...)
+ }
+
targetField := GetCompoundTargetField(os, arch)
targetName := fmt.Sprintf("%s_%s", os.Name, arch.Name)
- archOsToProp[targetName] = getTargetStruct(ctx, propertySet, archProperties, targetField)
+ targetStructs := getTargetStructs(ctx, archProperties, targetField)
+ osArchStructs = append(osArchStructs, targetStructs...)
+
+ archOsToProp[targetName] = mergeStructs(ctx, osArchStructs, propertySet)
}
}
+
axisToProps[bazel.OsConfigurationAxis] = osToProp
axisToProps[bazel.OsArchConfigurationAxis] = archOsToProp
-
- axisToProps[bazel.BionicConfigurationAxis] = map[string]interface{}{
- "bionic": getTargetStruct(ctx, propertySet, archProperties, "Bionic"),
- }
-
return axisToProps
}
@@ -2048,17 +2092,23 @@
// }
// }
// This would return a BaseCompilerProperties with BaseCompilerProperties.Srcs = ["foo.c"]
-func getTargetStruct(ctx ArchVariantContext, propertySet interface{}, archProperties []interface{}, targetName string) interface{} {
- propertyStructs := make([]reflect.Value, 0)
+func getTargetStructs(ctx ArchVariantContext, archProperties []interface{}, targetName string) []reflect.Value {
+ var propertyStructs []reflect.Value
for _, archProperty := range archProperties {
archPropValues := reflect.ValueOf(archProperty).Elem()
targetProp := archPropValues.FieldByName("Target").Elem()
targetStruct, ok := getChildPropertyStruct(ctx, targetProp, targetName, targetName)
if ok {
propertyStructs = append(propertyStructs, targetStruct)
+ } else {
+ return []reflect.Value{}
}
}
+ return propertyStructs
+}
+
+func mergeStructs(ctx ArchVariantContext, propertyStructs []reflect.Value, propertySet interface{}) interface{} {
// Create a new instance of the requested property set
value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
diff --git a/android/bazel.go b/android/bazel.go
index 737533a..5dda655 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -175,85 +175,89 @@
// Configure modules in these directories to enable bp2build_available: true or false by default.
bp2buildDefaultConfig = Bp2BuildConfig{
- "bionic": Bp2BuildDefaultTrueRecursively,
- "build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
- "development/sdk": Bp2BuildDefaultTrueRecursively,
- "external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
- "external/brotli": Bp2BuildDefaultTrue,
- "external/fmtlib": Bp2BuildDefaultTrueRecursively,
- "external/gwp_asan": Bp2BuildDefaultTrueRecursively,
- "external/jemalloc_new": Bp2BuildDefaultTrueRecursively,
- "external/libcap": Bp2BuildDefaultTrueRecursively,
- "external/libcxx": Bp2BuildDefaultTrueRecursively,
- "external/libcxxabi": Bp2BuildDefaultTrueRecursively,
- "external/lz4/lib": Bp2BuildDefaultTrue,
- "external/protobuf": Bp2BuildDefaultTrueRecursively,
- "external/python/six": Bp2BuildDefaultTrueRecursively,
- "external/scudo": Bp2BuildDefaultTrueRecursively,
- "external/zlib": Bp2BuildDefaultTrueRecursively,
- "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively,
- "system/core/libasyncio": Bp2BuildDefaultTrue,
- "system/core/libcutils": Bp2BuildDefaultTrueRecursively,
- "system/core/libprocessgroup": Bp2BuildDefaultTrue,
+ "bionic": Bp2BuildDefaultTrueRecursively,
+ "build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
+ "development/sdk": Bp2BuildDefaultTrueRecursively,
+ "external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
+ "external/boringssl": Bp2BuildDefaultTrueRecursively,
+ "external/brotli": Bp2BuildDefaultTrue,
+ "external/fmtlib": Bp2BuildDefaultTrueRecursively,
+ "external/google-benchmark": Bp2BuildDefaultTrueRecursively,
+ "external/googletest/googletest": Bp2BuildDefaultTrueRecursively,
+ "external/gwp_asan": Bp2BuildDefaultTrueRecursively,
+ "external/jemalloc_new": Bp2BuildDefaultTrueRecursively,
+ "external/jsoncpp": Bp2BuildDefaultTrueRecursively,
+ "external/libcap": Bp2BuildDefaultTrueRecursively,
+ "external/libcxx": Bp2BuildDefaultTrueRecursively,
+ "external/libcxxabi": Bp2BuildDefaultTrueRecursively,
+ "external/lz4/lib": Bp2BuildDefaultTrue,
+ "external/mdnsresponder": Bp2BuildDefaultTrueRecursively,
+ "external/minijail": Bp2BuildDefaultTrueRecursively,
+ "external/pcre": Bp2BuildDefaultTrueRecursively,
+ "external/protobuf": Bp2BuildDefaultTrueRecursively,
+ "external/python/six": Bp2BuildDefaultTrueRecursively,
+ "external/scudo": Bp2BuildDefaultTrueRecursively,
+ "external/selinux/libselinux": Bp2BuildDefaultTrueRecursively,
+ "external/zlib": Bp2BuildDefaultTrueRecursively,
+ "external/zstd": Bp2BuildDefaultTrueRecursively,
+ "frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb": Bp2BuildDefaultTrue,
+ "packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively,
+ "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively,
+ "system/core/diagnose_usb": Bp2BuildDefaultTrueRecursively,
+ "system/core/libasyncio": Bp2BuildDefaultTrue,
+ "system/core/libcrypto_utils": Bp2BuildDefaultTrueRecursively,
+ "system/core/libcutils": Bp2BuildDefaultTrueRecursively,
+ "system/core/libpackagelistparser": Bp2BuildDefaultTrueRecursively,
+ "system/core/libprocessgroup": Bp2BuildDefaultTrue,
+ "system/core/libprocessgroup/cgrouprc": Bp2BuildDefaultTrue,
+ "system/core/libprocessgroup/cgrouprc_format": Bp2BuildDefaultTrue,
"system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively,
- "system/libbase": Bp2BuildDefaultTrueRecursively,
- "system/logging/liblog": Bp2BuildDefaultTrueRecursively,
- "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively,
- "system/timezone/apex": Bp2BuildDefaultTrueRecursively,
- "system/timezone/output_data": Bp2BuildDefaultTrueRecursively,
+ "system/libbase": Bp2BuildDefaultTrueRecursively,
+ "system/libziparchive": Bp2BuildDefaultTrueRecursively,
+ "system/logging/liblog": Bp2BuildDefaultTrueRecursively,
+ "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively,
+ "system/timezone/apex": Bp2BuildDefaultTrueRecursively,
+ "system/timezone/output_data": Bp2BuildDefaultTrueRecursively,
}
// Per-module denylist to always opt modules out of both bp2build and mixed builds.
bp2buildModuleDoNotConvertList = []string{
- // Things that transitively depend on unconverted libc_* modules.
- "libbionic_spawn_benchmark", // http://b/186824595, cc_library_static, depends on //external/google-benchmark (http://b/186822740)
- // also depends on //system/logging/liblog:liblog (http://b/186822772)
+ "libc_malloc_debug", // depends on libunwindstack, which depends on unsupported module art_cc_library_statics
- "libc_malloc_debug", // http://b/186824339, cc_library_static, depends on //system/libbase:libbase (http://b/186823646)
- "libc_malloc_debug_backtrace", // http://b/186824112, cc_library_static, depends on //external/libcxxabi:libc++demangle (http://b/186823773)
-
- "libcutils", // http://b/186827426, cc_library, depends on //system/core/libprocessgroup:libprocessgroup_headers (http://b/186826841)
- "libcutils_sockets", // http://b/186826853, cc_library, depends on //system/libbase:libbase (http://b/186826479)
-
- "liblinker_debuggerd_stub", // http://b/186824327, cc_library_static, depends on //external/zlib:libz (http://b/186823782)
- // also depends on //system/libziparchive:libziparchive (http://b/186823656)
- // also depends on //system/logging/liblog:liblog (http://b/186822772)
- "liblinker_main", // http://b/186825989, cc_library_static, depends on //external/zlib:libz (http://b/186823782)
- // also depends on //system/libziparchive:libziparchive (http://b/186823656)
- // also depends on//system/logging/liblog:liblog (http://b/186822772)
- "liblinker_malloc", // http://b/186826466, cc_library_static, depends on //external/zlib:libz (http://b/186823782)
- // also depends on //system/libziparchive:libziparchive (http://b/186823656)
- // also depends on //system/logging/liblog:liblog (http://b/186822772)
- "libc_ndk", // http://b/187013218, cc_library_static, depends on //bionic/libm:libm (http://b/183064661)
- "libc_malloc_hooks", // http://b/187016307, cc_library, ld.lld: error: undefined symbol: __malloc_hook
-
- // http://b/186823769: Needs C++ STL support, includes from unconverted standard libraries in //external/libcxx
- // c++_static
- "libbase_ndk", // http://b/186826477, cc_library, no such target '//build/bazel/platforms/os:darwin' when --platforms //build/bazel/platforms:android_x86 is added
- // libcxx
- "libBionicBenchmarksUtils", // cc_library_static, fatal error: 'map' file not found, from libcxx
- "libbase", // Depends on fmtlib via static_libs and also whole_static_libs, which results in bazel errors.
-
- "libfdtrack", // depends on liblzma and libbase
+ "libbase_ndk", // http://b/186826477, fails to link libctscamera2_jni for device (required for CtsCameraTestCases)
"libprotobuf-python", // contains .proto sources
"libprotobuf-internal-protos", // we don't handle path property for fileegroups
"libprotobuf-internal-python-srcs", // we don't handle path property for fileegroups
- "libseccomp_policy", // depends on libbase
+ "libseccomp_policy", // b/201094425: depends on func_to_syscall_nrs, which depends on py_binary, which is unsupported in mixed builds.
+ "libfdtrack", // depends on libunwindstack, which depends on unsupported module art_cc_library_statics
"gwp_asan_crash_handler", // cc_library, ld.lld: error: undefined symbol: memset
- //system/core/libprocessgroup/...
- "libprocessgroup", // depends on //system/core/libprocessgroup/cgrouprc:libcgrouprc
+ "brotli-fuzzer-corpus", // b/202015218: outputs are in location incompatible with bazel genrule handling.
- //external/brotli/...
- "brotli-fuzzer-corpus", // "declared output 'external/brotli/c/fuzz/73231c6592f195ffd41100b8706d1138ff6893b9' was not created by genrule"
+ // b/203369847: multiple genrules in the same package creating the same file
+ // //development/sdk/...
+ "platform_tools_properties",
+ "build_tools_source_properties",
// //external/libcap/...
"libcap", // http://b/198595332, depends on _makenames, a cc_binary
"cap_names.h", // http://b/198596102, depends on _makenames, a cc_binary
+ "libminijail", // depends on unconverted modules: libcap
+ "getcap", // depends on unconverted modules: libcap
+ "setcap", // depends on unconverted modules: libcap
+ "minijail0", // depends on unconverted modules: libcap, libminijail
+ "drop_privs", // depends on unconverted modules: libminijail
+
// Tests. Handle later.
"libbionic_tests_headers_posix", // http://b/186024507, cc_library_static, sched.h, time.h not found
"libjemalloc5_integrationtest",
@@ -261,7 +265,38 @@
"libjemalloc5_unittest",
// APEX support
- "com.android.runtime", // http://b/194746715, apex, depends on 'libc_malloc_debug' and 'libc_malloc_hooks'
+ "com.android.runtime", // http://b/194746715, apex, depends on 'libc_malloc_debug'
+
+ "libadb_crypto", // Depends on libadb_protos
+ "libadb_crypto_static", // Depends on libadb_protos_static
+ "libadb_pairing_connection", // Depends on libadb_protos
+ "libadb_pairing_connection_static", // Depends on libadb_protos_static
+ "libadb_pairing_server", // Depends on libadb_protos
+ "libadb_pairing_server_static", // Depends on libadb_protos_static
+ "libadbd", // Depends on libadbd_core
+ "libadbd_core", // Depends on libadb_protos
+ "libadbd_services", // Depends on libadb_protos
+
+ "libadb_protos_static", // b/200601772: Requires cc_library proto support
+ "libadb_protos", // b/200601772: Requires cc_library proto support
+ "libapp_processes_protos_lite", // b/200601772: Requires cc_library proto support
+
+ "libgtest_ndk_c++", // b/201816222: Requires sdk_version support.
+ "libgtest_main_ndk_c++", // b/201816222: Requires sdk_version support.
+
+ "abb", // depends on unconverted modules: libadbd_core, libadbd_services, libcmd, libbinder, libutils, libselinux
+ "adb", // depends on unconverted modules: bin2c_fastdeployagent, libadb_crypto, libadb_host, libadb_pairing_connection, libadb_protos, libandroidfw, libapp_processes_protos_full, libfastdeploy_host, libmdnssd, libopenscreen-discovery, libopenscreen-platform-impl, libusb, libutils, libziparchive, libzstd, AdbWinApi
+ "adbd", // depends on unconverted modules: libadb_crypto, libadb_pairing_connection, libadb_protos, libadbd, libadbd_core, libapp_processes_protos_lite, libmdnssd, libzstd, libadbd_services, libcap, libminijail, libselinux
+ "bionic_tests_zipalign", // depends on unconverted modules: libziparchive, libutils
+ "linker", // depends on unconverted modules: liblinker_debuggerd_stub, libdebuggerd_handler_fallback, libziparchive, liblinker_main, liblinker_malloc
+ "linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_*
+ "sefcontext_compile", // depends on unconverted modules: libsepol
+ "versioner", // depends on unconverted modules: libclang_cxx_host, libLLVM_host
+
+ "linkerconfig", // http://b/202876379 has arch-variant static_executable
+ "mdnsd", // http://b/202876379 has arch-variant static_executable
+
+ "acvp_modulewrapper", // disabled for android x86/x86_64
}
// Per-module denylist of cc_library modules to only generate the static
@@ -278,7 +313,7 @@
"libseccomp_policy_app_zygote_sources", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
"libseccomp_policy_app_sources", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
"libseccomp_policy_system_sources", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
-
+ "minijail_constants_json", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
}
// Used for quicker lookups
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 2241255..3c6212e 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -48,11 +48,17 @@
StarlarkFunctionBody() string
}
+// Portion of cquery map key to describe target configuration.
+type configKey struct {
+ archType ArchType
+ osType OsType
+}
+
// Map key to describe bazel cquery requests.
type cqueryKey struct {
label string
requestType cqueryRequest
- archType ArchType
+ configKey configKey
}
// bazelHandler is the interface for a helper object related to deferring to Bazel for
@@ -72,14 +78,14 @@
// has been queued to be run later.
// Returns result files built by building the given bazel target label.
- GetOutputFiles(label string, archType ArchType) ([]string, bool)
+ GetOutputFiles(label string, cfgKey configKey) ([]string, bool)
// TODO(cparsons): Other cquery-related methods should be added here.
// Returns the results of GetOutputFiles and GetCcObjectFiles in a single query (in that order).
- GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error)
+ GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, bool, error)
// Returns the executable binary resultant from building together the python sources
- GetPythonBinary(label string, archType ArchType) (string, bool)
+ GetPythonBinary(label string, cfgKey configKey) (string, bool)
// ** End cquery methods
@@ -140,17 +146,17 @@
LabelToPythonBinary map[string]string
}
-func (m MockBazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
+func (m MockBazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, bool) {
result, ok := m.LabelToOutputFiles[label]
return result, ok
}
-func (m MockBazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
+func (m MockBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, bool, error) {
result, ok := m.LabelToCcInfo[label]
return result, ok, nil
}
-func (m MockBazelContext) GetPythonBinary(label string, archType ArchType) (string, bool) {
+func (m MockBazelContext) GetPythonBinary(label string, cfgKey configKey) (string, bool) {
result, ok := m.LabelToPythonBinary[label]
return result, ok
}
@@ -171,8 +177,8 @@
var _ BazelContext = MockBazelContext{}
-func (bazelCtx *bazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
- rawString, ok := bazelCtx.cquery(label, cquery.GetOutputFiles, archType)
+func (bazelCtx *bazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, bool) {
+ rawString, ok := bazelCtx.cquery(label, cquery.GetOutputFiles, cfgKey)
var ret []string
if ok {
bazelOutput := strings.TrimSpace(rawString)
@@ -181,8 +187,8 @@
return ret, ok
}
-func (bazelCtx *bazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
- result, ok := bazelCtx.cquery(label, cquery.GetCcInfo, archType)
+func (bazelCtx *bazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, bool, error) {
+ result, ok := bazelCtx.cquery(label, cquery.GetCcInfo, cfgKey)
if !ok {
return cquery.CcInfo{}, ok, nil
}
@@ -192,8 +198,8 @@
return ret, ok, err
}
-func (bazelCtx *bazelContext) GetPythonBinary(label string, archType ArchType) (string, bool) {
- rawString, ok := bazelCtx.cquery(label, cquery.GetPythonBinary, archType)
+func (bazelCtx *bazelContext) GetPythonBinary(label string, cfgKey configKey) (string, bool) {
+ rawString, ok := bazelCtx.cquery(label, cquery.GetPythonBinary, cfgKey)
var ret string
if ok {
bazelOutput := strings.TrimSpace(rawString)
@@ -202,19 +208,15 @@
return ret, ok
}
-func (n noopBazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
+func (n noopBazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, bool) {
panic("unimplemented")
}
-func (n noopBazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
+func (n noopBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, bool, error) {
panic("unimplemented")
}
-func (n noopBazelContext) GetPythonBinary(label string, archType ArchType) (string, bool) {
- panic("unimplemented")
-}
-
-func (n noopBazelContext) GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool) {
+func (n noopBazelContext) GetPythonBinary(label string, cfgKey configKey) (string, bool) {
panic("unimplemented")
}
@@ -303,8 +305,8 @@
// returns (result, true). If the request is queued but no results are available,
// then returns ("", false).
func (context *bazelContext) cquery(label string, requestType cqueryRequest,
- archType ArchType) (string, bool) {
- key := cqueryKey{label, requestType, archType}
+ cfgKey configKey) (string, bool) {
+ key := cqueryKey{label, requestType, cfgKey}
if result, ok := context.results[key]; ok {
return result, true
} else {
@@ -419,7 +421,7 @@
def _config_node_transition_impl(settings, attr):
return {
- "//command_line_option:platforms": "@//build/bazel/platforms:android_%s" % attr.arch,
+ "//command_line_option:platforms": "@//build/bazel/platforms:%s_%s" % (attr.os, attr.arch),
}
_config_node_transition = transition(
@@ -437,7 +439,8 @@
implementation = _passthrough_rule_impl,
attrs = {
"arch" : attr.string(mandatory = True),
- "deps" : attr.label_list(cfg = _config_node_transition),
+ "os" : attr.string(mandatory = True),
+ "deps" : attr.label_list(cfg = _config_node_transition, allow_files = True),
"_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
},
)
@@ -488,38 +491,32 @@
configNodeFormatString := `
config_node(name = "%s",
arch = "%s",
+ os = "%s",
deps = [%s],
)
`
- commonArchFilegroupString := `
-filegroup(name = "common",
- srcs = [%s],
-)
-`
-
configNodesSection := ""
- labelsByArch := map[string][]string{}
+ labelsByConfig := map[string][]string{}
for val, _ := range context.requests {
labelString := fmt.Sprintf("\"@%s\"", val.label)
- archString := getArchString(val)
- labelsByArch[archString] = append(labelsByArch[archString], labelString)
+ configString := getConfigString(val)
+ labelsByConfig[configString] = append(labelsByConfig[configString], labelString)
}
allLabels := []string{}
- for archString, labels := range labelsByArch {
- if archString == "common" {
- // arch-less labels (e.g. filegroups) don't need a config_node
- allLabels = append(allLabels, "\":common\"")
- labelsString := strings.Join(labels, ",\n ")
- configNodesSection += fmt.Sprintf(commonArchFilegroupString, labelsString)
- } else {
- // Create a config_node, and add the config_node's label to allLabels
- allLabels = append(allLabels, fmt.Sprintf("\":%s\"", archString))
- labelsString := strings.Join(labels, ",\n ")
- configNodesSection += fmt.Sprintf(configNodeFormatString, archString, archString, labelsString)
+ for configString, labels := range labelsByConfig {
+ configTokens := strings.Split(configString, "|")
+ if len(configTokens) != 2 {
+ panic(fmt.Errorf("Unexpected config string format: %s", configString))
}
+ archString := configTokens[0]
+ osString := configTokens[1]
+ targetString := fmt.Sprintf("%s_%s", osString, archString)
+ allLabels = append(allLabels, fmt.Sprintf("\":%s\"", targetString))
+ labelsString := strings.Join(labels, ",\n ")
+ configNodesSection += fmt.Sprintf(configNodeFormatString, targetString, archString, osString, labelsString)
}
return []byte(fmt.Sprintf(formatString, configNodesSection, strings.Join(allLabels, ",\n ")))
@@ -591,9 +588,11 @@
# specific platform architecture in mixed builds. This is consistent with how
# Soong treats filegroups, but it may not be the case with manually-written
# filegroup BUILD targets.
- if target.kind in ["filegroup", ""]:
- return "common"
buildoptions = build_options(target)
+ if buildoptions == None:
+ # File targets do not have buildoptions. File targets aren't associated with
+ # any specific platform architecture in mixed builds, so use the host.
+ return "x86_64|linux"
platforms = build_options(target)["//command_line_option:platforms"]
if len(platforms) != 1:
# An individual configured target should have only one platform architecture.
@@ -603,10 +602,12 @@
platform_name = build_options(target)["//command_line_option:platforms"][0].name
if platform_name == "host":
return "HOST"
+ elif platform_name.startswith("linux_glibc_"):
+ return platform_name[len("linux_glibc_"):] + "|" + platform_name[:len("linux_glibc_")-1]
elif platform_name.startswith("android_"):
- return platform_name[len("android_"):]
+ return platform_name[len("android_"):] + "|" + platform_name[:len("android_")-1]
elif platform_name.startswith("linux_"):
- return platform_name[len("linux_"):]
+ return platform_name[len("linux_"):] + "|" + platform_name[:len("linux_")-1]
else:
fail("expected platform name of the form 'android_<arch>' or 'linux_<arch>', but was " + str(platforms))
return "UNKNOWN"
@@ -696,7 +697,7 @@
cqueryOutput, cqueryErr, err = context.issueBazelCommand(
context.paths,
bazel.CqueryBuildRootRunName,
- bazelCommand{"cquery", fmt.Sprintf("deps(%s)", buildrootLabel)},
+ bazelCommand{"cquery", fmt.Sprintf("deps(%s, 2)", buildrootLabel)},
"--output=starlark",
"--starlark:file="+absolutePath(cqueryFileRelpath))
err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"),
@@ -815,7 +816,7 @@
if len(buildStatement.OutputPaths) > 0 {
cmd.Text("rm -f")
for _, outputPath := range buildStatement.OutputPaths {
- cmd.Text(PathForBazelOut(ctx, outputPath).String())
+ cmd.Text(outputPath)
}
cmd.Text("&&")
}
@@ -854,14 +855,23 @@
}
func getCqueryId(key cqueryKey) string {
- return key.label + "|" + getArchString(key)
+ return key.label + "|" + getConfigString(key)
}
-func getArchString(key cqueryKey) string {
- arch := key.archType.Name
- if len(arch) > 0 {
- return arch
- } else {
- return "x86_64"
+func getConfigString(key cqueryKey) string {
+ arch := key.configKey.archType.Name
+ if len(arch) == 0 || arch == "common" {
+ // Use host platform, which is currently hardcoded to be x86_64.
+ arch = "x86_64"
}
+ os := key.configKey.osType.Name
+ if len(os) == 0 || os == "common_os" {
+ // Use host OS, which is currently hardcoded to be linux.
+ os = "linux"
+ }
+ return arch + "|" + os
+}
+
+func GetConfigKey(ctx ModuleContext) configKey {
+ return configKey{archType: ctx.Arch().ArchType, osType: ctx.Os()}
}
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
index cdf1a63..ad5b63b 100644
--- a/android/bazel_handler_test.go
+++ b/android/bazel_handler_test.go
@@ -9,11 +9,11 @@
func TestRequestResultsAfterInvokeBazel(t *testing.T) {
label := "//foo:bar"
- arch := Arm64
+ cfg := configKey{Arm64, Android}
bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
- bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: `//foo:bar|arm64>>out/foo/bar.txt`,
+ bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: `//foo:bar|arm64|android>>out/foo/bar.txt`,
})
- g, ok := bazelContext.GetOutputFiles(label, arch)
+ g, ok := bazelContext.GetOutputFiles(label, cfg)
if ok {
t.Errorf("Did not expect cquery results prior to running InvokeBazel(), but got %s", g)
}
@@ -21,7 +21,7 @@
if err != nil {
t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
}
- g, ok = bazelContext.GetOutputFiles(label, arch)
+ g, ok = bazelContext.GetOutputFiles(label, cfg)
if !ok {
t.Errorf("Expected cquery results after running InvokeBazel(), but got none")
} else if w := []string{"out/foo/bar.txt"}; !reflect.DeepEqual(w, g) {
diff --git a/android/config.go b/android/config.go
index e7ebdef..78d43c6 100644
--- a/android/config.go
+++ b/android/config.go
@@ -355,14 +355,14 @@
config.bp2buildModuleTypeConfig = map[string]bool{}
+ determineBuildOS(config)
+
return Config{config}
}
func modifyTestConfigToSupportArchMutator(testConfig Config) {
config := testConfig.config
- determineBuildOS(config)
-
config.Targets = map[OsType][]Target{
Android: []Target{
{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
@@ -568,15 +568,17 @@
}
func (c *config) HostToolPath(ctx PathContext, tool string) Path {
- return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool)
+ path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin", false, tool)
+ return path
}
-func (c *config) HostJNIToolPath(ctx PathContext, path string) Path {
+func (c *config) HostJNIToolPath(ctx PathContext, lib string) Path {
ext := ".so"
if runtime.GOOS == "darwin" {
ext = ".dylib"
}
- return PathForOutput(ctx, "host", c.PrebuiltOS(), "lib64", path+ext)
+ path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "lib64", false, lib+ext)
+ return path
}
func (c *config) HostJavaToolPath(ctx PathContext, path string) Path {
@@ -854,11 +856,6 @@
return Bool(c.productVariables.Always_use_prebuilt_sdks)
}
-// Returns true if the boot jars check should be skipped.
-func (c *config) SkipBootJarsCheck() bool {
- return Bool(c.productVariables.Skip_boot_jars_check)
-}
-
func (c *config) MinimizeJavaDebugInfo() bool {
return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng)
}
@@ -1583,6 +1580,10 @@
return c.config.productVariables.SepolicyFreezeTestExtraPrebuiltDirs
}
+func (c *deviceConfig) GenerateAidlNdkPlatformBackend() bool {
+ return c.config.productVariables.GenerateAidlNdkPlatformBackend
+}
+
// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
// Such lists are used in the build system for things like bootclasspath jars or system server jars.
// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
diff --git a/android/filegroup.go b/android/filegroup.go
index 4db165f..a79374d 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -72,7 +72,7 @@
Bzl_load_location: "//build/bazel/rules:filegroup.bzl",
}
- ctx.CreateBazelTargetModule(fg.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, CommonAttributes{Name: fg.Name()}, attrs)
}
type fileGroupProperties struct {
@@ -112,15 +112,24 @@
return module
}
-func (fg *fileGroup) GenerateBazelBuildActions(ctx ModuleContext) bool {
+func (fg *fileGroup) maybeGenerateBazelBuildActions(ctx ModuleContext) {
if !fg.MixedBuildsEnabled(ctx) {
- return false
+ return
+ }
+
+ archVariant := ctx.Arch().ArchType
+ osVariant := ctx.Os()
+ if len(fg.Srcs()) == 1 && fg.Srcs()[0].Base() == fg.Name() {
+ // This will be a regular file target, not filegroup, in Bazel.
+ // See FilegroupBp2Build for more information.
+ archVariant = Common
+ osVariant = CommonOS
}
bazelCtx := ctx.Config().BazelContext
- filePaths, ok := bazelCtx.GetOutputFiles(fg.GetBazelLabel(ctx, fg), Common)
+ filePaths, ok := bazelCtx.GetOutputFiles(fg.GetBazelLabel(ctx, fg), configKey{archVariant, osVariant})
if !ok {
- return false
+ return
}
bazelOuts := make(Paths, 0, len(filePaths))
@@ -130,19 +139,15 @@
}
fg.srcs = bazelOuts
-
- return true
}
func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
- if fg.GenerateBazelBuildActions(ctx) {
- return
- }
-
fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs)
if fg.properties.Path != nil {
fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path))
}
+
+ fg.maybeGenerateBazelBuildActions(ctx)
}
func (fg *fileGroup) Srcs() Paths {
diff --git a/android/module.go b/android/module.go
index c9b01a0..503fff3 100644
--- a/android/module.go
+++ b/android/module.go
@@ -409,7 +409,7 @@
PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
CheckbuildFile(srcPath Path)
- TidyFile(srcPath Path)
+ TidyFile(srcPath WritablePath)
InstallInData() bool
InstallInTestcases() bool
@@ -852,6 +852,16 @@
UnconvertedBp2buildDeps []string `blueprint:"mutated"`
}
+// CommonAttributes represents the common Bazel attributes from which properties
+// in `commonProperties` are translated/mapped; such properties are annotated in
+// a list their corresponding attribute. It is embedded within `bp2buildInfo`.
+type CommonAttributes struct {
+ // Soong nameProperties -> Bazel name
+ Name string
+ // Data mapped from: Required
+ Data bazel.LabelListAttribute
+}
+
type distProperties struct {
// configuration to distribute output files from this module to the distribution
// directory (default: $OUT/dist, configurable with $DIST_DIR)
@@ -1072,6 +1082,34 @@
m.base().commonProperties.CreateCommonOSVariant = true
}
+func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext) {
+ // Assert passed-in attributes include Name
+ name := attrs.Name
+ if len(name) == 0 {
+ ctx.ModuleErrorf("CommonAttributes in fillCommonBp2BuildModuleAttrs expects a `.Name`!")
+ }
+
+ mod := ctx.Module().base()
+ props := &mod.commonProperties
+
+ depsToLabelList := func(deps []string) bazel.LabelListAttribute {
+ return bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, deps))
+ }
+
+ data := &attrs.Data
+
+ required := depsToLabelList(props.Required)
+ archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{})
+ for axis, configToProps := range archVariantProps {
+ for config, _props := range configToProps {
+ if archProps, ok := _props.(*commonProperties); ok {
+ required.SetSelectValue(axis, config, depsToLabelList(archProps.Required).Value)
+ }
+ }
+ }
+ data.Append(required)
+}
+
// A ModuleBase object contains the properties that are common to all Android
// modules. It should be included as an anonymous field in every module
// struct definition. InitAndroidModule should then be called from the module's
@@ -1152,7 +1190,7 @@
installFiles InstallPaths
installFilesDepSet *installPathsDepSet
checkbuildFiles Paths
- tidyFiles Paths
+ tidyFiles WritablePaths
packagingSpecs []PackagingSpec
packagingSpecsDepSet *packagingSpecsDepSet
noticeFiles Paths
@@ -1183,15 +1221,15 @@
// A struct containing all relevant information about a Bazel target converted via bp2build.
type bp2buildInfo struct {
- Name string
- Dir string
- BazelProps bazel.BazelTargetModuleProperties
- Attrs interface{}
+ Dir string
+ BazelProps bazel.BazelTargetModuleProperties
+ CommonAttrs CommonAttributes
+ Attrs interface{}
}
// TargetName returns the Bazel target name of a bp2build converted target.
func (b bp2buildInfo) TargetName() string {
- return b.Name
+ return b.CommonAttrs.Name
}
// TargetPackage returns the Bazel package of a bp2build converted target.
@@ -1211,8 +1249,8 @@
}
// BazelAttributes returns the Bazel attributes of a bp2build converted target.
-func (b bp2buildInfo) BazelAttributes() interface{} {
- return b.Attrs
+func (b bp2buildInfo) BazelAttributes() []interface{} {
+ return []interface{}{&b.CommonAttrs, b.Attrs}
}
func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
@@ -1726,12 +1764,18 @@
func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
var allInstalledFiles InstallPaths
var allCheckbuildFiles Paths
- var allTidyFiles Paths
+ var allTidyFiles WritablePaths
ctx.VisitAllModuleVariants(func(module Module) {
a := module.base()
allInstalledFiles = append(allInstalledFiles, a.installFiles...)
- allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
- allTidyFiles = append(allTidyFiles, a.tidyFiles...)
+ // A module's -{checkbuild,tidy} phony targets should
+ // not be created if the module is not exported to make.
+ // Those could depend on the build target and fail to compile
+ // for the current build target.
+ if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(a) {
+ allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
+ allTidyFiles = append(allTidyFiles, a.tidyFiles...)
+ }
})
var deps Paths
@@ -1757,7 +1801,7 @@
if len(allTidyFiles) > 0 {
name := namespacePrefix + ctx.ModuleName() + "-tidy"
- ctx.Phony(name, allTidyFiles...)
+ ctx.Phony(name, allTidyFiles.Paths()...)
m.tidyTarget = PathForPhony(ctx, name)
deps = append(deps, m.tidyTarget)
}
@@ -2169,7 +2213,7 @@
packagingSpecs []PackagingSpec
installFiles InstallPaths
checkbuildFiles Paths
- tidyFiles Paths
+ tidyFiles WritablePaths
module Module
phonies map[string]Paths
@@ -2780,11 +2824,13 @@
}
func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
+ licenseFiles := m.Module().EffectiveLicenseFiles()
spec := PackagingSpec{
- relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
- srcPath: srcPath,
- symlinkTarget: "",
- executable: executable,
+ relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
+ srcPath: srcPath,
+ symlinkTarget: "",
+ executable: executable,
+ effectiveLicenseFiles: &licenseFiles,
}
m.packagingSpecs = append(m.packagingSpecs, spec)
return spec
@@ -2902,7 +2948,7 @@
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
}
-func (m *moduleContext) TidyFile(srcPath Path) {
+func (m *moduleContext) TidyFile(srcPath WritablePath) {
m.tidyFiles = append(m.tidyFiles, srcPath)
}
diff --git a/android/mutator.go b/android/mutator.go
index b361c51..4b37377 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -15,10 +15,11 @@
package android
import (
- "android/soong/bazel"
"reflect"
"sync"
+ "android/soong/bazel"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -268,7 +269,7 @@
// factory method, just like in CreateModule, but also requires
// BazelTargetModuleProperties containing additional metadata for the
// bp2build codegenerator.
- CreateBazelTargetModule(string, bazel.BazelTargetModuleProperties, interface{})
+ CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
}
type topDownMutatorContext struct {
@@ -514,17 +515,18 @@
}
func (t *topDownMutatorContext) CreateBazelTargetModule(
- name string,
bazelProps bazel.BazelTargetModuleProperties,
+ commonAttrs CommonAttributes,
attrs interface{}) {
-
+ commonAttrs.fillCommonBp2BuildModuleAttrs(t)
+ mod := t.Module()
info := bp2buildInfo{
- Name: name,
- Dir: t.OtherModuleDir(t.Module()),
- BazelProps: bazelProps,
- Attrs: attrs,
+ Dir: t.OtherModuleDir(mod),
+ BazelProps: bazelProps,
+ CommonAttrs: commonAttrs,
+ Attrs: attrs,
}
- t.Module().base().addBp2buildInfo(info)
+ mod.base().addBp2buildInfo(info)
}
func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
diff --git a/android/neverallow.go b/android/neverallow.go
index 94cceb2..04366d3 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -150,6 +150,7 @@
func createJavaDeviceForHostRules() []Rule {
javaDeviceForHostProjectsAllowedList := []string{
+ "development/build",
"external/guava",
"external/robolectric-shadows",
"frameworks/layoutlib",
@@ -175,6 +176,7 @@
"tools/test/graphicsbenchmark/apps/sample_app",
"tools/test/graphicsbenchmark/functional_tests/java",
"vendor/xts/gts-tests/hostsidetests/gamedevicecert/apps/javatests",
+ "external/libtextclassifier/native",
}
platformVariantPropertiesAllowedList := []string{
diff --git a/android/notices.go b/android/notices.go
index 07cf3e4..d8cfaf2 100644
--- a/android/notices.go
+++ b/android/notices.go
@@ -100,3 +100,56 @@
HtmlGzOutput: OptionalPathForPath(htmlGzOutput),
}
}
+
+// BuildNotices merges the supplied NOTICE files into a single file that lists notices
+// for every key in noticeMap (which would normally be installed files).
+func BuildNotices(ctx ModuleContext, noticeMap map[string]Paths) NoticeOutputs {
+ // TODO(jungjw): We should just produce a well-formatted NOTICE.html file in a single pass.
+ //
+ // generate-notice-files.py, which processes the merged NOTICE file, has somewhat strict rules
+ // about input NOTICE file paths.
+ // 1. Their relative paths to the src root become their NOTICE index titles. We want to use
+ // on-device paths as titles, and so output the merged NOTICE file the corresponding location.
+ // 2. They must end with .txt extension. Otherwise, they're ignored.
+
+ mergeTool := PathForSource(ctx, "build/soong/scripts/mergenotice.py")
+ generateNoticeTool := PathForSource(ctx, "build/soong/scripts/generate-notice-files.py")
+
+ outputDir := PathForModuleOut(ctx, "notices")
+ builder := NewRuleBuilder(pctx, ctx).
+ Sbox(outputDir, PathForModuleOut(ctx, "notices.sbox.textproto"))
+ for _, installPath := range SortedStringKeys(noticeMap) {
+ noticePath := outputDir.Join(ctx, installPath+".txt")
+ // It would be nice if sbox created directories for temporaries, but until then
+ // this is simple enough.
+ builder.Command().
+ Text("(cd").OutputDir().Text("&&").
+ Text("mkdir -p").Text(filepath.Dir(installPath)).Text(")")
+ builder.Temporary(noticePath)
+ builder.Command().
+ Tool(mergeTool).
+ Flag("--output").Output(noticePath).
+ Inputs(noticeMap[installPath])
+ }
+
+ // Transform the merged NOTICE file into a gzipped HTML file.
+ txtOutput := outputDir.Join(ctx, "NOTICE.txt")
+ htmlOutput := outputDir.Join(ctx, "NOTICE.html")
+ htmlGzOutput := outputDir.Join(ctx, "NOTICE.html.gz")
+ title := "\"Notices for " + ctx.ModuleName() + "\""
+ builder.Command().Tool(generateNoticeTool).
+ FlagWithOutput("--text-output ", txtOutput).
+ FlagWithOutput("--html-output ", htmlOutput).
+ FlagWithArg("-t ", title).
+ Flag("-s").OutputDir()
+ builder.Command().BuiltTool("minigzip").
+ FlagWithInput("-c ", htmlOutput).
+ FlagWithOutput("> ", htmlGzOutput)
+ builder.Build("build_notices", "generate notice output")
+
+ return NoticeOutputs{
+ TxtOutput: OptionalPathForPath(txtOutput),
+ HtmlOutput: OptionalPathForPath(htmlOutput),
+ HtmlGzOutput: OptionalPathForPath(htmlGzOutput),
+ }
+}
diff --git a/android/packaging.go b/android/packaging.go
index 9065826..e3a0b54 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -38,6 +38,8 @@
// Whether relPathInPackage should be marked as executable or not
executable bool
+
+ effectiveLicenseFiles *Paths
}
// Get file name of installed package
@@ -54,6 +56,17 @@
return p.relPathInPackage
}
+func (p *PackagingSpec) SetRelPathInPackage(relPathInPackage string) {
+ p.relPathInPackage = relPathInPackage
+}
+
+func (p *PackagingSpec) EffectiveLicenseFiles() Paths {
+ if p.effectiveLicenseFiles == nil {
+ return Paths{}
+ }
+ return *p.effectiveLicenseFiles
+}
+
type PackageModule interface {
Module
packagingBase() *PackagingBase
@@ -214,15 +227,9 @@
return m
}
-// See PackageModule.CopyDepsToZip
-func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, zipOut WritablePath) (entries []string) {
- m := p.GatherPackagingSpecs(ctx)
- builder := NewRuleBuilder(pctx, ctx)
-
- dir := PathForModuleOut(ctx, ".zip")
- builder.Command().Text("rm").Flag("-rf").Text(dir.String())
- builder.Command().Text("mkdir").Flag("-p").Text(dir.String())
-
+// CopySpecsToDir is a helper that will add commands to the rule builder to copy the PackagingSpec
+// entries into the specified directory.
+func (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, m map[string]PackagingSpec, dir ModuleOutPath) (entries []string) {
seenDir := make(map[string]bool)
for _, k := range SortedStringKeys(m) {
ps := m[k]
@@ -243,6 +250,19 @@
}
}
+ return entries
+}
+
+// See PackageModule.CopyDepsToZip
+func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, zipOut WritablePath) (entries []string) {
+ m := p.GatherPackagingSpecs(ctx)
+ builder := NewRuleBuilder(pctx, ctx)
+
+ dir := PathForModuleOut(ctx, ".zip")
+ builder.Command().Text("rm").Flag("-rf").Text(dir.String())
+ builder.Command().Text("mkdir").Flag("-p").Text(dir.String())
+ entries = p.CopySpecsToDir(ctx, builder, m, dir)
+
builder.Command().
BuiltTool("soong_zip").
FlagWithOutput("-o ", zipOut).
diff --git a/android/paths.go b/android/paths.go
index 2e378ba..69ab5f7 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -462,6 +462,13 @@
return ret
}
+// PathForGoBinary returns the path to the installed location of a bootstrap_go_binary module.
+func PathForGoBinary(ctx PathContext, goBinary bootstrap.GoBinaryTool) Path {
+ goBinaryInstallDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin", false)
+ rel := Rel(ctx, goBinaryInstallDir.String(), goBinary.InstallPath())
+ return goBinaryInstallDir.Join(ctx, rel)
+}
+
// Expands Paths to a SourceFileProducer or OutputFileProducer module dependency referenced via ":name" or ":name{.tag}" syntax.
// If the dependency is not found, a missingErrorDependency is returned.
// If the module dependency is not a SourceFileProducer or OutputFileProducer, appropriate errors will be returned.
@@ -482,11 +489,8 @@
} else if tag != "" {
return nil, fmt.Errorf("path dependency %q is not an output file producing module", path)
} else if goBinary, ok := module.(bootstrap.GoBinaryTool); ok {
- if rel, err := filepath.Rel(PathForOutput(ctx).String(), goBinary.InstallPath()); err == nil {
- return Paths{PathForOutput(ctx, rel).WithoutRel()}, nil
- } else {
- return nil, fmt.Errorf("cannot find output path for %q: %w", goBinary.InstallPath(), err)
- }
+ goBinaryPath := PathForGoBinary(ctx, goBinary)
+ return Paths{goBinaryPath}, nil
} else if srcProducer, ok := module.(SourceFileProducer); ok {
return srcProducer.Srcs(), nil
} else {
@@ -1571,6 +1575,8 @@
// For example, it is host/<os>-<arch> for host modules, and target/product/<device>/<partition> for device modules.
partitionDir string
+ partition string
+
// makePath indicates whether this path is for Soong (false) or Make (true).
makePath bool
}
@@ -1716,6 +1722,7 @@
basePath: basePath{partionPath, ""},
soongOutDir: ctx.Config().soongOutDir,
partitionDir: partionPath,
+ partition: partition,
makePath: false,
}
@@ -1741,8 +1748,7 @@
}
func InstallPathToOnDevicePath(ctx PathContext, path InstallPath) string {
- rel := Rel(ctx, PathForOutput(ctx, "target", "product", ctx.Config().DeviceName()).String(), path.String())
-
+ rel := Rel(ctx, strings.TrimSuffix(path.PartitionDir(), path.partition), path.String())
return "/" + rel
}
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 6605869..1c6b1c0 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -769,16 +769,25 @@
paths Paths
}
+func checkPathNotNil(path Path) {
+ if path == nil {
+ panic("rule_builder paths cannot be nil")
+ }
+}
+
func (c *RuleBuilderCommand) addInput(path Path) string {
+ checkPathNotNil(path)
c.inputs = append(c.inputs, path)
return c.PathForInput(path)
}
func (c *RuleBuilderCommand) addImplicit(path Path) {
+ checkPathNotNil(path)
c.implicits = append(c.implicits, path)
}
func (c *RuleBuilderCommand) addOrderOnly(path Path) {
+ checkPathNotNil(path)
c.orderOnlys = append(c.orderOnlys, path)
}
@@ -824,10 +833,11 @@
func sboxPathForToolRel(ctx BuilderContext, path Path) string {
// Errors will be handled in RuleBuilder.Build where we have a context to report them
- relOut, isRelOut, _ := maybeRelErr(PathForOutput(ctx, "host", ctx.Config().PrebuiltOS()).String(), path.String())
- if isRelOut {
- // The tool is in the output directory, it will be copied to __SBOX_OUT_DIR__/tools/out
- return filepath.Join(sboxToolsSubDir, "out", relOut)
+ toolDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "", false)
+ relOutSoong, isRelOutSoong, _ := maybeRelErr(toolDir.String(), path.String())
+ if isRelOutSoong {
+ // The tool is in the Soong output directory, it will be copied to __SBOX_OUT_DIR__/tools/out
+ return filepath.Join(sboxToolsSubDir, "out", relOutSoong)
}
// The tool is in the source directory, it will be copied to __SBOX_OUT_DIR__/tools/src
return filepath.Join(sboxToolsSubDir, "src", path.String())
@@ -1004,19 +1014,23 @@
// Tool adds the specified tool path to the command line. The path will be also added to the dependencies returned by
// RuleBuilder.Tools.
func (c *RuleBuilderCommand) Tool(path Path) *RuleBuilderCommand {
+ checkPathNotNil(path)
c.tools = append(c.tools, path)
return c.Text(c.PathForTool(path))
}
// Tool adds the specified tool path to the dependencies returned by RuleBuilder.Tools.
func (c *RuleBuilderCommand) ImplicitTool(path Path) *RuleBuilderCommand {
+ checkPathNotNil(path)
c.tools = append(c.tools, path)
return c
}
// Tool adds the specified tool path to the dependencies returned by RuleBuilder.Tools.
func (c *RuleBuilderCommand) ImplicitTools(paths Paths) *RuleBuilderCommand {
- c.tools = append(c.tools, paths...)
+ for _, path := range paths {
+ c.ImplicitTool(path)
+ }
return c
}
@@ -1093,6 +1107,7 @@
// Validation adds the specified input path to the validation dependencies by
// RuleBuilder.Validations without modifying the command line.
func (c *RuleBuilderCommand) Validation(path Path) *RuleBuilderCommand {
+ checkPathNotNil(path)
c.validations = append(c.validations, path)
return c
}
@@ -1100,13 +1115,16 @@
// Validations adds the specified input paths to the validation dependencies by
// RuleBuilder.Validations without modifying the command line.
func (c *RuleBuilderCommand) Validations(paths Paths) *RuleBuilderCommand {
- c.validations = append(c.validations, paths...)
+ for _, path := range paths {
+ c.Validation(path)
+ }
return c
}
// Output adds the specified output path to the command line. The path will also be added to the outputs returned by
// RuleBuilder.Outputs.
func (c *RuleBuilderCommand) Output(path WritablePath) *RuleBuilderCommand {
+ checkPathNotNil(path)
c.outputs = append(c.outputs, path)
return c.Text(c.PathForOutput(path))
}
@@ -1133,6 +1151,7 @@
// line, and causes RuleBuilder.Build file to set the depfile flag for ninja. If multiple depfiles are added to
// commands in a single RuleBuilder then RuleBuilder.Build will add an extra command to merge the depfiles together.
func (c *RuleBuilderCommand) DepFile(path WritablePath) *RuleBuilderCommand {
+ checkPathNotNil(path)
c.depFiles = append(c.depFiles, path)
return c.Text(c.PathForOutput(path))
}
@@ -1155,6 +1174,7 @@
// will be a symlink instead of a regular file. Does not modify the command
// line.
func (c *RuleBuilderCommand) ImplicitSymlinkOutput(path WritablePath) *RuleBuilderCommand {
+ checkPathNotNil(path)
c.symlinkOutputs = append(c.symlinkOutputs, path)
return c.ImplicitOutput(path)
}
@@ -1172,6 +1192,7 @@
// SymlinkOutput declares the specified path as an output that will be a symlink
// instead of a regular file. Modifies the command line.
func (c *RuleBuilderCommand) SymlinkOutput(path WritablePath) *RuleBuilderCommand {
+ checkPathNotNil(path)
c.symlinkOutputs = append(c.symlinkOutputs, path)
return c.Output(path)
}
diff --git a/android/sdk_version.go b/android/sdk_version.go
index c6c75a3..1813e7e 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -157,7 +157,7 @@
return ctx.Config().AlwaysUsePrebuiltSdks()
} else if !s.ApiLevel.IsPreview() {
// validation check
- if s.Kind != SdkPublic && s.Kind != SdkSystem && s.Kind != SdkTest && s.Kind != SdkModule {
+ if s.Kind != SdkPublic && s.Kind != SdkSystem && s.Kind != SdkTest && s.Kind != SdkModule && s.Kind != SdkSystemServer {
panic(fmt.Errorf("prebuilt SDK is not not available for SdkKind=%q", s.Kind))
return false
}
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index b2f8eaa..0ec9bcb 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -60,7 +60,7 @@
module_type: "test",
config_namespace: "acme",
variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
- bool_variables: ["feature2", "unused_feature"],
+ bool_variables: ["feature2", "unused_feature", "always_true"],
value_variables: ["size", "unused_size"],
properties: ["cflags", "srcs", "defaults"],
}
@@ -148,6 +148,11 @@
cflags: ["DEFAULT_B"],
}
+ test_defaults {
+ name: "foo_defaults_always_true",
+ cflags: ["DEFAULT_ALWAYS_TRUE"],
+ }
+
acme_test {
name: "foo_with_defaults",
cflags: ["-DGENERIC"],
@@ -176,6 +181,15 @@
FEATURE3: {
cflags: ["-DFEATURE3"],
},
+ always_true: {
+ defaults: ["foo_defaults_always_true"],
+ conditions_default: {
+ // verify that conditions_default is skipped if the
+ // soong config variable is true by specifying a
+ // non-existent module in conditions_default
+ defaults: ["//nonexistent:defaults"],
+ }
+ },
},
}
`
@@ -205,6 +219,7 @@
"unused_feature": "true", // unused
"unused_size": "1", // unused
"unused_string_var": "a", // unused
+ "always_true": "true",
},
}),
fooExpectedFlags: []string{
@@ -217,6 +232,7 @@
},
fooDefaultsExpectedFlags: []string{
"DEFAULT_A",
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
"-DSIZE=42",
@@ -227,7 +243,10 @@
{
name: "empty_prop_for_string_var",
preparer: fixtureForVendorVars(map[string]map[string]string{
- "acme": {"board": "soc_c"}}),
+ "acme": {
+ "board": "soc_c",
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -236,6 +255,7 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
@@ -243,7 +263,10 @@
{
name: "unused_string_var",
preparer: fixtureForVendorVars(map[string]map[string]string{
- "acme": {"board": "soc_d"}}),
+ "acme": {
+ "board": "soc_d",
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -253,14 +276,18 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
},
{
- name: "conditions_default",
- preparer: fixtureForVendorVars(map[string]map[string]string{}),
+ name: "conditions_default",
+ preparer: fixtureForVendorVars(map[string]map[string]string{
+ "acme": {
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -270,6 +297,7 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
diff --git a/android/variable.go b/android/variable.go
index c35a323..baa6dfa 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -40,6 +40,7 @@
Platform_sdk_version struct {
Asflags []string
Cflags []string
+ Cmd *string
}
Platform_sdk_version_or_codename struct {
@@ -50,6 +51,10 @@
Cmd *string
}
+ Platform_version_name struct {
+ Base_dir *string
+ }
+
// unbundled_build is a catch-all property to annotate modules that don't build in one or
// more unbundled branches, usually due to dependencies missing from the manifest.
Unbundled_build struct {
@@ -145,6 +150,7 @@
Arc struct {
Cflags []string `android:"arch_variant"`
Exclude_srcs []string `android:"arch_variant"`
+ Header_libs []string `android:"arch_variant"`
Include_dirs []string `android:"arch_variant"`
Shared_libs []string `android:"arch_variant"`
Static_libs []string `android:"arch_variant"`
@@ -413,6 +419,8 @@
SepolicyFreezeTestExtraDirs []string `json:",omitempty"`
SepolicyFreezeTestExtraPrebuiltDirs []string `json:",omitempty"`
+
+ GenerateAidlNdkPlatformBackend bool `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/android_sdk/Android.bp b/android_sdk/Android.bp
new file mode 100644
index 0000000..e686d59
--- /dev/null
+++ b/android_sdk/Android.bp
@@ -0,0 +1,22 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-android-sdk",
+ pkgPath: "android/soong/android_sdk",
+ deps: [
+ "blueprint",
+ "soong",
+ "soong-android",
+ "soong-cc",
+ "soong-cc-config",
+ ],
+ srcs: [
+ "sdk_repo_host.go",
+ ],
+ testSrcs: [
+ "sdk_repo_host_test.go",
+ ],
+ pluginFor: ["soong_build"],
+}
diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go
new file mode 100644
index 0000000..d64eb7a
--- /dev/null
+++ b/android_sdk/sdk_repo_host.go
@@ -0,0 +1,294 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android_sdk
+
+import (
+ "fmt"
+ "io"
+ "path/filepath"
+ "strings"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/pathtools"
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/android"
+ "android/soong/cc/config"
+)
+
+var pctx = android.NewPackageContext("android/soong/android_sdk")
+
+func init() {
+ registerBuildComponents(android.InitRegistrationContext)
+}
+
+func registerBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("android_sdk_repo_host", SdkRepoHostFactory)
+}
+
+type sdkRepoHost struct {
+ android.ModuleBase
+ android.PackagingBase
+
+ properties sdkRepoHostProperties
+
+ outputBaseName string
+ outputFile android.OptionalPath
+}
+
+type remapProperties struct {
+ From string
+ To string
+}
+
+type sdkRepoHostProperties struct {
+ // The top level directory to use for the SDK repo.
+ Base_dir *string
+
+ // List of src:dst mappings to rename files from `deps`.
+ Deps_remap []remapProperties `android:"arch_variant"`
+
+ // List of zip files to merge into the SDK repo.
+ Merge_zips []string `android:"arch_variant,path"`
+
+ // List of sources to include into the SDK repo. These are usually raw files, filegroups,
+ // or genrules, as most built modules should be referenced via `deps`.
+ Srcs []string `android:"arch_variant,path"`
+
+ // List of files to strip. This should be a list of files, not modules. This happens after
+ // `deps_remap` and `merge_zips` are applied, but before the `base_dir` is added.
+ Strip_files []string `android:"arch_variant"`
+}
+
+// android_sdk_repo_host defines an Android SDK repo containing host tools.
+//
+// This implementation is trying to be a faithful reproduction of how these sdk-repos were produced
+// in the Make system, which may explain some of the oddities (like `strip_files` not being
+// automatic)
+func SdkRepoHostFactory() android.Module {
+ return newSdkRepoHostModule()
+}
+
+func newSdkRepoHostModule() *sdkRepoHost {
+ s := &sdkRepoHost{}
+ s.AddProperties(&s.properties)
+ android.InitPackageModule(s)
+ android.InitAndroidMultiTargetsArchModule(s, android.HostSupported, android.MultilibCommon)
+ return s
+}
+
+type dependencyTag struct {
+ blueprint.BaseDependencyTag
+ android.PackagingItemAlwaysDepTag
+}
+
+// TODO(b/201696252): Evaluate whether licenses should be propagated through this dependency.
+func (d dependencyTag) PropagateLicenses() bool {
+ return false
+}
+
+var depTag = dependencyTag{}
+
+func (s *sdkRepoHost) DepsMutator(ctx android.BottomUpMutatorContext) {
+ s.AddDeps(ctx, depTag)
+}
+
+func (s *sdkRepoHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ dir := android.PathForModuleOut(ctx, "zip")
+ builder := android.NewRuleBuilder(pctx, ctx).
+ Sbox(dir, android.PathForModuleOut(ctx, "out.sbox.textproto")).
+ SandboxInputs()
+
+ // Get files from modules listed in `deps`
+ packageSpecs := s.GatherPackagingSpecs(ctx)
+
+ // Handle `deps_remap` renames
+ err := remapPackageSpecs(packageSpecs, s.properties.Deps_remap)
+ if err != nil {
+ ctx.PropertyErrorf("deps_remap", "%s", err.Error())
+ }
+
+ s.CopySpecsToDir(ctx, builder, packageSpecs, dir)
+
+ // Collect licenses to write into NOTICE.txt
+ noticeMap := map[string]android.Paths{}
+ for path, pkgSpec := range packageSpecs {
+ licenseFiles := pkgSpec.EffectiveLicenseFiles()
+ if len(licenseFiles) > 0 {
+ noticeMap[path] = pkgSpec.EffectiveLicenseFiles()
+ }
+ }
+ notices := android.BuildNotices(ctx, noticeMap)
+ builder.Command().Text("cp").
+ Input(notices.TxtOutput.Path()).
+ Text(filepath.Join(dir.String(), "NOTICE.txt"))
+
+ // Handle `merge_zips` by extracting their contents into our tmpdir
+ for _, zip := range android.PathsForModuleSrc(ctx, s.properties.Merge_zips) {
+ builder.Command().
+ Text("unzip").
+ Flag("-DD").
+ Flag("-q").
+ FlagWithArg("-d ", dir.String()).
+ Input(zip)
+ }
+
+ // Copy files from `srcs` into our tmpdir
+ for _, src := range android.PathsForModuleSrc(ctx, s.properties.Srcs) {
+ builder.Command().
+ Text("cp").Input(src).Flag(dir.Join(ctx, src.Rel()).String())
+ }
+
+ // Handle `strip_files` by calling the necessary strip commands
+ //
+ // Note: this stripping logic was copied over from the old Make implementation
+ // It's not using the same flags as the regular stripping support, nor does it
+ // support the array of per-module stripping options. It would be nice if we
+ // pulled the stripped versions from the CC modules, but that doesn't exist
+ // for host tools today. (And not all the things we strip are CC modules today)
+ if ctx.Darwin() {
+ macStrip := config.MacStripPath(ctx)
+ for _, strip := range s.properties.Strip_files {
+ builder.Command().
+ Text(macStrip).Flag("-x").
+ Flag(dir.Join(ctx, strip).String())
+ }
+ } else {
+ llvmStrip := config.ClangPath(ctx, "bin/llvm-strip")
+ llvmLib := config.ClangPath(ctx, "lib64/libc++.so.1")
+ for _, strip := range s.properties.Strip_files {
+ cmd := builder.Command().Tool(llvmStrip).ImplicitTool(llvmLib)
+ if !ctx.Windows() {
+ cmd.Flag("-x")
+ }
+ cmd.Flag(dir.Join(ctx, strip).String())
+ }
+ }
+
+ // Fix up the line endings of all text files. This also removes executable permissions.
+ builder.Command().
+ Text("find").
+ Flag(dir.String()).
+ Flag("-name '*.aidl' -o -name '*.css' -o -name '*.html' -o -name '*.java'").
+ Flag("-o -name '*.js' -o -name '*.prop' -o -name '*.template'").
+ Flag("-o -name '*.txt' -o -name '*.windows' -o -name '*.xml' -print0").
+ // Using -n 500 for xargs to limit the max number of arguments per call to line_endings
+ // to 500. This avoids line_endings failing with "arguments too long".
+ Text("| xargs -0 -n 500 ").
+ BuiltTool("line_endings").
+ Flag("unix")
+
+ // Exclude some file types (roughly matching sdk.exclude.atree)
+ builder.Command().
+ Text("find").
+ Flag(dir.String()).
+ Flag("'('").
+ Flag("-name '.*' -o -name '*~' -o -name 'Makefile' -o -name 'Android.mk' -o").
+ Flag("-name '.*.swp' -o -name '.DS_Store' -o -name '*.pyc' -o -name 'OWNERS' -o").
+ Flag("-name 'MODULE_LICENSE_*' -o -name '*.ezt' -o -name 'Android.bp'").
+ Flag("')' -print0").
+ Text("| xargs -0 -r rm -rf")
+ builder.Command().
+ Text("find").
+ Flag(dir.String()).
+ Flag("-name '_*' ! -name '__*' -print0").
+ Text("| xargs -0 -r rm -rf")
+
+ if ctx.Windows() {
+ // Fix EOL chars to make window users happy
+ builder.Command().
+ Text("find").
+ Flag(dir.String()).
+ Flag("-maxdepth 2 -name '*.bat' -type f -print0").
+ Text("| xargs -0 -r unix2dos")
+ }
+
+ // Zip up our temporary directory as the sdk-repo
+ outputZipFile := dir.Join(ctx, "output.zip")
+ builder.Command().
+ BuiltTool("soong_zip").
+ FlagWithOutput("-o ", outputZipFile).
+ FlagWithArg("-P ", proptools.StringDefault(s.properties.Base_dir, ".")).
+ FlagWithArg("-C ", dir.String()).
+ FlagWithArg("-D ", dir.String())
+ builder.Command().Text("rm").Flag("-rf").Text(dir.String())
+
+ builder.Build("build_sdk_repo", "Creating sdk-repo-"+s.BaseModuleName())
+
+ osName := ctx.Os().String()
+ if osName == "linux_glibc" {
+ osName = "linux"
+ }
+ name := fmt.Sprintf("sdk-repo-%s-%s", osName, s.BaseModuleName())
+
+ s.outputBaseName = name
+ s.outputFile = android.OptionalPathForPath(outputZipFile)
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "sdk-repo"), name+".zip", outputZipFile)
+}
+
+func (s *sdkRepoHost) AndroidMk() android.AndroidMkData {
+ return android.AndroidMkData{
+ Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+ fmt.Fprintln(w, ".PHONY:", name, "sdk_repo", "sdk-repo-"+name)
+ fmt.Fprintln(w, "sdk_repo", "sdk-repo-"+name+":", strings.Join(s.FilesToInstall().Strings(), " "))
+
+ fmt.Fprintf(w, "$(call dist-for-goals,sdk_repo sdk-repo-%s,%s:%s-$(FILE_NAME_TAG).zip)\n\n", s.BaseModuleName(), s.outputFile.String(), s.outputBaseName)
+ },
+ }
+}
+
+func remapPackageSpecs(specs map[string]android.PackagingSpec, remaps []remapProperties) error {
+ for _, remap := range remaps {
+ for path, spec := range specs {
+ if match, err := pathtools.Match(remap.From, path); err != nil {
+ return fmt.Errorf("Error parsing %q: %v", remap.From, err)
+ } else if match {
+ newPath := remap.To
+ if pathtools.IsGlob(remap.From) {
+ rel, err := filepath.Rel(constantPartOfPattern(remap.From), path)
+ if err != nil {
+ return fmt.Errorf("Error handling %q", path)
+ }
+ newPath = filepath.Join(remap.To, rel)
+ }
+ delete(specs, path)
+ spec.SetRelPathInPackage(newPath)
+ specs[newPath] = spec
+ }
+ }
+ }
+ return nil
+}
+
+func constantPartOfPattern(pattern string) string {
+ ret := ""
+ for pattern != "" {
+ var first string
+ first, pattern = splitFirst(pattern)
+ if pathtools.IsGlob(first) {
+ return ret
+ }
+ ret = filepath.Join(ret, first)
+ }
+ return ret
+}
+
+func splitFirst(path string) (string, string) {
+ i := strings.IndexRune(path, filepath.Separator)
+ if i < 0 {
+ return path, ""
+ }
+ return path[:i], path[i+1:]
+}
diff --git a/android_sdk/sdk_repo_host_test.go b/android_sdk/sdk_repo_host_test.go
new file mode 100644
index 0000000..0688921
--- /dev/null
+++ b/android_sdk/sdk_repo_host_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 android_sdk
+
+import (
+ "fmt"
+ "runtime"
+ "sort"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/cc"
+
+ "github.com/google/blueprint/pathtools"
+)
+
+var fixture = android.GroupFixturePreparers(
+ android.PrepareForIntegrationTestWithAndroid,
+ cc.PrepareForIntegrationTestWithCc,
+ android.FixtureRegisterWithContext(registerBuildComponents),
+)
+
+func TestSdkRepoHostDeps(t *testing.T) {
+ if runtime.GOOS != "linux" {
+ t.Skipf("Skipping sdk_repo_host testing that is only supported on linux not %s", runtime.GOOS)
+ }
+
+ result := fixture.RunTestWithBp(t, `
+ android_sdk_repo_host {
+ name: "platform-tools",
+ }
+ `)
+
+ // produces "sdk-repo-{OS}-platform-tools.zip"
+ result.ModuleForTests("platform-tools", "linux_glibc_common").Output("sdk-repo-linux-platform-tools.zip")
+}
+
+func TestRemapPackageSpecs(t *testing.T) {
+ testcases := []struct {
+ name string
+ input []string
+ remaps []remapProperties
+ output []string
+ err string
+ }{
+ {
+ name: "basic remap",
+ input: []string{"a", "c"},
+ remaps: []remapProperties{
+ {From: "a", To: "b"},
+ },
+ output: []string{"b", "c"},
+ },
+ {
+ name: "non-matching remap",
+ input: []string{"a"},
+ remaps: []remapProperties{
+ {From: "b", To: "c"},
+ },
+ output: []string{"a"},
+ },
+ {
+ name: "glob",
+ input: []string{"bin/d", "liba.so", "libb.so", "lib/c.so"},
+ remaps: []remapProperties{
+ {From: "lib*.so", To: "lib/"},
+ },
+ output: []string{"bin/d", "lib/c.so", "lib/liba.so", "lib/libb.so"},
+ },
+ {
+ name: "bad glob",
+ input: []string{"a"},
+ remaps: []remapProperties{
+ {From: "**", To: "./"},
+ },
+ err: fmt.Sprintf("Error parsing \"**\": %v", pathtools.GlobLastRecursiveErr.Error()),
+ },
+ {
+ name: "globbed dirs",
+ input: []string{"a/b/c"},
+ remaps: []remapProperties{
+ {From: "a/*/c", To: "./"},
+ },
+ output: []string{"b/c"},
+ },
+ }
+
+ for _, test := range testcases {
+ t.Run(test.name, func(t *testing.T) {
+ specs := map[string]android.PackagingSpec{}
+ for _, input := range test.input {
+ spec := android.PackagingSpec{}
+ spec.SetRelPathInPackage(input)
+ specs[input] = spec
+ }
+
+ err := remapPackageSpecs(specs, test.remaps)
+
+ if test.err != "" {
+ android.AssertErrorMessageEquals(t, "", test.err, err)
+ } else {
+ outputs := []string{}
+ for path, spec := range specs {
+ android.AssertStringEquals(t, "path does not match rel path", path, spec.RelPathInPackage())
+ outputs = append(outputs, path)
+ }
+ sort.Strings(outputs)
+ android.AssertArrayString(t, "outputs mismatch", test.output, outputs)
+ }
+ })
+ }
+}
diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go
index 80801b2..f3ad152 100644
--- a/androidmk/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -15,11 +15,12 @@
package androidmk
import (
- mkparser "android/soong/androidmk/parser"
"fmt"
"sort"
"strings"
+ mkparser "android/soong/androidmk/parser"
+
bpparser "github.com/google/blueprint/parser"
)
@@ -128,6 +129,8 @@
"LOCAL_STATIC_LIBRARIES": "static_libs",
"LOCAL_WHOLE_STATIC_LIBRARIES": "whole_static_libs",
"LOCAL_SYSTEM_SHARED_LIBRARIES": "system_shared_libs",
+ "LOCAL_USES_LIBRARIES": "uses_libs",
+ "LOCAL_OPTIONAL_USES_LIBRARIES": "optional_uses_libs",
"LOCAL_ASFLAGS": "asflags",
"LOCAL_CLANG_ASFLAGS": "clang_asflags",
"LOCAL_COMPATIBILITY_SUPPORT_FILES": "data",
@@ -636,6 +639,12 @@
if len(val.Variables) == 1 && varLiteralName(val.Variables[0]) != "" && len(val.Strings) == 2 && val.Strings[0] == "" {
fixed = val.Strings[1]
varname = val.Variables[0].Name.Strings[0]
+ // TARGET_OUT_OPTIONAL_EXECUTABLES puts the artifact in xbin, which is
+ // deprecated. TARGET_OUT_DATA_APPS install location will be handled
+ // automatically by Soong
+ if varname == "TARGET_OUT_OPTIONAL_EXECUTABLES" || varname == "TARGET_OUT_DATA_APPS" {
+ return nil
+ }
} else if len(val.Variables) == 2 && varLiteralName(val.Variables[0]) == "PRODUCT_OUT" && varLiteralName(val.Variables[1]) == "TARGET_COPY_OUT_VENDOR" &&
len(val.Strings) == 3 && val.Strings[0] == "" && val.Strings[1] == "/" {
fixed = val.Strings[2]
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index 02ab89d..775a9a8 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -1479,6 +1479,60 @@
}
`,
},
+ {
+ desc: "LOCAL_USES_LIBRARIES",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_USES_LIBRARIES := foo.test bar.test baz.test
+include $(BUILD_PACKAGE)
+`,
+ expected: `
+android_app {
+ name: "foo",
+ uses_libs: [
+ "foo.test",
+ "bar.test",
+ "baz.test",
+ ],
+}
+`,
+ },
+ {
+ desc: "LOCAL_OPTIONAL_USES_LIBRARIES",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_OPTIONAL_USES_LIBRARIES := foo.test bar.test baz.test
+include $(BUILD_PACKAGE)
+`,
+ expected: `
+android_app {
+ name: "foo",
+ optional_uses_libs: [
+ "foo.test",
+ "bar.test",
+ "baz.test",
+ ],
+}
+`,
+ }, {
+ desc: "Obsolete LOCAL_MODULE_PATH",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_CTS_TEST_PACKAGE := bar
+LOCAL_USE_AAPT2 := blah
+include $(BUILD_PACKAGE)
+`,
+ expected: `
+android_app {
+ name: "foo",
+
+}
+`},
}
func TestEndToEnd(t *testing.T) {
diff --git a/apex/apex.go b/apex/apex.go
index 5294b6c..33188cb 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -141,11 +141,6 @@
// Default: true.
Compressible *bool
- // For native libraries and binaries, use the vendor variant instead of the core (platform)
- // variant. Default is false. DO NOT use this for APEXes that are installed to the system or
- // system_ext partition.
- Use_vendor *bool
-
// If set true, VNDK libs are considered as stable libs and are not included in this APEX.
// Should be only used in non-system apexes (e.g. vendor: true). Default is false.
Use_vndk_as_stable *bool
@@ -163,8 +158,8 @@
// is 'image'.
Payload_type *string
- // The type of filesystem to use when the payload_type is 'image'. Either 'ext4' or 'f2fs'.
- // Default 'ext4'.
+ // The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
+ // or 'erofs'. Default 'ext4'.
Payload_fs_type *string
// For telling the APEX to ignore special handling for system libraries such as bionic.
@@ -183,6 +178,10 @@
// used in tests.
Test_only_force_compression *bool
+ // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
+ // with the tool to sign payload contents.
+ Custom_sign_tool *string
+
// Canonical name of this APEX bundle. Used to determine the path to the
// activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
// apex mutator variations. For override_apex modules, this is the name of the
@@ -353,7 +352,6 @@
// Flags for special variants of APEX
testApex bool
vndkApex bool
- artApex bool
// Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
// one gets installed to the device.
@@ -654,10 +652,7 @@
var prefix string
var vndkVersion string
if deviceConfig.VndkVersion() != "" {
- if proptools.Bool(a.properties.Use_vendor) {
- prefix = cc.VendorVariationPrefix
- vndkVersion = deviceConfig.PlatformVndkVersion()
- } else if a.SocSpecific() || a.DeviceSpecific() {
+ if a.SocSpecific() || a.DeviceSpecific() {
prefix = cc.VendorVariationPrefix
vndkVersion = deviceConfig.VndkVersion()
} else if a.ProductSpecific() {
@@ -676,9 +671,6 @@
}
func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
- // TODO(jiyong): move this kind of checks to GenerateAndroidBuildActions?
- checkUseVendorProperty(ctx, a)
-
// apexBundle is a multi-arch targets module. Arch variant of apexBundle is set to 'common'.
// arch-specific targets are enabled by the compile_multilib setting of the apex bundle. For
// each target os/architectures, appropriate dependencies are selected by their
@@ -765,13 +757,6 @@
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
- if a.artApex {
- // With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library.
- if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- ctx.AddFarVariationDependencies(commonVariation, javaLibTag, "jacocoagent")
- }
- }
-
// Marks that this APEX (in fact all the modules in it) has to be built with the given SDKs.
// This field currently isn't used.
// TODO(jiyong): consider dropping this feature
@@ -1162,8 +1147,9 @@
zipApexType = "zip"
flattenedApexType = "flattened"
- ext4FsType = "ext4"
- f2fsFsType = "f2fs"
+ ext4FsType = "ext4"
+ f2fsFsType = "f2fs"
+ erofsFsType = "erofs"
)
// The suffix for the output "file", not the module
@@ -1240,42 +1226,6 @@
}
}
-// checkUseVendorProperty checks if the use of `use_vendor` property is allowed for the given APEX.
-// When use_vendor is used, native modules are built with __ANDROID_VNDK__ and __ANDROID_APEX__,
-// which may cause compatibility issues. (e.g. libbinder) Even though libbinder restricts its
-// availability via 'apex_available' property and relies on yet another macro
-// __ANDROID_APEX_<NAME>__, we restrict usage of "use_vendor:" from other APEX modules to avoid
-// similar problems.
-func checkUseVendorProperty(ctx android.BottomUpMutatorContext, a *apexBundle) {
- if proptools.Bool(a.properties.Use_vendor) && !android.InList(a.Name(), useVendorAllowList(ctx.Config())) {
- ctx.PropertyErrorf("use_vendor", "not allowed to set use_vendor: true")
- }
-}
-
-var (
- useVendorAllowListKey = android.NewOnceKey("useVendorAllowList")
-)
-
-func useVendorAllowList(config android.Config) []string {
- return config.Once(useVendorAllowListKey, func() interface{} {
- return []string{
- // swcodec uses "vendor" variants for smaller size
- "com.android.media.swcodec",
- "test_com.android.media.swcodec",
- }
- }).([]string)
-}
-
-// setUseVendorAllowListForTest returns a FixturePreparer that overrides useVendorAllowList and
-// must be called before the first call to useVendorAllowList()
-func setUseVendorAllowListForTest(allowList []string) android.FixturePreparer {
- return android.FixtureModifyConfig(func(config android.Config) {
- config.Once(useVendorAllowListKey, func() interface{} {
- return allowList
- })
- })
-}
-
var _ android.DepIsInSameApex = (*apexBundle)(nil)
// Implements android.DepInInSameApex
@@ -1508,12 +1458,7 @@
func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
dirInApex := "bin"
- s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath())
- if err != nil {
- ctx.ModuleErrorf("Unable to use compiled binary at %s", gb.InstallPath())
- return apexFile{}
- }
- fileToCopy := android.PathForOutput(ctx, s)
+ fileToCopy := android.PathForGoBinary(ctx, gb)
// NB: Since go binaries are static we don't need the module for anything here, which is
// good since the go tool is a blueprint.Module not an android.Module like we would
// normally use.
@@ -1672,6 +1617,7 @@
const (
ext4 fsType = iota
f2fs
+ erofs
)
func (f fsType) string() string {
@@ -1680,6 +1626,8 @@
return ext4FsType
case f2fs:
return f2fsFsType
+ case erofs:
+ return erofsFsType
default:
panic(fmt.Errorf("unknown APEX payload type %d", f))
}
@@ -1726,6 +1674,9 @@
if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
return false
}
+ if mod, ok := child.(android.Module); ok && !mod.Enabled() {
+ return false
+ }
depName := ctx.OtherModuleName(child)
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
switch depTag {
@@ -1928,13 +1879,7 @@
// system libraries.
if !am.DirectlyInAnyApex() {
// we need a module name for Make
- name := cc.ImplementationModuleNameForMake(ctx)
-
- if !proptools.Bool(a.properties.Use_vendor) {
- // we don't use subName(.vendor) for a "use_vendor: true" apex
- // which is supposed to be installed in /system
- name += cc.Properties.SubName
- }
+ name := cc.ImplementationModuleNameForMake(ctx) + cc.Properties.SubName
if !android.InList(name, a.requiredDeps) {
a.requiredDeps = append(a.requiredDeps, name)
}
@@ -2109,8 +2054,10 @@
a.payloadFsType = ext4
case f2fsFsType:
a.payloadFsType = f2fs
+ case erofsFsType:
+ a.payloadFsType = erofs
default:
- ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs]", *a.properties.Payload_fs_type)
+ ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type)
}
// Optimization. If we are building bundled APEX, for the files that are gathered due to the
@@ -2118,7 +2065,7 @@
// the same library in the system partition, thus effectively sharing the same libraries
// across the APEX boundary. For unbundled APEX, all the gathered files are actually placed
// in the APEX.
- a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable() && !proptools.Bool(a.properties.Use_vendor)
+ a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable()
// APEXes targeting other than system/system_ext partitions use vendor/product variants.
// So we can't link them to /system/lib libs which are core variants.
@@ -2247,10 +2194,9 @@
return module
}
-func ApexBundleFactory(testApex bool, artApex bool) android.Module {
+func ApexBundleFactory(testApex bool) android.Module {
bundle := newApexBundle()
bundle.testApex = testApex
- bundle.artApex = artApex
return bundle
}
@@ -2327,10 +2273,6 @@
if a.testApex || a.vndkApex {
return
}
- // Meaningless to check min_sdk_version when building use_vendor modules against non-Trebleized targets
- if proptools.Bool(a.properties.Use_vendor) && ctx.DeviceConfig().VndkVersion() == "" {
- return
- }
// apexBundle::minSdkVersion reports its own errors.
minSdkVersion := a.minSdkVersion(ctx)
android.CheckMinSdkVersion(a, ctx, minSdkVersion)
@@ -2950,7 +2892,6 @@
"libstagefright_amrwbdec",
"libstagefright_amrwbenc",
"libstagefright_bufferpool@2.0.1",
- "libstagefright_bufferqueue_helper",
"libstagefright_enc_common",
"libstagefright_flacdec",
"libstagefright_foundation",
@@ -3325,5 +3266,5 @@
Bzl_load_location: "//build/bazel/rules:apex.bzl",
}
- ctx.CreateBazelTargetModule(module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
}
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index 9178431..6faed70 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -17,9 +17,9 @@
package apex
import (
- "android/soong/android"
-
"github.com/google/blueprint"
+
+ "android/soong/android"
)
func init() {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 420489e..8aaa31a 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -1509,7 +1509,6 @@
apex {
name: "myapex",
key: "myapex.key",
- use_vendor: true,
native_shared_libs: ["mylib"],
updatable: false,
`+tc.minSdkVersion+`
@@ -1543,7 +1542,6 @@
}
}
`,
- setUseVendorAllowListForTest([]string{"myapex"}),
withUnbundledBuild,
)
@@ -1557,13 +1555,13 @@
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_vendor.29_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"]
- ensureContains(t, mylibLdFlags, "libbar/android_vendor.29_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"]
+ ensureContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
for _, ver := range tc.shouldNotLink {
- ensureNotContains(t, mylibLdFlags, "libbar/android_vendor.29_arm64_armv8-a_shared_"+ver+"/libbar.so")
+ ensureNotContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+ver+"/libbar.so")
}
- mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.29_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]
+ mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]
ver := tc.shouldLink
if tc.shouldLink == "current" {
ver = strconv.Itoa(android.FutureApiLevelInt)
@@ -2657,119 +2655,6 @@
})
}
-func TestUseVendor(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- use_vendor: true,
- updatable: false,
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib2"],
- system_shared_libs: [],
- vendor_available: true,
- stl: "none",
- apex_available: [ "myapex" ],
- }
-
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- vendor_available: true,
- stl: "none",
- apex_available: [ "myapex" ],
- }
- `,
- setUseVendorAllowListForTest([]string{"myapex"}),
- )
-
- inputsList := []string{}
- for _, i := range ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().BuildParamsForTests() {
- for _, implicit := range i.Implicits {
- inputsList = append(inputsList, implicit.String())
- }
- }
- inputsString := strings.Join(inputsList, " ")
-
- // ensure that the apex includes vendor variants of the direct and indirect deps
- ensureContains(t, inputsString, "android_vendor.29_arm64_armv8-a_shared_apex10000/mylib.so")
- ensureContains(t, inputsString, "android_vendor.29_arm64_armv8-a_shared_apex10000/mylib2.so")
-
- // ensure that the apex does not include core variants
- ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_apex10000/mylib.so")
- ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_apex10000/mylib2.so")
-}
-
-func TestUseVendorNotAllowedForSystemApexes(t *testing.T) {
- testApexError(t, `module "myapex" .*: use_vendor: not allowed`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- use_vendor: true,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `,
- setUseVendorAllowListForTest([]string{""}),
- )
- // no error with allow list
- testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- use_vendor: true,
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `,
- setUseVendorAllowListForTest([]string{"myapex"}),
- )
-}
-
-func TestUseVendorFailsIfNotVendorAvailable(t *testing.T) {
- testApexError(t, `dependency "mylib" of "myapex" missing variant:\n.*image:vendor`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- use_vendor: true,
- updatable: false,
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- }
- `)
-}
-
func TestVendorApex(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -2944,41 +2829,6 @@
}
}
-func TestAndroidMk_UseVendorRequired(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- use_vendor: true,
- native_shared_libs: ["mylib"],
- updatable: false,
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "mylib",
- vendor_available: true,
- apex_available: ["myapex"],
- }
- `,
- setUseVendorAllowListForTest([]string{"myapex"}),
- )
-
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- name := apexBundle.BaseModuleName()
- prefix := "TARGET_"
- var builder strings.Builder
- data.Custom(&builder, name, prefix, "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += libc libm libdl\n")
-}
-
func TestAndroidMk_VendorApexRequired(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -3333,7 +3183,6 @@
"myapex",
"otherapex",
],
- use_apex_name_macro: true,
recovery_available: true,
min_sdk_version: "29",
}
@@ -3348,13 +3197,11 @@
mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=10000")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=29")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
// When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and
// each variant defines additional macros to distinguish which apex variant it is built for
@@ -3363,42 +3210,15 @@
mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- // APEX variant has __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
-
- // APEX variant has __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
-
// recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__
mylibCFlags = ctx.ModuleForTests("mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__")
- // When a dependency of a cc_library sets use_apex_name_macro: true each apex gets a unique
- // variant.
-
// non-APEX variant does not have __ANDROID_APEX__ defined
mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- // APEX variant has __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
-
- // APEX variant has __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static_otherapex").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
-
// recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__
mylibCFlags = ctx.ModuleForTests("mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
@@ -5058,8 +4878,9 @@
annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
metadata: "my-bootclasspath-fragment/metadata.csv",
index: "my-bootclasspath-fragment/index.csv",
- stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
- all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
+ filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
+ filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
},
}
@@ -5109,8 +4930,9 @@
annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
metadata: "my-bootclasspath-fragment/metadata.csv",
index: "my-bootclasspath-fragment/index.csv",
- stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
- all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
+ filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
+ filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
},
}
@@ -5238,8 +5060,9 @@
annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
metadata: "my-bootclasspath-fragment/metadata.csv",
index: "my-bootclasspath-fragment/index.csv",
- stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
- all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
+ filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
+ filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
},
}
@@ -5324,8 +5147,9 @@
annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
metadata: "my-bootclasspath-fragment/metadata.csv",
index: "my-bootclasspath-fragment/index.csv",
- stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
- all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
+ filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
+ filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
},
}
@@ -5408,8 +5232,9 @@
annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
metadata: "my-bootclasspath-fragment/metadata.csv",
index: "my-bootclasspath-fragment/index.csv",
- stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
- all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
+ filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
+ filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
},
}
@@ -7441,8 +7266,9 @@
annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
metadata: "my-bootclasspath-fragment/metadata.csv",
index: "my-bootclasspath-fragment/index.csv",
- stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
- all_flags: "my-bootclasspath-fragment/all-flags.csv",
+ signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
+ filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
+ filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
},
}
@@ -7857,6 +7683,28 @@
name: "myapex",
key: "myapex.key",
updatable: false,
+ custom_sign_tool: "sign_myapex",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `)
+
+ apexKeysText := ctx.SingletonForTests("apex_keys_text")
+ content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"]
+ ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system_ext" sign_tool="sign_myapex"`)
+}
+
+func TestApexKeysTxtOverrides(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: false,
+ custom_sign_tool: "sign_myapex",
}
apex_key {
@@ -8433,6 +8281,75 @@
`)
}
+func TestAndroidMk_DexpreoptBuiltInstalledForApex(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: false,
+ java_libs: ["foo"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["foo.java"],
+ apex_available: ["myapex"],
+ installable: true,
+ }
+ `,
+ dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
+ )
+
+ apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+ data := android.AndroidMkDataForTest(t, ctx, apexBundle)
+ var builder strings.Builder
+ data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
+ androidMk := builder.String()
+ ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex")
+}
+
+func TestAndroidMk_DexpreoptBuiltInstalledForApex_Prebuilt(t *testing.T) {
+ ctx := testApex(t, `
+ prebuilt_apex {
+ name: "myapex",
+ arch: {
+ arm64: {
+ src: "myapex-arm64.apex",
+ },
+ arm: {
+ src: "myapex-arm.apex",
+ },
+ },
+ exported_java_libs: ["foo"],
+ }
+
+ java_import {
+ name: "foo",
+ jars: ["foo.jar"],
+ installable: true,
+ }
+ `,
+ dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
+ )
+
+ prebuilt := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*Prebuilt)
+ entriesList := android.AndroidMkEntriesForTest(t, ctx, prebuilt)
+ mainModuleEntries := entriesList[0]
+ android.AssertArrayString(t,
+ "LOCAL_REQUIRED_MODULES",
+ mainModuleEntries.EntryMap["LOCAL_REQUIRED_MODULES"],
+ []string{
+ "foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex",
+ "foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex",
+ })
+}
+
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
diff --git a/apex/builder.go b/apex/builder.go
index 38e99d2..e22d694 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -65,6 +65,7 @@
pctx.HostBinToolVariable("extract_apks", "extract_apks")
pctx.HostBinToolVariable("make_f2fs", "make_f2fs")
pctx.HostBinToolVariable("sload_f2fs", "sload_f2fs")
+ pctx.HostBinToolVariable("make_erofs", "make_erofs")
pctx.HostBinToolVariable("apex_compression_tool", "apex_compression_tool")
pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh")
}
@@ -120,7 +121,7 @@
`--payload_type image ` +
`--key ${key} ${opt_flags} ${image_dir} ${out} `,
CommandDeps: []string{"${apexer}", "${avbtool}", "${e2fsdroid}", "${merge_zips}",
- "${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}", "${sload_f2fs}",
+ "${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}", "${sload_f2fs}", "${make_erofs}",
"${soong_zip}", "${zipalign}", "${aapt2}", "prebuilts/sdk/current/public/android.jar"},
Rspfile: "${out}.copy_commands",
RspfileContent: "${copy_commands}",
@@ -523,7 +524,7 @@
}
unsignedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix+".unsigned")
- outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
+ outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
// Figure out if need to compress apex.
@@ -715,12 +716,10 @@
}
}
apisBackedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_backing.txt")
- ndkLibraryList := android.PathForSource(ctx, "system/core/rootdir/etc/public.libraries.android.txt")
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
Tool(android.PathForSource(ctx, "build/soong/scripts/gen_ndk_backedby_apex.sh")).
Output(apisBackedbyOutputFile).
- Input(ndkLibraryList).
Flags(libNames)
rule.Build("ndk_backedby_list", "Generate API libraries backed by Apex")
a.apisBackedByModuleFile = apisBackedbyOutputFile
@@ -824,10 +823,8 @@
a.outputFile = signedCompressedOutputFile
}
- // Install to $OUT/soong/{target,host}/.../apex
- if a.installable() {
- ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
- }
+ // Install to $OUT/soong/{target,host}/.../apex.
+ ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
// installed-files.txt is dist'ed
a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
diff --git a/apex/key.go b/apex/key.go
index 468bb8a..259060f 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -123,13 +123,18 @@
containerCertificate string
containerPrivateKey string
partition string
+ signTool string
}
toString := func(e apexKeyEntry) string {
- format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q\n"
+ signTool := ""
+ if e.signTool != "" {
+ signTool = fmt.Sprintf(" sign_tool=%q", e.signTool)
+ }
+ format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q%s\n"
if e.presigned {
- return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition)
+ return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition, signTool)
} else {
- return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition)
+ return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition, signTool)
}
}
@@ -145,6 +150,7 @@
containerCertificate: pem.String(),
containerPrivateKey: key.String(),
partition: m.PartitionTag(ctx.DeviceConfig()),
+ signTool: proptools.String(m.properties.Custom_sign_tool),
}
}
})
@@ -240,5 +246,5 @@
Bzl_load_location: "//build/bazel/rules:apex_key.bzl",
}
- ctx.CreateBazelTargetModule(module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
}
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index d8a4a7a..06c39ee 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -168,6 +168,76 @@
android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
}
+// TestPlatformBootclasspath_LegacyPrebuiltFragment verifies that the
+// prebuilt_bootclasspath_fragment falls back to using the complete stub-flags/all-flags if the
+// filtered files are not provided.
+//
+// TODO: Remove once all prebuilts use the filtered_... properties.
+func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ java.FixtureConfigureApexBootJars("myapex:foo"),
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ ).RunTestWithBp(t, `
+ prebuilt_apex {
+ name: "myapex",
+ src: "myapex.apex",
+ exported_bootclasspath_fragments: ["mybootclasspath-fragment"],
+ }
+
+ // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
+ // because AlwaysUsePrebuiltSdks() is true.
+ java_sdk_library_import {
+ name: "foo",
+ prefer: false,
+ shared_library: false,
+ permitted_packages: ["foo"],
+ public: {
+ jars: ["sdk_library/public/foo-stubs.jar"],
+ stub_srcs: ["sdk_library/public/foo_stub_sources"],
+ current_api: "sdk_library/public/foo.txt",
+ removed_api: "sdk_library/public/foo-removed.txt",
+ sdk_version: "current",
+ },
+ apex_available: ["myapex"],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "mybootclasspath-fragment",
+ apex_available: [
+ "myapex",
+ ],
+ contents: [
+ "foo",
+ ],
+ hidden_api: {
+ stub_flags: "prebuilt-stub-flags.csv",
+ annotation_flags: "prebuilt-annotation-flags.csv",
+ metadata: "prebuilt-metadata.csv",
+ index: "prebuilt-index.csv",
+ all_flags: "prebuilt-all-flags.csv",
+ },
+ }
+
+ platform_bootclasspath {
+ name: "myplatform-bootclasspath",
+ fragments: [
+ {
+ apex: "myapex",
+ module:"mybootclasspath-fragment",
+ },
+ ],
+ }
+`,
+ )
+
+ pbcp := result.Module("myplatform-bootclasspath", "android_common")
+ info := result.ModuleProvider(pbcp, java.MonolithicHiddenAPIInfoProvider).(java.MonolithicHiddenAPIInfo)
+
+ android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
+ android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
+}
+
func TestPlatformBootclasspathDependencies(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index d59f8bf..61e7a0b 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -22,7 +22,6 @@
"android/soong/android"
"android/soong/java"
-
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -103,6 +102,10 @@
// List of bootclasspath fragments inside this prebuilt APEX bundle and for which this APEX
// bundle will create an APEX variant.
Exported_bootclasspath_fragments []string
+
+ // List of systemserverclasspath fragments inside this prebuilt APEX bundle and for which this
+ // APEX bundle will create an APEX variant.
+ Exported_systemserverclasspath_fragments []string
}
// initPrebuiltCommon initializes the prebuiltCommon structure and performs initialization of the
@@ -134,10 +137,6 @@
// to build the prebuilts themselves.
forceDisable = forceDisable || ctx.Config().UnbundledBuild()
- // Force disable the prebuilts when coverage is enabled.
- forceDisable = forceDisable || ctx.DeviceConfig().NativeCoverageEnabled()
- forceDisable = forceDisable || ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
-
// b/137216042 don't use prebuilts when address sanitizer is on, unless the prebuilt has a sanitized source
sanitized := ctx.Module().(sanitizedPrebuilt)
forceDisable = forceDisable || (android.InList("address", ctx.Config().SanitizeDevice()) && !sanitized.hasSanitizedSource("address"))
@@ -174,7 +173,8 @@
tag := ctx.OtherModuleDependencyTag(child)
name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
- if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
+ if java.IsBootclasspathFragmentContentDepTag(tag) ||
+ java.IsSystemServerClasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
// If the exported java module provides a dex jar path then add it to the list of apexFiles.
path := child.(interface {
DexJarBuildPath() java.OptionalDexJarPath
@@ -194,8 +194,9 @@
}
p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
}
- } else if tag == exportedBootclasspathFragmentTag {
- // Visit the children of the bootclasspath_fragment.
+ } else if tag == exportedBootclasspathFragmentTag ||
+ tag == exportedSystemserverclasspathFragmentTag {
+ // Visit the children of the bootclasspath_fragment and systemserver_fragment.
return true
}
@@ -263,17 +264,6 @@
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
// we will have foo.jar.jar
entries.SetString("LOCAL_MODULE_STEM", strings.TrimSuffix(fi.stem(), ".jar"))
- var classesJar android.Path
- var headerJar android.Path
- if javaModule, ok := fi.module.(java.ApexDependency); ok {
- classesJar = javaModule.ImplementationAndResourcesJars()[0]
- headerJar = javaModule.HeaderJars()[0]
- } else {
- classesJar = fi.builtFile
- headerJar = fi.builtFile
- }
- entries.SetString("LOCAL_SOONG_CLASSES_JAR", classesJar.String())
- entries.SetString("LOCAL_SOONG_HEADER_JAR", headerJar.String())
entries.SetString("LOCAL_SOONG_DEX_JAR", fi.builtFile.String())
entries.SetString("LOCAL_DEX_PREOPT", "false")
},
@@ -311,21 +301,31 @@
}
}
+func (p *prebuiltCommon) getExportedDependencies() map[string]exportedDependencyTag {
+ dependencies := make(map[string]exportedDependencyTag)
+
+ for _, dep := range p.prebuiltCommonProperties.Exported_java_libs {
+ dependencies[dep] = exportedJavaLibTag
+ }
+
+ for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments {
+ dependencies[dep] = exportedBootclasspathFragmentTag
+ }
+
+ for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments {
+ dependencies[dep] = exportedSystemserverclasspathFragmentTag
+ }
+
+ return dependencies
+}
+
// prebuiltApexContentsDeps adds dependencies onto the prebuilt apex module's contents.
func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorContext) {
module := ctx.Module()
- // Add dependencies onto the java modules that represent the java libraries that are provided by
- // and exported from this prebuilt apex.
- for _, exported := range p.prebuiltCommonProperties.Exported_java_libs {
- dep := android.PrebuiltNameFromSource(exported)
- ctx.AddDependency(module, exportedJavaLibTag, dep)
- }
- // Add dependencies onto the bootclasspath fragment modules that are exported from this prebuilt
- // apex.
- for _, exported := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments {
- dep := android.PrebuiltNameFromSource(exported)
- ctx.AddDependency(module, exportedBootclasspathFragmentTag, dep)
+ for dep, tag := range p.getExportedDependencies() {
+ prebuiltDep := android.PrebuiltNameFromSource(dep)
+ ctx.AddDependency(module, tag, prebuiltDep)
}
}
@@ -576,9 +576,9 @@
// A deapexer module is only needed when the prebuilt apex specifies one or more modules in either
// the `exported_java_libs` or `exported_bootclasspath_fragments` properties as that indicates that
// the listed modules need access to files from within the prebuilt .apex file.
-func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string, properties *PrebuiltCommonProperties) {
+func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) {
// Only create the deapexer module if it is needed.
- if len(properties.Exported_java_libs)+len(properties.Exported_bootclasspath_fragments) == 0 {
+ if len(p.getExportedDependencies()) == 0 {
return
}
@@ -674,8 +674,9 @@
var _ android.RequiresFilesFromPrebuiltApexTag = exportedDependencyTag{}
var (
- exportedJavaLibTag = exportedDependencyTag{name: "exported_java_libs"}
- exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
+ exportedJavaLibTag = exportedDependencyTag{name: "exported_java_libs"}
+ exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
+ exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"}
)
var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
@@ -716,7 +717,7 @@
createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
apexFileSource := ":" + apexSelectorModuleName
- createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, p.prebuiltCommonProperties)
+ p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)
// Add a source reference to retrieve the selected apex from the selector module.
p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
@@ -919,7 +920,7 @@
createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
apexFileSource := ":" + apexExtractorModuleName
- createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, a.prebuiltCommonProperties)
+ a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)
// After passing the arch specific src properties to the creating the apex selector module
a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
@@ -968,17 +969,6 @@
for _, overridden := range a.prebuiltCommonProperties.Overrides {
a.compatSymlinks = append(a.compatSymlinks, makeCompatSymlinks(overridden, ctx)...)
}
-
- if ctx.Config().InstallExtraFlattenedApexes() {
- // flattened apex should be in /system_ext/apex
- flattenedApexDir := android.PathForModuleInstall(&systemExtContext{ctx}, "apex", a.BaseModuleName())
- a.postInstallCommands = append(a.postInstallCommands,
- fmt.Sprintf("$(HOST_OUT_EXECUTABLES)/deapexer --debugfs_path $(HOST_OUT_EXECUTABLES)/debugfs extract %s %s",
- a.outputApex.String(),
- flattenedApexDir.ToMakePath().String(),
- ))
- a.hostRequired = []string{"deapexer", "debugfs"}
- }
}
type systemExtContext struct {
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index a8d5931..412fa0e 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -138,7 +138,7 @@
dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
).
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
- `in contents must also be declared in PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS`)).
+ `in contents must also be declared in PRODUCT_APEX_SYSTEM_SERVER_JARS`)).
RunTestWithBp(t, `
apex {
name: "myapex",
@@ -181,3 +181,53 @@
}
`)
}
+
+func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithSystemserverclasspathFragment,
+ prepareForTestWithMyapex,
+ dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
+ ).RunTestWithBp(t, `
+ prebuilt_apex {
+ name: "myapex",
+ arch: {
+ arm64: {
+ src: "myapex-arm64.apex",
+ },
+ arm: {
+ src: "myapex-arm.apex",
+ },
+ },
+ exported_systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+ }
+
+ java_import {
+ name: "foo",
+ jars: ["foo.jar"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ prebuilt_systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ prefer: true,
+ contents: [
+ "foo",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ `)
+
+ java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
+ `myapex.apex.selector`,
+ `prebuilt_mysystemserverclasspathfragment`,
+ })
+
+ java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{
+ `myapex.deapexer`,
+ `prebuilt_foo`,
+ })
+}
diff --git a/bazel/aquery.go b/bazel/aquery.go
index 8741afb..0dedcf4 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -246,7 +246,8 @@
outDir := proptools.ShellEscapeIncludingSpaces(filepath.Dir(out))
out = proptools.ShellEscapeIncludingSpaces(out)
in := proptools.ShellEscapeIncludingSpaces(inputPaths[0])
- buildStatement.Command = fmt.Sprintf("mkdir -p %[1]s && rm -f %[2]s && ln -rsf %[3]s %[2]s", outDir, out, in)
+ // Use hard links, because some soong actions expect real files (for example, `cp -d`).
+ buildStatement.Command = fmt.Sprintf("mkdir -p %[1]s && rm -f %[2]s && ln -f %[3]s %[2]s", outDir, out, in)
buildStatement.SymlinkPaths = outputPaths[:]
} else if len(actionEntry.Arguments) < 1 {
return nil, fmt.Errorf("received action with no command: [%v]", buildStatement)
diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go
index 43e4155..88066c8 100644
--- a/bazel/aquery_test.go
+++ b/bazel/aquery_test.go
@@ -859,7 +859,7 @@
BuildStatement{
Command: "mkdir -p one/symlink_subdir && " +
"rm -f one/symlink_subdir/symlink && " +
- "ln -rsf one/file_subdir/file one/symlink_subdir/symlink",
+ "ln -f one/file_subdir/file one/symlink_subdir/symlink",
InputPaths: []string{"one/file_subdir/file"},
OutputPaths: []string{"one/symlink_subdir/symlink"},
SymlinkPaths: []string{"one/symlink_subdir/symlink"},
@@ -923,7 +923,7 @@
BuildStatement{
Command: "mkdir -p 'one/symlink subdir' && " +
"rm -f 'one/symlink subdir/symlink' && " +
- "ln -rsf 'one/file subdir/file' 'one/symlink subdir/symlink'",
+ "ln -f 'one/file subdir/file' 'one/symlink subdir/symlink'",
InputPaths: []string{"one/file subdir/file"},
OutputPaths: []string{"one/symlink subdir/symlink"},
SymlinkPaths: []string{"one/symlink subdir/symlink"},
diff --git a/bazel/configurability.go b/bazel/configurability.go
index 7aaff9a..e9641e7 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -91,11 +91,6 @@
ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
}
- platformBionicMap = map[string]string{
- "bionic": "//build/bazel/platforms/os:bionic",
- ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
- }
-
platformOsArchMap = map[string]string{
osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm",
osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
@@ -122,7 +117,6 @@
arch
os
osArch
- bionic
productVariables
)
@@ -132,7 +126,6 @@
arch: "arch",
os: "os",
osArch: "arch_os",
- bionic: "bionic",
productVariables: "product_variables",
}[ct]
}
@@ -155,10 +148,6 @@
if _, ok := platformOsArchMap[config]; !ok {
panic(fmt.Errorf("Unknown os+arch: %s", config))
}
- case bionic:
- if _, ok := platformBionicMap[config]; !ok {
- panic(fmt.Errorf("Unknown for %s: %s", ct.String(), config))
- }
case productVariables:
// do nothing
default:
@@ -178,8 +167,6 @@
return platformOsMap[config]
case osArch:
return platformOsArchMap[config]
- case bionic:
- return platformBionicMap[config]
case productVariables:
if config == ConditionsDefaultConfigKey {
return ConditionsDefaultSelectKey
@@ -199,8 +186,6 @@
OsConfigurationAxis = ConfigurationAxis{configurationType: os}
// An axis for arch+os-specific configurations
OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch}
- // An axis for bionic os-specific configurations
- BionicConfigurationAxis = ConfigurationAxis{configurationType: bionic}
)
// ProductVariableConfigurationAxis returns an axis for the given product variable
diff --git a/bazel/properties.go b/bazel/properties.go
index bd8ef0d..6a06c1b 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -164,48 +164,36 @@
// Subtract needle from haystack
func SubtractStrings(haystack []string, needle []string) []string {
// This is really a set
- remainder := make(map[string]bool)
-
- for _, s := range haystack {
- remainder[s] = true
- }
+ needleMap := make(map[string]bool)
for _, s := range needle {
- delete(remainder, s)
+ needleMap[s] = true
}
var strings []string
- for s, _ := range remainder {
- strings = append(strings, s)
+ for _, s := range haystack {
+ if exclude := needleMap[s]; !exclude {
+ strings = append(strings, s)
+ }
}
- sort.SliceStable(strings, func(i, j int) bool {
- return strings[i] < strings[j]
- })
-
return strings
}
// Subtract needle from haystack
func SubtractBazelLabels(haystack []Label, needle []Label) []Label {
// This is really a set
- remainder := make(map[Label]bool)
-
- for _, label := range haystack {
- remainder[label] = true
- }
- for _, label := range needle {
- delete(remainder, label)
+ needleMap := make(map[Label]bool)
+ for _, s := range needle {
+ needleMap[s] = true
}
var labels []Label
- for label, _ := range remainder {
- labels = append(labels, label)
+ for _, label := range haystack {
+ if exclude := needleMap[label]; !exclude {
+ labels = append(labels, label)
+ }
}
- sort.SliceStable(labels, func(i, j int) bool {
- return labels[i].Label < labels[j].Label
- })
-
return labels
}
@@ -264,7 +252,7 @@
switch axis.configurationType {
case noConfig:
la.Value = &value
- case arch, os, osArch, bionic, productVariables:
+ case arch, os, osArch, productVariables:
if la.ConfigurableValues == nil {
la.ConfigurableValues = make(configurableLabels)
}
@@ -280,7 +268,7 @@
switch axis.configurationType {
case noConfig:
return *la.Value
- case arch, os, osArch, bionic, productVariables:
+ case arch, os, osArch, productVariables:
return *la.ConfigurableValues[axis][config]
default:
panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
@@ -337,7 +325,7 @@
switch axis.configurationType {
case noConfig:
ba.Value = value
- case arch, os, osArch, bionic, productVariables:
+ case arch, os, osArch, productVariables:
if ba.ConfigurableValues == nil {
ba.ConfigurableValues = make(configurableBools)
}
@@ -353,7 +341,7 @@
switch axis.configurationType {
case noConfig:
return ba.Value
- case arch, os, osArch, bionic, productVariables:
+ case arch, os, osArch, productVariables:
if v, ok := ba.ConfigurableValues[axis][config]; ok {
return &v
} else {
@@ -459,7 +447,7 @@
switch axis.configurationType {
case noConfig:
lla.Value = list
- case arch, os, osArch, bionic, productVariables:
+ case arch, os, osArch, productVariables:
if lla.ConfigurableValues == nil {
lla.ConfigurableValues = make(configurableLabelLists)
}
@@ -475,7 +463,7 @@
switch axis.configurationType {
case noConfig:
return lla.Value
- case arch, os, osArch, bionic, productVariables:
+ case arch, os, osArch, productVariables:
return lla.ConfigurableValues[axis][config]
default:
panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
@@ -773,7 +761,7 @@
switch axis.configurationType {
case noConfig:
sla.Value = list
- case arch, os, osArch, bionic, productVariables:
+ case arch, os, osArch, productVariables:
if sla.ConfigurableValues == nil {
sla.ConfigurableValues = make(configurableStringLists)
}
@@ -789,7 +777,7 @@
switch axis.configurationType {
case noConfig:
return sla.Value
- case arch, os, osArch, bionic, productVariables:
+ case arch, os, osArch, productVariables:
return sla.ConfigurableValues[axis][config]
default:
panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
diff --git a/bootstrap.bash b/bootstrap.bash
index 4db8539..726692a 100755
--- a/bootstrap.bash
+++ b/bootstrap.bash
@@ -15,9 +15,9 @@
# limitations under the License.
echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
-echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
+echo 'Use `m --soong-only` with a standalone OUT_DIR instead.' >&2
echo 'Without envsetup.sh, use:' >&2
-echo ' build/soong/soong_ui.bash --make-mode --skip-make' >&2
+echo ' build/soong/soong_ui.bash --make-mode --soong-only' >&2
echo '======================================================' >&2
exit 1
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index 45a3cb6..b0c3899 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -15,11 +15,12 @@
package bp2build
import (
- "android/soong/android"
- "android/soong/bazel"
"fmt"
"os"
"strings"
+
+ "android/soong/android"
+ "android/soong/bazel"
)
// Codegen is the backend of bp2build. The code generator is responsible for
@@ -43,7 +44,7 @@
writeFiles(ctx, bp2buildDir, bp2buildFiles)
soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
- writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(res.metrics))
+ writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(ctx.Config(), res.metrics))
return res.metrics
}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 4a0eeea..aa1cf70 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -239,9 +239,7 @@
func propsToAttributes(props map[string]string) string {
var attributes string
for _, propName := range android.SortedStringKeys(props) {
- if shouldGenerateAttribute(propName) {
- attributes += fmt.Sprintf(" %s = %s,\n", propName, props[propName])
- }
+ attributes += fmt.Sprintf(" %s = %s,\n", propName, props[propName])
}
return attributes
}
@@ -411,7 +409,7 @@
TargetPackage() string
BazelRuleClass() string
BazelRuleLoadLocation() string
- BazelAttributes() interface{}
+ BazelAttributes() []interface{}
}
func generateBazelTarget(ctx bpToBuildContext, m bp2buildModule) BazelTarget {
@@ -419,9 +417,11 @@
bzlLoadLocation := m.BazelRuleLoadLocation()
// extract the bazel attributes from the module.
- props := extractModuleProperties([]interface{}{m.BazelAttributes()})
+ attrs := m.BazelAttributes()
+ props := extractModuleProperties(attrs, true)
- delete(props.Attrs, "bp2build_available")
+ // name is handled in a special manner
+ delete(props.Attrs, "name")
// Return the Bazel target with rule class and attributes, ready to be
// code-generated.
@@ -456,6 +456,10 @@
depLabels[qualifiedTargetLabel(ctx, depModule)] = true
})
}
+
+ for p, _ := range ignoredPropNames {
+ delete(props.Attrs, p)
+ }
attributes := propsToAttributes(props.Attrs)
depLabelList := "[\n"
@@ -482,14 +486,14 @@
// TODO: this omits properties for blueprint modules (blueprint_go_binary,
// bootstrap_go_binary, bootstrap_go_package), which will have to be handled separately.
if aModule, ok := m.(android.Module); ok {
- return extractModuleProperties(aModule.GetProperties())
+ return extractModuleProperties(aModule.GetProperties(), false)
}
return BazelAttributes{}
}
// Generically extract module properties and types into a map, keyed by the module property name.
-func extractModuleProperties(props []interface{}) BazelAttributes {
+func extractModuleProperties(props []interface{}, checkForDuplicateProperties bool) BazelAttributes {
ret := map[string]string{}
// Iterate over this android.Module's property structs.
@@ -503,6 +507,11 @@
if isStructPtr(propertiesValue.Type()) {
structValue := propertiesValue.Elem()
for k, v := range extractStructProperties(structValue, 0) {
+ if existing, exists := ret[k]; checkForDuplicateProperties && exists {
+ panic(fmt.Errorf(
+ "%s (%v) is present in properties whereas it should be consolidated into a commonAttributes",
+ k, existing))
+ }
ret[k] = v
}
} else {
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index e904627..ee1d862 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -15,10 +15,12 @@
package bp2build
import (
- "android/soong/android"
"fmt"
"strings"
"testing"
+
+ "android/soong/android"
+ "android/soong/python"
)
func TestGenerateSoongModuleTargets(t *testing.T) {
@@ -221,6 +223,7 @@
func TestGenerateBazelTargetModules(t *testing.T) {
testCases := []bp2buildTestCase{
{
+ description: "string props",
blueprint: `custom {
name: "foo",
string_list_prop: ["a", "b"],
@@ -238,6 +241,7 @@
},
},
{
+ description: "control characters",
blueprint: `custom {
name: "control_characters",
string_list_prop: ["\t", "\n"],
@@ -255,6 +259,7 @@
},
},
{
+ description: "handles dep",
blueprint: `custom {
name: "has_dep",
arch_paths: [":dep"],
@@ -277,25 +282,98 @@
},
},
{
+ description: "arch-variant srcs",
blueprint: `custom {
name: "arch_paths",
arch: {
- x86: {
- arch_paths: ["abc"],
- },
+ x86: { arch_paths: ["x86.txt"] },
+ x86_64: { arch_paths: ["x86_64.txt"] },
+ arm: { arch_paths: ["arm.txt"] },
+ arm64: { arch_paths: ["arm64.txt"] },
+ },
+ target: {
+ linux: { arch_paths: ["linux.txt"] },
+ bionic: { arch_paths: ["bionic.txt"] },
+ host: { arch_paths: ["host.txt"] },
+ not_windows: { arch_paths: ["not_windows.txt"] },
+ android: { arch_paths: ["android.txt"] },
+ linux_musl: { arch_paths: ["linux_musl.txt"] },
+ musl: { arch_paths: ["musl.txt"] },
+ linux_glibc: { arch_paths: ["linux_glibc.txt"] },
+ glibc: { arch_paths: ["glibc.txt"] },
+ linux_bionic: { arch_paths: ["linux_bionic.txt"] },
+ darwin: { arch_paths: ["darwin.txt"] },
+ windows: { arch_paths: ["windows.txt"] },
+ },
+ multilib: {
+ lib32: { arch_paths: ["lib32.txt"] },
+ lib64: { arch_paths: ["lib64.txt"] },
},
bazel_module: { bp2build_available: true },
}`,
expectedBazelTargets: []string{`custom(
name = "arch_paths",
arch_paths = select({
- "//build/bazel/platforms/arch:x86": ["abc"],
+ "//build/bazel/platforms/arch:arm": [
+ "arm.txt",
+ "lib32.txt",
+ ],
+ "//build/bazel/platforms/arch:arm64": [
+ "arm64.txt",
+ "lib64.txt",
+ ],
+ "//build/bazel/platforms/arch:x86": [
+ "x86.txt",
+ "lib32.txt",
+ ],
+ "//build/bazel/platforms/arch:x86_64": [
+ "x86_64.txt",
+ "lib64.txt",
+ ],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": [
+ "linux.txt",
+ "bionic.txt",
+ "android.txt",
+ ],
+ "//build/bazel/platforms/os:darwin": [
+ "host.txt",
+ "darwin.txt",
+ "not_windows.txt",
+ ],
+ "//build/bazel/platforms/os:linux": [
+ "host.txt",
+ "linux.txt",
+ "glibc.txt",
+ "linux_glibc.txt",
+ "not_windows.txt",
+ ],
+ "//build/bazel/platforms/os:linux_bionic": [
+ "host.txt",
+ "linux.txt",
+ "bionic.txt",
+ "linux_bionic.txt",
+ "not_windows.txt",
+ ],
+ "//build/bazel/platforms/os:linux_musl": [
+ "host.txt",
+ "linux.txt",
+ "musl.txt",
+ "linux_musl.txt",
+ "not_windows.txt",
+ ],
+ "//build/bazel/platforms/os:windows": [
+ "host.txt",
+ "windows.txt",
+ ],
"//conditions:default": [],
}),
)`,
},
},
{
+ description: "arch-variant deps",
blueprint: `custom {
name: "has_dep",
arch: {
@@ -325,6 +403,7 @@
},
},
{
+ description: "embedded props",
blueprint: `custom {
name: "embedded_props",
embedded_prop: "abc",
@@ -337,6 +416,7 @@
},
},
{
+ description: "ptr to embedded props",
blueprint: `custom {
name: "ptr_to_embedded_props",
other_embedded_prop: "abc",
@@ -352,38 +432,40 @@
dir := "."
for _, testCase := range testCases {
- config := android.TestConfig(buildDir, nil, testCase.blueprint, nil)
- ctx := android.NewTestContext(config)
+ t.Run(testCase.description, func(t *testing.T) {
+ config := android.TestConfig(buildDir, nil, testCase.blueprint, nil)
+ ctx := android.NewTestContext(config)
- registerCustomModuleForBp2buildConversion(ctx)
+ registerCustomModuleForBp2buildConversion(ctx)
- _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
- if errored(t, testCase, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if errored(t, testCase, errs) {
- continue
- }
+ _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+ if errored(t, testCase, errs) {
+ return
+ }
+ _, errs = ctx.ResolveDependencies(config)
+ if errored(t, testCase, errs) {
+ return
+ }
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
- android.FailIfErrored(t, err)
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
+ android.FailIfErrored(t, err)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
- } else {
- for i, expectedBazelTarget := range testCase.expectedBazelTargets {
- actualBazelTarget := bazelTargets[i]
- if actualBazelTarget.content != expectedBazelTarget {
- t.Errorf(
- "Expected generated Bazel target to be '%s', got '%s'",
- expectedBazelTarget,
- actualBazelTarget.content,
- )
+ if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
+ t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
+ } else {
+ for i, expectedBazelTarget := range testCase.expectedBazelTargets {
+ actualBazelTarget := bazelTargets[i]
+ if actualBazelTarget.content != expectedBazelTarget {
+ t.Errorf(
+ "Expected generated Bazel target to be '%s', got '%s'",
+ expectedBazelTarget,
+ actualBazelTarget.content,
+ )
+ }
}
}
- }
+ })
}
}
@@ -1215,3 +1297,133 @@
}
}
}
+
+func TestCommonBp2BuildModuleAttrs(t *testing.T) {
+ testCases := []bp2buildTestCase{
+ {
+ description: "Required into data test",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ blueprint: `filegroup {
+ name: "reqd",
+}
+
+filegroup {
+ name: "fg_foo",
+ required: ["reqd"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{`filegroup(
+ name = "fg_foo",
+ data = [":reqd"],
+)`,
+ `filegroup(
+ name = "reqd",
+)`,
+ },
+ },
+ {
+ description: "Required via arch into data test",
+ moduleTypeUnderTest: "python_library",
+ moduleTypeUnderTestFactory: python.PythonLibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build,
+ blueprint: `python_library {
+ name: "reqdx86",
+ bazel_module: { bp2build_available: false, },
+}
+
+python_library {
+ name: "reqdarm",
+ bazel_module: { bp2build_available: false, },
+}
+
+python_library {
+ name: "fg_foo",
+ arch: {
+ arm: {
+ required: ["reqdarm"],
+ },
+ x86: {
+ required: ["reqdx86"],
+ },
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{`py_library(
+ name = "fg_foo",
+ data = select({
+ "//build/bazel/platforms/arch:arm": [":reqdarm"],
+ "//build/bazel/platforms/arch:x86": [":reqdx86"],
+ "//conditions:default": [],
+ }),
+ srcs_version = "PY3",
+)`,
+ },
+ },
+ {
+ description: "Required appended to data test",
+ moduleTypeUnderTest: "python_library",
+ moduleTypeUnderTestFactory: python.PythonLibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: python.PythonLibraryBp2Build,
+ blueprint: `python_library {
+ name: "reqd",
+ srcs: ["src.py"],
+}
+
+python_library {
+ name: "fg_foo",
+ data: ["data.bin"],
+ required: ["reqd"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ `py_library(
+ name = "fg_foo",
+ data = [
+ "data.bin",
+ ":reqd",
+ ],
+ srcs_version = "PY3",
+)`,
+ `py_library(
+ name = "reqd",
+ srcs = ["src.py"],
+ srcs_version = "PY3",
+)`,
+ },
+ filesystem: map[string]string{
+ "data.bin": "",
+ "src.py": "",
+ },
+ },
+ {
+ description: "All props-to-attrs at once together test",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ blueprint: `filegroup {
+ name: "reqd"
+}
+filegroup {
+ name: "fg_foo",
+ required: ["reqd"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ `filegroup(
+ name = "fg_foo",
+ data = [":reqd"],
+)`,
+ `filegroup(
+ name = "reqd",
+)`,
+ },
+ filesystem: map[string]string{},
+ },
+ }
+
+ for _, test := range testCases {
+ runBp2BuildTestCaseSimple(t, test)
+ }
+}
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
new file mode 100644
index 0000000..0b71d89
--- /dev/null
+++ b/bp2build/cc_binary_conversion_test.go
@@ -0,0 +1,435 @@
+// 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 (
+ "android/soong/android"
+ "android/soong/cc"
+ "android/soong/genrule"
+ "fmt"
+ "strings"
+ "testing"
+)
+
+const (
+ ccBinaryTypePlaceHolder = "{rule_name}"
+ compatibleWithPlaceHolder = "{target_compatible_with}"
+)
+
+func registerCcBinaryModuleTypes(ctx android.RegistrationContext) {
+ cc.RegisterCCBuildComponents(ctx)
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
+ ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+ ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
+}
+
+var binaryReplacer = strings.NewReplacer(ccBinaryTypePlaceHolder, "cc_binary", compatibleWithPlaceHolder, "")
+var hostBinaryReplacer = strings.NewReplacer(ccBinaryTypePlaceHolder, "cc_binary_host", compatibleWithPlaceHolder, `
+ target_compatible_with = select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ }),`)
+
+func runCcBinaryTests(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runCcBinaryTestCase(t, tc)
+ runCcHostBinaryTestCase(t, tc)
+}
+
+func runCcBinaryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ testCase := tc
+ testCase.expectedBazelTargets = append([]string{}, tc.expectedBazelTargets...)
+ testCase.moduleTypeUnderTest = "cc_binary"
+ testCase.moduleTypeUnderTestFactory = cc.BinaryFactory
+ testCase.moduleTypeUnderTestBp2BuildMutator = cc.BinaryBp2build
+ testCase.description = fmt.Sprintf("%s %s", testCase.moduleTypeUnderTest, testCase.description)
+ testCase.blueprint = binaryReplacer.Replace(testCase.blueprint)
+ for i, et := range testCase.expectedBazelTargets {
+ testCase.expectedBazelTargets[i] = binaryReplacer.Replace(et)
+ }
+ t.Run(testCase.description, func(t *testing.T) {
+ runBp2BuildTestCase(t, registerCcBinaryModuleTypes, testCase)
+ })
+}
+
+func runCcHostBinaryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ testCase := tc
+ testCase.expectedBazelTargets = append([]string{}, tc.expectedBazelTargets...)
+ testCase.moduleTypeUnderTest = "cc_binary_host"
+ testCase.moduleTypeUnderTestFactory = cc.BinaryHostFactory
+ testCase.moduleTypeUnderTestBp2BuildMutator = cc.BinaryHostBp2build
+ testCase.description = fmt.Sprintf("%s %s", testCase.moduleTypeUnderTest, testCase.description)
+ testCase.blueprint = hostBinaryReplacer.Replace(testCase.blueprint)
+ for i, et := range testCase.expectedBazelTargets {
+ testCase.expectedBazelTargets[i] = hostBinaryReplacer.Replace(et)
+ }
+ t.Run(testCase.description, func(t *testing.T) {
+ runBp2BuildTestCase(t, registerCcBinaryModuleTypes, testCase)
+ })
+}
+
+func TestBasicCcBinary(t *testing.T) {
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: "basic -- properties -> attrs with little/no transformation",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ srcs: ["a.cc"],
+ local_include_dirs: ["dir"],
+ include_dirs: ["absolute_dir"],
+ cflags: ["-Dcopt"],
+ cppflags: ["-Dcppflag"],
+ conlyflags: ["-Dconlyflag"],
+ asflags: ["-Dasflag"],
+ ldflags: ["ld-flag"],
+ rtti: true,
+ strip: {
+ all: true,
+ keep_symbols: true,
+ keep_symbols_and_debug_frame: true,
+ keep_symbols_list: ["symbol"],
+ none: true,
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ absolute_includes = ["absolute_dir"],
+ asflags = ["-Dasflag"],
+ conlyflags = ["-Dconlyflag"],
+ copts = ["-Dcopt"],
+ cppflags = ["-Dcppflag"],
+ linkopts = ["ld-flag"],
+ local_includes = [
+ "dir",
+ ".",
+ ],
+ rtti = True,
+ srcs = ["a.cc"],
+ strip = {
+ "all": True,
+ "keep_symbols": True,
+ "keep_symbols_and_debug_frame": True,
+ "keep_symbols_list": ["symbol"],
+ "none": True,
+ },{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinaryWithSharedLdflagDisableFeature(t *testing.T) {
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: `ldflag "-shared" disables static_flag feature`,
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ ldflags: ["-shared"],
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ features = ["-static_flag"],
+ linkopts = ["-shared"],{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinaryWithLinkStatic(t *testing.T) {
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: "link static",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ static_executable: true,
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ linkshared = False,{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinaryVersionScript(t *testing.T) {
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: `version script`,
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ include_build_directory: false,
+ version_script: "vs",
+}
+`,
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ additional_linker_inputs = ["vs"],
+ linkopts = ["-Wl,--version-script,$(location vs)"],{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinarySplitSrcsByLang(t *testing.T) {
+ runCcHostBinaryTestCase(t, bp2buildTestCase{
+ description: "split srcs by lang",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ srcs: [
+ "asonly.S",
+ "conly.c",
+ "cpponly.cpp",
+ ":fg_foo",
+ ],
+ include_build_directory: false,
+}
+` + simpleModuleDoNotConvertBp2build("filegroup", "fg_foo"),
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ srcs = [
+ "cpponly.cpp",
+ ":fg_foo_cpp_srcs",
+ ],
+ srcs_as = [
+ "asonly.S",
+ ":fg_foo_as_srcs",
+ ],
+ srcs_c = [
+ "conly.c",
+ ":fg_foo_c_srcs",
+ ],{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinaryDoNotDistinguishBetweenDepsAndImplementationDeps(t *testing.T) {
+ runCcBinaryTestCase(t, bp2buildTestCase{
+ description: "no implementation deps",
+ blueprint: `
+genrule {
+ name: "generated_hdr",
+ cmd: "nothing to see here",
+}
+
+genrule {
+ name: "export_generated_hdr",
+ cmd: "nothing to see here",
+}
+
+{rule_name} {
+ name: "foo",
+ srcs: ["foo.cpp"],
+ shared_libs: ["implementation_shared_dep", "shared_dep"],
+ export_shared_lib_headers: ["shared_dep"],
+ static_libs: ["implementation_static_dep", "static_dep"],
+ export_static_lib_headers: ["static_dep", "whole_static_dep"],
+ whole_static_libs: ["not_explicitly_exported_whole_static_dep", "whole_static_dep"],
+ include_build_directory: false,
+ generated_headers: ["generated_hdr", "export_generated_hdr"],
+ export_generated_headers: ["export_generated_hdr"],
+}
+` +
+ simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library", "shared_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep"),
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ deps = [
+ ":implementation_static_dep",
+ ":static_dep",
+ ],
+ dynamic_deps = [
+ ":implementation_shared_dep",
+ ":shared_dep",
+ ],
+ srcs = [
+ "foo.cpp",
+ ":generated_hdr",
+ ":export_generated_hdr",
+ ],{target_compatible_with}
+ whole_archive_deps = [
+ ":not_explicitly_exported_whole_static_dep",
+ ":whole_static_dep",
+ ],
+)`},
+ })
+}
+
+func TestCcBinaryNocrtTests(t *testing.T) {
+ baseTestCases := []struct {
+ description string
+ soongProperty string
+ bazelAttr string
+ }{
+ {
+ description: "nocrt: true",
+ soongProperty: `nocrt: true,`,
+ bazelAttr: ` link_crt = False,`,
+ },
+ {
+ description: "nocrt: false",
+ soongProperty: `nocrt: false,`,
+ },
+ {
+ description: "nocrt: not set",
+ },
+ }
+
+ baseBlueprint := `{rule_name} {
+ name: "foo",%s
+ include_build_directory: false,
+}
+`
+
+ baseBazelTarget := `cc_binary(
+ name = "foo",%s{target_compatible_with}
+)`
+
+ for _, btc := range baseTestCases {
+ prop := btc.soongProperty
+ if len(prop) > 0 {
+ prop = "\n" + prop
+ }
+ attr := btc.bazelAttr
+ if len(attr) > 0 {
+ attr = "\n" + attr
+ }
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: btc.description,
+ blueprint: fmt.Sprintf(baseBlueprint, prop),
+ expectedBazelTargets: []string{
+ fmt.Sprintf(baseBazelTarget, attr),
+ },
+ })
+ }
+}
+
+func TestCcBinaryNo_libcrtTests(t *testing.T) {
+ baseTestCases := []struct {
+ description string
+ soongProperty string
+ bazelAttr string
+ }{
+ {
+ description: "no_libcrt: true",
+ soongProperty: `no_libcrt: true,`,
+ bazelAttr: ` use_libcrt = False,`,
+ },
+ {
+ description: "no_libcrt: false",
+ soongProperty: `no_libcrt: false,`,
+ bazelAttr: ` use_libcrt = True,`,
+ },
+ {
+ description: "no_libcrt: not set",
+ },
+ }
+
+ baseBlueprint := `{rule_name} {
+ name: "foo",%s
+ include_build_directory: false,
+}
+`
+
+ baseBazelTarget := `cc_binary(
+ name = "foo",{target_compatible_with}%s
+)`
+
+ for _, btc := range baseTestCases {
+ prop := btc.soongProperty
+ if len(prop) > 0 {
+ prop = "\n" + prop
+ }
+ attr := btc.bazelAttr
+ if len(attr) > 0 {
+ attr = "\n" + attr
+ }
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: btc.description,
+ blueprint: fmt.Sprintf(baseBlueprint, prop),
+ expectedBazelTargets: []string{
+ fmt.Sprintf(baseBazelTarget, attr),
+ },
+ })
+ }
+}
+
+func TestCcBinaryPropertiesToFeatures(t *testing.T) {
+ baseTestCases := []struct {
+ description string
+ soongProperty string
+ bazelAttr string
+ }{
+ {
+ description: "pack_relocation: true",
+ soongProperty: `pack_relocations: true,`,
+ },
+ {
+ description: "pack_relocations: false",
+ soongProperty: `pack_relocations: false,`,
+ bazelAttr: ` features = ["disable_pack_relocations"],`,
+ },
+ {
+ description: "pack_relocations: not set",
+ },
+ {
+ description: "pack_relocation: true",
+ soongProperty: `allow_undefined_symbols: true,`,
+ bazelAttr: ` features = ["-no_undefined_symbols"],`,
+ },
+ {
+ description: "allow_undefined_symbols: false",
+ soongProperty: `allow_undefined_symbols: false,`,
+ },
+ {
+ description: "allow_undefined_symbols: not set",
+ },
+ }
+
+ baseBlueprint := `{rule_name} {
+ name: "foo",%s
+ include_build_directory: false,
+}
+`
+
+ baseBazelTarget := `cc_binary(
+ name = "foo",%s{target_compatible_with}
+)`
+
+ for _, btc := range baseTestCases {
+ prop := btc.soongProperty
+ if len(prop) > 0 {
+ prop = "\n" + prop
+ }
+ attr := btc.bazelAttr
+ if len(attr) > 0 {
+ attr = "\n" + attr
+ }
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: btc.description,
+ blueprint: fmt.Sprintf(baseBlueprint, prop),
+ expectedBazelTargets: []string{
+ fmt.Sprintf(baseBazelTarget, attr),
+ },
+ })
+ }
+}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 5952b15..cbdc167 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -15,6 +15,7 @@
package bp2build
import (
+ "fmt"
"testing"
"android/soong/android"
@@ -131,12 +132,13 @@
"//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
"//conditions:default": [],
}) + select({
- "//build/bazel/platforms/os:android": ["android.cpp"],
+ "//build/bazel/platforms/os:android": [
+ "bionic.cpp",
+ "android.cpp",
+ ],
"//build/bazel/platforms/os:darwin": ["darwin.cpp"],
"//build/bazel/platforms/os:linux": ["linux.cpp"],
- "//conditions:default": [],
- }) + select({
- "//build/bazel/platforms/os:bionic": ["bionic.cpp"],
+ "//build/bazel/platforms/os:linux_bionic": ["bionic.cpp"],
"//conditions:default": [],
}),
)`}})
@@ -801,8 +803,9 @@
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
+ additional_linker_inputs = ["v.map"],
+ linkopts = ["-Wl,--version-script,$(location v.map)"],
srcs = ["a.cpp"],
- version_script = "v.map",
)`},
})
}
@@ -836,12 +839,17 @@
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- srcs = ["a.cpp"],
- version_script = select({
- "//build/bazel/platforms/arch:arm": "arm.map",
- "//build/bazel/platforms/arch:arm64": "arm64.map",
- "//conditions:default": None,
+ additional_linker_inputs = select({
+ "//build/bazel/platforms/arch:arm": ["arm.map"],
+ "//build/bazel/platforms/arch:arm64": ["arm64.map"],
+ "//conditions:default": [],
}),
+ linkopts = select({
+ "//build/bazel/platforms/arch:arm": ["-Wl,--version-script,$(location arm.map)"],
+ "//build/bazel/platforms/arch:arm64": ["-Wl,--version-script,$(location arm64.map)"],
+ "//conditions:default": [],
+ }),
+ srcs = ["a.cpp"],
)`},
})
}
@@ -871,7 +879,7 @@
})
}
-func TestCcLibraryPackRelocations(t *testing.T) {
+func TestCcLibraryFeatures(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library pack_relocations test",
moduleTypeUnderTest: "cc_library",
@@ -882,6 +890,7 @@
name: "a",
srcs: ["a.cpp"],
pack_relocations: false,
+ allow_undefined_symbols: true,
include_build_directory: false,
}
@@ -891,6 +900,7 @@
arch: {
x86_64: {
pack_relocations: false,
+ allow_undefined_symbols: true,
},
},
include_build_directory: false,
@@ -902,25 +912,35 @@
target: {
darwin: {
pack_relocations: false,
+ allow_undefined_symbols: true,
},
},
include_build_directory: false,
}`,
expectedBazelTargets: []string{`cc_library(
name = "a",
- linkopts = ["-Wl,--pack-dyn-relocs=none"],
+ features = [
+ "disable_pack_relocations",
+ "-no_undefined_symbols",
+ ],
srcs = ["a.cpp"],
)`, `cc_library(
name = "b",
- linkopts = select({
- "//build/bazel/platforms/arch:x86_64": ["-Wl,--pack-dyn-relocs=none"],
+ features = select({
+ "//build/bazel/platforms/arch:x86_64": [
+ "disable_pack_relocations",
+ "-no_undefined_symbols",
+ ],
"//conditions:default": [],
}),
srcs = ["b.cpp"],
)`, `cc_library(
name = "c",
- linkopts = select({
- "//build/bazel/platforms/os:darwin": ["-Wl,--pack-dyn-relocs=none"],
+ features = select({
+ "//build/bazel/platforms/os:darwin": [
+ "disable_pack_relocations",
+ "-no_undefined_symbols",
+ ],
"//conditions:default": [],
}),
srcs = ["c.cpp"],
@@ -996,39 +1016,6 @@
})
}
-func TestCcLibraryLabelAttributeGetTargetProperties(t *testing.T) {
- runCcLibraryTestCase(t, bp2buildTestCase{
- description: "cc_library GetTargetProperties on a LabelAttribute",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- blueprint: soongCcLibraryPreamble + `
-cc_library {
- name: "a",
- srcs: ["a.cpp"],
- target: {
- android_arm: {
- version_script: "android_arm.map",
- },
- linux_bionic_arm64: {
- version_script: "linux_bionic_arm64.map",
- },
- },
- include_build_directory: false,
-}
- `,
- expectedBazelTargets: []string{`cc_library(
- name = "a",
- srcs = ["a.cpp"],
- version_script = select({
- "//build/bazel/platforms/os_arch:android_arm": "android_arm.map",
- "//build/bazel/platforms/os_arch:linux_bionic_arm64": "linux_bionic_arm64.map",
- "//conditions:default": None,
- }),
-)`},
- })
-}
-
func TestCcLibraryExcludeLibs(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
moduleTypeUnderTest: "cc_library",
@@ -1141,6 +1128,81 @@
func TestCCLibraryNoCrtTrue(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library - nocrt: true emits attribute",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ nocrt: true,
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ link_crt = False,
+ srcs = ["impl.cpp"],
+)`}})
+}
+
+func TestCCLibraryNoCrtFalse(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library - nocrt: false - does not emit attribute",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ nocrt: false,
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ srcs = ["impl.cpp"],
+)`}})
+}
+
+func TestCCLibraryNoCrtArchVariant(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library - nocrt in select",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ arch: {
+ arm: {
+ nocrt: true,
+ },
+ x86: {
+ nocrt: false,
+ },
+ },
+ include_build_directory: false,
+}
+`,
+ expectedErr: fmt.Errorf("Android.bp:16:1: module \"foo-lib\": nocrt is not supported for arch variants"),
+ })
+}
+
+func TestCCLibraryNoLibCrtTrue(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library - simple example",
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
@@ -1164,7 +1226,7 @@
)`}})
}
-func TestCCLibraryNoCrtFalse(t *testing.T) {
+func TestCCLibraryNoLibCrtFalse(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
@@ -1188,7 +1250,7 @@
)`}})
}
-func TestCCLibraryNoCrtArchVariant(t *testing.T) {
+func TestCCLibraryNoLibCrtArchVariant(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
@@ -1222,41 +1284,6 @@
)`}})
}
-func TestCCLibraryNoCrtArchVariantWithDefault(t *testing.T) {
- runCcLibraryTestCase(t, bp2buildTestCase{
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- filesystem: map[string]string{
- "impl.cpp": "",
- },
- blueprint: soongCcLibraryPreamble + `
-cc_library {
- name: "foo-lib",
- srcs: ["impl.cpp"],
- no_libcrt: false,
- arch: {
- arm: {
- no_libcrt: true,
- },
- x86: {
- no_libcrt: true,
- },
- },
- include_build_directory: false,
-}
-`,
- expectedBazelTargets: []string{`cc_library(
- name = "foo-lib",
- srcs = ["impl.cpp"],
- use_libcrt = select({
- "//build/bazel/platforms/arch:arm": False,
- "//build/bazel/platforms/arch:x86": False,
- "//conditions:default": True,
- }),
-)`}})
-}
-
func TestCcLibraryStrip(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library strip args",
@@ -1571,3 +1598,190 @@
)`},
})
}
+
+func TestCcLibraryOsSelects(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library - selects for all os targets",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryPreamble + `
+cc_library_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["base.cpp"],
+ target: {
+ android: {
+ srcs: ["android.cpp"],
+ },
+ linux: {
+ srcs: ["linux.cpp"],
+ },
+ linux_glibc: {
+ srcs: ["linux_glibc.cpp"],
+ },
+ darwin: {
+ srcs: ["darwin.cpp"],
+ },
+ bionic: {
+ srcs: ["bionic.cpp"],
+ },
+ linux_musl: {
+ srcs: ["linux_musl.cpp"],
+ },
+ windows: {
+ srcs: ["windows.cpp"],
+ },
+ },
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ srcs = ["base.cpp"] + select({
+ "//build/bazel/platforms/os:android": [
+ "linux.cpp",
+ "bionic.cpp",
+ "android.cpp",
+ ],
+ "//build/bazel/platforms/os:darwin": ["darwin.cpp"],
+ "//build/bazel/platforms/os:linux": [
+ "linux.cpp",
+ "linux_glibc.cpp",
+ ],
+ "//build/bazel/platforms/os:linux_bionic": [
+ "linux.cpp",
+ "bionic.cpp",
+ ],
+ "//build/bazel/platforms/os:linux_musl": [
+ "linux.cpp",
+ "linux_musl.cpp",
+ ],
+ "//build/bazel/platforms/os:windows": ["windows.cpp"],
+ "//conditions:default": [],
+ }),
+)`}})
+
+}
+
+func TestCcLibraryCppStdWithGnuExtensions_ConvertsToFeatureAttr(t *testing.T) {
+ type testCase struct {
+ cpp_std string
+ gnu_extensions string
+ bazel_cpp_std string
+ }
+
+ testCases := []testCase{
+ // Existing usages of cpp_std in AOSP are:
+ // experimental, c++11, c++17, c++2a, c++98, gnu++11, gnu++17
+ //
+ // not set, only emit if gnu_extensions is disabled. the default (gnu+17
+ // is set in the toolchain.)
+ {cpp_std: "", gnu_extensions: "", bazel_cpp_std: ""},
+ {cpp_std: "", gnu_extensions: "false", bazel_cpp_std: "c++17"},
+ {cpp_std: "", gnu_extensions: "true", bazel_cpp_std: ""},
+ // experimental defaults to gnu++2a
+ {cpp_std: "experimental", gnu_extensions: "", bazel_cpp_std: "gnu++2a"},
+ {cpp_std: "experimental", gnu_extensions: "false", bazel_cpp_std: "c++2a"},
+ {cpp_std: "experimental", gnu_extensions: "true", bazel_cpp_std: "gnu++2a"},
+ // Explicitly setting a c++ std does not use replace gnu++ std even if
+ // gnu_extensions is true.
+ // "c++11",
+ {cpp_std: "c++11", gnu_extensions: "", bazel_cpp_std: "c++11"},
+ {cpp_std: "c++11", gnu_extensions: "false", bazel_cpp_std: "c++11"},
+ {cpp_std: "c++11", gnu_extensions: "true", bazel_cpp_std: "c++11"},
+ // "c++17",
+ {cpp_std: "c++17", gnu_extensions: "", bazel_cpp_std: "c++17"},
+ {cpp_std: "c++17", gnu_extensions: "false", bazel_cpp_std: "c++17"},
+ {cpp_std: "c++17", gnu_extensions: "true", bazel_cpp_std: "c++17"},
+ // "c++2a",
+ {cpp_std: "c++2a", gnu_extensions: "", bazel_cpp_std: "c++2a"},
+ {cpp_std: "c++2a", gnu_extensions: "false", bazel_cpp_std: "c++2a"},
+ {cpp_std: "c++2a", gnu_extensions: "true", bazel_cpp_std: "c++2a"},
+ // "c++98",
+ {cpp_std: "c++98", gnu_extensions: "", bazel_cpp_std: "c++98"},
+ {cpp_std: "c++98", gnu_extensions: "false", bazel_cpp_std: "c++98"},
+ {cpp_std: "c++98", gnu_extensions: "true", bazel_cpp_std: "c++98"},
+ // gnu++ is replaced with c++ if gnu_extensions is explicitly false.
+ // "gnu++11",
+ {cpp_std: "gnu++11", gnu_extensions: "", bazel_cpp_std: "gnu++11"},
+ {cpp_std: "gnu++11", gnu_extensions: "false", bazel_cpp_std: "c++11"},
+ {cpp_std: "gnu++11", gnu_extensions: "true", bazel_cpp_std: "gnu++11"},
+ // "gnu++17",
+ {cpp_std: "gnu++17", gnu_extensions: "", bazel_cpp_std: "gnu++17"},
+ {cpp_std: "gnu++17", gnu_extensions: "false", bazel_cpp_std: "c++17"},
+ {cpp_std: "gnu++17", gnu_extensions: "true", bazel_cpp_std: "gnu++17"},
+ }
+ for _, tc := range testCases {
+ cppStdAttr := ""
+ if tc.cpp_std != "" {
+ cppStdAttr = fmt.Sprintf(" cpp_std: \"%s\",", tc.cpp_std)
+ }
+ gnuExtensionsAttr := ""
+ if tc.gnu_extensions != "" {
+ gnuExtensionsAttr = fmt.Sprintf(" gnu_extensions: %s,", tc.gnu_extensions)
+ }
+ bazelCppStdAttr := ""
+ if tc.bazel_cpp_std != "" {
+ bazelCppStdAttr = fmt.Sprintf("\n cpp_std = \"%s\",", tc.bazel_cpp_std)
+ }
+
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: fmt.Sprintf(
+ "cc_library with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
+cc_library {
+ name: "a",
+%s // cpp_std: *string
+%s // gnu_extensions: *bool
+ include_build_directory: false,
+}
+`, cppStdAttr, gnuExtensionsAttr),
+ expectedBazelTargets: []string{fmt.Sprintf(`cc_library(
+ name = "a",%s
+)`, bazelCppStdAttr)},
+ })
+
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: fmt.Sprintf(
+ "cc_library_static with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
+cc_library_static {
+ name: "a",
+%s // cpp_std: *string
+%s // gnu_extensions: *bool
+ include_build_directory: false,
+}
+`, cppStdAttr, gnuExtensionsAttr),
+ expectedBazelTargets: []string{fmt.Sprintf(`cc_library_static(
+ name = "a",%s
+)`, bazelCppStdAttr)},
+ })
+
+ runCcLibrarySharedTestCase(t, bp2buildTestCase{
+ description: fmt.Sprintf(
+ "cc_library_shared with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
+ moduleTypeUnderTest: "cc_library_shared",
+ moduleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build,
+ blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
+cc_library_shared {
+ name: "a",
+%s // cpp_std: *string
+%s // gnu_extensions: *bool
+ include_build_directory: false,
+}
+`, cppStdAttr, gnuExtensionsAttr),
+ expectedBazelTargets: []string{fmt.Sprintf(`cc_library_shared(
+ name = "a",%s
+)`, bazelCppStdAttr)},
+ })
+ }
+}
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 3dcfbd7..bb15776 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -15,6 +15,7 @@
package bp2build
import (
+ "fmt"
"testing"
"android/soong/android"
@@ -360,7 +361,83 @@
}`,
expectedBazelTargets: []string{`cc_library_shared(
name = "foo_shared",
- version_script = "version_script",
+ additional_linker_inputs = ["version_script"],
+ linkopts = ["-Wl,--version-script,$(location version_script)"],
)`},
})
}
+
+func TestCcLibrarySharedNoCrtTrue(t *testing.T) {
+ runCcLibrarySharedTestCase(t, bp2buildTestCase{
+ description: "cc_library_shared - nocrt: true emits attribute",
+ moduleTypeUnderTest: "cc_library_shared",
+ moduleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library_shared {
+ name: "foo_shared",
+ srcs: ["impl.cpp"],
+ nocrt: true,
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_library_shared(
+ name = "foo_shared",
+ link_crt = False,
+ srcs = ["impl.cpp"],
+)`}})
+}
+
+func TestCcLibrarySharedNoCrtFalse(t *testing.T) {
+ runCcLibrarySharedTestCase(t, bp2buildTestCase{
+ description: "cc_library_shared - nocrt: false doesn't emit attribute",
+ moduleTypeUnderTest: "cc_library_shared",
+ moduleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library_shared {
+ name: "foo_shared",
+ srcs: ["impl.cpp"],
+ nocrt: false,
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_library_shared(
+ name = "foo_shared",
+ srcs = ["impl.cpp"],
+)`}})
+}
+
+func TestCcLibrarySharedNoCrtArchVariant(t *testing.T) {
+ runCcLibrarySharedTestCase(t, bp2buildTestCase{
+ description: "cc_library_shared - nocrt in select",
+ moduleTypeUnderTest: "cc_library_shared",
+ moduleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library_shared {
+ name: "foo_shared",
+ srcs: ["impl.cpp"],
+ arch: {
+ arm: {
+ nocrt: true,
+ },
+ x86: {
+ nocrt: false,
+ },
+ },
+ include_build_directory: false,
+}
+`,
+ expectedErr: fmt.Errorf("Android.bp:16:1: module \"foo_shared\": nocrt is not supported for arch variants"),
+ })
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 91b7478..9887811 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -641,12 +641,12 @@
name = "foo_static",
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
- "for-arm.c",
"not-for-x86.c",
+ "for-arm.c",
],
"//build/bazel/platforms/arch:x86": [
- "for-x86.c",
"not-for-arm.c",
+ "for-x86.c",
],
"//conditions:default": [
"not-for-arm.c",
@@ -691,28 +691,28 @@
name = "foo_static",
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
- "for-arm.c",
"not-for-arm64.c",
"not-for-x86.c",
"not-for-x86_64.c",
+ "for-arm.c",
],
"//build/bazel/platforms/arch:arm64": [
- "for-arm64.c",
"not-for-arm.c",
"not-for-x86.c",
"not-for-x86_64.c",
+ "for-arm64.c",
],
"//build/bazel/platforms/arch:x86": [
- "for-x86.c",
"not-for-arm.c",
"not-for-arm64.c",
"not-for-x86_64.c",
+ "for-x86.c",
],
"//build/bazel/platforms/arch:x86_64": [
- "for-x86_64.c",
"not-for-arm.c",
"not-for-arm64.c",
"not-for-x86.c",
+ "for-x86_64.c",
],
"//conditions:default": [
"not-for-arm.c",
@@ -875,20 +875,20 @@
name = "foo_static2",
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
- "for-lib32.c",
"not-for-lib64.c",
+ "for-lib32.c",
],
"//build/bazel/platforms/arch:arm64": [
- "for-lib64.c",
"not-for-lib32.c",
+ "for-lib64.c",
],
"//build/bazel/platforms/arch:x86": [
- "for-lib32.c",
"not-for-lib64.c",
+ "for-lib32.c",
],
"//build/bazel/platforms/arch:x86_64": [
- "for-lib64.c",
"not-for-lib32.c",
+ "for-lib64.c",
],
"//conditions:default": [
"not-for-lib32.c",
@@ -942,36 +942,36 @@
name = "foo_static3",
srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
+ "not-for-arm64.c",
+ "not-for-lib64.c",
+ "not-for-x86.c",
+ "not-for-x86_64.c",
"for-arm.c",
"for-lib32.c",
- "not-for-arm64.c",
- "not-for-lib64.c",
- "not-for-x86.c",
- "not-for-x86_64.c",
],
"//build/bazel/platforms/arch:arm64": [
- "for-arm64.c",
- "for-lib64.c",
"not-for-arm.c",
"not-for-lib32.c",
"not-for-x86.c",
"not-for-x86_64.c",
+ "for-arm64.c",
+ "for-lib64.c",
],
"//build/bazel/platforms/arch:x86": [
- "for-lib32.c",
- "for-x86.c",
"not-for-arm.c",
"not-for-arm64.c",
"not-for-lib64.c",
"not-for-x86_64.c",
+ "for-x86.c",
+ "for-lib32.c",
],
"//build/bazel/platforms/arch:x86_64": [
- "for-lib64.c",
- "for-x86_64.c",
"not-for-arm.c",
"not-for-arm64.c",
"not-for-lib32.c",
"not-for-x86.c",
+ "for-x86_64.c",
+ "for-lib64.c",
],
"//conditions:default": [
"not-for-arm.c",
@@ -986,6 +986,48 @@
})
}
+func TestCcLibraryStaticGeneratedHeadersAllPartitions(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ blueprint: soongCcLibraryStaticPreamble + `
+genrule {
+ name: "generated_hdr",
+ cmd: "nothing to see here",
+}
+
+genrule {
+ name: "export_generated_hdr",
+ cmd: "nothing to see here",
+}
+
+cc_library_static {
+ name: "foo_static",
+ srcs: ["cpp_src.cpp", "as_src.S", "c_src.c"],
+ generated_headers: ["generated_hdr", "export_generated_hdr"],
+ export_generated_headers: ["export_generated_hdr"],
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ hdrs = [":export_generated_hdr"],
+ srcs = [
+ "cpp_src.cpp",
+ ":generated_hdr",
+ ],
+ srcs_as = [
+ "as_src.S",
+ ":generated_hdr",
+ ],
+ srcs_c = [
+ "c_src.c",
+ ":generated_hdr",
+ ],
+)`},
+ })
+}
+
func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
runCcLibraryStaticTestCase(t, bp2buildTestCase{
description: "cc_library_static arch srcs/exclude_srcs with generated files",
@@ -1000,73 +1042,92 @@
"dep/Android.bp": `
genrule {
name: "generated_src_other_pkg",
- out: ["generated_src_other_pkg.cpp"],
cmd: "nothing to see here",
}
genrule {
name: "generated_hdr_other_pkg",
- out: ["generated_hdr_other_pkg.cpp"],
cmd: "nothing to see here",
}
genrule {
name: "generated_hdr_other_pkg_x86",
- out: ["generated_hdr_other_pkg_x86.cpp"],
+ cmd: "nothing to see here",
+}
+
+genrule {
+ name: "generated_hdr_other_pkg_android",
cmd: "nothing to see here",
}`,
},
blueprint: soongCcLibraryStaticPreamble + `
genrule {
name: "generated_src",
- out: ["generated_src.cpp"],
cmd: "nothing to see here",
}
genrule {
- name: "generated_src_x86",
- out: ["generated_src_x86.cpp"],
+ name: "generated_src_not_x86",
+ cmd: "nothing to see here",
+}
+
+genrule {
+ name: "generated_src_android",
cmd: "nothing to see here",
}
genrule {
name: "generated_hdr",
- out: ["generated_hdr.h"],
cmd: "nothing to see here",
}
cc_library_static {
- name: "foo_static3",
- srcs: ["common.cpp", "not-for-*.cpp"],
- exclude_srcs: ["not-for-everything.cpp"],
- generated_sources: ["generated_src", "generated_src_other_pkg"],
- generated_headers: ["generated_hdr", "generated_hdr_other_pkg"],
- arch: {
- x86: {
- srcs: ["for-x86.cpp"],
- exclude_srcs: ["not-for-x86.cpp"],
- generated_sources: ["generated_src_x86"],
- generated_headers: ["generated_hdr_other_pkg_x86"],
- },
- },
+ name: "foo_static3",
+ srcs: ["common.cpp", "not-for-*.cpp"],
+ exclude_srcs: ["not-for-everything.cpp"],
+ generated_sources: ["generated_src", "generated_src_other_pkg", "generated_src_not_x86"],
+ generated_headers: ["generated_hdr", "generated_hdr_other_pkg"],
+ arch: {
+ x86: {
+ srcs: ["for-x86.cpp"],
+ exclude_srcs: ["not-for-x86.cpp"],
+ generated_headers: ["generated_hdr_other_pkg_x86"],
+ exclude_generated_sources: ["generated_src_not_x86"],
+ },
+ },
+ target: {
+ android: {
+ generated_sources: ["generated_src_android"],
+ generated_headers: ["generated_hdr_other_pkg_android"],
+ },
+ },
+
include_build_directory: false,
}
`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static3",
srcs = [
- "//dep:generated_hdr_other_pkg",
+ "common.cpp",
+ ":generated_src",
"//dep:generated_src_other_pkg",
":generated_hdr",
- ":generated_src",
- "common.cpp",
+ "//dep:generated_hdr_other_pkg",
] + select({
"//build/bazel/platforms/arch:x86": [
- "//dep:generated_hdr_other_pkg_x86",
- ":generated_src_x86",
"for-x86.cpp",
+ "//dep:generated_hdr_other_pkg_x86",
],
- "//conditions:default": ["not-for-x86.cpp"],
+ "//conditions:default": [
+ "not-for-x86.cpp",
+ ":generated_src_not_x86",
+ ],
+ }) + select({
+ "//build/bazel/platforms/os:android": [
+ ":generated_src_android",
+ "//dep:generated_hdr_other_pkg_android",
+ ],
+ "//conditions:default": [],
}),
)`},
})
@@ -1382,7 +1443,8 @@
expectedBazelTargets: []string{`cc_library_static(
name = "target_bionic",
system_dynamic_deps = select({
- "//build/bazel/platforms/os:bionic": [":libc"],
+ "//build/bazel/platforms/os:android": [":libc"],
+ "//build/bazel/platforms/os:linux_bionic": [":libc"],
"//conditions:default": [],
}),
)`},
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index b0a88ae..c4b276a 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -71,6 +71,7 @@
".",
],
srcs = ["a/b/c.c"],
+ system_dynamic_deps = [],
)`,
},
})
@@ -116,6 +117,7 @@
],
local_includes = ["."],
srcs = ["a/b/c.c"],
+ system_dynamic_deps = [],
)`,
}})
}
@@ -149,11 +151,13 @@
name = "bar",
copts = ["-fno-addrsig"],
srcs = ["x/y/z.c"],
+ system_dynamic_deps = [],
)`, `cc_object(
name = "foo",
copts = ["-fno-addrsig"],
deps = [":bar"],
srcs = ["a/b/c.c"],
+ system_dynamic_deps = [],
)`,
},
})
@@ -180,6 +184,7 @@
name = "foo",
copts = ["-fno-addrsig"],
srcs = ["a/b/c.c"],
+ system_dynamic_deps = [],
)`,
},
})
@@ -211,6 +216,7 @@
}),
copts = ["-fno-addrsig"],
srcs_as = ["src.S"],
+ system_dynamic_deps = [],
)`,
},
})
@@ -248,6 +254,7 @@
"//build/bazel/platforms/arch:arm": ["arch/arm/file.cpp"],
"//conditions:default": [],
}),
+ system_dynamic_deps = [],
)`,
},
})
@@ -301,30 +308,126 @@
"//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
"//conditions:default": [],
}),
+ system_dynamic_deps = [],
)`,
},
})
}
-func TestCcObjectCflagsMultiOs(t *testing.T) {
+func TestCcObjectLinkerScript(t *testing.T) {
runCcObjectTestCase(t, bp2buildTestCase{
- description: "cc_object setting cflags for multiple OSes",
+ description: "cc_object setting linker_script",
moduleTypeUnderTest: "cc_object",
moduleTypeUnderTestFactory: cc.ObjectFactory,
moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
blueprint: `cc_object {
name: "foo",
+ srcs: ["base.cpp"],
+ linker_script: "bunny.lds",
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{
+ `cc_object(
+ name = "foo",
+ copts = ["-fno-addrsig"],
+ linker_script = "bunny.lds",
+ srcs = ["base.cpp"],
+)`,
+ },
+ })
+}
+
+func TestCcObjectDepsAndLinkerScriptSelects(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "cc_object setting deps and linker_script across archs",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
+ name: "foo",
+ srcs: ["base.cpp"],
+ arch: {
+ x86: {
+ objs: ["x86_obj"],
+ linker_script: "x86.lds",
+ },
+ x86_64: {
+ objs: ["x86_64_obj"],
+ linker_script: "x86_64.lds",
+ },
+ arm: {
+ objs: ["arm_obj"],
+ linker_script: "arm.lds",
+ },
+ },
+ include_build_directory: false,
+}
+
+cc_object {
+ name: "x86_obj",
system_shared_libs: [],
+ srcs: ["x86.cpp"],
+ include_build_directory: false,
+ bazel_module: { bp2build_available: false },
+}
+
+cc_object {
+ name: "x86_64_obj",
+ system_shared_libs: [],
+ srcs: ["x86_64.cpp"],
+ include_build_directory: false,
+ bazel_module: { bp2build_available: false },
+}
+
+cc_object {
+ name: "arm_obj",
+ system_shared_libs: [],
+ srcs: ["arm.cpp"],
+ include_build_directory: false,
+ bazel_module: { bp2build_available: false },
+}
+`,
+ expectedBazelTargets: []string{
+ `cc_object(
+ name = "foo",
+ copts = ["-fno-addrsig"],
+ deps = select({
+ "//build/bazel/platforms/arch:arm": [":arm_obj"],
+ "//build/bazel/platforms/arch:x86": [":x86_obj"],
+ "//build/bazel/platforms/arch:x86_64": [":x86_64_obj"],
+ "//conditions:default": [],
+ }),
+ linker_script = select({
+ "//build/bazel/platforms/arch:arm": "arm.lds",
+ "//build/bazel/platforms/arch:x86": "x86.lds",
+ "//build/bazel/platforms/arch:x86_64": "x86_64.lds",
+ "//conditions:default": None,
+ }),
+ srcs = ["base.cpp"],
+)`,
+ },
+ })
+}
+
+func TestCcObjectSelectOnLinuxAndBionicArchs(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "cc_object setting srcs based on linux and bionic archs",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
+ name: "foo",
srcs: ["base.cpp"],
target: {
- android: {
- cflags: ["-fPIC"],
+ linux_arm64: {
+ srcs: ["linux_arm64.cpp",]
},
- windows: {
- cflags: ["-fPIC"],
+ linux_x86: {
+ srcs: ["linux_x86.cpp",]
},
- darwin: {
- cflags: ["-Wall"],
+ bionic_arm64: {
+ srcs: ["bionic_arm64.cpp",]
},
},
include_build_directory: false,
@@ -333,13 +436,21 @@
expectedBazelTargets: []string{
`cc_object(
name = "foo",
- copts = ["-fno-addrsig"] + select({
- "//build/bazel/platforms/os:android": ["-fPIC"],
- "//build/bazel/platforms/os:darwin": ["-Wall"],
- "//build/bazel/platforms/os:windows": ["-fPIC"],
+ copts = ["-fno-addrsig"],
+ srcs = ["base.cpp"] + select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "linux_arm64.cpp",
+ "bionic_arm64.cpp",
+ ],
+ "//build/bazel/platforms/os_arch:android_x86": ["linux_x86.cpp"],
+ "//build/bazel/platforms/os_arch:linux_bionic_arm64": [
+ "linux_arm64.cpp",
+ "bionic_arm64.cpp",
+ ],
+ "//build/bazel/platforms/os_arch:linux_glibc_x86": ["linux_x86.cpp"],
+ "//build/bazel/platforms/os_arch:linux_musl_x86": ["linux_x86.cpp"],
"//conditions:default": [],
}),
- srcs = ["base.cpp"],
)`,
},
})
diff --git a/bp2build/cc_prebuilt_library_shared_test.go b/bp2build/cc_prebuilt_library_shared_test.go
new file mode 100644
index 0000000..97545c8
--- /dev/null
+++ b/bp2build/cc_prebuilt_library_shared_test.go
@@ -0,0 +1,65 @@
+package bp2build
+
+import (
+ "testing"
+
+ "android/soong/cc"
+)
+
+func TestSharedPrebuiltLibrary(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library shared simple",
+ moduleTypeUnderTest: "cc_prebuilt_library_shared",
+ moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.PrebuiltLibrarySharedBp2Build,
+ filesystem: map[string]string{
+ "libf.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library_shared {
+ name: "libtest",
+ srcs: ["libf.so"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ `prebuilt_library_shared(
+ name = "libtest",
+ shared_library = "libf.so",
+)`,
+ },
+ })
+}
+
+func TestSharedPrebuiltLibraryWithArchVariance(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library shared with arch variance",
+ moduleTypeUnderTest: "cc_prebuilt_library_shared",
+ moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.PrebuiltLibrarySharedBp2Build,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library_shared {
+ name: "libtest",
+ arch: {
+ arm64: { srcs: ["libf.so"], },
+ arm: { srcs: ["libg.so"], },
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ `prebuilt_library_shared(
+ name = "libtest",
+ shared_library = select({
+ "//build/bazel/platforms/arch:arm": "libg.so",
+ "//build/bazel/platforms/arch:arm64": "libf.so",
+ "//conditions:default": None,
+ }),
+)`,
+ },
+ })
+}
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index 005f13d..0bcf91d 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -48,6 +48,12 @@
}
}
+ // if there is a select, use the base value as the conditions default value
+ if len(ret) > 0 {
+ ret[bazel.ConditionsDefaultSelectKey] = value
+ value = reflect.Zero(value.Type())
+ }
+
return value, []selects{ret}
}
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 0a86a79..944cb83 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -1,12 +1,13 @@
package bp2build
import (
- "android/soong/android"
- "android/soong/cc/config"
"fmt"
"reflect"
"strings"
+ "android/soong/android"
+ "android/soong/cc/config"
+
"github.com/google/blueprint/proptools"
)
@@ -16,11 +17,11 @@
Contents string
}
-func CreateSoongInjectionFiles(metrics CodegenMetrics) []BazelFile {
+func CreateSoongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []BazelFile {
var files []BazelFile
files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
- files = append(files, newFile("cc_toolchain", "constants.bzl", config.BazelCcToolchainVars()))
+ files = append(files, newFile("cc_toolchain", "constants.bzl", config.BazelCcToolchainVars(cfg)))
files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.convertedModules, "\n")))
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index dfa1a9e..d09238a 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -17,6 +17,8 @@
import (
"sort"
"testing"
+
+ "android/soong/android"
)
type bazelFilepath struct {
@@ -80,7 +82,7 @@
}
func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
- files := CreateSoongInjectionFiles(CodegenMetrics{})
+ files := CreateSoongInjectionFiles(android.Config{}, CodegenMetrics{})
expectedFilePaths := []bazelFilepath{
{
diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go
index 4e25d1b..62e407b 100644
--- a/bp2build/prebuilt_etc_conversion_test.go
+++ b/bp2build/prebuilt_etc_conversion_test.go
@@ -53,3 +53,40 @@
sub_dir = "tz",
)`}})
}
+
+func TestPrebuiltEtcArchVariant(t *testing.T) {
+ runPrebuiltEtcTestCase(t, bp2buildTestCase{
+ description: "prebuilt_etc - simple example",
+ moduleTypeUnderTest: "prebuilt_etc",
+ moduleTypeUnderTestFactory: etc.PrebuiltEtcFactory,
+ moduleTypeUnderTestBp2BuildMutator: etc.PrebuiltEtcBp2Build,
+ filesystem: map[string]string{},
+ blueprint: `
+prebuilt_etc {
+ name: "apex_tz_version",
+ src: "version/tz_version",
+ filename: "tz_version",
+ sub_dir: "tz",
+ installable: false,
+ arch: {
+ arm: {
+ src: "arm",
+ },
+ arm64: {
+ src: "arm64",
+ },
+ }
+}
+`,
+ expectedBazelTargets: []string{`prebuilt_etc(
+ name = "apex_tz_version",
+ filename = "tz_version",
+ installable = False,
+ src = select({
+ "//build/bazel/platforms/arch:arm": "arm",
+ "//build/bazel/platforms/arch:arm64": "arm64",
+ "//conditions:default": "version/tz_version",
+ }),
+ sub_dir = "tz",
+)`}})
+}
diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go
index 6f6fc11..5b4829e 100644
--- a/bp2build/python_binary_conversion_test.go
+++ b/bp2build/python_binary_conversion_test.go
@@ -116,3 +116,37 @@
},
})
}
+
+func TestPythonBinaryHostArchVariance(t *testing.T) {
+ runBp2BuildTestCaseSimple(t, bp2buildTestCase{
+ description: "test arch variants",
+ moduleTypeUnderTest: "python_binary_host",
+ moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
+ moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build,
+ filesystem: map[string]string{
+ "dir/arm.py": "",
+ "dir/x86.py": "",
+ },
+ blueprint: `python_binary_host {
+ name: "foo-arm",
+ arch: {
+ arm: {
+ srcs: ["arm.py"],
+ },
+ x86: {
+ srcs: ["x86.py"],
+ },
+ },
+ }`,
+ expectedBazelTargets: []string{
+ `py_binary(
+ name = "foo-arm",
+ srcs = select({
+ "//build/bazel/platforms/arch:arm": ["arm.py"],
+ "//build/bazel/platforms/arch:x86": ["x86.py"],
+ "//conditions:default": [],
+ }),
+)`,
+ },
+ })
+}
diff --git a/bp2build/python_library_conversion_test.go b/bp2build/python_library_conversion_test.go
index b6f45e5..7f983ad 100644
--- a/bp2build/python_library_conversion_test.go
+++ b/bp2build/python_library_conversion_test.go
@@ -154,3 +154,54 @@
},
})
}
+
+func TestPythonLibraryArchVariance(t *testing.T) {
+ testPythonArchVariance(t, "python_library", "py_library",
+ python.PythonLibraryFactory, python.PythonLibraryBp2Build,
+ func(ctx android.RegistrationContext) {})
+}
+
+func TestPythonLibraryHostArchVariance(t *testing.T) {
+ testPythonArchVariance(t, "python_library_host", "py_library",
+ python.PythonLibraryHostFactory, python.PythonLibraryHostBp2Build,
+ func(ctx android.RegistrationContext) {})
+}
+
+// TODO: refactor python_binary_conversion_test to use this
+func testPythonArchVariance(t *testing.T, modType, bazelTarget string,
+ factory android.ModuleFactory, mutator PythonLibBp2Build,
+ registration func(ctx android.RegistrationContext)) {
+ t.Helper()
+ runBp2BuildTestCase(t, registration, bp2buildTestCase{
+ description: fmt.Sprintf("test %s arch variants", modType),
+ moduleTypeUnderTest: modType,
+ moduleTypeUnderTestFactory: factory,
+ moduleTypeUnderTestBp2BuildMutator: mutator,
+ filesystem: map[string]string{
+ "dir/arm.py": "",
+ "dir/x86.py": "",
+ },
+ blueprint: fmt.Sprintf(`%s {
+ name: "foo",
+ arch: {
+ arm: {
+ srcs: ["arm.py"],
+ },
+ x86: {
+ srcs: ["x86.py"],
+ },
+ },
+ }`, modType),
+ expectedBazelTargets: []string{
+ fmt.Sprintf(`%s(
+ name = "foo",
+ srcs = select({
+ "//build/bazel/platforms/arch:arm": ["arm.py"],
+ "//build/bazel/platforms/arch:x86": ["x86.py"],
+ "//conditions:default": [],
+ }),
+ srcs_version = "PY3",
+)`, bazelTarget),
+ },
+ })
+}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 1e7e53c..7c2f43a 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -135,17 +135,14 @@
android.FailIfErrored(t, errs)
}
if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d; %v",
- tc.description, expectedCount, actualCount, bazelTargets)
+ t.Errorf("%s: Expected %d bazel target, got `%d``",
+ tc.description, expectedCount, actualCount)
} else {
for i, target := range bazelTargets {
if w, g := tc.expectedBazelTargets[i], target.content; w != g {
t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- tc.description,
- w,
- g,
- )
+ "%s: Expected generated Bazel target to be `%s`, got `%s`",
+ tc.description, w, g)
}
}
}
@@ -286,7 +283,7 @@
return
}
- paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.props.Arch_paths, m.props.Arch_paths_exclude))
+ paths := bazel.LabelListAttribute{}
for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
for config, props := range configToProps {
@@ -312,7 +309,7 @@
Rule_class: "custom",
}
- ctx.CreateBazelTargetModule(m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
}
}
@@ -331,19 +328,19 @@
Rule_class: "my_library",
Bzl_load_location: "//build/bazel/rules:rules.bzl",
}
- ctx.CreateBazelTargetModule(baseName, myLibraryProps, attrs)
+ ctx.CreateBazelTargetModule(myLibraryProps, android.CommonAttributes{Name: baseName}, attrs)
protoLibraryProps := bazel.BazelTargetModuleProperties{
Rule_class: "proto_library",
Bzl_load_location: "//build/bazel/rules:proto.bzl",
}
- ctx.CreateBazelTargetModule(baseName+"_proto_library_deps", protoLibraryProps, attrs)
+ ctx.CreateBazelTargetModule(protoLibraryProps, android.CommonAttributes{Name: baseName + "_proto_library_deps"}, attrs)
myProtoLibraryProps := bazel.BazelTargetModuleProperties{
Rule_class: "my_proto_library",
Bzl_load_location: "//build/bazel/rules:proto.bzl",
}
- ctx.CreateBazelTargetModule(baseName+"_my_proto_library_deps", myProtoLibraryProps, attrs)
+ ctx.CreateBazelTargetModule(myProtoLibraryProps, android.CommonAttributes{Name: baseName + "_my_proto_library_deps"}, attrs)
}
}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index cd52363..93283d0 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -294,9 +294,6 @@
if library.buildStubs() {
entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
}
- if library.apiListCoverageXmlPath.String() != "" {
- entries.SetString("SOONG_CC_API_XML", "$(SOONG_CC_API_XML) "+library.apiListCoverageXmlPath.String())
- }
})
}
// If a library providing a stub is included in an APEX, the private APIs of the library
@@ -394,6 +391,8 @@
if Bool(test.Properties.Test_options.Unit_test) {
entries.SetBool("LOCAL_IS_UNIT_TEST", true)
}
+
+ entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(test.Properties.Per_testcase_directory))
})
AndroidMkWriteTestData(test.data, entries)
diff --git a/cc/binary.go b/cc/binary.go
index b423c50..a5afb07 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -20,6 +20,7 @@
"github.com/google/blueprint"
"android/soong/android"
+ "android/soong/bazel"
)
type BinaryLinkerProperties struct {
@@ -62,7 +63,7 @@
func RegisterBinaryBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("cc_binary", BinaryFactory)
- ctx.RegisterModuleType("cc_binary_host", binaryHostFactory)
+ ctx.RegisterModuleType("cc_binary_host", BinaryHostFactory)
}
// cc_binary produces a binary that is runnable on a device.
@@ -72,7 +73,7 @@
}
// cc_binary_host produces a binary that is runnable on a host.
-func binaryHostFactory() android.Module {
+func BinaryHostFactory() android.Module {
module, _ := NewBinary(android.HostSupported)
return module.Init()
}
@@ -412,7 +413,7 @@
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
}
- linkerDeps = append(linkerDeps, objs.tidyFiles...)
+ validations = append(validations, objs.tidyFiles...)
linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
// Register link action.
@@ -541,3 +542,124 @@
},
})
}
+
+func init() {
+ android.RegisterBp2BuildMutator("cc_binary", BinaryBp2build)
+ android.RegisterBp2BuildMutator("cc_binary_host", BinaryHostBp2build)
+}
+
+func BinaryBp2build(ctx android.TopDownMutatorContext) {
+ binaryBp2build(ctx, "cc_binary")
+}
+
+func BinaryHostBp2build(ctx android.TopDownMutatorContext) {
+ binaryBp2build(ctx, "cc_binary_host")
+}
+
+func binaryBp2build(ctx android.TopDownMutatorContext, typ string) {
+ m, ok := ctx.Module().(*Module)
+ if !ok {
+ // Not a cc module
+ return
+ }
+ if !m.ConvertWithBp2build(ctx) {
+ return
+ }
+
+ if ctx.ModuleType() != typ {
+ return
+ }
+
+ var compatibleWith bazel.StringListAttribute
+ if typ == "cc_binary_host" {
+ //incompatible with android OS
+ compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, []string{"@platforms//:incompatible"})
+ compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, bazel.ConditionsDefaultConfigKey, []string{})
+ }
+
+ baseAttrs := bp2BuildParseBaseProps(ctx, m)
+
+ attrs := &binaryAttributes{
+ binaryLinkerAttrs: bp2buildBinaryLinkerProps(ctx, m),
+
+ Srcs: baseAttrs.srcs,
+ Srcs_c: baseAttrs.cSrcs,
+ Srcs_as: baseAttrs.asSrcs,
+
+ Copts: baseAttrs.copts,
+ Cppflags: baseAttrs.cppFlags,
+ Conlyflags: baseAttrs.conlyFlags,
+ Asflags: baseAttrs.asFlags,
+
+ Deps: baseAttrs.implementationDeps,
+ Dynamic_deps: baseAttrs.implementationDynamicDeps,
+ Whole_archive_deps: baseAttrs.wholeArchiveDeps,
+ System_deps: baseAttrs.systemDynamicDeps,
+
+ Local_includes: baseAttrs.localIncludes,
+ Absolute_includes: baseAttrs.absoluteIncludes,
+ Linkopts: baseAttrs.linkopts,
+ Link_crt: baseAttrs.linkCrt,
+ Use_libcrt: baseAttrs.useLibcrt,
+ Rtti: baseAttrs.rtti,
+ Stl: baseAttrs.stl,
+ Cpp_std: baseAttrs.cppStd,
+
+ Additional_linker_inputs: baseAttrs.additionalLinkerInputs,
+
+ Strip: stripAttributes{
+ Keep_symbols: baseAttrs.stripKeepSymbols,
+ Keep_symbols_and_debug_frame: baseAttrs.stripKeepSymbolsAndDebugFrame,
+ Keep_symbols_list: baseAttrs.stripKeepSymbolsList,
+ All: baseAttrs.stripAll,
+ None: baseAttrs.stripNone,
+ },
+
+ Target_compatible_with: compatibleWith,
+ Features: baseAttrs.features,
+ }
+
+ ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_binary",
+ Bzl_load_location: "//build/bazel/rules:cc_binary.bzl",
+ },
+ android.CommonAttributes{Name: m.Name()},
+ attrs)
+}
+
+// binaryAttributes contains Bazel attributes corresponding to a cc binary
+type binaryAttributes struct {
+ binaryLinkerAttrs
+ Srcs bazel.LabelListAttribute
+ Srcs_c bazel.LabelListAttribute
+ Srcs_as bazel.LabelListAttribute
+
+ Copts bazel.StringListAttribute
+ Cppflags bazel.StringListAttribute
+ Conlyflags bazel.StringListAttribute
+ Asflags bazel.StringListAttribute
+
+ Deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ System_deps bazel.LabelListAttribute
+
+ Local_includes bazel.StringListAttribute
+ Absolute_includes bazel.StringListAttribute
+
+ Linkopts bazel.StringListAttribute
+ Additional_linker_inputs bazel.LabelListAttribute
+
+ Link_crt bazel.BoolAttribute
+ Use_libcrt bazel.BoolAttribute
+
+ Rtti bazel.BoolAttribute
+ Stl *string
+ Cpp_std *string
+
+ Strip stripAttributes
+
+ Features bazel.StringListAttribute
+
+ Target_compatible_with bazel.StringListAttribute
+}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 22bd90b..e20f7c3 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -14,6 +14,7 @@
package cc
import (
+ "fmt"
"path/filepath"
"strings"
@@ -25,12 +26,19 @@
"github.com/google/blueprint/proptools"
)
+const (
+ cSrcPartition = "c"
+ asSrcPartition = "as"
+ cppSrcPartition = "cpp"
+)
+
// 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 {
Srcs bazel.LabelListAttribute
Srcs_c bazel.LabelListAttribute
Srcs_as bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
Copts bazel.StringListAttribute
Deps bazel.LabelListAttribute
@@ -42,7 +50,7 @@
System_dynamic_deps bazel.LabelListAttribute
}
-func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) {
+func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
// Check that a module is a filegroup type named <label>.
isFilegroupNamed := func(m android.Module, fullLabel string) bool {
if ctx.OtherModuleType(m) != "filegroup" {
@@ -74,17 +82,14 @@
// TODO(b/190006308): Handle language detection of sources in a Bazel rule.
partitioned := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{
- "c": bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
- "as": bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
+ 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.
- "cpp": bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
+ cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
})
- cSrcs = partitioned["c"]
- asSrcs = partitioned["as"]
- cppSrcs = partitioned["cpp"]
- return
+ return partitioned
}
// bp2BuildParseLibProps returns the attributes for a variant of a cc_library.
@@ -113,7 +118,13 @@
type bazelLabelForDepsFn func(android.TopDownMutatorContext, []string) bazel.LabelList
-func partitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
+func maybePartitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
+ if !exportsDeps {
+ return depsPartition{
+ implementation: fn(ctx, allDeps),
+ }
+ }
+
implementation, export := android.FilterList(allDeps, exportedDeps)
return depsPartition{
@@ -124,7 +135,12 @@
type bazelLabelForDepsExcludesFn func(android.TopDownMutatorContext, []string, []string) bazel.LabelList
-func partitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
+func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
+ if !exportsDeps {
+ return depsPartition{
+ implementation: fn(ctx, allDeps, excludes),
+ }
+ }
implementation, export := android.FilterList(allDeps, exportedDeps)
return depsPartition{
@@ -141,11 +157,11 @@
attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs))
- staticDeps := partitionExportedAndImplementationsDeps(ctx, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps)
+ staticDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps)
attrs.Deps.SetSelectValue(axis, config, staticDeps.export)
attrs.Implementation_deps.SetSelectValue(axis, config, staticDeps.implementation)
- sharedDeps := partitionExportedAndImplementationsDeps(ctx, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps)
+ sharedDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps)
attrs.Dynamic_deps.SetSelectValue(axis, config, sharedDeps.export)
attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation)
@@ -174,10 +190,10 @@
}
}
- cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
- attrs.Srcs = cppSrcs
- attrs.Srcs_c = cSrcs
- attrs.Srcs_as = asSrcs
+ partitionedSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
+ attrs.Srcs = partitionedSrcs[cppSrcPartition]
+ attrs.Srcs_c = partitionedSrcs[cSrcPartition]
+ attrs.Srcs_as = partitionedSrcs[asSrcPartition]
return attrs
}
@@ -211,6 +227,11 @@
}
}
+type baseAttributes struct {
+ compilerAttributes
+ linkerAttributes
+}
+
// Convenience struct to hold all attributes parsed from compiler properties.
type compilerAttributes struct {
// Options for all languages
@@ -225,88 +246,79 @@
cppFlags bazel.StringListAttribute
srcs bazel.LabelListAttribute
+ hdrs bazel.LabelListAttribute
+
rtti bazel.BoolAttribute
- stl *string
+
+ // Not affected by arch variants
+ stl *string
+ cppStd *string
localIncludes bazel.StringListAttribute
absoluteIncludes bazel.StringListAttribute
}
-// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
-func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
- var srcs bazel.LabelListAttribute
- var copts bazel.StringListAttribute
- var asFlags bazel.StringListAttribute
- var conlyFlags bazel.StringListAttribute
- var cppFlags bazel.StringListAttribute
- var rtti bazel.BoolAttribute
- var localIncludes bazel.StringListAttribute
- var absoluteIncludes bazel.StringListAttribute
+func parseCommandLineFlags(soongFlags []string) []string {
+ var result []string
+ for _, flag := range soongFlags {
+ // Soong's cflags can contain spaces, like `-include header.h`. For
+ // Bazel's copts, split them up to be compatible with the
+ // no_copts_tokenization feature.
+ result = append(result, strings.Split(flag, " ")...)
+ }
+ return result
+}
- parseCommandLineFlags := func(soongFlags []string) []string {
- var result []string
- for _, flag := range soongFlags {
- // Soong's cflags can contain spaces, like `-include header.h`. For
- // Bazel's copts, split them up to be compatible with the
- // no_copts_tokenization feature.
- result = append(result, strings.Split(flag, " ")...)
+func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.TopDownMutatorContext, axis bazel.ConfigurationAxis, config string, props *BaseCompilerProperties) {
+ // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
+ // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
+ if srcsList, ok := parseSrcs(ctx, props); ok {
+ ca.srcs.SetSelectValue(axis, config, srcsList)
+ }
+
+ localIncludeDirs := props.Local_include_dirs
+ if axis == bazel.NoConfigAxis {
+ ca.cppStd = bp2buildResolveCppStdValue(props.Cpp_std, props.Gnu_extensions)
+
+ if includeBuildDirectory(props.Include_build_directory) {
+ localIncludeDirs = append(localIncludeDirs, ".")
}
- return result
}
- // Parse srcs from an arch or OS's props value.
- parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
- // Add srcs-like dependencies such as generated files.
- // First create a LabelList containing these dependencies, then merge the values with srcs.
- generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
- generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
- generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
+ ca.absoluteIncludes.SetSelectValue(axis, config, props.Include_dirs)
+ ca.localIncludes.SetSelectValue(axis, config, localIncludeDirs)
- allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
- return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
- }
+ ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags))
+ ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags))
+ ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags))
+ ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags))
+ ca.rtti.SetSelectValue(axis, config, props.Rtti)
+}
- archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
- for axis, configToProps := range archVariantCompilerProps {
- for config, props := range configToProps {
- if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
- // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
- if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
- srcsList := parseSrcs(baseCompilerProps)
- srcs.SetSelectValue(axis, config, srcsList)
+func (ca *compilerAttributes) convertStlProps(ctx android.TopDownMutatorContext, module *Module) {
+ stlPropsByArch := module.GetArchVariantProperties(ctx, &StlProperties{})
+ for _, configToProps := range stlPropsByArch {
+ for _, props := range configToProps {
+ if stlProps, ok := props.(*StlProperties); ok {
+ if stlProps.Stl == nil {
+ continue
}
-
- archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
- archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
-
- localIncludeDirs := baseCompilerProps.Local_include_dirs
- if axis == bazel.NoConfigAxis && includeBuildDirectory(baseCompilerProps.Include_build_directory) {
- localIncludeDirs = append(localIncludeDirs, ".")
+ if ca.stl == nil {
+ ca.stl = stlProps.Stl
+ } else if ca.stl != stlProps.Stl {
+ ctx.ModuleErrorf("Unsupported conversion: module with different stl for different variants: %s and %s", *ca.stl, stlProps.Stl)
}
-
- absoluteIncludes.SetSelectValue(axis, config, baseCompilerProps.Include_dirs)
- localIncludes.SetSelectValue(axis, config, localIncludeDirs)
-
- copts.SetSelectValue(axis, config, archVariantCopts)
- asFlags.SetSelectValue(axis, config, archVariantAsflags)
- conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
- cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
- rtti.SetSelectValue(axis, config, baseCompilerProps.Rtti)
}
}
}
+}
- srcs.ResolveExcludes()
- absoluteIncludes.DeduplicateAxesFromBase()
- localIncludes.DeduplicateAxesFromBase()
-
+func (ca *compilerAttributes) convertProductVariables(ctx android.TopDownMutatorContext, productVariableProps android.ProductConfigProperties) {
productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
- "Cflags": &copts,
- "Asflags": &asFlags,
- "CppFlags": &cppFlags,
+ "Cflags": &ca.copts,
+ "Asflags": &ca.asFlags,
+ "CppFlags": &ca.cppFlags,
}
- productVariableProps := android.ProductVariableProperties(ctx)
for propName, attr := range productVarPropNameToAttribute {
if props, exists := productVariableProps[propName]; exists {
for _, prop := range props {
@@ -319,39 +331,126 @@
}
}
}
+}
- srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
+func (ca *compilerAttributes) finalize(ctx android.TopDownMutatorContext, implementationHdrs bazel.LabelListAttribute) {
+ ca.srcs.ResolveExcludes()
+ partitionedSrcs := groupSrcsByExtension(ctx, ca.srcs)
- var stl *string = nil
- stlPropsByArch := module.GetArchVariantProperties(ctx, &StlProperties{})
- for _, configToProps := range stlPropsByArch {
- for _, props := range configToProps {
- if stlProps, ok := props.(*StlProperties); ok {
- if stlProps.Stl != nil {
- if stl == nil {
- stl = stlProps.Stl
- } else {
- if stl != stlProps.Stl {
- ctx.ModuleErrorf("Unsupported conversion: module with different stl for different variants: %s and %s", *stl, stlProps.Stl)
- }
- }
- }
+ for p, lla := range partitionedSrcs {
+ // if there are no sources, there is no need for headers
+ if lla.IsEmpty() {
+ continue
+ }
+ lla.Append(implementationHdrs)
+ partitionedSrcs[p] = lla
+ }
+
+ ca.srcs = partitionedSrcs[cppSrcPartition]
+ ca.cSrcs = partitionedSrcs[cSrcPartition]
+ ca.asSrcs = partitionedSrcs[asSrcPartition]
+
+ ca.absoluteIncludes.DeduplicateAxesFromBase()
+ ca.localIncludes.DeduplicateAxesFromBase()
+}
+
+// Parse srcs from an arch or OS's props value.
+func parseSrcs(ctx android.TopDownMutatorContext, props *BaseCompilerProperties) (bazel.LabelList, bool) {
+ anySrcs := false
+ // Add srcs-like dependencies such as generated files.
+ // First create a LabelList containing these dependencies, then merge the values with srcs.
+ generatedSrcsLabelList := android.BazelLabelForModuleDepsExcludes(ctx, props.Generated_sources, props.Exclude_generated_sources)
+ if len(props.Generated_sources) > 0 || len(props.Exclude_generated_sources) > 0 {
+ anySrcs = true
+ }
+
+ allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, props.Srcs, props.Exclude_srcs)
+ if len(props.Srcs) > 0 || len(props.Exclude_srcs) > 0 {
+ anySrcs = true
+ }
+ return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedSrcsLabelList), anySrcs
+}
+
+func bp2buildResolveCppStdValue(cpp_std *string, gnu_extensions *bool) *string {
+ var cppStd *string
+ // If cpp_std is not specified, don't generate it in the
+ // BUILD file. For readability purposes, cpp_std and gnu_extensions are
+ // combined into a single -std=<version> copt, except in the
+ // default case where cpp_std is nil and gnu_extensions is true or unspecified,
+ // then the toolchain's default "gnu++17" will be used.
+ if cpp_std != nil {
+ // TODO(b/202491296): Handle C_std.
+ // These transformations are shared with compiler.go.
+ cppStdVal := parseCppStd(cpp_std)
+ _, cppStdVal = maybeReplaceGnuToC(gnu_extensions, "", cppStdVal)
+ cppStd = &cppStdVal
+ } else if gnu_extensions != nil && !*gnu_extensions {
+ cppStdVal := "c++17"
+ cppStd = &cppStdVal
+ }
+ return cppStd
+}
+
+// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
+func bp2BuildParseBaseProps(ctx android.TopDownMutatorContext, module *Module) baseAttributes {
+ archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
+ archVariantLinkerProps := module.GetArchVariantProperties(ctx, &BaseLinkerProperties{})
+
+ var implementationHdrs bazel.LabelListAttribute
+
+ axisToConfigs := map[bazel.ConfigurationAxis]map[string]bool{}
+ allAxesAndConfigs := func(cp android.ConfigurationAxisToArchVariantProperties) {
+ for axis, configMap := range cp {
+ if _, ok := axisToConfigs[axis]; !ok {
+ axisToConfigs[axis] = map[string]bool{}
+ }
+ for config, _ := range configMap {
+ axisToConfigs[axis][config] = true
}
}
}
+ allAxesAndConfigs(archVariantCompilerProps)
+ allAxesAndConfigs(archVariantLinkerProps)
- return compilerAttributes{
- copts: copts,
- srcs: srcs,
- asFlags: asFlags,
- asSrcs: asSrcs,
- cSrcs: cSrcs,
- conlyFlags: conlyFlags,
- cppFlags: cppFlags,
- rtti: rtti,
- stl: stl,
- localIncludes: localIncludes,
- absoluteIncludes: absoluteIncludes,
+ compilerAttrs := compilerAttributes{}
+ linkerAttrs := linkerAttributes{}
+
+ for axis, configs := range axisToConfigs {
+ for config, _ := range configs {
+ var allHdrs []string
+ if baseCompilerProps, ok := archVariantCompilerProps[axis][config].(*BaseCompilerProperties); ok {
+ allHdrs = baseCompilerProps.Generated_headers
+
+ (&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, config, baseCompilerProps)
+ }
+
+ var exportHdrs []string
+
+ if baseLinkerProps, ok := archVariantLinkerProps[axis][config].(*BaseLinkerProperties); ok {
+ exportHdrs = baseLinkerProps.Export_generated_headers
+
+ (&linkerAttrs).bp2buildForAxisAndConfig(ctx, module.Binary(), axis, config, baseLinkerProps)
+ }
+ headers := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrs, exportHdrs, android.BazelLabelForModuleDeps)
+ implementationHdrs.SetSelectValue(axis, config, headers.implementation)
+ compilerAttrs.hdrs.SetSelectValue(axis, config, headers.export)
+ }
+ }
+
+ compilerAttrs.convertStlProps(ctx, module)
+ (&linkerAttrs).convertStripProps(ctx, module)
+
+ productVariableProps := android.ProductVariableProperties(ctx)
+
+ (&compilerAttrs).convertProductVariables(ctx, productVariableProps)
+ (&linkerAttrs).convertProductVariables(ctx, productVariableProps)
+
+ (&compilerAttrs).finalize(ctx, implementationHdrs)
+ (&linkerAttrs).finalize()
+
+ return baseAttributes{
+ compilerAttrs,
+ linkerAttrs,
}
}
@@ -364,102 +463,106 @@
wholeArchiveDeps bazel.LabelListAttribute
systemDynamicDeps bazel.LabelListAttribute
+ linkCrt bazel.BoolAttribute
useLibcrt bazel.BoolAttribute
linkopts bazel.StringListAttribute
- versionScript bazel.LabelAttribute
+ additionalLinkerInputs bazel.LabelListAttribute
stripKeepSymbols bazel.BoolAttribute
stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
stripKeepSymbolsList bazel.StringListAttribute
stripAll bazel.BoolAttribute
stripNone bazel.BoolAttribute
+ features bazel.StringListAttribute
}
-// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
-func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
- flags := linkerProperties.Ldflags
- if !BoolDefault(linkerProperties.Pack_relocations, true) {
- flags = append(flags, "-Wl,--pack-dyn-relocs=none")
+func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.TopDownMutatorContext, isBinary bool, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) {
+ // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module
+ var axisFeatures []string
+
+ // Excludes to parallel Soong:
+ // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
+ staticLibs := android.FirstUniqueStrings(props.Static_libs)
+ staticDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, staticLibs, props.Exclude_static_libs, props.Export_static_lib_headers, bazelLabelForStaticDepsExcludes)
+
+ headerLibs := android.FirstUniqueStrings(props.Header_libs)
+ hDeps := maybePartitionExportedAndImplementationsDeps(ctx, !isBinary, headerLibs, props.Export_header_lib_headers, bazelLabelForHeaderDeps)
+
+ (&hDeps.export).Append(staticDeps.export)
+ la.deps.SetSelectValue(axis, config, hDeps.export)
+
+ (&hDeps.implementation).Append(staticDeps.implementation)
+ la.implementationDeps.SetSelectValue(axis, config, hDeps.implementation)
+
+ wholeStaticLibs := android.FirstUniqueStrings(props.Whole_static_libs)
+ la.wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, props.Exclude_static_libs))
+
+ systemSharedLibs := props.System_shared_libs
+ // systemSharedLibs distinguishes between nil/empty list behavior:
+ // nil -> use default values
+ // empty list -> no values specified
+ if len(systemSharedLibs) > 0 {
+ systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
}
- return flags
+ la.systemDynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
+
+ sharedLibs := android.FirstUniqueStrings(props.Shared_libs)
+ sharedDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, sharedLibs, props.Exclude_shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes)
+ la.dynamicDeps.SetSelectValue(axis, config, sharedDeps.export)
+ la.implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation)
+
+ if !BoolDefault(props.Pack_relocations, packRelocationsDefault) {
+ axisFeatures = append(axisFeatures, "disable_pack_relocations")
+ }
+
+ if Bool(props.Allow_undefined_symbols) {
+ axisFeatures = append(axisFeatures, "-no_undefined_symbols")
+ }
+
+ var linkerFlags []string
+ if len(props.Ldflags) > 0 {
+ linkerFlags = append(linkerFlags, props.Ldflags...)
+ // binaries remove static flag if -shared is in the linker flags
+ if isBinary && android.InList("-shared", linkerFlags) {
+ axisFeatures = append(axisFeatures, "-static_flag")
+ }
+ }
+ if props.Version_script != nil {
+ label := android.BazelLabelForModuleSrcSingle(ctx, *props.Version_script)
+ la.additionalLinkerInputs.SetSelectValue(axis, config, bazel.LabelList{Includes: []bazel.Label{label}})
+ linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--version-script,$(location %s)", label.Label))
+ }
+ la.linkopts.SetSelectValue(axis, config, linkerFlags)
+ la.useLibcrt.SetSelectValue(axis, config, props.libCrt())
+
+ // it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it.
+ if props.crt() != nil {
+ if axis == bazel.NoConfigAxis {
+ la.linkCrt.SetSelectValue(axis, config, props.crt())
+ } else if axis == bazel.ArchConfigurationAxis {
+ ctx.ModuleErrorf("nocrt is not supported for arch variants")
+ }
+ }
+
+ if axisFeatures != nil {
+ la.features.SetSelectValue(axis, config, axisFeatures)
+ }
}
-// bp2BuildParseLinkerProps parses the linker properties of a module, including
-// configurable attribute values.
-func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
-
- var headerDeps bazel.LabelListAttribute
- var implementationHeaderDeps bazel.LabelListAttribute
- var deps bazel.LabelListAttribute
- var implementationDeps bazel.LabelListAttribute
- var dynamicDeps bazel.LabelListAttribute
- var implementationDynamicDeps bazel.LabelListAttribute
- var wholeArchiveDeps bazel.LabelListAttribute
- systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
-
- var linkopts bazel.StringListAttribute
- var versionScript bazel.LabelAttribute
- var useLibcrt bazel.BoolAttribute
-
- var stripKeepSymbols bazel.BoolAttribute
- var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
- var stripKeepSymbolsList bazel.StringListAttribute
- var stripAll bazel.BoolAttribute
- var stripNone bazel.BoolAttribute
-
+func (la *linkerAttributes) convertStripProps(ctx android.TopDownMutatorContext, module *Module) {
for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
for config, props := range configToProps {
if stripProperties, ok := props.(*StripProperties); ok {
- stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
- stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
- stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
- stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
- stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
+ la.stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
+ la.stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
+ la.stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
+ la.stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
+ la.stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
}
}
}
+}
- for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
- for config, props := range configToProps {
- if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
-
- // Excludes to parallel Soong:
- // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
- staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
- staticDeps := partitionExportedAndImplementationsDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs, baseLinkerProps.Export_static_lib_headers, bazelLabelForStaticDepsExcludes)
- deps.SetSelectValue(axis, config, staticDeps.export)
- implementationDeps.SetSelectValue(axis, config, staticDeps.implementation)
-
- wholeStaticLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
- wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, baseLinkerProps.Exclude_static_libs))
-
- systemSharedLibs := baseLinkerProps.System_shared_libs
- // systemSharedLibs distinguishes between nil/empty list behavior:
- // nil -> use default values
- // empty list -> no values specified
- if len(systemSharedLibs) > 0 {
- systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
- }
- systemSharedDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
-
- sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
- sharedDeps := partitionExportedAndImplementationsDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs, baseLinkerProps.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes)
- dynamicDeps.SetSelectValue(axis, config, sharedDeps.export)
- implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation)
-
- headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
- hDeps := partitionExportedAndImplementationsDeps(ctx, headerLibs, baseLinkerProps.Export_header_lib_headers, bazelLabelForHeaderDeps)
-
- headerDeps.SetSelectValue(axis, config, hDeps.export)
- implementationHeaderDeps.SetSelectValue(axis, config, hDeps.implementation)
-
- linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
- if baseLinkerProps.Version_script != nil {
- versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
- }
- useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
- }
- }
- }
+func (la *linkerAttributes) convertProductVariables(ctx android.TopDownMutatorContext, productVariableProps android.ProductConfigProperties) {
type productVarDep struct {
// the name of the corresponding excludes field, if one exists
@@ -472,12 +575,11 @@
productVarToDepFields := map[string]productVarDep{
// product variables do not support exclude_shared_libs
- "Shared_libs": productVarDep{attribute: &implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
- "Static_libs": productVarDep{"Exclude_static_libs", &implementationDeps, bazelLabelForStaticDepsExcludes},
- "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
+ "Shared_libs": productVarDep{attribute: &la.implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
+ "Static_libs": productVarDep{"Exclude_static_libs", &la.implementationDeps, bazelLabelForStaticDepsExcludes},
+ "Whole_static_libs": productVarDep{"Exclude_static_libs", &la.wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
}
- productVariableProps := android.ProductVariableProperties(ctx)
for name, dep := range productVarToDepFields {
props, exists := productVariableProps[name]
excludeProps, excludesExists := productVariableProps[dep.excludesField]
@@ -512,35 +614,15 @@
dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
}
}
+}
- headerDeps.Append(deps)
- implementationHeaderDeps.Append(implementationDeps)
-
- headerDeps.ResolveExcludes()
- implementationHeaderDeps.ResolveExcludes()
- dynamicDeps.ResolveExcludes()
- implementationDynamicDeps.ResolveExcludes()
- wholeArchiveDeps.ResolveExcludes()
-
- return linkerAttributes{
- deps: headerDeps,
- implementationDeps: implementationHeaderDeps,
- dynamicDeps: dynamicDeps,
- implementationDynamicDeps: implementationDynamicDeps,
- wholeArchiveDeps: wholeArchiveDeps,
- systemDynamicDeps: systemSharedDeps,
-
- linkopts: linkopts,
- useLibcrt: useLibcrt,
- versionScript: versionScript,
-
- // Strip properties
- stripKeepSymbols: stripKeepSymbols,
- stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
- stripKeepSymbolsList: stripKeepSymbolsList,
- stripAll: stripAll,
- stripNone: stripNone,
- }
+func (la *linkerAttributes) finalize() {
+ la.deps.ResolveExcludes()
+ la.implementationDeps.ResolveExcludes()
+ la.dynamicDeps.ResolveExcludes()
+ la.implementationDynamicDeps.ResolveExcludes()
+ la.wholeArchiveDeps.ResolveExcludes()
+ la.systemDynamicDeps.ForceSpecifyEmptyList = true
}
// Relativize a list of root-relative paths with respect to the module's
@@ -663,3 +745,29 @@
func bazelLabelForSharedDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
}
+
+type binaryLinkerAttrs struct {
+ Linkshared *bool
+}
+
+func bp2buildBinaryLinkerProps(ctx android.TopDownMutatorContext, m *Module) binaryLinkerAttrs {
+ attrs := binaryLinkerAttrs{}
+ archVariantProps := m.GetArchVariantProperties(ctx, &BinaryLinkerProperties{})
+ for axis, configToProps := range archVariantProps {
+ for _, p := range configToProps {
+ props := p.(*BinaryLinkerProperties)
+ staticExecutable := props.Static_executable
+ if axis == bazel.NoConfigAxis {
+ if linkBinaryShared := !proptools.Bool(staticExecutable); !linkBinaryShared {
+ attrs.Linkshared = &linkBinaryShared
+ }
+ } else if staticExecutable != nil {
+ // TODO(b/202876379): Static_executable is arch-variant; however, linkshared is a
+ // nonconfigurable attribute. Only 4 AOSP modules use this feature, defer handling
+ ctx.ModuleErrorf("bp2build cannot migrate a module with arch/target-specific static_executable values")
+ }
+ }
+ }
+
+ return attrs
+}
diff --git a/cc/builder.go b/cc/builder.go
index b494f7b..abd5f1d 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -238,14 +238,6 @@
},
"asFlags")
- // Rule to invoke windres, for interaction with Windows resources.
- windres = pctx.AndroidStaticRule("windres",
- blueprint.RuleParams{
- Command: "$windresCmd $flags -I$$(dirname $in) -i $in -o $out --preprocessor \"${config.ClangBin}/clang -E -xc-header -DRC_INVOKED\"",
- CommandDeps: []string{"$windresCmd"},
- },
- "windresCmd", "flags")
-
_ = pctx.SourcePathVariable("sAbiDumper", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-dumper")
// -w has been added since header-abi-dumper does not need to produce any sort of diagnostic information.
@@ -421,7 +413,7 @@
// Objects is a collection of file paths corresponding to outputs for C++ related build statements.
type Objects struct {
objFiles android.Paths
- tidyFiles android.Paths
+ tidyFiles android.WritablePaths
coverageFiles android.Paths
sAbiDumpFiles android.Paths
kytheFiles android.Paths
@@ -430,7 +422,7 @@
func (a Objects) Copy() Objects {
return Objects{
objFiles: append(android.Paths{}, a.objFiles...),
- tidyFiles: append(android.Paths{}, a.tidyFiles...),
+ tidyFiles: append(android.WritablePaths{}, a.tidyFiles...),
coverageFiles: append(android.Paths{}, a.coverageFiles...),
sAbiDumpFiles: append(android.Paths{}, a.sAbiDumpFiles...),
kytheFiles: append(android.Paths{}, a.kytheFiles...),
@@ -459,11 +451,11 @@
// Source files are one-to-one with tidy, coverage, or kythe files, if enabled.
objFiles := make(android.Paths, len(srcFiles))
- var tidyFiles android.Paths
+ var tidyFiles android.WritablePaths
noTidySrcsMap := make(map[android.Path]bool)
var tidyVars string
if flags.tidy {
- tidyFiles = make(android.Paths, 0, len(srcFiles))
+ tidyFiles = make(android.WritablePaths, 0, len(srcFiles))
for _, path := range noTidySrcs {
noTidySrcsMap[path] = true
}
@@ -577,20 +569,6 @@
},
})
continue
- case ".rc":
- ctx.Build(pctx, android.BuildParams{
- Rule: windres,
- Description: "windres " + srcFile.Rel(),
- Output: objFile,
- Input: srcFile,
- Implicits: cFlagsDeps,
- OrderOnly: pathDeps,
- Args: map[string]string{
- "windresCmd": mingwCmd(flags.toolchain, "windres"),
- "flags": shareFlags("flags", flags.toolchain.WindresFlags()),
- },
- })
- continue
case ".o":
objFiles[i] = srcFile
continue
@@ -741,7 +719,7 @@
// Generate a rule for compiling multiple .o files to a static library (.a)
func transformObjToStaticLib(ctx android.ModuleContext,
objFiles android.Paths, wholeStaticLibs android.Paths,
- flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths) {
+ flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths, validations android.WritablePaths) {
arCmd := "${config.ClangBin}/llvm-ar"
arFlags := ""
@@ -756,6 +734,7 @@
Output: outputFile,
Inputs: objFiles,
Implicits: deps,
+ Validations: validations.Paths(),
Args: map[string]string{
"arFlags": "crsPD" + arFlags,
"arCmd": arCmd,
diff --git a/cc/cc.go b/cc/cc.go
index 57e7887..32652c1 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -95,6 +95,7 @@
// Used for data dependencies adjacent to tests
DataLibs []string
+ DataBins []string
// Used by DepsMutator to pass system_shared_libs information to check_elf_file.py.
SystemSharedLibs []string
@@ -324,7 +325,7 @@
SnapshotStaticLibs []string `blueprint:"mutated"`
SnapshotRuntimeLibs []string `blueprint:"mutated"`
- Installable *bool
+ Installable *bool `android:"arch_variant"`
// Set by factories of module types that can only be referenced from variants compiled against
// the SDK.
@@ -718,6 +719,7 @@
staticVariantTag = dependencyTag{name: "static variant"}
vndkExtDepTag = dependencyTag{name: "vndk extends"}
dataLibDepTag = dependencyTag{name: "data lib"}
+ dataBinDepTag = dependencyTag{name: "data bin"}
runtimeDepTag = installDependencyTag{name: "runtime lib"}
testPerSrcDepTag = dependencyTag{name: "test_per_src"}
stubImplDepTag = dependencyTag{name: "stub_impl"}
@@ -1863,7 +1865,7 @@
}
func (c *Module) maybeInstall(ctx ModuleContext, apexInfo android.ApexInfo) {
- if !proptools.BoolDefault(c.Properties.Installable, true) {
+ if !proptools.BoolDefault(c.Installable(), true) {
// If the module has been specifically configure to not be installed then
// hide from make as otherwise it will break when running inside make
// as the output path to install will not be specified. Not all uninstallable
@@ -2274,6 +2276,8 @@
{Mutator: "link", Variation: "shared"},
}, dataLibDepTag, deps.DataLibs...)
+ actx.AddVariationDependencies(nil, dataBinDepTag, deps.DataBins...)
+
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "shared"},
}, runtimeDepTag, deps.RuntimeLibs...)
@@ -3245,16 +3249,6 @@
return c.Properties.Test_for
}
-func (c *Module) UniqueApexVariations() bool {
- if u, ok := c.compiler.(interface {
- uniqueApexVariations() bool
- }); ok {
- return u.uniqueApexVariations()
- } else {
- return false
- }
-}
-
func (c *Module) EverInstallable() bool {
return c.installer != nil &&
// Check to see whether the module is actually ever installable.
@@ -3266,6 +3260,11 @@
}
func (c *Module) Installable() *bool {
+ if c.library != nil {
+ if i := c.library.installable(); i != nil {
+ return i
+ }
+ }
return c.Properties.Installable
}
@@ -3451,6 +3450,7 @@
&android.ProtoProperties{},
// RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules.
&RustBindgenClangProperties{},
+ &prebuiltLinkerProperties{},
)
// Bazel module must be initialized _before_ Defaults to be included in cc_defaults module.
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 84c3a86..4c9f579 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3869,10 +3869,99 @@
}
func TestIncludeDirectoryOrdering(t *testing.T) {
- bp := `
+ baseExpectedFlags := []string{
+ "${config.ArmThumbCflags}",
+ "${config.ArmCflags}",
+ "${config.CommonGlobalCflags}",
+ "${config.DeviceGlobalCflags}",
+ "${config.ExternalCflags}",
+ "${config.ArmToolchainCflags}",
+ "${config.ArmArmv7ANeonCflags}",
+ "${config.ArmGenericCflags}",
+ "-target",
+ "armv7a-linux-androideabi20",
+ "-B${config.ArmGccRoot}/arm-linux-androideabi/bin",
+ }
+
+ expectedIncludes := []string{
+ "external/foo/android_arm_export_include_dirs",
+ "external/foo/lib32_export_include_dirs",
+ "external/foo/arm_export_include_dirs",
+ "external/foo/android_export_include_dirs",
+ "external/foo/linux_export_include_dirs",
+ "external/foo/export_include_dirs",
+ "external/foo/android_arm_local_include_dirs",
+ "external/foo/lib32_local_include_dirs",
+ "external/foo/arm_local_include_dirs",
+ "external/foo/android_local_include_dirs",
+ "external/foo/linux_local_include_dirs",
+ "external/foo/local_include_dirs",
+ "external/foo",
+ "external/foo/libheader1",
+ "external/foo/libheader2",
+ "external/foo/libwhole1",
+ "external/foo/libwhole2",
+ "external/foo/libstatic1",
+ "external/foo/libstatic2",
+ "external/foo/libshared1",
+ "external/foo/libshared2",
+ "external/foo/liblinux",
+ "external/foo/libandroid",
+ "external/foo/libarm",
+ "external/foo/lib32",
+ "external/foo/libandroid_arm",
+ "defaults/cc/common/ndk_libc++_shared",
+ "defaults/cc/common/ndk_libandroid_support",
+ }
+
+ conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
+ cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
+
+ cflags := []string{"-Wall", "-Werror"}
+ cstd := []string{"-std=gnu99"}
+ cppstd := []string{"-std=gnu++17", "-fno-rtti"}
+
+ lastIncludes := []string{
+ "out/soong/ndk/sysroot/usr/include",
+ "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
+ }
+
+ combineSlices := func(slices ...[]string) []string {
+ var ret []string
+ for _, s := range slices {
+ ret = append(ret, s...)
+ }
+ return ret
+ }
+
+ testCases := []struct {
+ name string
+ src string
+ expected []string
+ }{
+ {
+ name: "c",
+ src: "foo.c",
+ expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}"}),
+ },
+ {
+ name: "cc",
+ src: "foo.cc",
+ expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}"}),
+ },
+ {
+ name: "assemble",
+ src: "foo.s",
+ expected: combineSlices(baseExpectedFlags, []string{"-D__ASSEMBLY__"}, expectedIncludes, lastIncludes),
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ bp := fmt.Sprintf(`
cc_library {
name: "libfoo",
- srcs: ["foo.c"],
+ srcs: ["%s"],
local_include_dirs: ["local_include_dirs"],
export_include_dirs: ["export_include_dirs"],
export_system_include_dirs: ["export_system_include_dirs"],
@@ -3928,24 +4017,24 @@
sdk_version: "20",
stl: "none",
}
- `
+ `, tc.src)
- libs := []string{
- "libstatic1",
- "libstatic2",
- "libwhole1",
- "libwhole2",
- "libshared1",
- "libshared2",
- "libandroid",
- "libandroid_arm",
- "liblinux",
- "lib32",
- "libarm",
- }
+ libs := []string{
+ "libstatic1",
+ "libstatic2",
+ "libwhole1",
+ "libwhole2",
+ "libshared1",
+ "libshared2",
+ "libandroid",
+ "libandroid_arm",
+ "liblinux",
+ "lib32",
+ "libarm",
+ }
- for _, lib := range libs {
- bp += fmt.Sprintf(`
+ for _, lib := range libs {
+ bp += fmt.Sprintf(`
cc_library {
name: "%s",
export_include_dirs: ["%s"],
@@ -3953,69 +4042,30 @@
stl: "none",
}
`, lib, lib)
+ }
+
+ ctx := android.GroupFixturePreparers(
+ PrepareForIntegrationTestWithCc,
+ android.FixtureAddTextFile("external/foo/Android.bp", bp),
+ ).RunTest(t)
+ // Use the arm variant instead of the arm64 variant so that it gets headers from
+ // ndk_libandroid_support to test LateStaticLibs.
+ cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
+
+ var includes []string
+ flags := strings.Split(cflags, " ")
+ for _, flag := range flags {
+ if strings.HasPrefix(flag, "-I") {
+ includes = append(includes, strings.TrimPrefix(flag, "-I"))
+ } else if flag == "-isystem" {
+ // skip isystem, include next
+ } else if len(flag) > 0 {
+ includes = append(includes, flag)
+ }
+ }
+
+ android.AssertArrayString(t, "includes", tc.expected, includes)
+ })
}
- ctx := android.GroupFixturePreparers(
- PrepareForIntegrationTestWithCc,
- android.FixtureAddTextFile("external/foo/Android.bp", bp),
- ).RunTest(t)
- // Use the arm variant instead of the arm64 variant so that it gets headers from
- // ndk_libandroid_support to test LateStaticLibs.
- cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
-
- var includes []string
- flags := strings.Split(cflags, " ")
- for i, flag := range flags {
- if strings.Contains(flag, "Cflags") {
- includes = append(includes, flag)
- } else if strings.HasPrefix(flag, "-I") {
- includes = append(includes, strings.TrimPrefix(flag, "-I"))
- } else if flag == "-isystem" {
- includes = append(includes, flags[i+1])
- }
- }
-
- want := []string{
- "${config.ArmThumbCflags}",
- "${config.ArmCflags}",
- "${config.CommonGlobalCflags}",
- "${config.DeviceGlobalCflags}",
- "${config.ExternalCflags}",
- "${config.ArmToolchainCflags}",
- "${config.ArmArmv7ANeonCflags}",
- "${config.ArmGenericCflags}",
- "external/foo/android_arm_export_include_dirs",
- "external/foo/lib32_export_include_dirs",
- "external/foo/arm_export_include_dirs",
- "external/foo/android_export_include_dirs",
- "external/foo/linux_export_include_dirs",
- "external/foo/export_include_dirs",
- "external/foo/android_arm_local_include_dirs",
- "external/foo/lib32_local_include_dirs",
- "external/foo/arm_local_include_dirs",
- "external/foo/android_local_include_dirs",
- "external/foo/linux_local_include_dirs",
- "external/foo/local_include_dirs",
- "external/foo",
- "external/foo/libheader1",
- "external/foo/libheader2",
- "external/foo/libwhole1",
- "external/foo/libwhole2",
- "external/foo/libstatic1",
- "external/foo/libstatic2",
- "external/foo/libshared1",
- "external/foo/libshared2",
- "external/foo/liblinux",
- "external/foo/libandroid",
- "external/foo/libarm",
- "external/foo/lib32",
- "external/foo/libandroid_arm",
- "defaults/cc/common/ndk_libc++_shared",
- "defaults/cc/common/ndk_libandroid_support",
- "out/soong/ndk/sysroot/usr/include",
- "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
- "${config.NoOverrideGlobalCflags}",
- }
-
- android.AssertArrayString(t, "includes", want, includes)
}
diff --git a/cc/compiler.go b/cc/compiler.go
index b535e7f..00df669 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -209,15 +209,6 @@
// Build and link with OpenMP
Openmp *bool `android:"arch_variant"`
-
- // Deprecated.
- // Adds __ANDROID_APEX_<APEX_MODULE_NAME>__ macro defined for apex variants in addition to __ANDROID_APEX__
- Use_apex_name_macro *bool
-
- // Adds two macros for apex variants in addition to __ANDROID_APEX__
- // * __ANDROID_APEX_COM_ANDROID_FOO__
- // * __ANDROID_APEX_NAME__="com.android.foo"
- UseApexNameMacro bool `blueprint:"mutated"`
}
func NewBaseCompiler() *baseCompiler {
@@ -291,10 +282,6 @@
return deps
}
-func (compiler *baseCompiler) useApexNameMacro() bool {
- return Bool(compiler.Properties.Use_apex_name_macro) || compiler.Properties.UseApexNameMacro
-}
-
// Return true if the module is in the WarningAllowedProjects.
func warningsAreAllowed(subdir string) bool {
subdir += "/"
@@ -305,6 +292,25 @@
getNamedMapForConfig(ctx.Config(), key).Store(module, true)
}
+func maybeReplaceGnuToC(gnuExtensions *bool, cStd string, cppStd string) (string, string) {
+ if gnuExtensions != nil && *gnuExtensions == false {
+ cStd = gnuToCReplacer.Replace(cStd)
+ cppStd = gnuToCReplacer.Replace(cppStd)
+ }
+ return cStd, cppStd
+}
+
+func parseCppStd(cppStdPtr *string) string {
+ cppStd := String(cppStdPtr)
+ switch cppStd {
+ case "":
+ cppStd = config.CppStdVersion
+ case "experimental":
+ cppStd = config.ExperimentalCppStdVersion
+ }
+ return cppStd
+}
+
// Create a Flags struct that collects the compile flags from global values,
// per-target values, module type values, and per-module Blueprints properties
func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
@@ -386,10 +392,6 @@
if ctx.apexVariationName() != "" {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
- if compiler.useApexNameMacro() {
- flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexVariationName())+"__")
- flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_NAME__='\""+ctx.apexVariationName()+"\"'")
- }
if ctx.Device() {
flags.Global.CommonFlags = append(flags.Global.CommonFlags,
fmt.Sprintf("-D__ANDROID_APEX_MIN_SDK_VERSION__=%d",
@@ -484,18 +486,9 @@
cStd = String(compiler.Properties.C_std)
}
- cppStd := String(compiler.Properties.Cpp_std)
- switch String(compiler.Properties.Cpp_std) {
- case "":
- cppStd = config.CppStdVersion
- case "experimental":
- cppStd = config.ExperimentalCppStdVersion
- }
+ cppStd := parseCppStd(compiler.Properties.Cpp_std)
- if compiler.Properties.Gnu_extensions != nil && *compiler.Properties.Gnu_extensions == false {
- cStd = gnuToCReplacer.Replace(cStd)
- cppStd = gnuToCReplacer.Replace(cppStd)
- }
+ cStd, cppStd = maybeReplaceGnuToC(compiler.Properties.Gnu_extensions, cStd, cppStd)
flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...)
flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...)
@@ -544,11 +537,6 @@
"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
}
- if compiler.hasSrcExt(".mc") {
- flags.Local.CommonFlags = append(flags.Local.CommonFlags,
- "-I"+android.PathForModuleGen(ctx, "windmc", ctx.ModuleDir()).String())
- }
-
if compiler.hasSrcExt(".aidl") {
flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...)
if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
@@ -624,10 +612,6 @@
return false
}
-func (compiler *baseCompiler) uniqueApexVariations() bool {
- return compiler.useApexNameMacro()
-}
-
var invalidDefineCharRegex = regexp.MustCompile("[^a-zA-Z0-9_]")
// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
diff --git a/cc/config/bp2build.go b/cc/config/bp2build.go
index d19f5ac..4797acc 100644
--- a/cc/config/bp2build.go
+++ b/cc/config/bp2build.go
@@ -16,9 +16,13 @@
import (
"fmt"
+ "reflect"
"regexp"
"sort"
"strings"
+
+ "android/soong/android"
+ "github.com/google/blueprint"
)
const (
@@ -26,18 +30,27 @@
)
type bazelVarExporter interface {
- asBazel(exportedStringVariables, exportedStringListVariables) []bazelConstant
+ asBazel(android.Config, exportedStringVariables, exportedStringListVariables, exportedConfigDependingVariables) []bazelConstant
}
// Helpers for exporting cc configuration information to Bazel.
var (
- // Map containing toolchain variables that are independent of the
+ // Maps containing toolchain variables that are independent of the
// environment variables of the build.
exportedStringListVars = exportedStringListVariables{}
exportedStringVars = exportedStringVariables{}
exportedStringListDictVars = exportedStringListDictVariables{}
+
+ /// Maps containing variables that are dependent on the build config.
+ exportedConfigDependingVars = exportedConfigDependingVariables{}
)
+type exportedConfigDependingVariables map[string]interface{}
+
+func (m exportedConfigDependingVariables) Set(k string, v interface{}) {
+ m[k] = v
+}
+
// Ensure that string s has no invalid characters to be generated into the bzl file.
func validateCharacters(s string) string {
for _, c := range []string{`\n`, `"`, `\`} {
@@ -74,10 +87,14 @@
return strings.Join(list, "\n")
}
-func (m exportedStringVariables) asBazel(stringScope exportedStringVariables, stringListScope exportedStringListVariables) []bazelConstant {
+func (m exportedStringVariables) asBazel(config android.Config,
+ stringVars exportedStringVariables, stringListVars exportedStringListVariables, cfgDepVars exportedConfigDependingVariables) []bazelConstant {
ret := make([]bazelConstant, 0, len(m))
for k, variableValue := range m {
- expandedVar := expandVar(variableValue, exportedStringVars, exportedStringListVars)
+ expandedVar, err := expandVar(config, variableValue, stringVars, stringListVars, cfgDepVars)
+ if err != nil {
+ panic(fmt.Errorf("error expanding config variable %s: %s", k, err))
+ }
if len(expandedVar) > 1 {
panic(fmt.Errorf("%s expands to more than one string value: %s", variableValue, expandedVar))
}
@@ -101,7 +118,9 @@
m[k] = v
}
-func (m exportedStringListVariables) asBazel(stringScope exportedStringVariables, stringListScope exportedStringListVariables) []bazelConstant {
+func (m exportedStringListVariables) asBazel(config android.Config,
+ stringScope exportedStringVariables, stringListScope exportedStringListVariables,
+ exportedVars exportedConfigDependingVariables) []bazelConstant {
ret := make([]bazelConstant, 0, len(m))
// For each exported variable, recursively expand elements in the variableValue
// list to ensure that interpolated variables are expanded according to their values
@@ -109,7 +128,11 @@
for k, variableValue := range m {
var expandedVars []string
for _, v := range variableValue {
- expandedVars = append(expandedVars, expandVar(v, stringScope, stringListScope)...)
+ expandedVar, err := expandVar(config, v, stringScope, stringListScope, exportedVars)
+ if err != nil {
+ panic(fmt.Errorf("Error expanding config variable %s=%s: %s", k, v, err))
+ }
+ expandedVars = append(expandedVars, expandedVar...)
}
// Assign the list as a bzl-private variable; this variable will be exported
// out through a constants struct later.
@@ -121,6 +144,18 @@
return ret
}
+// Convenience function to declare a static "source path" variable and export it to Bazel's cc_toolchain.
+func exportVariableConfigMethod(name string, method interface{}) blueprint.Variable {
+ exportedConfigDependingVars.Set(name, method)
+ return pctx.VariableConfigMethod(name, method)
+}
+
+// Convenience function to declare a static "source path" variable and export it to Bazel's cc_toolchain.
+func exportSourcePathVariable(name string, value string) {
+ pctx.SourcePathVariable(name, value)
+ exportedStringVars.Set(name, value)
+}
+
// Convenience function to declare a static variable and export it to Bazel's cc_toolchain.
func exportStringListStaticVariable(name string, value []string) {
pctx.StaticVariable(name, strings.Join(value, " "))
@@ -145,7 +180,8 @@
}
// Since dictionaries are not supported in Ninja, we do not expand variables for dictionaries
-func (m exportedStringListDictVariables) asBazel(_ exportedStringVariables, _ exportedStringListVariables) []bazelConstant {
+func (m exportedStringListDictVariables) asBazel(_ android.Config, _ exportedStringVariables,
+ _ exportedStringListVariables, _ exportedConfigDependingVariables) []bazelConstant {
ret := make([]bazelConstant, 0, len(m))
for k, dict := range m {
ret = append(ret, bazelConstant{
@@ -158,19 +194,20 @@
// BazelCcToolchainVars generates bzl file content containing variables for
// Bazel's cc_toolchain configuration.
-func BazelCcToolchainVars() string {
+func BazelCcToolchainVars(config android.Config) string {
return bazelToolchainVars(
+ config,
exportedStringListDictVars,
exportedStringListVars,
exportedStringVars)
}
-func bazelToolchainVars(vars ...bazelVarExporter) string {
+func bazelToolchainVars(config android.Config, vars ...bazelVarExporter) string {
ret := "# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.\n\n"
results := []bazelConstant{}
for _, v := range vars {
- results = append(results, v.asBazel(exportedStringVars, exportedStringListVars)...)
+ results = append(results, v.asBazel(config, exportedStringVars, exportedStringListVars, exportedConfigDependingVars)...)
}
sort.Slice(results, func(i, j int) bool { return results[i].variableName < results[j].variableName })
@@ -201,34 +238,35 @@
// string slice than to handle a pass-by-referenced map, which would make it
// quite complex to track depth-first interpolations. It's also unlikely the
// interpolation stacks are deep (n > 1).
-func expandVar(toExpand string, stringScope exportedStringVariables, stringListScope exportedStringListVariables) []string {
+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
- expandVarInternal = func(toExpand string, seenVars map[string]bool) []string {
- var ret []string
- for _, v := range strings.Split(toExpand, " ") {
- matches := r.FindStringSubmatch(v)
+ var expandVarInternal func(string, map[string]bool) (string, error)
+ expandVarInternal = func(toExpand string, seenVars map[string]bool) (string, error) {
+ var ret string
+ remainingString := toExpand
+ for len(remainingString) > 0 {
+ matches := r.FindStringSubmatch(remainingString)
if len(matches) == 0 {
- return []string{v}
+ return ret + remainingString, nil
}
-
if len(matches) != 2 {
- panic(fmt.Errorf(
- "Expected to only match 1 subexpression in %s, got %d",
- v,
- len(matches)-1))
+ panic(fmt.Errorf("Expected to only match 1 subexpression in %s, got %d", remainingString, len(matches)-1))
}
+ matchIndex := strings.Index(remainingString, matches[0])
+ ret += remainingString[:matchIndex]
+ remainingString = remainingString[matchIndex+len(matches[0]):]
// Index 1 of FindStringSubmatch contains the subexpression match
// (variable name) of the capture group.
variable := matches[1]
// toExpand contains a variable.
if _, ok := seenVars[variable]; ok {
- panic(fmt.Errorf(
- "Unbounded recursive interpolation of variable: %s", variable))
+ return ret, fmt.Errorf(
+ "Unbounded recursive interpolation of variable: %s", variable)
}
// A map is passed-by-reference. Create a new map for
// this scope to prevent variables seen in one depth-first expansion
@@ -239,15 +277,65 @@
}
newSeenVars[variable] = true
if unexpandedVars, ok := stringListScope[variable]; ok {
+ expandedVars := []string{}
for _, unexpandedVar := range unexpandedVars {
- ret = append(ret, expandVarInternal(unexpandedVar, newSeenVars)...)
+ expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ expandedVars = append(expandedVars, expandedVar)
}
+ ret += strings.Join(expandedVars, " ")
} else if unexpandedVar, ok := stringScope[variable]; ok {
- ret = append(ret, expandVarInternal(unexpandedVar, newSeenVars)...)
+ expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ ret += expandedVar
+ } else if unevaluatedVar, ok := exportedVars[variable]; ok {
+ evalFunc := reflect.ValueOf(unevaluatedVar)
+ validateVariableMethod(variable, evalFunc)
+ evaluatedResult := evalFunc.Call([]reflect.Value{reflect.ValueOf(config)})
+ evaluatedValue := evaluatedResult[0].Interface().(string)
+ expandedVar, err := expandVarInternal(evaluatedValue, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ ret += expandedVar
+ } else {
+ return "", fmt.Errorf("Unbound config variable %s", variable)
}
}
- return ret
+ return ret, nil
+ }
+ var ret []string
+ for _, v := range strings.Split(toExpand, " ") {
+ val, err := expandVarInternal(v, map[string]bool{})
+ if err != nil {
+ return ret, err
+ }
+ ret = append(ret, val)
}
- return expandVarInternal(toExpand, map[string]bool{})
+ return ret, nil
+}
+
+func validateVariableMethod(name string, methodValue reflect.Value) {
+ methodType := methodValue.Type()
+ if methodType.Kind() != reflect.Func {
+ panic(fmt.Errorf("method given for variable %s is not a function",
+ name))
+ }
+ if n := methodType.NumIn(); n != 1 {
+ panic(fmt.Errorf("method for variable %s has %d inputs (should be 1)",
+ name, n))
+ }
+ if n := methodType.NumOut(); n != 1 {
+ panic(fmt.Errorf("method for variable %s has %d outputs (should be 1)",
+ name, n))
+ }
+ if kind := methodType.Out(0).Kind(); kind != reflect.String {
+ panic(fmt.Errorf("method for variable %s does not return a string",
+ name))
+ }
}
diff --git a/cc/config/bp2build_test.go b/cc/config/bp2build_test.go
index 883597a..3118df1 100644
--- a/cc/config/bp2build_test.go
+++ b/cc/config/bp2build_test.go
@@ -16,13 +16,21 @@
import (
"testing"
+
+ "android/soong/android"
)
func TestExpandVars(t *testing.T) {
+ android_arm64_config := android.TestConfig("out", nil, "", nil)
+ android_arm64_config.BuildOS = android.Android
+ android_arm64_config.BuildArch = android.Arm64
+
testCases := []struct {
description string
+ config android.Config
stringScope exportedStringVariables
stringListScope exportedStringListVariables
+ configVars exportedConfigDependingVariables
toExpand string
expectedValues []string
}{
@@ -57,7 +65,7 @@
"bar": []string{"baz", "${qux}"},
},
toExpand: "${foo}",
- expectedValues: []string{"baz", "hello"},
+ expectedValues: []string{"baz hello"},
},
{
description: "double level expansion",
@@ -75,7 +83,7 @@
"b": []string{"d"},
},
toExpand: "${a}",
- expectedValues: []string{"d", "c"},
+ expectedValues: []string{"d c"},
},
{
description: "double level expansion, with two variables in a string",
@@ -85,7 +93,7 @@
"c": []string{"e"},
},
toExpand: "${a}",
- expectedValues: []string{"d", "e"},
+ expectedValues: []string{"d e"},
},
{
description: "triple level expansion with two variables in a string",
@@ -96,13 +104,38 @@
"d": []string{"foo"},
},
toExpand: "${a}",
- expectedValues: []string{"foo", "foo", "foo"},
+ expectedValues: []string{"foo foo foo"},
+ },
+ {
+ description: "expansion with config depending vars",
+ configVars: exportedConfigDependingVariables{
+ "a": func(c android.Config) string { return c.BuildOS.String() },
+ "b": func(c android.Config) string { return c.BuildArch.String() },
+ },
+ config: android_arm64_config,
+ toExpand: "${a}-${b}",
+ expectedValues: []string{"android-arm64"},
+ },
+ {
+ description: "double level multi type expansion",
+ stringListScope: exportedStringListVariables{
+ "platform": []string{"${os}-${arch}"},
+ "const": []string{"const"},
+ },
+ configVars: exportedConfigDependingVariables{
+ "os": func(c android.Config) string { return c.BuildOS.String() },
+ "arch": func(c android.Config) string { return c.BuildArch.String() },
+ "foo": func(c android.Config) string { return "foo" },
+ },
+ config: android_arm64_config,
+ toExpand: "${const}/${platform}/${foo}",
+ expectedValues: []string{"const/android-arm64/foo"},
},
}
for _, testCase := range testCases {
t.Run(testCase.description, func(t *testing.T) {
- output := expandVar(testCase.toExpand, testCase.stringScope, testCase.stringListScope)
+ output, _ := expandVar(testCase.config, testCase.toExpand, testCase.stringScope, testCase.stringListScope, testCase.configVars)
if len(output) != len(testCase.expectedValues) {
t.Errorf("Expected %d values, got %d", len(testCase.expectedValues), len(output))
}
@@ -119,6 +152,7 @@
func TestBazelToolchainVars(t *testing.T) {
testCases := []struct {
name string
+ config android.Config
vars []bazelVarExporter
expectedOut string
}{
@@ -248,7 +282,7 @@
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- out := bazelToolchainVars(tc.vars...)
+ out := bazelToolchainVars(tc.config, tc.vars...)
if out != tc.expectedOut {
t.Errorf("Expected \n%s, got \n%s", tc.expectedOut, out)
}
diff --git a/cc/config/global.go b/cc/config/global.go
index 5f41f9e..7abd2fc 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -77,10 +77,6 @@
// TODO: can we remove this now?
"-Wno-reserved-id-macro",
- // Workaround for ccache with clang.
- // See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html.
- "-Wno-unused-command-line-argument",
-
// Force clang to always output color diagnostics. Ninja will strip the ANSI
// color codes if it is not running in a terminal.
"-fcolor-diagnostics",
@@ -274,8 +270,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r433403"
- ClangDefaultShortVersion = "13.0.2"
+ ClangDefaultVersion = "clang-r433403b"
+ ClangDefaultShortVersion = "13.0.3"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
@@ -329,6 +325,12 @@
// Default to zero initialization.
flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang")
}
+
+ // Workaround for ccache with clang.
+ // See http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html.
+ if ctx.Config().IsEnvTrue("USE_CCACHE") {
+ flags = append(flags, "-Wno-unused-command-line-argument")
+ }
return strings.Join(flags, " ")
})
@@ -364,28 +366,12 @@
exportStringStaticVariable("CLANG_DEFAULT_VERSION", ClangDefaultVersion)
exportStringStaticVariable("CLANG_DEFAULT_SHORT_VERSION", ClangDefaultShortVersion)
- pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase)
- pctx.VariableFunc("ClangBase", func(ctx android.PackageVarContext) string {
- if override := ctx.Config().Getenv("LLVM_PREBUILTS_BASE"); override != "" {
- return override
- }
- return "${ClangDefaultBase}"
- })
- pctx.VariableFunc("ClangVersion", func(ctx android.PackageVarContext) string {
- if override := ctx.Config().Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
- return override
- }
- return ClangDefaultVersion
- })
+ pctx.StaticVariableWithEnvOverride("ClangBase", "LLVM_PREBUILTS_BASE", ClangDefaultBase)
+ pctx.StaticVariableWithEnvOverride("ClangVersion", "LLVM_PREBUILTS_VERSION", ClangDefaultVersion)
pctx.StaticVariable("ClangPath", "${ClangBase}/${HostPrebuiltTag}/${ClangVersion}")
pctx.StaticVariable("ClangBin", "${ClangPath}/bin")
- pctx.VariableFunc("ClangShortVersion", func(ctx android.PackageVarContext) string {
- if override := ctx.Config().Getenv("LLVM_RELEASE_VERSION"); override != "" {
- return override
- }
- return ClangDefaultShortVersion
- })
+ pctx.StaticVariableWithEnvOverride("ClangShortVersion", "LLVM_RELEASE_VERSION", ClangDefaultShortVersion)
pctx.StaticVariable("ClangAsanLibDir", "${ClangBase}/linux-x86/${ClangVersion}/lib64/clang/${ClangShortVersion}/lib/linux")
// These are tied to the version of LLVM directly in external/llvm, so they might trail the host prebuilts
@@ -418,4 +404,30 @@
pctx.StaticVariableWithEnvOverride("REAbiLinkerExecStrategy", "RBE_ABI_LINKER_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
}
-var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
+var HostPrebuiltTag = exportVariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
+
+func ClangPath(ctx android.PathContext, file string) android.SourcePath {
+ type clangToolKey string
+
+ key := android.NewCustomOnceKey(clangToolKey(file))
+
+ return ctx.Config().OnceSourcePath(key, func() android.SourcePath {
+ return clangPath(ctx).Join(ctx, file)
+ })
+}
+
+var clangPathKey = android.NewOnceKey("clangPath")
+
+func clangPath(ctx android.PathContext) android.SourcePath {
+ return ctx.Config().OnceSourcePath(clangPathKey, func() android.SourcePath {
+ clangBase := ClangDefaultBase
+ if override := ctx.Config().Getenv("LLVM_PREBUILTS_BASE"); override != "" {
+ clangBase = override
+ }
+ clangVersion := ClangDefaultVersion
+ if override := ctx.Config().Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
+ clangVersion = override
+ }
+ return android.PathForSource(ctx, clangBase, ctx.Config().PrebuiltOS(), clangVersion)
+ })
+}
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 20384a8..6320dbb 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -95,8 +95,6 @@
YasmFlags() string
- WindresFlags() string
-
Is64Bit() bool
ShlibSuffix() string
@@ -169,10 +167,6 @@
return ""
}
-func (toolchainBase) WindresFlags() string {
- return ""
-}
-
func (toolchainBase) LibclangRuntimeLibraryArch() string {
return ""
}
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index e72efae..9577a8c 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -25,12 +25,20 @@
"android.hardware.authsecret-unstable-ndk_platform",
"android.hardware.automotive.occupant_awareness-V1-ndk",
"android.hardware.automotive.occupant_awareness-V1-ndk_platform",
+ "android.hardware.automotive.occupant_awareness-ndk_platform",
+ "android.hardware.gnss-V1-ndk",
+ "android.hardware.gnss-V1-ndk_platform",
+ "android.hardware.gnss-ndk_platform",
+ "android.hardware.gnss-unstable-ndk_platform",
+ "android.hardware.health-V1-ndk",
+ "android.hardware.health-ndk",
"android.hardware.health.storage-V1-ndk",
"android.hardware.health.storage-V1-ndk_platform",
"android.hardware.health.storage-ndk_platform",
"android.hardware.health.storage-unstable-ndk_platform",
- "android.hardware.identity-V2-ndk",
"android.hardware.identity-V2-ndk_platform",
+ "android.hardware.identity-V3-ndk",
+ "android.hardware.identity-V3-ndk_platform",
"android.hardware.identity-ndk_platform",
"android.hardware.light-V1-ndk",
"android.hardware.light-V1-ndk_platform",
@@ -44,8 +52,9 @@
"android.hardware.oemlock-V1-ndk_platform",
"android.hardware.oemlock-ndk_platform",
"android.hardware.oemlock-unstable-ndk_platform",
- "android.hardware.power-V1-ndk",
"android.hardware.power-V1-ndk_platform",
+ "android.hardware.power-V2-ndk",
+ "android.hardware.power-V2-ndk_platform",
"android.hardware.power-ndk_platform",
"android.hardware.power.stats-V1-ndk",
"android.hardware.power.stats-V1-ndk_platform",
@@ -82,20 +91,22 @@
"android.hardware.security.sharedsecret-V1-ndk_platform",
"android.hardware.security.sharedsecret-ndk_platform",
"android.hardware.security.sharedsecret-unstable-ndk_platform",
- "android.hardware.vibrator-V1-ndk",
"android.hardware.vibrator-V1-ndk_platform",
+ "android.hardware.vibrator-V2-ndk",
+ "android.hardware.vibrator-V2-ndk_platform",
"android.hardware.vibrator-ndk_platform",
"android.hardware.weaver-V1-ndk",
"android.hardware.weaver-V1-ndk_platform",
"android.hardware.weaver-ndk_platform",
"android.hardware.weaver-unstable-ndk_platform",
+ "android.system.suspend-V1-ndk",
"android.system.keystore2-V1-ndk",
"android.hardware.wifi.hostapd-V1-ndk",
"android.hardware.wifi.hostapd-V1-ndk_platform",
+ "android.hardware.wifi.supplicant-V1-ndk",
"android.system.keystore2-V1-ndk_platform",
"android.system.keystore2-ndk_platform",
"android.system.keystore2-unstable-ndk_platform",
- "android.system.suspend-V1-ndk",
"android.system.suspend-V1-ndk_platform",
"libbinder",
"libcrypto",
diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go
index 0bb1a81..ad82b94 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -56,9 +56,7 @@
"10.13",
"10.14",
"10.15",
- "11.0",
- "11.1",
- "11.3",
+ "11",
}
darwinAvailableLibraries = append(
@@ -113,6 +111,10 @@
pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64")
}
+func MacStripPath(ctx android.PathContext) string {
+ return getMacTools(ctx).stripPath
+}
+
type macPlatformTools struct {
once sync.Once
err error
@@ -125,7 +127,7 @@
var macTools = &macPlatformTools{}
-func getMacTools(ctx android.PackageVarContext) *macPlatformTools {
+func getMacTools(ctx android.PathContext) *macPlatformTools {
macTools.once.Do(func() {
xcrunTool := "/usr/bin/xcrun"
@@ -134,7 +136,7 @@
return ""
}
- bytes, err := exec.Command(xcrunTool, args...).Output()
+ bytes, err := exec.Command(xcrunTool, append([]string{"--sdk", "macosx"}, args...)...).Output()
if err != nil {
macTools.err = fmt.Errorf("xcrun %q failed with: %q", args, err)
return ""
@@ -143,34 +145,26 @@
return strings.TrimSpace(string(bytes))
}
- xcrunSdk := func(arg string) string {
- if selected := ctx.Config().Getenv("MAC_SDK_VERSION"); selected != "" {
- if !inList(selected, darwinSupportedSdkVersions) {
- macTools.err = fmt.Errorf("MAC_SDK_VERSION %s isn't supported: %q", selected, darwinSupportedSdkVersions)
- return ""
- }
-
- return xcrun("--sdk", "macosx"+selected, arg)
+ sdkVersion := xcrun("--show-sdk-version")
+ sdkVersionSupported := false
+ for _, version := range darwinSupportedSdkVersions {
+ if version == sdkVersion || strings.HasPrefix(sdkVersion, version+".") {
+ sdkVersionSupported = true
}
-
- for _, sdk := range darwinSupportedSdkVersions {
- bytes, err := exec.Command(xcrunTool, "--sdk", "macosx"+sdk, arg).Output()
- if err == nil {
- return strings.TrimSpace(string(bytes))
- }
- }
- macTools.err = fmt.Errorf("Could not find a supported mac sdk: %q", darwinSupportedSdkVersions)
- return ""
+ }
+ if !sdkVersionSupported {
+ macTools.err = fmt.Errorf("Unsupported macOS SDK version %q not in %v", sdkVersion, darwinSupportedSdkVersions)
+ return
}
- macTools.sdkRoot = xcrunSdk("--show-sdk-path")
+ macTools.sdkRoot = xcrun("--show-sdk-path")
macTools.arPath = xcrun("--find", "ar")
macTools.stripPath = xcrun("--find", "strip")
macTools.toolPath = filepath.Dir(xcrun("--find", "ld"))
})
if macTools.err != nil {
- ctx.Errorf("%q", macTools.err)
+ android.ReportPathErrorf(ctx, "%q", macTools.err)
}
return macTools
}
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index ac5d5f7..43333fa 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -120,40 +120,40 @@
)
func init() {
- pctx.StaticVariable("LinuxGccVersion", linuxGccVersion)
- pctx.StaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
+ exportStringStaticVariable("LinuxGccVersion", linuxGccVersion)
+ exportStringStaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
+
// Most places use the full GCC version. A few only use up to the first two numbers.
if p := strings.Split(linuxGccVersion, "."); len(p) > 2 {
- pctx.StaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
+ exportStringStaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
} else {
- pctx.StaticVariable("ShortLinuxGccVersion", linuxGccVersion)
+ exportStringStaticVariable("ShortLinuxGccVersion", linuxGccVersion)
}
- pctx.SourcePathVariable("LinuxGccRoot",
- "prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}")
+ exportSourcePathVariable("LinuxGccRoot",
+ "prebuilts/gcc/linux-x86/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}")
- pctx.StaticVariable("LinuxGccTriple", "x86_64-linux")
+ exportStringListStaticVariable("LinuxGccTriple", []string{"x86_64-linux"})
- pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " "))
- pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " "))
- pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLdflags, " "))
+ exportStringListStaticVariable("LinuxCflags", linuxCflags)
+ exportStringListStaticVariable("LinuxLdflags", linuxLdflags)
+ exportStringListStaticVariable("LinuxLldflags", linuxLdflags)
+ exportStringListStaticVariable("LinuxGlibcCflags", linuxGlibcCflags)
+ exportStringListStaticVariable("LinuxGlibcLdflags", linuxGlibcLdflags)
+ exportStringListStaticVariable("LinuxGlibcLldflags", linuxGlibcLdflags)
+ exportStringListStaticVariable("LinuxMuslCflags", linuxMuslCflags)
+ exportStringListStaticVariable("LinuxMuslLdflags", linuxMuslLdflags)
+ exportStringListStaticVariable("LinuxMuslLldflags", linuxMuslLdflags)
- pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " "))
- pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " "))
- pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " "))
- pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " "))
- pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " "))
- pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " "))
+ exportStringListStaticVariable("LinuxX86Cflags", linuxX86Cflags)
+ exportStringListStaticVariable("LinuxX8664Cflags", linuxX8664Cflags)
+ exportStringListStaticVariable("LinuxX86Ldflags", linuxX86Ldflags)
+ exportStringListStaticVariable("LinuxX86Lldflags", linuxX86Ldflags)
+ exportStringListStaticVariable("LinuxX8664Ldflags", linuxX8664Ldflags)
+ exportStringListStaticVariable("LinuxX8664Lldflags", linuxX8664Ldflags)
// Yasm flags
- pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86")
- pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64")
-
- pctx.StaticVariable("LinuxGlibcCflags", strings.Join(linuxGlibcCflags, " "))
- pctx.StaticVariable("LinuxGlibcLdflags", strings.Join(linuxGlibcLdflags, " "))
- pctx.StaticVariable("LinuxGlibcLldflags", strings.Join(linuxGlibcLdflags, " "))
- pctx.StaticVariable("LinuxMuslCflags", strings.Join(linuxMuslCflags, " "))
- pctx.StaticVariable("LinuxMuslLdflags", strings.Join(linuxMuslLdflags, " "))
- pctx.StaticVariable("LinuxMuslLldflags", strings.Join(linuxMuslLdflags, " "))
+ exportStringListStaticVariable("LinuxX86YasmFlags", []string{"-f elf32 -m x86"})
+ exportStringListStaticVariable("LinuxX8664YasmFlags", []string{"-f elf64 -m amd64"})
}
type toolchainLinux struct {
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index d9a7537..9daf40f 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -188,14 +188,6 @@
return "${config.WindowsIncludeFlags}"
}
-func (t *toolchainWindowsX86) WindresFlags() string {
- return "-F pe-i386"
-}
-
-func (t *toolchainWindowsX8664) WindresFlags() string {
- return "-F pe-x86-64"
-}
-
func (t *toolchainWindowsX86) ClangTriple() string {
return "i686-windows-gnu"
}
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 83f0037..e987fe4 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -79,54 +79,21 @@
return flags
}
-// This function performs a breadth-first search over the provided module's
-// dependencies using `visitDirectDeps` to enumerate all shared library
-// dependencies. We require breadth-first expansion, as otherwise we may
-// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
-// from a dependency. This may cause issues when dependencies have explicit
-// sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
-func collectAllSharedDependencies(ctx android.SingletonContext, module android.Module) android.Paths {
- var fringe []android.Module
-
- seen := make(map[string]bool)
-
- // Enumerate the first level of dependencies, as we discard all non-library
- // modules in the BFS loop below.
- ctx.VisitDirectDeps(module, func(dep android.Module) {
- if isValidSharedDependency(dep) {
- fringe = append(fringe, dep)
- }
- })
-
- var sharedLibraries android.Paths
-
- for i := 0; i < len(fringe); i++ {
- module := fringe[i]
- if seen[module.Name()] {
- continue
- }
- seen[module.Name()] = true
-
- ccModule := module.(*Module)
- sharedLibraries = append(sharedLibraries, ccModule.UnstrippedOutputFile())
- ctx.VisitDirectDeps(module, func(dep android.Module) {
- if isValidSharedDependency(dep) && !seen[dep.Name()] {
- fringe = append(fringe, dep)
- }
- })
+func UnstrippedOutputFile(module android.Module) android.Path {
+ if mod, ok := module.(LinkableInterface); ok {
+ return mod.UnstrippedOutputFile()
}
-
- return sharedLibraries
+ panic("UnstrippedOutputFile called on non-LinkableInterface module: " + module.Name())
}
-// This function takes a module and determines if it is a unique shared library
+// IsValidSharedDependency takes a module and determines if it is a unique shared library
// that should be installed in the fuzz target output directories. This function
// returns true, unless:
// - The module is not an installable shared library, or
// - The module is a header or stub, or
// - The module is a prebuilt and its source is available, or
// - The module is a versioned member of an SDK snapshot.
-func isValidSharedDependency(dependency android.Module) bool {
+func IsValidSharedDependency(dependency android.Module) bool {
// TODO(b/144090547): We should be parsing these modules using
// ModuleDependencyTag instead of the current brute-force checking.
@@ -156,7 +123,7 @@
}
// Discard installable:false libraries because they are expected to be absent
// in runtime.
- if !proptools.BoolDefault(ccLibrary.Properties.Installable, true) {
+ if !proptools.BoolDefault(ccLibrary.Installable(), true) {
return false
}
}
@@ -246,7 +213,7 @@
}
seen[child.Name()] = true
- if isValidSharedDependency(child) {
+ if IsValidSharedDependency(child) {
sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
return true
}
@@ -304,7 +271,6 @@
// their architecture & target/host specific zip file.
type ccFuzzPackager struct {
fuzz.FuzzPackager
- sharedLibInstallStrings []string
}
func fuzzPackagingFactory() android.Singleton {
@@ -317,14 +283,14 @@
// archive}).
archDirs := make(map[fuzz.ArchOs][]fuzz.FileToZip)
- // Map tracking whether each shared library has an install rule to avoid duplicate install rules from
- // multiple fuzzers that depend on the same shared library.
- sharedLibraryInstalled := make(map[string]bool)
-
// List of individual fuzz targets, so that 'make fuzz' also installs the targets
// to the correct output directories as well.
s.FuzzTargets = make(map[string]bool)
+ // Map tracking whether each shared library has an install rule to avoid duplicate install rules from
+ // multiple fuzzers that depend on the same shared library.
+ sharedLibraryInstalled := make(map[string]bool)
+
ctx.VisitAllModules(func(module android.Module) {
ccModule, ok := module.(*Module)
if !ok || ccModule.Properties.PreventInstall {
@@ -351,7 +317,7 @@
archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
// Grab the list of required shared libraries.
- sharedLibraries := collectAllSharedDependencies(ctx, module)
+ sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, UnstrippedOutputFile, IsValidSharedDependency)
var files []fuzz.FileToZip
builder := android.NewRuleBuilder(pctx, ctx)
@@ -359,39 +325,8 @@
// Package the corpus, data, dict and config into a zipfile.
files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder)
- // Find and mark all the transiently-dependent shared libraries for
- // packaging.
- for _, library := range sharedLibraries {
- files = append(files, fuzz.FileToZip{library, "lib"})
-
- // For each architecture-specific shared library dependency, we need to
- // install it to the output directory. Setup the install destination here,
- // which will be used by $(copy-many-files) in the Make backend.
- installDestination := sharedLibraryInstallLocation(
- library, ccModule.Host(), archString)
- if sharedLibraryInstalled[installDestination] {
- continue
- }
- sharedLibraryInstalled[installDestination] = true
-
- // Escape all the variables, as the install destination here will be called
- // via. $(eval) in Make.
- installDestination = strings.ReplaceAll(
- installDestination, "$", "$$")
- s.sharedLibInstallStrings = append(s.sharedLibInstallStrings,
- library.String()+":"+installDestination)
-
- // Ensure that on device, the library is also reinstalled to the /symbols/
- // dir. Symbolized DSO's are always installed to the device when fuzzing, but
- // we want symbolization tools (like `stack`) to be able to find the symbols
- // in $ANDROID_PRODUCT_OUT/symbols automagically.
- if !ccModule.Host() {
- symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString)
- symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
- s.sharedLibInstallStrings = append(s.sharedLibInstallStrings,
- library.String()+":"+symbolsInstallDestination)
- }
- }
+ // Package shared libraries
+ files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...)
// The executable.
files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""})
@@ -409,15 +344,54 @@
func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
packages := s.Packages.Strings()
sort.Strings(packages)
- sort.Strings(s.sharedLibInstallStrings)
+ sort.Strings(s.FuzzPackager.SharedLibInstallStrings)
// TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's
// ready to handle phony targets created in Soong. In the meantime, this
// exports the phony 'fuzz' target and dependencies on packages to
// core/main.mk so that we can use dist-for-goals.
ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
ctx.Strict("FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
- strings.Join(s.sharedLibInstallStrings, " "))
+ strings.Join(s.FuzzPackager.SharedLibInstallStrings, " "))
// Preallocate the slice of fuzz targets to minimise memory allocations.
s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS")
}
+
+// GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for
+// packaging.
+func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip {
+ var files []fuzz.FileToZip
+
+ for _, library := range sharedLibraries {
+ files = append(files, fuzz.FileToZip{library, "lib"})
+
+ // For each architecture-specific shared library dependency, we need to
+ // install it to the output directory. Setup the install destination here,
+ // which will be used by $(copy-many-files) in the Make backend.
+ installDestination := sharedLibraryInstallLocation(
+ library, module.Host(), archString)
+ if (*sharedLibraryInstalled)[installDestination] {
+ continue
+ }
+ (*sharedLibraryInstalled)[installDestination] = true
+
+ // Escape all the variables, as the install destination here will be called
+ // via. $(eval) in Make.
+ installDestination = strings.ReplaceAll(
+ installDestination, "$", "$$")
+ s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
+ library.String()+":"+installDestination)
+
+ // Ensure that on device, the library is also reinstalled to the /symbols/
+ // dir. Symbolized DSO's are always installed to the device when fuzzing, but
+ // we want symbolization tools (like `stack`) to be able to find the symbols
+ // in $ANDROID_PRODUCT_OUT/symbols automagically.
+ if !module.Host() {
+ symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString)
+ symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
+ s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
+ library.String()+":"+symbolsInstallDestination)
+ }
+ }
+ return files
+}
diff --git a/cc/gen.go b/cc/gen.go
index 3a1a0e2..8f62363 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -45,13 +45,6 @@
CommandDeps: []string{"$syspropCmd"},
},
"headerOutDir", "publicOutDir", "srcOutDir", "includeName")
-
- windmc = pctx.AndroidStaticRule("windmc",
- blueprint.RuleParams{
- Command: "$windmcCmd -r$$(dirname $out) -h$$(dirname $out) $in",
- CommandDeps: []string{"$windmcCmd"},
- },
- "windmcCmd")
)
type YaccProperties struct {
@@ -200,26 +193,6 @@
return cppFile, headers.Paths()
}
-func genWinMsg(ctx android.ModuleContext, srcFile android.Path, flags builderFlags) (android.Path, android.Path) {
- headerFile := android.GenPathWithExt(ctx, "windmc", srcFile, "h")
- rcFile := android.GenPathWithExt(ctx, "windmc", srcFile, "rc")
-
- windmcCmd := mingwCmd(flags.toolchain, "windmc")
-
- ctx.Build(pctx, android.BuildParams{
- Rule: windmc,
- Description: "windmc " + srcFile.Rel(),
- Output: rcFile,
- ImplicitOutput: headerFile,
- Input: srcFile,
- Args: map[string]string{
- "windmcCmd": windmcCmd,
- },
- })
-
- return rcFile, headerFile
-}
-
// Used to communicate information from the genSources method back to the library code that uses
// it.
type generatedSourceInfo struct {
@@ -305,10 +278,6 @@
cppFile := rsGeneratedCppFile(ctx, srcFile)
rsFiles = append(rsFiles, srcFiles[i])
srcFiles[i] = cppFile
- case ".mc":
- rcFile, headerFile := genWinMsg(ctx, srcFile, buildFlags)
- srcFiles[i] = rcFile
- deps = append(deps, headerFile)
case ".sysprop":
cppFile, headerFiles := genSysprop(ctx, srcFile)
srcFiles[i] = cppFile
diff --git a/cc/genrule.go b/cc/genrule.go
index 9df5228..239064f 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -15,6 +15,8 @@
package cc
import (
+ "fmt"
+
"android/soong/android"
"android/soong/genrule"
"android/soong/snapshot"
@@ -36,13 +38,23 @@
// cc_genrule is a genrule that can depend on other cc_* objects.
// The cmd may be run multiple times, once for each of the different arch/etc
-// variations.
+// variations. The following environment variables will be set when the command
+// execute:
+//
+// CC_ARCH the name of the architecture the command is being executed for
+//
+// CC_MULTILIB "lib32" if the architecture the command is being executed for is 32-bit,
+// "lib64" if it is 64-bit.
+//
+// CC_NATIVE_BRIDGE the name of the subdirectory that native bridge libraries are stored in if
+// the architecture has native bridge enabled, empty if it is disabled.
func GenRuleFactory() android.Module {
module := genrule.NewGenRule()
extra := &GenruleExtraProperties{}
module.Extra = extra
module.ImageInterface = extra
+ module.CmdModifier = genruleCmdModifier
module.AddProperties(module.Extra)
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibBoth)
@@ -53,6 +65,13 @@
return module
}
+func genruleCmdModifier(ctx android.ModuleContext, cmd string) string {
+ target := ctx.Target()
+ arch := target.Arch.ArchType
+ return fmt.Sprintf("CC_ARCH=%s CC_NATIVE_BRIDGE=%s CC_MULTILIB=%s && %s",
+ arch.Name, target.NativeBridgeRelativePath, arch.Multilib, cmd)
+}
+
var _ android.ImageInterface = (*GenruleExtraProperties)(nil)
func (g *GenruleExtraProperties) ImageMutatorBegin(ctx android.BaseModuleContext) {}
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index b6afb05..f25f704 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -115,3 +115,75 @@
t.Errorf(`want inputs %v, got %v`, expected, got)
}
}
+
+func TestCmdPrefix(t *testing.T) {
+ bp := `
+ cc_genrule {
+ name: "gen",
+ cmd: "echo foo",
+ out: ["out"],
+ native_bridge_supported: true,
+ }
+ `
+
+ testCases := []struct {
+ name string
+ variant string
+ preparer android.FixturePreparer
+
+ arch string
+ nativeBridge string
+ multilib string
+ }{
+ {
+ name: "arm",
+ variant: "android_arm_armv7-a-neon",
+ arch: "arm",
+ multilib: "lib32",
+ },
+ {
+ name: "arm64",
+ variant: "android_arm64_armv8-a",
+ arch: "arm64",
+ multilib: "lib64",
+ },
+ {
+ name: "nativebridge",
+ variant: "android_native_bridge_arm_armv7-a-neon",
+ preparer: android.FixtureModifyConfig(func(config android.Config) {
+ config.Targets[android.Android] = []android.Target{
+ {
+ Os: android.Android,
+ Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}},
+ NativeBridge: android.NativeBridgeDisabled,
+ },
+ {
+ Os: android.Android,
+ Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}},
+ NativeBridge: android.NativeBridgeEnabled,
+ NativeBridgeHostArchName: "x86",
+ NativeBridgeRelativePath: "arm",
+ },
+ }
+ }),
+ arch: "arm",
+ multilib: "lib32",
+ nativeBridge: "arm",
+ },
+ }
+
+ for _, tt := range testCases {
+ t.Run(tt.name, func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForIntegrationTestWithCc,
+ android.OptionalFixturePreparer(tt.preparer),
+ ).RunTestWithBp(t, bp)
+ gen := result.ModuleForTests("gen", tt.variant)
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, gen.Output("genrule.sbox.textproto"))
+ cmd := *sboxProto.Commands[0].Command
+ android.AssertStringDoesContain(t, "incorrect CC_ARCH", cmd, "CC_ARCH="+tt.arch+" ")
+ android.AssertStringDoesContain(t, "incorrect CC_NATIVE_BRIDGE", cmd, "CC_NATIVE_BRIDGE="+tt.nativeBridge+" ")
+ android.AssertStringDoesContain(t, "incorrect CC_MULTILIB", cmd, "CC_MULTILIB="+tt.multilib+" ")
+ })
+ }
+}
diff --git a/cc/installer.go b/cc/installer.go
index f95b493..2522610 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -29,6 +29,9 @@
// Install output directly in {partition}/, not in any subdir. This is only intended for use by
// init_first_stage.
Install_in_root *bool `android:"arch_variant"`
+
+ // Install output directly in {partition}/xbin
+ Install_in_xbin *bool `android:"arch_vvariant"`
}
type installLocation int
@@ -73,6 +76,8 @@
if installer.installInRoot() {
dir = ""
+ } else if installer.installInXbin() {
+ dir = "xbin"
}
if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
@@ -123,3 +128,7 @@
func (installer *baseInstaller) installInRoot() bool {
return Bool(installer.Properties.Install_in_root)
}
+
+func (installer *baseInstaller) installInXbin() bool {
+ return Bool(installer.Properties.Install_in_xbin)
+}
diff --git a/cc/library.go b/cc/library.go
index de9d01e..c3f7305 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -159,6 +159,8 @@
Export_static_lib_headers []string `android:"arch_variant"`
Apex_available []string `android:"arch_variant"`
+
+ Installable *bool `android:"arch_variant"`
}
type LibraryMutatedProperties struct {
@@ -248,16 +250,21 @@
Linkopts bazel.StringListAttribute
Use_libcrt bazel.BoolAttribute
Rtti bazel.BoolAttribute
- Stl *string
+
+ Stl *string
+ Cpp_std *string
// This is shared only.
- Version_script bazel.LabelAttribute
+ Link_crt bazel.BoolAttribute
+ Additional_linker_inputs bazel.LabelListAttribute
// Common properties shared between both shared and static variants.
Shared staticOrSharedAttributes
Static staticOrSharedAttributes
Strip stripAttributes
+
+ Features bazel.StringListAttribute
}
type stripAttributes struct {
@@ -288,8 +295,9 @@
sharedAttrs := bp2BuildParseSharedProps(ctx, m)
staticAttrs := bp2BuildParseStaticProps(ctx, m)
- compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
- linkerAttrs := bp2BuildParseLinkerProps(ctx, m)
+ baseAttributes := bp2BuildParseBaseProps(ctx, m)
+ compilerAttrs := baseAttributes.compilerAttributes
+ linkerAttrs := baseAttributes.linkerAttributes
exportedIncludes := bp2BuildParseExportedIncludes(ctx, m)
srcs := compilerAttrs.srcs
@@ -304,6 +312,7 @@
Srcs: srcs,
Srcs_c: compilerAttrs.cSrcs,
Srcs_as: compilerAttrs.asSrcs,
+ Hdrs: compilerAttrs.hdrs,
Copts: compilerAttrs.copts,
Cppflags: compilerAttrs.cppFlags,
@@ -321,11 +330,13 @@
Local_includes: compilerAttrs.localIncludes,
Absolute_includes: compilerAttrs.absoluteIncludes,
Linkopts: linkerAttrs.linkopts,
+ Link_crt: linkerAttrs.linkCrt,
Use_libcrt: linkerAttrs.useLibcrt,
Rtti: compilerAttrs.rtti,
Stl: compilerAttrs.stl,
+ Cpp_std: compilerAttrs.cppStd,
- Version_script: linkerAttrs.versionScript,
+ Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
Strip: stripAttributes{
Keep_symbols: linkerAttrs.stripKeepSymbols,
@@ -338,6 +349,8 @@
Shared: sharedAttrs,
Static: staticAttrs,
+
+ Features: linkerAttrs.features,
}
props := bazel.BazelTargetModuleProperties{
@@ -345,7 +358,7 @@
Bzl_load_location: "//build/bazel/rules:full_cc_library.bzl",
}
- ctx.CreateBazelTargetModule(m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
}
// cc_library creates both static and/or shared libraries for a device and/or
@@ -630,7 +643,7 @@
func (handler *ccLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
if err != nil {
ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
return false
@@ -956,7 +969,7 @@
nativeAbiResult.versionScript)
// Parse symbol file to get API list for coverage
- if library.stubsVersion() == "current" && ctx.PrimaryArch() {
+ if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
}
@@ -1035,6 +1048,10 @@
androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer)
availableFor(string) bool
+
+ getAPIListCoverageXMLPath() android.ModuleOutPath
+
+ installable() *bool
}
type versionedInterface interface {
@@ -1277,7 +1294,7 @@
}
}
- transformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, objs.tidyFiles)
+ transformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, nil, objs.tidyFiles)
library.coverageOutputFile = transformCoverageFilesToZip(ctx, library.objects, ctx.ModuleName())
@@ -1406,10 +1423,9 @@
linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
- linkerDeps = append(linkerDeps, objs.tidyFiles...)
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
- linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, nil)
+ linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyFiles)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
@@ -1960,6 +1976,15 @@
return android.CheckAvailableForApex(what, list)
}
+func (library *libraryDecorator) installable() *bool {
+ if library.static() {
+ return library.StaticProperties.Static.Installable
+ } else if library.shared() {
+ return library.SharedProperties.Shared.Installable
+ }
+ return nil
+}
+
func (library *libraryDecorator) makeUninstallable(mod *Module) {
if library.static() && library.buildStatic() && !library.buildStubs() {
// If we're asked to make a static library uninstallable we don't do
@@ -1971,6 +1996,10 @@
mod.ModuleBase.MakeUninstallable()
}
+func (library *libraryDecorator) getAPIListCoverageXMLPath() android.ModuleOutPath {
+ return library.apiListCoverageXmlPath
+}
+
var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList")
// versioningMacroNamesList returns a singleton map, where keys are "version macro names",
@@ -2342,8 +2371,10 @@
}
isStatic := modType == "cc_library_static"
- compilerAttrs := bp2BuildParseCompilerProps(ctx, module)
- linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
+ baseAttributes := bp2BuildParseBaseProps(ctx, module)
+ compilerAttrs := baseAttributes.compilerAttributes
+ linkerAttrs := baseAttributes.linkerAttributes
+
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
// Append shared/static{} stanza properties. These won't be specified on
@@ -2373,6 +2404,7 @@
Srcs_c: compilerAttrs.cSrcs,
Srcs_as: compilerAttrs.asSrcs,
Copts: compilerAttrs.copts,
+ Hdrs: compilerAttrs.hdrs,
Deps: linkerAttrs.deps,
Implementation_deps: linkerAttrs.implementationDeps,
@@ -2387,10 +2419,10 @@
attrs = &bazelCcLibraryStaticAttributes{
staticOrSharedAttributes: commonAttrs,
- Linkopts: linkerAttrs.linkopts,
Use_libcrt: linkerAttrs.useLibcrt,
Rtti: compilerAttrs.rtti,
Stl: compilerAttrs.stl,
+ Cpp_std: compilerAttrs.cppStd,
Export_includes: exportedIncludes.Includes,
Export_system_includes: exportedIncludes.SystemIncludes,
Local_includes: compilerAttrs.localIncludes,
@@ -2399,6 +2431,8 @@
Cppflags: compilerAttrs.cppFlags,
Conlyflags: compilerAttrs.conlyFlags,
Asflags: asFlags,
+
+ Features: linkerAttrs.features,
}
} else {
attrs = &bazelCcLibrarySharedAttributes{
@@ -2409,15 +2443,17 @@
Asflags: asFlags,
Linkopts: linkerAttrs.linkopts,
+ Link_crt: linkerAttrs.linkCrt,
Use_libcrt: linkerAttrs.useLibcrt,
Rtti: compilerAttrs.rtti,
Stl: compilerAttrs.stl,
+ Cpp_std: compilerAttrs.cppStd,
- Export_includes: exportedIncludes.Includes,
- Export_system_includes: exportedIncludes.SystemIncludes,
- Local_includes: compilerAttrs.localIncludes,
- Absolute_includes: compilerAttrs.absoluteIncludes,
- Version_script: linkerAttrs.versionScript,
+ Export_includes: exportedIncludes.Includes,
+ Export_system_includes: exportedIncludes.SystemIncludes,
+ Local_includes: compilerAttrs.localIncludes,
+ Absolute_includes: compilerAttrs.absoluteIncludes,
+ Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
Strip: stripAttributes{
Keep_symbols: linkerAttrs.stripKeepSymbols,
@@ -2426,6 +2462,8 @@
All: linkerAttrs.stripAll,
None: linkerAttrs.stripNone,
},
+
+ Features: linkerAttrs.features,
}
}
@@ -2434,17 +2472,17 @@
Bzl_load_location: fmt.Sprintf("//build/bazel/rules:%s.bzl", modType),
}
- ctx.CreateBazelTargetModule(module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
}
// TODO(b/199902614): Can this be factored to share with the other Attributes?
type bazelCcLibraryStaticAttributes struct {
staticOrSharedAttributes
- Linkopts bazel.StringListAttribute
Use_libcrt bazel.BoolAttribute
Rtti bazel.BoolAttribute
Stl *string
+ Cpp_std *string
Export_includes bazel.StringListAttribute
Export_system_includes bazel.StringListAttribute
@@ -2455,6 +2493,8 @@
Cppflags bazel.StringListAttribute
Conlyflags bazel.StringListAttribute
Asflags bazel.StringListAttribute
+
+ Features bazel.StringListAttribute
}
func CcLibraryStaticBp2Build(ctx android.TopDownMutatorContext) {
@@ -2466,9 +2506,11 @@
staticOrSharedAttributes
Linkopts bazel.StringListAttribute
+ Link_crt bazel.BoolAttribute // Only for linking shared library (and cc_binary)
Use_libcrt bazel.BoolAttribute
Rtti bazel.BoolAttribute
Stl *string
+ Cpp_std *string
Export_includes bazel.StringListAttribute
Export_system_includes bazel.StringListAttribute
@@ -2476,12 +2518,14 @@
Absolute_includes bazel.StringListAttribute
Hdrs bazel.LabelListAttribute
- Strip stripAttributes
- Version_script bazel.LabelAttribute
+ Strip stripAttributes
+ Additional_linker_inputs bazel.LabelListAttribute
Cppflags bazel.StringListAttribute
Conlyflags bazel.StringListAttribute
Asflags bazel.StringListAttribute
+
+ Features bazel.StringListAttribute
}
func CcLibrarySharedBp2Build(ctx android.TopDownMutatorContext) {
diff --git a/cc/library_headers.go b/cc/library_headers.go
index cabeb01..ede6ab3 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -57,7 +57,7 @@
func (h *libraryHeaderBazelHander) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
if err != nil {
ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
return false
@@ -132,7 +132,8 @@
}
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
- linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
+ baseAttributes := bp2BuildParseBaseProps(ctx, module)
+ linkerAttrs := baseAttributes.linkerAttributes
attrs := &bazelCcLibraryHeadersAttributes{
Export_includes: exportedIncludes.Includes,
@@ -140,6 +141,7 @@
Implementation_deps: linkerAttrs.implementationDeps,
Deps: linkerAttrs.deps,
System_dynamic_deps: linkerAttrs.systemDynamicDeps,
+ Hdrs: baseAttributes.hdrs,
}
props := bazel.BazelTargetModuleProperties{
@@ -147,5 +149,5 @@
Bzl_load_location: "//build/bazel/rules:cc_library_headers.bzl",
}
- ctx.CreateBazelTargetModule(module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
}
diff --git a/cc/linkable.go b/cc/linkable.go
index b510508..560c9de 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -110,6 +110,7 @@
BaseModuleName() string
OutputFile() android.OptionalPath
+ UnstrippedOutputFile() android.Path
CoverageFiles() android.Paths
NonCcVariants() bool
diff --git a/cc/linker.go b/cc/linker.go
index 0d612b5..aaaca7a 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -27,6 +27,10 @@
// This file contains the basic functionality for linking against static libraries and shared
// libraries. Final linking into libraries or executables is handled in library.go, binary.go, etc.
+const (
+ packRelocationsDefault = true
+)
+
type BaseLinkerProperties struct {
// list of modules whose object files should be linked into this module
// in their entirety. For static library modules, all of the .o files from the intermediate
@@ -238,6 +242,19 @@
return &ret
}
+func (blp *BaseLinkerProperties) crt() *bool {
+ val := invertBoolPtr(blp.Nocrt)
+ if val != nil && *val {
+ // == True
+ //
+ // Since crt is enabled for almost every module compiling against the Bionic runtime,
+ // use `nil` when it's enabled, and rely on the Starlark macro to set it to True by default.
+ // This keeps the BUILD files clean.
+ return nil
+ }
+ return val // can be False or nil
+}
+
func (blp *BaseLinkerProperties) libCrt() *bool {
return invertBoolPtr(blp.No_libcrt)
}
@@ -458,7 +475,7 @@
if linker.useClangLld(ctx) {
flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod))
- if !BoolDefault(linker.Properties.Pack_relocations, true) {
+ if !BoolDefault(linker.Properties.Pack_relocations, packRelocationsDefault) {
flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none")
} else if ctx.Device() {
// SHT_RELR relocations are only supported at API level >= 30.
diff --git a/cc/lto.go b/cc/lto.go
index d9a0118..6d55579 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -49,8 +49,9 @@
// Dep properties indicate that this module needs to be built with LTO
// since it is an object dependency of an LTO module.
- FullDep bool `blueprint:"mutated"`
- ThinDep bool `blueprint:"mutated"`
+ FullDep bool `blueprint:"mutated"`
+ ThinDep bool `blueprint:"mutated"`
+ NoLtoDep bool `blueprint:"mutated"`
// Use clang lld instead of gnu ld.
Use_clang_lld *bool
@@ -70,15 +71,6 @@
func (lto *lto) begin(ctx BaseModuleContext) {
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
lto.Properties.Lto.Never = proptools.BoolPtr(true)
- } else if ctx.Config().IsEnvTrue("GLOBAL_THINLTO") {
- staticLib := ctx.static() && !ctx.staticBinary()
- hostBin := ctx.Host()
- vndk := ctx.isVndk() // b/169217596
- if !staticLib && !hostBin && !vndk {
- if !lto.Never() && !lto.FullLTO() {
- lto.Properties.Lto.Thin = proptools.BoolPtr(true)
- }
- }
}
}
@@ -96,22 +88,27 @@
return flags
}
- if lto.LTO() {
- var ltoFlag string
+ if lto.LTO(ctx) {
+ var ltoCFlag string
+ var ltoLdFlag string
if lto.ThinLTO() {
- ltoFlag = "-flto=thin -fsplit-lto-unit"
+ ltoCFlag = "-flto=thin -fsplit-lto-unit"
+ } else if lto.FullLTO() {
+ ltoCFlag = "-flto"
} else {
- ltoFlag = "-flto"
+ ltoCFlag = "-flto=thin -fsplit-lto-unit"
+ ltoLdFlag = "-Wl,--lto-O0"
}
- flags.Local.CFlags = append(flags.Local.CFlags, ltoFlag)
- flags.Local.LdFlags = append(flags.Local.LdFlags, ltoFlag)
+ flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlag)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, ltoCFlag)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, ltoLdFlag)
if Bool(lto.Properties.Whole_program_vtables) {
flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-program-vtables")
}
- if lto.ThinLTO() && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) {
+ if (lto.DefaultThinLTO(ctx) || lto.ThinLTO()) && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) {
// Set appropriate ThinLTO cache policy
cacheDirFormat := "-Wl,--thinlto-cache-dir="
cacheDir := android.PathForOutput(ctx, "thinlto-cache").String()
@@ -134,33 +131,40 @@
return flags
}
-// Can be called with a null receiver
-func (lto *lto) LTO() bool {
- if lto == nil || lto.Never() {
- return false
- }
+func (lto *lto) LTO(ctx BaseModuleContext) bool {
+ return lto.ThinLTO() || lto.FullLTO() || lto.DefaultThinLTO(ctx)
+}
- return lto.FullLTO() || lto.ThinLTO()
+func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool {
+ host := ctx.Host()
+ vndk := ctx.isVndk() // b/169217596
+ return GlobalThinLTO(ctx) && !lto.Never() && !host && !vndk
}
func (lto *lto) FullLTO() bool {
- return Bool(lto.Properties.Lto.Full)
+ return lto != nil && Bool(lto.Properties.Lto.Full)
}
func (lto *lto) ThinLTO() bool {
- return Bool(lto.Properties.Lto.Thin)
+ return lto != nil && Bool(lto.Properties.Lto.Thin)
}
-// Is lto.never explicitly set to true?
func (lto *lto) Never() bool {
- return Bool(lto.Properties.Lto.Never)
+ return lto != nil && Bool(lto.Properties.Lto.Never)
+}
+
+func GlobalThinLTO(ctx android.BaseModuleContext) bool {
+ return ctx.Config().IsEnvTrue("GLOBAL_THINLTO")
}
// Propagate lto requirements down from binaries
func ltoDepsMutator(mctx android.TopDownMutatorContext) {
- if m, ok := mctx.Module().(*Module); ok && m.lto.LTO() {
+ globalThinLTO := GlobalThinLTO(mctx)
+
+ if m, ok := mctx.Module().(*Module); ok {
full := m.lto.FullLTO()
thin := m.lto.ThinLTO()
+ never := m.lto.Never()
if full && thin {
mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive")
}
@@ -180,14 +184,16 @@
}
}
- if dep, ok := dep.(*Module); ok && dep.lto != nil &&
- !dep.lto.Never() {
+ if dep, ok := dep.(*Module); ok {
if full && !dep.lto.FullLTO() {
dep.lto.Properties.FullDep = true
}
- if thin && !dep.lto.ThinLTO() {
+ if !globalThinLTO && thin && !dep.lto.ThinLTO() {
dep.lto.Properties.ThinDep = true
}
+ if globalThinLTO && never && !dep.lto.Never() {
+ dep.lto.Properties.NoLtoDep = true
+ }
}
// Recursively walk static dependencies
@@ -198,6 +204,8 @@
// Create lto variants for modules that need them
func ltoMutator(mctx android.BottomUpMutatorContext) {
+ globalThinLTO := GlobalThinLTO(mctx)
+
if m, ok := mctx.Module().(*Module); ok && m.lto != nil {
// Create variations for LTO types required as static
// dependencies
@@ -205,18 +213,25 @@
if m.lto.Properties.FullDep && !m.lto.FullLTO() {
variationNames = append(variationNames, "lto-full")
}
- if m.lto.Properties.ThinDep && !m.lto.ThinLTO() {
+ if !globalThinLTO && m.lto.Properties.ThinDep && !m.lto.ThinLTO() {
variationNames = append(variationNames, "lto-thin")
}
+ if globalThinLTO && m.lto.Properties.NoLtoDep && !m.lto.Never() {
+ variationNames = append(variationNames, "lto-none")
+ }
// Use correct dependencies if LTO property is explicitly set
// (mutually exclusive)
if m.lto.FullLTO() {
mctx.SetDependencyVariation("lto-full")
}
- if m.lto.ThinLTO() {
+ if !globalThinLTO && m.lto.ThinLTO() {
mctx.SetDependencyVariation("lto-thin")
}
+ // Never must be the last, it overrides Thin or Full.
+ if globalThinLTO && m.lto.Never() {
+ mctx.SetDependencyVariation("lto-none")
+ }
if len(variationNames) > 1 {
modules := mctx.CreateVariations(variationNames...)
@@ -232,16 +247,18 @@
// LTO properties for dependencies
if name == "lto-full" {
variation.lto.Properties.Lto.Full = proptools.BoolPtr(true)
- variation.lto.Properties.Lto.Thin = proptools.BoolPtr(false)
}
if name == "lto-thin" {
- variation.lto.Properties.Lto.Full = proptools.BoolPtr(false)
variation.lto.Properties.Lto.Thin = proptools.BoolPtr(true)
}
+ if name == "lto-none" {
+ variation.lto.Properties.Lto.Never = proptools.BoolPtr(true)
+ }
variation.Properties.PreventInstall = true
variation.Properties.HideFromMake = true
variation.lto.Properties.FullDep = false
variation.lto.Properties.ThinDep = false
+ variation.lto.Properties.NoLtoDep = false
}
}
}
diff --git a/cc/object.go b/cc/object.go
index 99b257a..0327a45 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -54,7 +54,7 @@
func (handler *objectBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- objPaths, ok := bazelCtx.GetOutputFiles(label, ctx.Arch().ArchType)
+ objPaths, ok := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
if ok {
if len(objPaths) != 1 {
ctx.ModuleErrorf("expected exactly one object file for '%s', but got %s", label, objPaths)
@@ -122,14 +122,17 @@
// For bp2build conversion.
type bazelObjectAttributes struct {
- Srcs bazel.LabelListAttribute
- Srcs_as bazel.LabelListAttribute
- Hdrs bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
- Copts bazel.StringListAttribute
- Asflags bazel.StringListAttribute
- Local_includes bazel.StringListAttribute
- Absolute_includes bazel.StringListAttribute
+ Srcs bazel.LabelListAttribute
+ Srcs_as bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ System_dynamic_deps bazel.LabelListAttribute
+ Copts bazel.StringListAttribute
+ Asflags bazel.StringListAttribute
+ Local_includes bazel.StringListAttribute
+ Absolute_includes bazel.StringListAttribute
+ Stl *string
+ Linker_script bazel.LabelAttribute
}
// ObjectBp2Build is the bp2build converter from cc_object modules to the
@@ -151,14 +154,29 @@
}
// Set arch-specific configurable attributes
- compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
+ baseAttributes := bp2BuildParseBaseProps(ctx, m)
+ compilerAttrs := baseAttributes.compilerAttributes
var deps bazel.LabelListAttribute
- for _, props := range m.linker.linkerProps() {
- if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
- deps = bazel.MakeLabelListAttribute(
- android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
+ systemDynamicDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
+
+ var linkerScript bazel.LabelAttribute
+
+ for axis, configToProps := range m.GetArchVariantProperties(ctx, &ObjectLinkerProperties{}) {
+ for config, props := range configToProps {
+ if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
+ if objectLinkerProps.Linker_script != nil {
+ linkerScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *objectLinkerProps.Linker_script))
+ }
+ deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
+ systemSharedLibs := objectLinkerProps.System_shared_libs
+ if len(systemSharedLibs) > 0 {
+ systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
+ }
+ systemDynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
+ }
}
}
+ deps.ResolveExcludes()
// Don't split cc_object srcs across languages. Doing so would add complexity,
// and this isn't typically done for cc_object.
@@ -172,13 +190,16 @@
}
attrs := &bazelObjectAttributes{
- Srcs: srcs,
- Srcs_as: compilerAttrs.asSrcs,
- Deps: deps,
- Copts: compilerAttrs.copts,
- Asflags: asFlags,
- Local_includes: compilerAttrs.localIncludes,
- Absolute_includes: compilerAttrs.absoluteIncludes,
+ Srcs: srcs,
+ Srcs_as: compilerAttrs.asSrcs,
+ Deps: deps,
+ System_dynamic_deps: systemDynamicDeps,
+ Copts: compilerAttrs.copts,
+ Asflags: asFlags,
+ Local_includes: compilerAttrs.localIncludes,
+ Absolute_includes: compilerAttrs.absoluteIncludes,
+ Stl: compilerAttrs.stl,
+ Linker_script: linkerScript,
}
props := bazel.BazelTargetModuleProperties{
@@ -186,7 +207,7 @@
Bzl_load_location: "//build/bazel/rules:cc_object.bzl",
}
- ctx.CreateBazelTargetModule(m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
}
func (object *objectLinker) appendLdflags(flags []string) {
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index d324241..3401e36 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -16,9 +16,9 @@
import (
"path/filepath"
- "strings"
"android/soong/android"
+ "android/soong/bazel"
)
func init() {
@@ -32,6 +32,8 @@
ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory)
ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory)
ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
+
+ android.RegisterBp2BuildMutator("cc_prebuilt_library_shared", PrebuiltLibrarySharedBp2Build)
}
type prebuiltLinkerInterface interface {
@@ -232,7 +234,7 @@
// Implements versionedInterface
func (p *prebuiltLibraryLinker) implementationModuleName(name string) string {
- return strings.TrimPrefix(name, "prebuilt_")
+ return android.RemoveOptionalPrebuiltPrefix(name)
}
func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
@@ -310,6 +312,42 @@
return module, library
}
+type bazelPrebuiltLibrarySharedAttributes struct {
+ Shared_library bazel.LabelAttribute
+}
+
+func PrebuiltLibrarySharedBp2Build(ctx android.TopDownMutatorContext) {
+ module, ok := ctx.Module().(*Module)
+ if !ok {
+ // Not a cc module
+ return
+ }
+ if !module.ConvertWithBp2build(ctx) {
+ return
+ }
+ if ctx.ModuleType() != "cc_prebuilt_library_shared" {
+ return
+ }
+
+ prebuiltLibrarySharedBp2BuildInternal(ctx, module)
+}
+
+func prebuiltLibrarySharedBp2BuildInternal(ctx android.TopDownMutatorContext, module *Module) {
+ prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module)
+
+ attrs := &bazelPrebuiltLibrarySharedAttributes{
+ Shared_library: prebuiltAttrs.Src,
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "prebuilt_library_shared",
+ Bzl_load_location: "//build/bazel/rules:prebuilt_library_shared.bzl",
+ }
+
+ name := android.RemoveOptionalPrebuiltPrefix(module.Name())
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs)
+}
+
type prebuiltObjectProperties struct {
Srcs []string `android:"path,arch_variant"`
}
@@ -330,7 +368,7 @@
func (h *prebuiltStaticLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
if err != nil {
ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
}
diff --git a/cc/stub_library.go b/cc/stub_library.go
index 1722c80..76da782 100644
--- a/cc/stub_library.go
+++ b/cc/stub_library.go
@@ -15,6 +15,7 @@
package cc
import (
+ "sort"
"strings"
"android/soong/android"
@@ -27,6 +28,8 @@
type stubLibraries struct {
stubLibraryMap map[string]bool
+
+ apiListCoverageXmlPaths []string
}
// Check if the module defines stub, or itself is stub
@@ -53,6 +56,11 @@
s.stubLibraryMap[name] = true
}
}
+ if m.library != nil {
+ if p := m.library.getAPIListCoverageXMLPath().String(); p != "" {
+ s.apiListCoverageXmlPaths = append(s.apiListCoverageXmlPaths, p)
+ }
+ }
}
})
}
@@ -66,4 +74,8 @@
func (s *stubLibraries) MakeVars(ctx android.MakeVarsContext) {
// Convert stub library file names into Makefile variable.
ctx.Strict("STUB_LIBRARIES", strings.Join(android.SortedStringKeys(s.stubLibraryMap), " "))
+
+ // Export the list of API XML files to Make.
+ sort.Strings(s.apiListCoverageXmlPaths)
+ ctx.Strict("SOONG_CC_API_XML", strings.Join(s.apiListCoverageXmlPaths, " "))
}
diff --git a/cc/test.go b/cc/test.go
index 047a69e..c589165 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -80,6 +80,9 @@
// list of shared library modules that should be installed alongside the test
Data_libs []string `android:"arch_variant"`
+ // list of binary modules that should be installed alongside the test
+ Data_bins []string `android:"arch_variant"`
+
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites []string `android:"arch_variant"`
@@ -115,6 +118,9 @@
// Add parameterized mainline modules to auto generated test config. The options will be
// handled by TradeFed to download and install the specified modules on the device.
Test_mainline_modules []string
+
+ // Install the test into a folder named for the module in all test suites.
+ Per_testcase_directory *bool
}
func init() {
@@ -347,6 +353,7 @@
deps = test.testDecorator.linkerDeps(ctx, deps)
deps = test.binaryDecorator.linkerDeps(ctx, deps)
deps.DataLibs = append(deps.DataLibs, test.Properties.Data_libs...)
+ deps.DataBins = append(deps.DataBins, test.Properties.Data_bins...)
return deps
}
@@ -386,6 +393,18 @@
RelativeInstallPath: ccModule.installer.relativeInstallPath()})
}
})
+ ctx.VisitDirectDepsWithTag(dataBinDepTag, func(dep android.Module) {
+ depName := ctx.OtherModuleName(dep)
+ ccModule, ok := dep.(*Module)
+ if !ok {
+ ctx.ModuleErrorf("data_bin %q is not a cc module", depName)
+ }
+ if ccModule.OutputFile().Valid() {
+ test.data = append(test.data,
+ android.DataPath{SrcPath: ccModule.OutputFile().Path(),
+ RelativeInstallPath: ccModule.installer.relativeInstallPath()})
+ }
+ })
var configs []tradefed.Config
for _, module := range test.Properties.Test_mainline_modules {
diff --git a/cmd/multiproduct_kati/Android.bp b/cmd/multiproduct_kati/Android.bp
index e5be6c0..20ca2a3 100644
--- a/cmd/multiproduct_kati/Android.bp
+++ b/cmd/multiproduct_kati/Android.bp
@@ -31,4 +31,14 @@
testSrcs: [
"main_test.go",
],
+ linux: {
+ srcs: [
+ "main_linux.go",
+ ],
+ },
+ darwin: {
+ srcs: [
+ "main_darwin.go",
+ ],
+ },
}
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 3c9cac1..0577c86 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -166,15 +166,6 @@
MainLogsDir string
}
-func detectTotalRAM() uint64 {
- var info syscall.Sysinfo_t
- err := syscall.Sysinfo(&info)
- if err != nil {
- panic(err)
- }
- return info.Totalram * uint64(info.Unit)
-}
-
func findNamedProducts(soongUi string, log logger.Logger) []string {
cmd := exec.Command(soongUi, "--dumpvars-mode", "--vars=all_named_products")
output, err := cmd.Output()
@@ -301,7 +292,7 @@
jobs = runtime.NumCPU() / 4
ramGb := int(detectTotalRAM() / (1024 * 1024 * 1024))
- if ramJobs := ramGb / 25; ramGb > 0 && jobs > ramJobs {
+ if ramJobs := ramGb / 30; ramGb > 0 && jobs > ramJobs {
jobs = ramJobs
}
diff --git a/cmd/multiproduct_kati/main_darwin.go b/cmd/multiproduct_kati/main_darwin.go
new file mode 100644
index 0000000..3d1b12a
--- /dev/null
+++ b/cmd/multiproduct_kati/main_darwin.go
@@ -0,0 +1,20 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+func detectTotalRAM() uint64 {
+ // unimplemented stub on darwin
+ return 0
+}
diff --git a/cmd/multiproduct_kati/main_linux.go b/cmd/multiproduct_kati/main_linux.go
new file mode 100644
index 0000000..db74496
--- /dev/null
+++ b/cmd/multiproduct_kati/main_linux.go
@@ -0,0 +1,28 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "syscall"
+)
+
+func detectTotalRAM() uint64 {
+ var info syscall.Sysinfo_t
+ err := syscall.Sysinfo(&info)
+ if err != nil {
+ panic(err)
+ }
+ return info.Totalram * uint64(info.Unit)
+}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index c5e8896..e9eabd3 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -217,15 +217,6 @@
generateModuleGraphFile := moduleGraphFile != ""
generateDocFile := docFile != ""
- blueprintArgs := cmdlineArgs
-
- var stopBefore bootstrap.StopBefore
- if !generateModuleGraphFile && !generateQueryView && !generateDocFile {
- stopBefore = bootstrap.DoEverything
- } else {
- stopBefore = bootstrap.StopBeforePrepareBuildActions
- }
-
if generateBazelWorkspace {
// Run the alternate pipeline of bp2build mutators and singleton to convert
// Blueprint to BUILD files before everything else.
@@ -233,6 +224,19 @@
return bp2buildMarker
}
+ blueprintArgs := cmdlineArgs
+
+ var stopBefore bootstrap.StopBefore
+ if generateModuleGraphFile {
+ stopBefore = bootstrap.StopBeforeWriteNinja
+ } else if generateQueryView {
+ stopBefore = bootstrap.StopBeforePrepareBuildActions
+ } else if generateDocFile {
+ stopBefore = bootstrap.StopBeforePrepareBuildActions
+ } else {
+ stopBefore = bootstrap.DoEverything
+ }
+
ctx := newContext(configuration)
if mixedModeBuild {
runMixedModeBuild(configuration, ctx, extraNinjaDeps)
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index 1bdd040..658e8e2 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -598,11 +598,18 @@
func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) []*jsonClassLoaderContext {
jClcs := make([]*jsonClassLoaderContext, len(clcs))
for i, clc := range clcs {
+ var host string
+ if clc.Host == nil {
+ // Defer build failure to when this CLC is actually used.
+ host = fmt.Sprintf("implementation-jar-for-%s-is-not-available.jar", clc.Name)
+ } else {
+ host = clc.Host.String()
+ }
jClcs[i] = &jsonClassLoaderContext{
Name: clc.Name,
Optional: clc.Optional,
Implicit: clc.Implicit,
- Host: clc.Host.String(),
+ Host: host,
Device: clc.Device,
Subcontexts: toJsonClassLoaderContextRec(clc.Subcontexts),
}
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 965b755..3145315 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -204,6 +204,17 @@
return fmt.Sprintf("/system/framework/%s.jar", lib)
}
+// Returns the location to the odex file for the dex file at `path`.
+func ToOdexPath(path string, arch android.ArchType) string {
+ if strings.HasPrefix(path, "/apex/") {
+ return filepath.Join("/system/framework/oat", arch.String(),
+ strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
+ }
+
+ return filepath.Join(filepath.Dir(path), "oat", arch.String(),
+ pathtools.ReplaceExtension(filepath.Base(path), "odex"))
+}
+
func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
appImage bool, generateDM bool) {
@@ -218,23 +229,8 @@
base = "package.apk"
}
- toOdexPath := func(path string) string {
- if global.ApexSystemServerJars.ContainsJar(module.Name) {
- return filepath.Join(
- "/system/framework/oat",
- arch.String(),
- strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
- }
-
- return filepath.Join(
- filepath.Dir(path),
- "oat",
- arch.String(),
- pathtools.ReplaceExtension(filepath.Base(path), "odex"))
- }
-
odexPath := module.BuildPath.InSameDir(ctx, "oat", arch.String(), pathtools.ReplaceExtension(base, "odex"))
- odexInstallPath := toOdexPath(module.DexLocation)
+ odexInstallPath := ToOdexPath(module.DexLocation, arch)
if odexOnSystemOther(module, global) {
odexInstallPath = filepath.Join(SystemOtherPartition, odexInstallPath)
}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 85abf59..2865ffa 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -439,6 +439,7 @@
InitPrebuiltEtcModule(module, "etc")
// This module is host-only
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
return module
}
@@ -449,6 +450,7 @@
InitPrebuiltRootModule(module)
// This module is device-only
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitDefaultableModule(module)
return module
}
@@ -459,6 +461,7 @@
InitPrebuiltEtcModule(module, "usr/share")
// This module is device-only
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitDefaultableModule(module)
return module
}
@@ -469,6 +472,7 @@
InitPrebuiltEtcModule(module, "usr/share")
// This module is host-only
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
return module
}
@@ -478,6 +482,7 @@
InitPrebuiltEtcModule(module, "fonts")
// This module is device-only
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitDefaultableModule(module)
return module
}
@@ -491,6 +496,7 @@
InitPrebuiltEtcModule(module, "etc/firmware")
// This module is device-only
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitDefaultableModule(module)
return module
}
@@ -503,6 +509,7 @@
InitPrebuiltEtcModule(module, "etc/dsp")
// This module is device-only
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitDefaultableModule(module)
return module
}
@@ -516,6 +523,7 @@
InitPrebuiltEtcModule(module, "lib/rfsa")
// This module is device-only
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitDefaultableModule(module)
return module
}
@@ -673,8 +681,16 @@
func prebuiltEtcBp2BuildInternal(ctx android.TopDownMutatorContext, module *PrebuiltEtc) {
var srcLabelAttribute bazel.LabelAttribute
- if module.properties.Src != nil {
- srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.Src))
+ for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltEtcProperties{}) {
+ for config, p := range configToProps {
+ props, ok := p.(*prebuiltEtcProperties)
+ if !ok {
+ continue
+ }
+ if props.Src != nil {
+ srcLabelAttribute.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *props.Src))
+ }
+ }
}
var filename string
@@ -704,5 +720,5 @@
Bzl_load_location: "//build/bazel/rules:prebuilt_etc.bzl",
}
- ctx.CreateBazelTargetModule(module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
}
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index ccadc0f..8861d1b 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -42,8 +42,9 @@
}
type FuzzPackager struct {
- Packages android.Paths
- FuzzTargets map[string]bool
+ Packages android.Paths
+ FuzzTargets map[string]bool
+ SharedLibInstallStrings []string
}
type FileToZip struct {
@@ -251,3 +252,42 @@
sort.Strings(fuzzTargets)
ctx.Strict(targets, strings.Join(fuzzTargets, " "))
}
+
+// CollectAllSharedDependencies performs a breadth-first search over the provided module's
+// dependencies using `visitDirectDeps` to enumerate all shared library
+// dependencies. We require breadth-first expansion, as otherwise we may
+// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
+// from a dependency. This may cause issues when dependencies have explicit
+// sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
+func CollectAllSharedDependencies(ctx android.SingletonContext, module android.Module, unstrippedOutputFile func(module android.Module) android.Path, isValidSharedDependency func(dependency android.Module) bool) android.Paths {
+ var fringe []android.Module
+
+ seen := make(map[string]bool)
+
+ // Enumerate the first level of dependencies, as we discard all non-library
+ // modules in the BFS loop below.
+ ctx.VisitDirectDeps(module, func(dep android.Module) {
+ if isValidSharedDependency(dep) {
+ fringe = append(fringe, dep)
+ }
+ })
+
+ var sharedLibraries android.Paths
+
+ for i := 0; i < len(fringe); i++ {
+ module := fringe[i]
+ if seen[module.Name()] {
+ continue
+ }
+ seen[module.Name()] = true
+
+ sharedLibraries = append(sharedLibraries, unstrippedOutputFile(module))
+ ctx.VisitDirectDeps(module, func(dep android.Module) {
+ if isValidSharedDependency(dep) && !seen[dep.Name()] {
+ fringe = append(fringe, dep)
+ }
+ })
+ }
+
+ return sharedLibraries
+}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index f4bde70..c9bf958 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -156,6 +156,11 @@
// For other packages to make their own genrules with extra
// properties
Extra interface{}
+
+ // CmdModifier can be set by wrappers around genrule to modify the command, for example to
+ // prefix environment variables to it.
+ CmdModifier func(ctx android.ModuleContext, cmd string) string
+
android.ImageInterface
properties generatorProperties
@@ -243,7 +248,7 @@
// Returns true if information was available from Bazel, false if bazel invocation still needs to occur.
func (c *Module) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- filePaths, ok := bazelCtx.GetOutputFiles(label, ctx.Arch().ArchType)
+ filePaths, ok := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
if ok {
var bazelOutputFiles android.Paths
exportIncludeDirs := map[string]bool{}
@@ -331,14 +336,9 @@
}
case bootstrap.GoBinaryTool:
// A GoBinaryTool provides the install path to a tool, which will be copied.
- if s, err := filepath.Rel(android.PathForOutput(ctx).String(), t.InstallPath()); err == nil {
- toolPath := android.PathForOutput(ctx, s)
- tools = append(tools, toolPath)
- addLocationLabel(tag.label, toolLocation{android.Paths{toolPath}})
- } else {
- ctx.ModuleErrorf("cannot find path for %q: %v", tool, err)
- return
- }
+ p := android.PathForGoBinary(ctx, t)
+ tools = append(tools, p)
+ addLocationLabel(tag.label, toolLocation{android.Paths{p}})
default:
ctx.ModuleErrorf("%q is not a host tool provider", tool)
return
@@ -398,8 +398,13 @@
var outputFiles android.WritablePaths
var zipArgs strings.Builder
+ cmd := String(g.properties.Cmd)
+ if g.CmdModifier != nil {
+ cmd = g.CmdModifier(ctx, cmd)
+ }
+
// Generate tasks, either from genrule or gensrcs.
- for _, task := range g.taskGenerator(ctx, String(g.properties.Cmd), srcFiles) {
+ for _, task := range g.taskGenerator(ctx, cmd, srcFiles) {
if len(task.out) == 0 {
ctx.ModuleErrorf("must have at least one output file")
return
@@ -918,7 +923,7 @@
}
// Create the BazelTargetModule.
- ctx.CreateBazelTargetModule(m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
}
var Bool = proptools.Bool
diff --git a/java/Android.bp b/java/Android.bp
index 9ffa123..78d0cc1 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -40,6 +40,7 @@
"dex.go",
"dexpreopt.go",
"dexpreopt_bootjars.go",
+ "dexpreopt_check.go",
"dexpreopt_config.go",
"droiddoc.go",
"droidstubs.go",
diff --git a/java/androidmk.go b/java/androidmk.go
index 1914595..eca5caa 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -60,6 +60,11 @@
func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
var entriesList []android.AndroidMkEntries
+ if library.Os() == android.Windows {
+ // Make does not support Windows Java modules
+ return nil
+ }
+
if library.hideApexVariantFromMake {
// For a java library built for an APEX, we don't need a Make module for itself. Otherwise, it
// will conflict with the platform variant because they have the same module name in the
@@ -71,23 +76,7 @@
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
// Platform variant. If not available for the platform, we don't need Make module.
- // May still need to add some additional dependencies.
- checkedModulePaths := library.additionalCheckedModules
- if len(checkedModulePaths) != 0 {
- entriesList = append(entriesList, android.AndroidMkEntries{
- Class: "FAKE",
- // Need at least one output file in order for this to take effect.
- OutputFile: android.OptionalPathForPath(checkedModulePaths[0]),
- Include: "$(BUILD_PHONY_PACKAGE)",
- ExtraEntries: []android.AndroidMkExtraEntriesFunc{
- func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", checkedModulePaths.Strings()...)
- },
- },
- })
- } else {
- entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
- }
+ entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
} else {
entriesList = append(entriesList, android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
@@ -123,10 +112,6 @@
requiredUsesLibs, optionalUsesLibs := library.classLoaderContexts.UsesLibs()
entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", append(requiredUsesLibs, optionalUsesLibs...)...)
- if len(library.additionalCheckedModules) != 0 {
- entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", library.additionalCheckedModules.Strings()...)
- }
-
entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_DICT", library.dexer.proguardDictionary)
entries.SetOptionalPath("LOCAL_SOONG_PROGUARD_USAGE_ZIP", library.dexer.proguardUsageZip)
entries.SetString("LOCAL_MODULE_STEM", library.Stem())
@@ -147,20 +132,21 @@
}
// Called for modules that are a component of a test suite.
-func testSuiteComponent(entries *android.AndroidMkEntries, test_suites []string) {
+func testSuiteComponent(entries *android.AndroidMkEntries, test_suites []string, perTestcaseDirectory bool) {
entries.SetString("LOCAL_MODULE_TAGS", "tests")
if len(test_suites) > 0 {
entries.AddCompatibilityTestSuites(test_suites...)
} else {
entries.AddCompatibilityTestSuites("null-suite")
}
+ entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", perTestcaseDirectory)
}
func (j *Test) AndroidMkEntries() []android.AndroidMkEntries {
entriesList := j.Library.AndroidMkEntries()
entries := &entriesList[0]
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- testSuiteComponent(entries, j.testProperties.Test_suites)
+ testSuiteComponent(entries, j.testProperties.Test_suites, Bool(j.testProperties.Per_testcase_directory))
if j.testConfig != nil {
entries.SetPath("LOCAL_FULL_TEST_CONFIG", j.testConfig)
}
@@ -188,7 +174,7 @@
entriesList := j.Library.AndroidMkEntries()
entries := &entriesList[0]
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- testSuiteComponent(entries, j.testHelperLibraryProperties.Test_suites)
+ testSuiteComponent(entries, j.testHelperLibraryProperties.Test_suites, Bool(j.testHelperLibraryProperties.Per_testcase_directory))
})
return entriesList
@@ -269,6 +255,10 @@
}
func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries {
+ if binary.Os() == android.Windows {
+ // Make does not support Windows Java modules
+ return nil
+ }
if !binary.isWrapperVariant {
return []android.AndroidMkEntries{android.AndroidMkEntries{
@@ -450,7 +440,7 @@
entriesList := a.AndroidApp.AndroidMkEntries()
entries := &entriesList[0]
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- testSuiteComponent(entries, a.testProperties.Test_suites)
+ testSuiteComponent(entries, a.testProperties.Test_suites, Bool(a.testProperties.Per_testcase_directory))
if a.testConfig != nil {
entries.SetPath("LOCAL_FULL_TEST_CONFIG", a.testConfig)
}
@@ -466,7 +456,7 @@
entriesList := a.AndroidApp.AndroidMkEntries()
entries := &entriesList[0]
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- testSuiteComponent(entries, a.appTestHelperAppProperties.Test_suites)
+ testSuiteComponent(entries, a.appTestHelperAppProperties.Test_suites, Bool(a.appTestHelperAppProperties.Per_testcase_directory))
// introduce a flag variable to control the generation of the .config file
entries.SetString("LOCAL_DISABLE_TEST_CONFIG", "true")
})
@@ -677,7 +667,7 @@
entriesList := a.AndroidAppImport.AndroidMkEntries()
entries := &entriesList[0]
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- testSuiteComponent(entries, a.testProperties.Test_suites)
+ testSuiteComponent(entries, a.testProperties.Test_suites, Bool(a.testProperties.Per_testcase_directory))
androidMkWriteTestData(a.data, entries)
})
return entriesList
diff --git a/java/app.go b/java/app.go
index 2fd6463..6554d66 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1070,6 +1070,9 @@
// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
// explicitly.
Auto_gen_config *bool
+
+ // Install the test into a folder named for the module in all test suites.
+ Per_testcase_directory *bool
}
type AndroidTestHelperApp struct {
@@ -1428,5 +1431,5 @@
Bzl_load_location: "//build/bazel/rules:android_app_certificate.bzl",
}
- ctx.CreateBazelTargetModule(module.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
}
diff --git a/java/base.go b/java/base.go
index 579085b..ca34f2e 100644
--- a/java/base.go
+++ b/java/base.go
@@ -433,9 +433,6 @@
// expanded Jarjar_rules
expandJarjarRules android.Path
- // list of additional targets for checkbuild
- additionalCheckedModules android.Paths
-
// Extra files generated by the module type to be added as java resources.
extraResources android.Paths
@@ -1265,10 +1262,25 @@
// Check package restrictions if necessary.
if len(j.properties.Permitted_packages) > 0 {
- // Check packages and copy to package-checked file.
+ // Time stamp file created by the package check rule.
pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")
+
+ // Create a rule to copy the output jar to another path and add a validate dependency that
+ // will check that the jar only contains the permitted packages. The new location will become
+ // the output file of this module.
+ inputFile := outputFile
+ outputFile = android.PathForModuleOut(ctx, "package-check", jarName).OutputPath
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: inputFile,
+ Output: outputFile,
+ // Make sure that any dependency on the output file will cause ninja to run the package check
+ // rule.
+ Validation: pkgckFile,
+ })
+
+ // Check packages and create a timestamp file when complete.
CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
- j.additionalCheckedModules = append(j.additionalCheckedModules, pkgckFile)
if ctx.Failed() {
return
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 79c73ca..8f18790 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -139,6 +139,74 @@
BootclasspathFragmentsDepsProperties
}
+type SourceOnlyBootclasspathProperties struct {
+ Hidden_api struct {
+ // Contains prefixes of a package hierarchy that is provided solely by this
+ // bootclasspath_fragment.
+ //
+ // This affects the signature patterns file that is used to select the subset of monolithic
+ // hidden API flags. See split_packages property for more details.
+ Package_prefixes []string
+
+ // The list of split packages provided by this bootclasspath_fragment.
+ //
+ // A split package is one that contains classes which are provided by multiple
+ // bootclasspath_fragment modules.
+ //
+ // This defaults to "*" - which treats all packages as being split. A module that has no split
+ // packages must specify an empty list.
+ //
+ // This affects the signature patterns file that is generated by a bootclasspath_fragment and
+ // used to select the subset of monolithic hidden API flags against which the flags generated
+ // by the bootclasspath_fragment are compared.
+ //
+ // The signature patterns file selects the subset of monolithic hidden API flags using a number
+ // of patterns, i.e.:
+ // * The qualified name (including package) of an outermost class, e.g. java/lang/Character.
+ // This selects all the flags for all the members of this class and any nested classes.
+ // * A package wildcard, e.g. java/lang/*. This selects all the flags for all the members of all
+ // the classes in this package (but not in sub-packages).
+ // * A recursive package wildcard, e.g. java/**. This selects all the flags for all the members
+ // of all the classes in this package and sub-packages.
+ //
+ // The signature patterns file is constructed as follows:
+ // * All the signatures are retrieved from the all-flags.csv file.
+ // * The member and inner class names are removed.
+ // * If a class is in a split package then that is kept, otherwise the class part is removed
+ // and replaced with a wildcard, i.e. *.
+ // * If a package matches a package prefix then the package is removed.
+ // * All the package prefixes are added with a recursive wildcard appended to each, i.e. **.
+ // * The resulting patterns are sorted.
+ //
+ // So, by default (i.e. without specifying any package_prefixes or split_packages) the signature
+ // patterns is a list of class names, because there are no package packages and all packages are
+ // assumed to be split.
+ //
+ // If any split packages are specified then only those packages are treated as split and all
+ // other packages are treated as belonging solely to the bootclasspath_fragment and so they use
+ // wildcard package patterns.
+ //
+ // So, if an empty list of split packages is specified then the signature patterns file just
+ // includes a wildcard package pattern for every package provided by the bootclasspath_fragment.
+ //
+ // If split_packages are specified and a package that is split is not listed then it could lead
+ // to build failures as it will select monolithic flags that are generated by another
+ // bootclasspath_fragment to compare against the flags provided by this fragment. The latter
+ // will obviously not contain those flags and that can cause the comparison and build to fail.
+ //
+ // If any package prefixes are specified then any matching packages are removed from the
+ // signature patterns and replaced with a single recursive package pattern.
+ //
+ // It is not strictly necessary to specify either package_prefixes or split_packages as the
+ // defaults will produce a valid set of signature patterns. However, those patterns may include
+ // implementation details, e.g. names of implementation classes or packages, which will be
+ // exported to the sdk snapshot in the signature patterns file. That is something that should be
+ // avoided where possible. Specifying package_prefixes and split_packages allows those
+ // implementation details to be excluded from the snapshot.
+ Split_packages []string
+ }
+}
+
type BootclasspathFragmentModule struct {
android.ModuleBase
android.ApexModuleBase
@@ -147,6 +215,8 @@
properties bootclasspathFragmentProperties
+ sourceOnlyProperties SourceOnlyBootclasspathProperties
+
// Collect the module directory for IDE info in java/jdeps.go.
modulePaths []string
}
@@ -180,7 +250,7 @@
func bootclasspathFragmentFactory() android.Module {
m := &BootclasspathFragmentModule{}
- m.AddProperties(&m.properties)
+ m.AddProperties(&m.properties, &m.sourceOnlyProperties)
android.InitApexModule(m)
android.InitSdkAwareModule(m)
initClasspathFragment(m, BOOTCLASSPATH)
@@ -590,7 +660,7 @@
// TODO(b/192868581): Remove once the source and prebuilts provide a signature patterns file of
// their own.
if output.SignaturePatternsPath == nil {
- output.SignaturePatternsPath = buildRuleSignaturePatternsFile(ctx, output.AllFlagsPath)
+ output.SignaturePatternsPath = buildRuleSignaturePatternsFile(ctx, output.AllFlagsPath, []string{"*"}, nil)
}
// Initialize a HiddenAPIInfo structure.
@@ -659,7 +729,20 @@
func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
// Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the
// paths to the created files.
- return hiddenAPIRulesForBootclasspathFragment(ctx, contents, input)
+ output := hiddenAPIRulesForBootclasspathFragment(ctx, contents, input)
+
+ // If the module specifies split_packages or package_prefixes then use those to generate the
+ // signature patterns.
+ splitPackages := b.sourceOnlyProperties.Hidden_api.Split_packages
+ packagePrefixes := b.sourceOnlyProperties.Hidden_api.Package_prefixes
+ if splitPackages != nil || packagePrefixes != nil {
+ if splitPackages == nil {
+ splitPackages = []string{"*"}
+ }
+ output.SignaturePatternsPath = buildRuleSignaturePatternsFile(ctx, output.AllFlagsPath, splitPackages, packagePrefixes)
+ }
+
+ return output
}
// produceBootImageFiles builds the boot image files from the source if it is required.
@@ -767,14 +850,20 @@
// The path to the generated index.csv file.
Index_path android.OptionalPath
- // The path to the generated signature-patterns.csv file.
- Signature_patterns_path android.OptionalPath
-
// The path to the generated stub-flags.csv file.
- Stub_flags_path android.OptionalPath
+ Stub_flags_path android.OptionalPath `supported_build_releases:"S"`
// The path to the generated all-flags.csv file.
- All_flags_path android.OptionalPath
+ All_flags_path android.OptionalPath `supported_build_releases:"S"`
+
+ // The path to the generated signature-patterns.csv file.
+ Signature_patterns_path android.OptionalPath `supported_build_releases:"T+"`
+
+ // The path to the generated filtered-stub-flags.csv file.
+ Filtered_stub_flags_path android.OptionalPath `supported_build_releases:"T+"`
+
+ // The path to the generated filtered-flags.csv file.
+ Filtered_flags_path android.OptionalPath `supported_build_releases:"T+"`
}
func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -793,10 +882,13 @@
b.Metadata_path = android.OptionalPathForPath(hiddenAPIInfo.MetadataPath)
b.Index_path = android.OptionalPathForPath(hiddenAPIInfo.IndexPath)
- b.Signature_patterns_path = android.OptionalPathForPath(hiddenAPIInfo.SignaturePatternsPath)
b.Stub_flags_path = android.OptionalPathForPath(hiddenAPIInfo.StubFlagsPath)
b.All_flags_path = android.OptionalPathForPath(hiddenAPIInfo.AllFlagsPath)
+ b.Signature_patterns_path = android.OptionalPathForPath(hiddenAPIInfo.SignaturePatternsPath)
+ b.Filtered_stub_flags_path = android.OptionalPathForPath(hiddenAPIInfo.FilteredStubFlagsPath)
+ b.Filtered_flags_path = android.OptionalPathForPath(hiddenAPIInfo.FilteredFlagsPath)
+
// Copy stub_libs properties.
b.Stub_libs = module.properties.Api.Stub_libs
b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs
@@ -861,9 +953,13 @@
copyOptionalPath(b.Annotation_flags_path, "annotation_flags")
copyOptionalPath(b.Metadata_path, "metadata")
copyOptionalPath(b.Index_path, "index")
- copyOptionalPath(b.Signature_patterns_path, "signature_patterns")
+
copyOptionalPath(b.Stub_flags_path, "stub_flags")
copyOptionalPath(b.All_flags_path, "all_flags")
+
+ copyOptionalPath(b.Signature_patterns_path, "signature_patterns")
+ copyOptionalPath(b.Filtered_stub_flags_path, "filtered_stub_flags")
+ copyOptionalPath(b.Filtered_flags_path, "filtered_flags")
}
var _ android.SdkMemberType = (*bootclasspathFragmentMemberType)(nil)
@@ -889,6 +985,12 @@
// The path to the all-flags.csv file created by the bootclasspath_fragment.
All_flags *string `android:"path"`
+
+ // The path to the filtered-stub-flags.csv file created by the bootclasspath_fragment.
+ Filtered_stub_flags *string `android:"path"`
+
+ // The path to the filtered-flags.csv file created by the bootclasspath_fragment.
+ Filtered_flags *string `android:"path"`
}
}
@@ -915,9 +1017,9 @@
// produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified.
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
- pathForOptionalSrc := func(src *string) android.Path {
+ pathForOptionalSrc := func(src *string, defaultPath android.Path) android.Path {
if src == nil {
- return nil
+ return defaultPath
}
return android.PathForModuleSrc(ctx, *src)
}
@@ -938,13 +1040,19 @@
AnnotationFlagsPath: pathForSrc("hidden_api.annotation_flags", module.prebuiltProperties.Hidden_api.Annotation_flags),
MetadataPath: pathForSrc("hidden_api.metadata", module.prebuiltProperties.Hidden_api.Metadata),
IndexPath: pathForSrc("hidden_api.index", module.prebuiltProperties.Hidden_api.Index),
- SignaturePatternsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Signature_patterns),
- StubFlagsPath: pathForSrc("hidden_api.stub_flags", module.prebuiltProperties.Hidden_api.Stub_flags),
- AllFlagsPath: pathForSrc("hidden_api.all_flags", module.prebuiltProperties.Hidden_api.All_flags),
+ SignaturePatternsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Signature_patterns, nil),
+ // TODO: Temporarily handle stub_flags/all_flags properties until prebuilts have been updated.
+ StubFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags, nil),
+ AllFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags, nil),
},
+
EncodedBootDexFilesByModule: encodedBootDexJarsByModule,
}
+ // TODO: Temporarily fallback to stub_flags/all_flags properties until prebuilts have been updated.
+ output.FilteredStubFlagsPath = pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Filtered_stub_flags, output.StubFlagsPath)
+ output.FilteredFlagsPath = pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Filtered_flags, output.AllFlagsPath)
+
return &output
}
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 39fb04a..4abdcc6 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -118,7 +118,7 @@
TransformJarsToJar(ctx, outputFile, "combine", d.implementationAndResourceJars,
android.OptionalPath{}, false, nil, nil)
d.combinedImplementationJar = outputFile
- } else {
+ } else if len(d.implementationAndResourceJars) == 1 {
d.combinedImplementationJar = d.implementationAndResourceJars[0]
}
@@ -127,7 +127,7 @@
TransformJarsToJar(ctx, outputFile, "turbine combine", d.headerJars,
android.OptionalPath{}, false, nil, []string{"META-INF/TRANSITIVE"})
d.combinedHeaderJar = outputFile
- } else {
+ } else if len(d.headerJars) == 1 {
d.combinedHeaderJar = d.headerJars[0]
}
@@ -174,7 +174,9 @@
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
OutputFile: android.OptionalPathForPath(d.combinedImplementationJar),
- Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+ // Make does not support Windows Java modules
+ Disabled: d.Os() == android.Windows,
+ Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
Extra: []android.AndroidMkExtraFunc{
func(w io.Writer, outputFile android.Path) {
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go
new file mode 100644
index 0000000..565901d
--- /dev/null
+++ b/java/dexpreopt_check.go
@@ -0,0 +1,96 @@
+// 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 java
+
+import (
+ "strings"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
+
+ "github.com/google/blueprint/pathtools"
+)
+
+func init() {
+ RegisterDexpreoptCheckBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterDexpreoptCheckBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonModuleType("dexpreopt_systemserver_check", dexpreoptSystemserverCheckFactory)
+}
+
+// A build-time check to verify if all compilation artifacts of system server jars are installed
+// into the system image. When the check fails, it means that dexpreopting is not working for some
+// system server jars and needs to be fixed.
+// This singleton module generates a list of the paths to the artifacts based on
+// PRODUCT_SYSTEM_SERVER_JARS and PRODUCT_APEX_SYSTEM_SERVER_JARS, and passes it to Make via a
+// variable. Make will then do the actual check.
+// Currently, it only checks artifacts of modules defined in Soong. Artifacts of modules defined in
+// Makefile are generated by a script generated by dexpreopt_gen, and their existence is unknown to
+// Make and Ninja.
+type dexpreoptSystemserverCheck struct {
+ android.SingletonModuleBase
+
+ // Mapping from the module name to the install paths to the compilation artifacts.
+ artifactsByModuleName map[string][]string
+
+ // The install paths to the compilation artifacts.
+ artifacts []string
+}
+
+func dexpreoptSystemserverCheckFactory() android.SingletonModule {
+ m := &dexpreoptSystemserverCheck{}
+ m.artifactsByModuleName = make(map[string][]string)
+ android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+ return m
+}
+
+func getInstallPath(ctx android.ModuleContext, location string) android.InstallPath {
+ return android.PathForModuleInPartitionInstall(
+ ctx, "", strings.TrimPrefix(location, "/")).ToMakePath()
+}
+
+func (m *dexpreoptSystemserverCheck) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ global := dexpreopt.GetGlobalConfig(ctx)
+ targets := ctx.Config().Targets[android.Android]
+
+ // The check should be skipped on unbundled builds because system server jars are not preopted on
+ // unbundled builds since the artifacts are installed into the system image, not the APEXes.
+ if global.DisablePreopt || len(targets) == 0 || ctx.Config().UnbundledBuild() {
+ return
+ }
+
+ systemServerJars := dexpreopt.AllSystemServerJars(ctx, global)
+ for _, jar := range systemServerJars.CopyOfJars() {
+ dexLocation := dexpreopt.GetSystemServerDexLocation(global, jar)
+ odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType)
+ odexPath := getInstallPath(ctx, odexLocation)
+ vdexPath := getInstallPath(ctx, pathtools.ReplaceExtension(odexLocation, "vdex"))
+ m.artifactsByModuleName[jar] = []string{odexPath.String(), vdexPath.String()}
+ }
+}
+
+func (m *dexpreoptSystemserverCheck) GenerateSingletonBuildActions(ctx android.SingletonContext) {
+ // Only keep modules defined in Soong.
+ ctx.VisitAllModules(func(module android.Module) {
+ if artifacts, ok := m.artifactsByModuleName[module.Name()]; ok {
+ m.artifacts = append(m.artifacts, artifacts...)
+ }
+ })
+}
+
+func (m *dexpreoptSystemserverCheck) MakeVars(ctx android.MakeVarsContext) {
+ ctx.Strict("DEXPREOPT_SYSTEMSERVER_ARTIFACTS", strings.Join(m.artifacts, " "))
+}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 7fd88fc..0c66ccf 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -25,6 +25,9 @@
"android/soong/remoteexec"
)
+// The values allowed for Droidstubs' Api_levels_sdk_type
+var allowedApiLevelSdkTypes = []string{"public", "system", "module-lib"}
+
func init() {
RegisterStubsBuildComponents(android.InitRegistrationContext)
}
@@ -134,7 +137,7 @@
// the dirs which Metalava extracts API levels annotations from.
Api_levels_annotations_dirs []string
- // the sdk kind which Metalava extracts API levels annotations from. Supports 'public' and 'system' for now; defaults to public.
+ // the sdk kind which Metalava extracts API levels annotations from. Supports 'public', 'system' and 'module-lib' for now; defaults to public.
Api_levels_sdk_type *string
// the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
@@ -404,19 +407,24 @@
// When parsing a stub jar for a specific version, Metalava picks the first pattern that defines
// an actual file present on disk (in the order the patterns were passed). For system APIs for
// privileged apps that are only defined since API level 21 (Lollipop), fallback to public stubs
- // for older releases.
- if sdkType := proptools.StringDefault(d.properties.Api_levels_sdk_type, "public"); sdkType != "public" {
- if sdkType != "system" {
- ctx.PropertyErrorf("api_levels_sdk_type", "only 'public' and 'system' are supported")
- }
- // If building non public stubs, add all sdkType patterns first...
- for _, dir := range dirs {
- cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkType, filename))
- }
+ // for older releases. Similarly, module-lib falls back to system API.
+ var sdkDirs []string
+ switch proptools.StringDefault(d.properties.Api_levels_sdk_type, "public") {
+ case "module-lib":
+ sdkDirs = []string{"module-lib", "system", "public"}
+ case "system":
+ sdkDirs = []string{"system", "public"}
+ case "public":
+ sdkDirs = []string{"public"}
+ default:
+ ctx.PropertyErrorf("api_levels_sdk_type", "needs to be one of %v", allowedApiLevelSdkTypes)
+ return
}
- for _, dir := range dirs {
- // ... and fallback to public ones, for Metalava to use if needed.
- cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, "public", filename))
+
+ for _, sdkDir := range sdkDirs {
+ for _, dir := range dirs {
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
+ }
}
}
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 60d0bea..10d99f3 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -15,6 +15,7 @@
package java
import (
+ "fmt"
"reflect"
"regexp"
"strings"
@@ -82,8 +83,10 @@
}
}
-func TestSystemDroidstubs(t *testing.T) {
- ctx, _ := testJavaWithFS(t, `
+// runs a test for droidstubs with a customizable sdkType argument and returns
+// the list of jar patterns that is passed as `--android-jar-pattern`
+func getAndroidJarPatternsForDroidstubs(t *testing.T, sdkType string) []string {
+ ctx, _ := testJavaWithFS(t, fmt.Sprintf(`
droiddoc_exported_dir {
name: "some-exported-dir",
path: "somedir",
@@ -102,9 +105,9 @@
"some-other-exported-dir",
],
api_levels_annotations_enabled: true,
- api_levels_sdk_type: "system",
+ api_levels_sdk_type: "%s",
}
- `,
+ `, sdkType),
map[string][]byte{
"foo-doc/a.java": nil,
})
@@ -113,13 +116,40 @@
manifest := m.Output("metalava.sbox.textproto")
cmd := String(android.RuleBuilderSboxProtoForTests(t, manifest).Commands[0].Command)
r := regexp.MustCompile(`--android-jar-pattern [^ ]+/android.jar`)
- matches := r.FindAllString(cmd, -1)
+ return r.FindAllString(cmd, -1)
+}
+
+func TestPublicDroidstubs(t *testing.T) {
+ patterns := getAndroidJarPatternsForDroidstubs(t, "public")
+
+ android.AssertArrayString(t, "order of patterns", []string{
+ "--android-jar-pattern somedir/%/public/android.jar",
+ "--android-jar-pattern someotherdir/%/public/android.jar",
+ }, patterns)
+}
+
+func TestSystemDroidstubs(t *testing.T) {
+ patterns := getAndroidJarPatternsForDroidstubs(t, "system")
+
android.AssertArrayString(t, "order of patterns", []string{
"--android-jar-pattern somedir/%/system/android.jar",
"--android-jar-pattern someotherdir/%/system/android.jar",
"--android-jar-pattern somedir/%/public/android.jar",
"--android-jar-pattern someotherdir/%/public/android.jar",
- }, matches)
+ }, patterns)
+}
+
+func TestModuleLibDroidstubs(t *testing.T) {
+ patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib")
+
+ android.AssertArrayString(t, "order of patterns", []string{
+ "--android-jar-pattern somedir/%/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/%/module-lib/android.jar",
+ "--android-jar-pattern somedir/%/system/android.jar",
+ "--android-jar-pattern someotherdir/%/system/android.jar",
+ "--android-jar-pattern somedir/%/public/android.jar",
+ "--android-jar-pattern someotherdir/%/public/android.jar",
+ }, patterns)
}
func TestDroidstubsSandbox(t *testing.T) {
diff --git a/java/genrule.go b/java/genrule.go
index e0a9c8f..16743b3 100644
--- a/java/genrule.go
+++ b/java/genrule.go
@@ -64,6 +64,7 @@
module := genrule.NewGenRule()
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
return module
}
@@ -76,6 +77,7 @@
module := genrule.NewGenRule()
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
return module
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index b9a1ca7..0cc960d 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -548,18 +548,18 @@
}
}
-// StubFlagSubset returns a SignatureCsvSubset that contains a path to a stub-flags.csv file and a
-// path to a signature-patterns.csv file that defines a subset of the monolithic stub flags file,
-// i.e. out/soong/hiddenapi/hiddenapi-stub-flags.txt, against which it will be compared.
+// StubFlagSubset returns a SignatureCsvSubset that contains a path to a filtered-stub-flags.csv
+// file and a path to a signature-patterns.csv file that defines a subset of the monolithic stub
+// flags file, i.e. out/soong/hiddenapi/hiddenapi-stub-flags.txt, against which it will be compared.
func (i *HiddenAPIInfo) StubFlagSubset() SignatureCsvSubset {
- return SignatureCsvSubset{i.StubFlagsPath, i.SignaturePatternsPath}
+ return SignatureCsvSubset{i.FilteredStubFlagsPath, i.SignaturePatternsPath}
}
-// FlagSubset returns a SignatureCsvSubset that contains a path to an all-flags.csv file and a
+// FlagSubset returns a SignatureCsvSubset that contains a path to a filtered-flags.csv file and a
// path to a signature-patterns.csv file that defines a subset of the monolithic flags file, i.e.
// out/soong/hiddenapi/hiddenapi-flags.csv, against which it will be compared.
func (i *HiddenAPIInfo) FlagSubset() SignatureCsvSubset {
- return SignatureCsvSubset{i.AllFlagsPath, i.SignaturePatternsPath}
+ return SignatureCsvSubset{i.FilteredFlagsPath, i.SignaturePatternsPath}
}
var HiddenAPIInfoProvider = blueprint.NewProvider(HiddenAPIInfo{})
@@ -784,9 +784,6 @@
// HiddenAPIFlagOutput contains paths to output files from the hidden API flag generation for a
// bootclasspath_fragment module.
type HiddenAPIFlagOutput struct {
- // The path to the generated stub-flags.csv file.
- StubFlagsPath android.Path
-
// The path to the generated annotation-flags.csv file.
AnnotationFlagsPath android.Path
@@ -796,12 +793,21 @@
// The path to the generated index.csv file.
IndexPath android.Path
+ // The path to the generated stub-flags.csv file.
+ StubFlagsPath android.Path
+
// The path to the generated all-flags.csv file.
AllFlagsPath android.Path
// The path to the generated signature-patterns.txt file which defines the subset of the
// monolithic hidden API files provided in this.
SignaturePatternsPath android.Path
+
+ // The path to the generated filtered-stub-flags.csv file.
+ FilteredStubFlagsPath android.Path
+
+ // The path to the generated filtered-flags.csv file.
+ FilteredFlagsPath android.Path
}
// bootDexJarByModule is a map from base module name (without prebuilt_ prefix) to the boot dex
@@ -937,13 +943,22 @@
// buildRuleSignaturePatternsFile creates a rule to generate a file containing the set of signature
// patterns that will select a subset of the monolithic flags.
-func buildRuleSignaturePatternsFile(ctx android.ModuleContext, flagsPath android.Path) android.Path {
+func buildRuleSignaturePatternsFile(ctx android.ModuleContext, flagsPath android.Path, splitPackages []string, packagePrefixes []string) android.Path {
patternsFile := android.PathForModuleOut(ctx, "modular-hiddenapi", "signature-patterns.csv")
// Create a rule to validate the output from the following rule.
rule := android.NewRuleBuilder(pctx, ctx)
+
+ // Quote any * in the packages to avoid them being expanded by the shell.
+ quotedSplitPackages := []string{}
+ for _, pkg := range splitPackages {
+ quotedSplitPackages = append(quotedSplitPackages, strings.ReplaceAll(pkg, "*", "\\*"))
+ }
+
rule.Command().
BuiltTool("signature_patterns").
FlagWithInput("--flags ", flagsPath).
+ FlagForEachArg("--split-package ", quotedSplitPackages).
+ FlagForEachArg("--package-prefix ", packagePrefixes).
FlagWithOutput("--output ", patternsFile)
rule.Build("hiddenAPISignaturePatterns", "hidden API signature patterns")
@@ -1067,11 +1082,13 @@
// Store the paths in the info for use by other modules and sdk snapshot generation.
output := HiddenAPIOutput{
HiddenAPIFlagOutput: HiddenAPIFlagOutput{
- StubFlagsPath: filteredStubFlagsCSV,
- AnnotationFlagsPath: annotationFlagsCSV,
- MetadataPath: metadataCSV,
- IndexPath: indexCSV,
- AllFlagsPath: filteredFlagsCSV,
+ AnnotationFlagsPath: annotationFlagsCSV,
+ MetadataPath: metadataCSV,
+ IndexPath: indexCSV,
+ StubFlagsPath: stubFlagsCSV,
+ AllFlagsPath: allFlagsCSV,
+ FilteredStubFlagsPath: filteredStubFlagsCSV,
+ FilteredFlagsPath: filteredFlagsCSV,
},
EncodedBootDexFilesByModule: encodedBootDexJarsByModule,
}
diff --git a/java/java.go b/java/java.go
index 94c12bd..854097b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -73,6 +73,7 @@
android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
android.RegisterSdkMemberType(javaLibsSdkMemberType)
android.RegisterSdkMemberType(javaBootLibsSdkMemberType)
+ android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType)
android.RegisterSdkMemberType(javaTestSdkMemberType)
}
@@ -146,6 +147,37 @@
onlyCopyJarToSnapshot,
}
+ // Supports adding java systemserver libraries to module_exports and sdk.
+ //
+ // The build has some implicit dependencies (via the systemserver jars configuration) on a number
+ // of modules that are part of the java systemserver classpath and which are provided by mainline
+ // modules but which are not otherwise used outside those mainline modules.
+ //
+ // As they are not needed outside the mainline modules adding them to the sdk/module-exports as
+ // either java_libs, or java_header_libs would end up exporting more information than was strictly
+ // necessary. The java_systemserver_libs property to allow those modules to be exported as part of
+ // the sdk/module_exports without exposing any unnecessary information.
+ javaSystemserverLibsSdkMemberType = &librarySdkMemberType{
+ android.SdkMemberTypeBase{
+ PropertyName: "java_systemserver_libs",
+ SupportsSdk: true,
+ },
+ func(ctx android.SdkMemberContext, j *Library) android.Path {
+ // Java systemserver libs are only provided in the SDK to provide access to their dex
+ // implementation jar for use by dexpreopting. They do not need to provide an actual
+ // implementation jar but the java_import will need a file that exists so just copy an empty
+ // file. Any attempt to use that file as a jar will cause a build error.
+ return ctx.SnapshotBuilder().EmptyFile()
+ },
+ func(osPrefix, name string) string {
+ // Create a special name for the implementation jar to try and provide some useful information
+ // to a developer that attempts to compile against this.
+ // TODO(b/175714559): Provide a proper error message in Soong not ninja.
+ return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
+ },
+ onlyCopyJarToSnapshot,
+ }
+
// Supports adding java test libraries to module_exports but not sdk.
javaTestSdkMemberType = &testSdkMemberType{
SdkMemberTypeBase: android.SdkMemberTypeBase{
@@ -500,6 +532,14 @@
return false
}
+// Sets `dexer.dexProperties.Uncompress_dex` to the proper value.
+func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) {
+ if dexer.dexProperties.Uncompress_dex == nil {
+ // If the value was not force-set by the user, use reasonable default based on the module.
+ dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, dexpreopter))
+ }
+}
+
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.sdkVersion = j.SdkVersion(ctx)
j.minSdkVersion = j.MinSdkVersion(ctx)
@@ -513,10 +553,7 @@
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
- if j.dexProperties.Uncompress_dex == nil {
- // If the value was not force-set by the user, use reasonable default based on the module.
- j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
- }
+ setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
j.compile(ctx, nil)
@@ -533,10 +570,6 @@
j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
j.Stem()+".jar", j.outputFile, extraInstallDeps...)
}
-
- if ctx.Windows() {
- j.HideFromMake()
- }
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -749,6 +782,9 @@
// Names of modules containing JNI libraries that should be installed alongside the test.
Jni_libs []string
+
+ // Install the test into a folder named for the module in all test suites.
+ Per_testcase_directory *bool
}
type hostTestProperties struct {
@@ -760,6 +796,9 @@
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites []string `android:"arch_variant"`
+
+ // Install the test into a folder named for the module in all test suites.
+ Per_testcase_directory *bool
}
type prebuiltTestProperties struct {
@@ -1097,10 +1136,6 @@
j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
ctx.ModuleName()+ext, j.wrapperFile)
}
-
- if ctx.Windows() {
- j.HideFromMake()
- }
}
func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -1360,10 +1395,16 @@
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil {
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
j.dexJarFile = dexJarFile
- j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
+ installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
+ j.dexJarInstallFile = installPath
+
+ j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath)
+ setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
+ j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
+ j.dexpreopt(ctx, dexOutputPath)
// Initialize the hiddenapi structure.
- j.initHiddenAPI(ctx, dexJarFile, outputFile, nil)
+ j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex)
} else {
// This should never happen as a variant for a prebuilt_apex is only created if the
// prebuilt_apex has been configured to export the java library dex file.
@@ -1383,10 +1424,7 @@
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
ctx, android.PathForModuleInstall(ctx, "framework", jarName))
- if j.dexProperties.Uncompress_dex == nil {
- // If the value was not force-set by the user, use reasonable default based on the module.
- j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
- }
+ setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
var dexOutputFile android.OutputPath
@@ -1502,9 +1540,6 @@
var _ android.IDECustomizedModuleName = (*Import)(nil)
// Collect information for opening IDE project files in java/jdeps.go.
-const (
- removedPrefix = "prebuilt_"
-)
func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
index 7749310..e3396c1 100644
--- a/java/legacy_core_platform_api_usage.go
+++ b/java/legacy_core_platform_api_usage.go
@@ -20,6 +20,8 @@
)
var legacyCorePlatformApiModules = []string{
+ "AAECarSystemUI",
+ "AAECarSystemUI-tests",
"ArcSettings",
"ahat-test-dump",
"android.car",
@@ -30,28 +32,33 @@
"api-stubs-docs",
"art_cts_jvmti_test_library",
"art-gtest-jars-MyClassNatives",
+ "BackupEncryption",
"BackupFrameworksServicesRoboTests",
"backuplib",
"BandwidthEnforcementTest",
"BlockedNumberProvider",
"BluetoothInstrumentationTests",
+ "BluetoothMidiLib",
"BluetoothMidiService",
- "CarDeveloperOptions",
+ "BTTestApp",
+ "CallEnhancement",
+ "CapCtrlInterface",
"CarService",
"CarServiceTest",
- "car-apps-common",
"car-service-test-lib",
"car-service-test-static-lib",
"CertInstaller",
+ "com.qti.location.sdk",
"com.qti.media.secureprocessor",
"ConnectivityManagerTest",
"ContactsProvider",
"CorePerfTests",
"core-tests-support",
+ "cronet_impl_common_java",
+ "cronet_impl_native_java",
+ "cronet_impl_platform_java",
"CtsAppExitTestCases",
"CtsContentTestCases",
- "CtsIkeTestCases",
- "CtsAppExitTestCases",
"CtsLibcoreWycheproofBCTestCases",
"CtsMediaTestCases",
"CtsNetTestCases",
@@ -64,8 +71,10 @@
"DeviceInfo",
"DiagnosticTools",
"DisplayCutoutEmulationEmu01Overlay",
+ "DocumentsUIGoogleTests",
"DocumentsUIPerfTests",
"DocumentsUITests",
+ "DocumentsUIUnitTests",
"DownloadProvider",
"DownloadProviderTests",
"DownloadProviderUi",
@@ -75,10 +84,12 @@
"ethernet-service",
"EthernetServiceTests",
"ExternalStorageProvider",
- "ExtServices",
- "ExtServices-core",
- "framework-all",
+ "face-V1-0-javalib",
+ "FloralClocks",
+ "framework-jobscheduler",
"framework-minus-apex",
+ "framework-minus-apex-intdefs",
+ "FrameworkOverlayG6QU3",
"FrameworksCoreTests",
"FrameworksIkeTests",
"FrameworksNetCommonTests",
@@ -87,29 +98,50 @@
"FrameworksServicesTests",
"FrameworksMockingServicesTests",
"FrameworksUtilTests",
- "FrameworksWifiTests",
+ "GtsIncrementalInstallTestCases",
+ "GtsIncrementalInstallTriggerApp",
+ "GtsInstallerV2TestCases",
+ "HelloOslo",
"hid",
"hidl_test_java_java",
"hwbinder",
- "ims",
+ "imssettings",
+ "izat.lib.glue",
"KeyChain",
- "ksoap2",
+ "LocalSettingsLib",
"LocalTransport",
"lockagent",
"mediaframeworktest",
- "MediaProvider",
+ "mediatek-ims-base",
"MmsService",
- "MtpDocumentsProvider",
+ "ModemTestMode",
+ "MtkCapCtrl",
+ "MtpService",
"MultiDisplayProvider",
+ "my.tests.snapdragonsdktest",
+ "NetworkSetting",
"NetworkStackIntegrationTestsLib",
"NetworkStackNextIntegrationTests",
"NetworkStackNextTests",
"NetworkStackTests",
"NetworkStackTestsLib",
- "NfcNci",
+ "online-gcm-ref-docs",
+ "online-gts-docs",
+ "PerformanceMode",
"platform_library-docs",
+ "PowerStatsService",
"PrintSpooler",
+ "pxp-monitor",
+ "QColor",
+ "qcom.fmradio",
+ "QDCMMobileApp",
+ "Qmmi",
+ "QPerformance",
+ "remotesimlockmanagerlibrary",
"RollbackTest",
+ "sam",
+ "saminterfacelibrary",
+ "sammanagerlibrary",
"service-blobstore",
"service-connectivity-pre-jarjar",
"service-jobscheduler",
@@ -123,21 +155,50 @@
"services.usb",
"Settings-core",
"SettingsGoogle",
+ "SettingsGoogleOverlayCoral",
+ "SettingsGoogleOverlayFlame",
"SettingsLib",
+ "SettingsOverlayG020A",
+ "SettingsOverlayG020B",
+ "SettingsOverlayG020C",
+ "SettingsOverlayG020D",
+ "SettingsOverlayG020E",
+ "SettingsOverlayG020E_VN",
+ "SettingsOverlayG020F",
+ "SettingsOverlayG020F_VN",
+ "SettingsOverlayG020G",
+ "SettingsOverlayG020G_VN",
+ "SettingsOverlayG020H",
+ "SettingsOverlayG020H_VN",
+ "SettingsOverlayG020I",
+ "SettingsOverlayG020I_VN",
+ "SettingsOverlayG020J",
+ "SettingsOverlayG020M",
+ "SettingsOverlayG020N",
+ "SettingsOverlayG020P",
+ "SettingsOverlayG020Q",
+ "SettingsOverlayG025H",
+ "SettingsOverlayG025J",
+ "SettingsOverlayG025M",
+ "SettingsOverlayG025N",
+ "SettingsOverlayG5NZ6",
"SettingsProvider",
"SettingsProviderTest",
"SettingsRoboTests",
"Shell",
"ShellTests",
+ "SimContact",
+ "SimContacts",
+ "SimSettings",
"sl4a.Common",
"StatementService",
"SystemUI-core",
"SystemUISharedLib",
"SystemUI-tests",
+ "tcmiface",
"Telecom",
"TelecomUnitTests",
"telephony-common",
- "TelephonyProvider",
"TelephonyProviderTests",
"TeleService",
"testables",
@@ -147,12 +208,16 @@
"time_zone_distro_installer-tests",
"time_zone_distro-tests",
"time_zone_updater",
+ "TMobilePlanProvider",
"TvProvider",
"uiautomator-stubs-docs",
+ "uimgbamanagerlibrary",
"UsbHostExternalManagementTestApp",
"UserDictionaryProvider",
+ "UxPerformance",
"WallpaperBackup",
- "wifi-service",
+ "WallpaperBackupAgentTests",
+ "WfdCommon",
}
var legacyCorePlatformApiLookup = make(map[string]struct{})
diff --git a/java/proto.go b/java/proto.go
index 983a13c..ab913d8 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -24,7 +24,7 @@
func genProto(ctx android.ModuleContext, protoFiles android.Paths, flags android.ProtoFlags) android.Paths {
// Shard proto files into groups of 100 to avoid having to recompile all of them if one changes and to avoid
// hitting command line length limits.
- shards := android.ShardPaths(protoFiles, 100)
+ shards := android.ShardPaths(protoFiles, 50)
srcJarFiles := make(android.Paths, 0, len(shards))
diff --git a/java/sdk.go b/java/sdk.go
index d1b899e..3c6b234 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -116,13 +116,13 @@
}
}
- toModule := func(modules []string, res string, aidl android.Path) sdkDep {
+ toModule := func(systemModules string, module string, aidl android.Path) sdkDep {
return sdkDep{
useModule: true,
- bootclasspath: append(modules, config.DefaultLambdaStubsLibrary),
- systemModules: "core-current-stubs-system-modules",
- java9Classpath: modules,
- frameworkResModule: res,
+ bootclasspath: []string{module, config.DefaultLambdaStubsLibrary},
+ systemModules: systemModules,
+ java9Classpath: []string{module},
+ frameworkResModule: "framework-res",
aidl: android.OptionalPathForPath(aidl),
}
}
@@ -161,11 +161,11 @@
noFrameworksLibs: true,
}
case android.SdkPublic:
- return toModule([]string{"android_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule("core-current-stubs-system-modules", "android_stubs_current", sdkFrameworkAidlPath(ctx))
case android.SdkSystem:
- return toModule([]string{"android_system_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule("core-current-stubs-system-modules", "android_system_stubs_current", sdkFrameworkAidlPath(ctx))
case android.SdkTest:
- return toModule([]string{"android_test_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule("core-current-stubs-system-modules", "android_test_stubs_current", sdkFrameworkAidlPath(ctx))
case android.SdkCore:
return sdkDep{
useModule: true,
@@ -175,24 +175,10 @@
}
case android.SdkModule:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return sdkDep{
- useModule: true,
- bootclasspath: []string{"android_module_lib_stubs_current", config.DefaultLambdaStubsLibrary},
- systemModules: "core-module-lib-stubs-system-modules",
- java9Classpath: []string{"android_module_lib_stubs_current"},
- frameworkResModule: "framework-res",
- aidl: android.OptionalPathForPath(nonUpdatableFrameworkAidlPath(ctx)),
- }
+ return toModule("core-module-lib-stubs-system-modules", "android_module_lib_stubs_current", nonUpdatableFrameworkAidlPath(ctx))
case android.SdkSystemServer:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return sdkDep{
- useModule: true,
- bootclasspath: []string{"android_system_server_stubs_current", config.DefaultLambdaStubsLibrary},
- systemModules: "core-module-lib-stubs-system-modules",
- java9Classpath: []string{"android_system_server_stubs_current"},
- frameworkResModule: "framework-res",
- aidl: android.OptionalPathForPath(sdkFrameworkAidlPath(ctx)),
- }
+ return toModule("core-module-lib-stubs-system-modules", "android_system_server_stubs_current", sdkFrameworkAidlPath(ctx))
default:
panic(fmt.Errorf("invalid sdk %q", sdkVersion.Raw))
}
@@ -370,7 +356,7 @@
"frameworks-base-api-current.txt",
"frameworks-base-api-system-current.txt",
"frameworks-base-api-module-lib-current.txt",
- "services-system-server-current.txt",
+ "frameworks-base-api-system-server-current.txt",
}
count := 0
ctx.VisitAllModules(func(module android.Module) {
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 6d62130..9a71192 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -25,27 +25,36 @@
"android/soong/java/config"
)
+type classpathTestCase struct {
+ name string
+ unbundled bool
+ moduleType string
+ host android.OsClass
+ properties string
+
+ // for java 8
+ bootclasspath []string
+ java8classpath []string
+
+ // for java 9
+ system string
+ java9classpath []string
+
+ forces8 bool // if set, javac will always be called with java 8 arguments
+
+ aidl string
+
+ // Indicates how this test case is affected by the setting of Always_use_prebuilt_sdks.
+ //
+ // If this is nil then the test case is unaffected by the setting of Always_use_prebuilt_sdks.
+ // Otherwise, the test case can only be used when
+ // Always_use_prebuilt_sdks=*forAlwaysUsePrebuiltSdks.
+ forAlwaysUsePrebuiltSdks *bool
+}
+
func TestClasspath(t *testing.T) {
const frameworkAidl = "-I" + defaultJavaDir + "/framework/aidl"
- var classpathTestcases = []struct {
- name string
- unbundled bool
- moduleType string
- host android.OsClass
- properties string
-
- // for java 8
- bootclasspath []string
- java8classpath []string
-
- // for java 9
- system string
- java9classpath []string
-
- forces8 bool // if set, javac will always be called with java 8 arguments
-
- aidl string
- }{
+ var classpathTestcases = []classpathTestCase{
{
name: "default",
bootclasspath: config.StableCorePlatformBootclasspathLibraries,
@@ -91,6 +100,8 @@
aidl: "-pprebuilts/sdk/30/public/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
name: "current",
properties: `sdk_version: "current",`,
@@ -100,6 +111,20 @@
aidl: "-pout/soong/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "current",
+ properties: `sdk_version: "current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
name: "system_current",
properties: `sdk_version: "system_current",`,
@@ -109,7 +134,18 @@
aidl: "-pout/soong/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+ name: "system_current",
+ properties: `sdk_version: "system_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
name: "system_29",
properties: `sdk_version: "system_29",`,
bootclasspath: []string{`""`},
@@ -118,7 +154,6 @@
aidl: "-pprebuilts/sdk/29/public/framework.aidl",
},
{
-
name: "system_30",
properties: `sdk_version: "system_30",`,
bootclasspath: []string{`""`},
@@ -128,6 +163,8 @@
aidl: "-pprebuilts/sdk/30/public/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
name: "test_current",
properties: `sdk_version: "test_current",`,
@@ -137,6 +174,29 @@
aidl: "-pout/soong/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "test_current",
+ properties: `sdk_version: "test_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/test/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/test/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
+ name: "test_30",
+ properties: `sdk_version: "test_30",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_30_system_modules",
+ java8classpath: []string{"prebuilts/sdk/30/test/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/30/test/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/30/public/framework.aidl",
+ },
+ {
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
name: "core_current",
properties: `sdk_version: "core_current",`,
@@ -144,6 +204,18 @@
system: "core-current-stubs-system-modules",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "core_current",
+ properties: `sdk_version: "core_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/core/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/core/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
name: "nostdlib",
properties: `sdk_version: "none", system_modules: "none"`,
@@ -214,8 +286,10 @@
java9classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
aidl: "-pprebuilts/sdk/current/public/framework.aidl",
},
-
{
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
+
name: "module_current",
properties: `sdk_version: "module_current",`,
bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"},
@@ -224,6 +298,48 @@
aidl: "-pout/soong/framework_non_updatable.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "module_current",
+ properties: `sdk_version: "module_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
+ name: "module_30",
+ properties: `sdk_version: "module_30",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_30_system_modules",
+ java8classpath: []string{"prebuilts/sdk/30/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/30/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/30/public/framework.aidl",
+ },
+ {
+ name: "module_31",
+ properties: `sdk_version: "module_31",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_31_system_modules",
+ java8classpath: []string{"prebuilts/sdk/31/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/31/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/31/public/framework.aidl",
+ },
+ {
+ name: "module_32",
+ properties: `sdk_version: "module_32",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_32_system_modules",
+ java8classpath: []string{"prebuilts/sdk/32/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/32/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/32/public/framework.aidl",
+ },
+ {
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
+
name: "system_server_current",
properties: `sdk_version: "system_server_current",`,
bootclasspath: []string{"android_system_server_stubs_current", "core-lambda-stubs"},
@@ -231,9 +347,62 @@
java9classpath: []string{"android_system_server_stubs_current"},
aidl: "-pout/soong/framework.aidl",
},
+ {
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "system_server_current",
+ properties: `sdk_version: "system_server_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
+ name: "system_server_30",
+ properties: `sdk_version: "system_server_30",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_30_system_modules",
+ java8classpath: []string{"prebuilts/sdk/30/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/30/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/30/public/framework.aidl",
+ },
+ {
+ name: "system_server_31",
+ properties: `sdk_version: "system_server_31",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_31_system_modules",
+ java8classpath: []string{"prebuilts/sdk/31/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/31/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/31/public/framework.aidl",
+ },
+ {
+ name: "system_server_32",
+ properties: `sdk_version: "system_server_32",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_32_system_modules",
+ java8classpath: []string{"prebuilts/sdk/32/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/32/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/32/public/framework.aidl",
+ },
}
+ t.Run("basic", func(t *testing.T) {
+ testClasspathTestCases(t, classpathTestcases, false)
+ })
+
+ t.Run("Always_use_prebuilt_sdks=true", func(t *testing.T) {
+ testClasspathTestCases(t, classpathTestcases, true)
+ })
+}
+
+func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks bool) {
for _, testcase := range classpathTestcases {
+ if testcase.forAlwaysUsePrebuiltSdks != nil && *testcase.forAlwaysUsePrebuiltSdks != alwaysUsePrebuiltSdks {
+ continue
+ }
+
t.Run(testcase.name, func(t *testing.T) {
moduleType := "java_library"
if testcase.moduleType != "" {
@@ -299,7 +468,9 @@
system = "--system=none"
} else if testcase.system != "" {
dir := ""
- if strings.HasPrefix(testcase.system, "sdk_public_") {
+ // If the system modules name starts with sdk_ then it is a prebuilt module and so comes
+ // from the prebuilt directory.
+ if strings.HasPrefix(testcase.system, "sdk_") {
dir = "prebuilts/sdk"
} else {
dir = defaultJavaDir
@@ -351,11 +522,20 @@
android.AssertPathsRelativeToTopEquals(t, "implicits", deps, javac.Implicits)
}
+ preparer := android.NullFixturePreparer
+ if alwaysUsePrebuiltSdks {
+ preparer = android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
+ })
+ }
+
fixtureFactory := android.GroupFixturePreparers(
prepareForJavaTest,
FixtureWithPrebuiltApis(map[string][]string{
"29": {},
"30": {},
+ "31": {},
+ "32": {},
"current": {},
}),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -369,6 +549,7 @@
env["ANDROID_JAVA8_HOME"] = "jdk8"
}
}),
+ preparer,
)
// Test with legacy javac -source 1.8 -target 1.8
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index de2a978..b5f52fd 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -23,11 +23,19 @@
func init() {
registerSystemserverClasspathBuildComponents(android.InitRegistrationContext)
+
+ android.RegisterSdkMemberType(&systemServerClasspathFragmentMemberType{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
+ PropertyName: "systemserverclasspath_fragments",
+ SupportsSdk: true,
+ },
+ })
}
func registerSystemserverClasspathBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("platform_systemserverclasspath", platformSystemServerClasspathFactory)
ctx.RegisterModuleType("systemserverclasspath_fragment", systemServerClasspathFactory)
+ ctx.RegisterModuleType("prebuilt_systemserverclasspath_fragment", prebuiltSystemServerClasspathModuleFactory)
}
type platformSystemServerClasspathModule struct {
@@ -61,6 +69,7 @@
type SystemServerClasspathModule struct {
android.ModuleBase
android.ApexModuleBase
+ android.SdkBase
ClasspathFragmentBase
@@ -85,6 +94,7 @@
m := &SystemServerClasspathModule{}
m.AddProperties(&m.properties)
android.InitApexModule(m)
+ android.InitSdkAwareModule(m)
initClasspathFragment(m, SYSTEMSERVERCLASSPATH)
android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
return m
@@ -110,10 +120,13 @@
jars, unknown := global.ApexSystemServerJars.Filter(possibleUpdatableModules)
// TODO(satayev): remove geotz ssc_fragment, since geotz is not part of SSCP anymore.
_, unknown = android.RemoveFromList("geotz", unknown)
-
+ // This module only exists in car products.
+ // So ignore it even if it is not in PRODUCT_APEX_SYSTEM_SERVER_JARS.
+ // TODO(b/203233647): Add better mechanism to make it optional.
+ _, unknown = android.RemoveFromList("car-frameworks-service-module", unknown)
// For non test apexes, make sure that all contents are actually declared in make.
- if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 {
- ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS", unknown)
+ if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
+ ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_SYSTEM_SERVER_JARS", unknown)
}
return jars
@@ -128,12 +141,33 @@
return false
}
+// SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if
+// they were specified using java_systemserver_libs or java_sdk_libs.
+func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
+ // If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs
+ // property, otherwise treat if it was specified in the java_systemserver_libs property.
+ if javaSdkLibrarySdkMemberType.IsInstance(child) {
+ return javaSdkLibrarySdkMemberType
+ }
+
+ return javaSystemserverLibsSdkMemberType
+}
+
+func (b systemServerClasspathFragmentContentDependencyTag) ExportMember() bool {
+ return true
+}
+
// Contents of system server fragments in an apex are considered to be directly in the apex, as if
// they were listed in java_libs.
func (systemServerClasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() {}
+// Contents of system server fragments require files from prebuilt apex files.
+func (systemServerClasspathFragmentContentDependencyTag) RequiresFilesFromPrebuiltApex() {}
+
var _ android.ReplaceSourceWithPrebuilt = systemServerClasspathFragmentContentDepTag
+var _ android.SdkMemberDependencyTag = systemServerClasspathFragmentContentDepTag
var _ android.CopyDirectlyInAnyApexTag = systemServerClasspathFragmentContentDepTag
+var _ android.RequiresFilesFromPrebuiltApexTag = systemServerClasspathFragmentContentDepTag
// The tag used for the dependency between the systemserverclasspath_fragment module and its contents.
var systemServerClasspathFragmentContentDepTag = systemServerClasspathFragmentContentDependencyTag{}
@@ -144,8 +178,14 @@
func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
module := ctx.Module()
+ _, isSourceModule := module.(*SystemServerClasspathModule)
for _, name := range s.properties.Contents {
+ // A systemserverclasspath_fragment must depend only on other source modules, while the
+ // prebuilt_systemserverclasspath_fragment_fragment must only depend on other prebuilt modules.
+ if !isSourceModule {
+ name = android.PrebuiltNameFromSource(name)
+ }
ctx.AddDependency(module, systemServerClasspathFragmentContentDepTag, name)
}
}
@@ -155,3 +195,80 @@
dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents...)
dpInfo.Paths = append(dpInfo.Paths, s.modulePaths...)
}
+
+type systemServerClasspathFragmentMemberType struct {
+ android.SdkMemberTypeBase
+}
+
+func (s *systemServerClasspathFragmentMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
+ ctx.AddVariationDependencies(nil, dependencyTag, names...)
+}
+
+func (s *systemServerClasspathFragmentMemberType) IsInstance(module android.Module) bool {
+ _, ok := module.(*SystemServerClasspathModule)
+ return ok
+}
+
+func (s *systemServerClasspathFragmentMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
+ return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_systemserverclasspath_fragment")
+}
+
+func (s *systemServerClasspathFragmentMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
+ return &systemServerClasspathFragmentSdkMemberProperties{}
+}
+
+type systemServerClasspathFragmentSdkMemberProperties struct {
+ android.SdkMemberPropertiesBase
+
+ // Contents of the systemserverclasspath fragment
+ Contents []string
+}
+
+func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
+ module := variant.(*SystemServerClasspathModule)
+
+ s.Contents = module.properties.Contents
+}
+
+func (s *systemServerClasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
+ builder := ctx.SnapshotBuilder()
+ requiredMemberDependency := builder.SdkMemberReferencePropertyTag(true)
+
+ if len(s.Contents) > 0 {
+ propertySet.AddPropertyWithTag("contents", s.Contents, requiredMemberDependency)
+ }
+}
+
+var _ android.SdkMemberType = (*systemServerClasspathFragmentMemberType)(nil)
+
+// A prebuilt version of the systemserverclasspath_fragment module.
+type prebuiltSystemServerClasspathModule struct {
+ SystemServerClasspathModule
+ prebuilt android.Prebuilt
+}
+
+func (module *prebuiltSystemServerClasspathModule) Prebuilt() *android.Prebuilt {
+ return &module.prebuilt
+}
+
+func (module *prebuiltSystemServerClasspathModule) Name() string {
+ return module.prebuilt.Name(module.ModuleBase.Name())
+}
+
+func (module *prebuiltSystemServerClasspathModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
+ return nil
+}
+
+var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltSystemServerClasspathModule)(nil)
+
+func prebuiltSystemServerClasspathModuleFactory() android.Module {
+ m := &prebuiltSystemServerClasspathModule{}
+ m.AddProperties(&m.properties)
+ // This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
+ // array.
+ android.InitPrebuiltModule(m, &[]string{"placeholder"})
+ android.InitApexModule(m)
+ android.InitSdkAwareModule(m)
+ android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+ return m
+}
diff --git a/java/testing.go b/java/testing.go
index 99d55a0..0a6a4fa 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -181,6 +181,9 @@
}
}
}
+ if level == "current" {
+ fs["prebuilts/sdk/current/core/android.jar"] = nil
+ }
fs[fmt.Sprintf("prebuilts/sdk/%s/public/framework.aidl", level)] = nil
}
return fs
diff --git a/mk2rbc/cmd/mk2rbc.go b/mk2rbc/cmd/mk2rbc.go
index 345b30e..b089f91 100644
--- a/mk2rbc/cmd/mk2rbc.go
+++ b/mk2rbc/cmd/mk2rbc.go
@@ -154,47 +154,39 @@
}
// Convert!
- ok := true
- if *launcher != "" {
- if len(flag.Args()) != 1 {
- quit(fmt.Errorf("a launcher can be generated only for a single product"))
- }
- product := flag.Args()[0]
+ files := flag.Args()
+ if *allInSource {
productConfigMap := buildProductConfigMap()
- path, found := productConfigMap[product]
- if !found {
- quit(fmt.Errorf("cannot generate configuration launcher for %s, it is not a known product",
- product))
+ for _, path := range productConfigMap {
+ files = append(files, path)
+ }
+ }
+ ok := true
+ for _, mkFile := range files {
+ ok = convertOne(mkFile) && ok
+ }
+
+ if *launcher != "" {
+ if len(files) != 1 {
+ quit(fmt.Errorf("a launcher can be generated only for a single product"))
}
versionDefaults, err := generateVersionDefaults()
if err != nil {
quit(err)
}
- ok = convertOne(path) && ok
versionDefaultsPath := outputFilePath(versionDefaultsMk)
err = writeGenerated(versionDefaultsPath, versionDefaults)
if err != nil {
- fmt.Fprintf(os.Stderr, "%s:%s", path, err)
+ fmt.Fprintf(os.Stderr, "%s:%s", files[0], err)
ok = false
}
- err = writeGenerated(*launcher, mk2rbc.Launcher(outputFilePath(path), versionDefaultsPath,
- mk2rbc.MakePath2ModuleName(path)))
+ err = writeGenerated(*launcher, mk2rbc.Launcher(outputFilePath(files[0]), versionDefaultsPath,
+ mk2rbc.MakePath2ModuleName(files[0])))
if err != nil {
- fmt.Fprintf(os.Stderr, "%s:%s", path, err)
+ fmt.Fprintf(os.Stderr, "%s:%s", files[0], err)
ok = false
}
- } else {
- files := flag.Args()
- if *allInSource {
- productConfigMap := buildProductConfigMap()
- for _, path := range productConfigMap {
- files = append(files, path)
- }
- }
- for _, mkFile := range files {
- ok = convertOne(mkFile) && ok
- }
}
printStats()
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 3ae8ab9..6227164 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -40,12 +40,15 @@
)
const (
- baseUri = "//build/make/core:product_config.rbc"
+ annotationCommentPrefix = "RBC#"
+ baseUri = "//build/make/core:product_config.rbc"
// The name of the struct exported by the product_config.rbc
// that contains the functions and variables available to
// product configuration Starlark files.
baseName = "rblf"
+ soongNsPrefix = "SOONG_CONFIG_"
+
// And here are the functions and variables:
cfnGetCfg = baseName + ".cfg"
cfnMain = baseName + ".product_configuration"
@@ -60,10 +63,14 @@
const (
// Phony makefile functions, they are eventually rewritten
// according to knownFunctions map
- addSoongNamespace = "add_soong_config_namespace"
- addSoongConfigVarValue = "add_soong_config_var_value"
- fileExistsPhony = "$file_exists"
- wildcardExistsPhony = "$wildcard_exists"
+ fileExistsPhony = "$file_exists"
+ // The following two macros are obsolete, and will we deleted once
+ // there are deleted from the makefiles:
+ soongConfigNamespaceOld = "add_soong_config_namespace"
+ soongConfigVarSetOld = "add_soong_config_var_value"
+ soongConfigAppend = "soong_config_append"
+ soongConfigAssign = "soong_config_set"
+ wildcardExistsPhony = "$wildcard_exists"
)
const (
@@ -82,8 +89,10 @@
"abspath": {baseName + ".abspath", starlarkTypeString, hiddenArgNone},
fileExistsPhony: {baseName + ".file_exists", starlarkTypeBool, hiddenArgNone},
wildcardExistsPhony: {baseName + ".file_wildcard_exists", starlarkTypeBool, hiddenArgNone},
- addSoongNamespace: {baseName + ".add_soong_config_namespace", starlarkTypeVoid, hiddenArgGlobal},
- addSoongConfigVarValue: {baseName + ".add_soong_config_var_value", starlarkTypeVoid, hiddenArgGlobal},
+ soongConfigNamespaceOld: {baseName + ".soong_config_namespace", starlarkTypeVoid, hiddenArgGlobal},
+ soongConfigVarSetOld: {baseName + ".soong_config_set", starlarkTypeVoid, hiddenArgGlobal},
+ soongConfigAssign: {baseName + ".soong_config_set", starlarkTypeVoid, hiddenArgGlobal},
+ soongConfigAppend: {baseName + ".soong_config_append", starlarkTypeVoid, hiddenArgGlobal},
"add-to-product-copy-files-if-exists": {baseName + ".copy_if_exists", starlarkTypeList, hiddenArgNone},
"addprefix": {baseName + ".addprefix", starlarkTypeList, hiddenArgNone},
"addsuffix": {baseName + ".addsuffix", starlarkTypeList, hiddenArgNone},
@@ -102,13 +111,16 @@
"is-android-codename": {"!is-android-codename", starlarkTypeBool, hiddenArgNone}, // unused by product config
"is-android-codename-in-list": {"!is-android-codename-in-list", starlarkTypeBool, hiddenArgNone}, // unused by product config
"is-board-platform": {"!is-board-platform", starlarkTypeBool, hiddenArgNone},
+ "is-board-platform2": {baseName + ".board_platform_is", starlarkTypeBool, hiddenArgGlobal},
"is-board-platform-in-list": {"!is-board-platform-in-list", starlarkTypeBool, hiddenArgNone},
+ "is-board-platform-in-list2": {baseName + ".board_platform_in", starlarkTypeBool, hiddenArgGlobal},
"is-chipset-in-board-platform": {"!is-chipset-in-board-platform", starlarkTypeUnknown, hiddenArgNone}, // unused by product config
"is-chipset-prefix-in-board-platform": {"!is-chipset-prefix-in-board-platform", starlarkTypeBool, hiddenArgNone}, // unused by product config
"is-not-board-platform": {"!is-not-board-platform", starlarkTypeBool, hiddenArgNone}, // defined but never used
"is-platform-sdk-version-at-least": {"!is-platform-sdk-version-at-least", starlarkTypeBool, hiddenArgNone}, // unused by product config
"is-product-in-list": {"!is-product-in-list", starlarkTypeBool, hiddenArgNone},
"is-vendor-board-platform": {"!is-vendor-board-platform", starlarkTypeBool, hiddenArgNone},
+ "is-vendor-board-qcom": {"!is-vendor-board-qcom", starlarkTypeBool, hiddenArgNone},
callLoadAlways: {"!inherit-product", starlarkTypeVoid, hiddenArgNone},
callLoadIf: {"!inherit-product-if-exists", starlarkTypeVoid, hiddenArgNone},
"lastword": {"!lastword", starlarkTypeString, hiddenArgNone},
@@ -399,6 +411,7 @@
outputDir string
dependentModules map[string]*moduleInfo
soongNamespaces map[string]map[string]bool
+ includeTops []string
}
func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
@@ -444,6 +457,7 @@
variables: make(map[string]variable),
dependentModules: make(map[string]*moduleInfo),
soongNamespaces: make(map[string]map[string]bool),
+ includeTops: []string{"vendor/google-devices"},
}
ctx.pushVarAssignments()
for _, item := range predefined {
@@ -522,7 +536,6 @@
return
}
name := a.Name.Strings[0]
- const soongNsPrefix = "SOONG_CONFIG_"
// Soong confuguration
if strings.HasPrefix(name, soongNsPrefix) {
ctx.handleSoongNsAssignment(strings.TrimPrefix(name, soongNsPrefix), a)
@@ -615,7 +628,7 @@
for _, ns := range strings.Fields(s) {
ctx.addSoongNamespace(ns)
ctx.receiver.newNode(&exprNode{&callExpr{
- name: addSoongNamespace,
+ name: soongConfigNamespaceOld,
args: []starlarkExpr{&stringLiteralExpr{ns}},
returnType: starlarkTypeVoid,
}})
@@ -665,8 +678,12 @@
ctx.errorf(asgn, "no %s variable in %s namespace, please use add_soong_config_var_value instead", varName, namespaceName)
return
}
+ fname := soongConfigVarSetOld
+ if asgn.Type == "+=" {
+ fname = soongConfigAppend
+ }
ctx.receiver.newNode(&exprNode{&callExpr{
- name: addSoongConfigVarValue,
+ name: fname,
args: []starlarkExpr{&stringLiteralExpr{namespaceName}, &stringLiteralExpr{varName}, val},
returnType: starlarkTypeVoid,
}})
@@ -799,21 +816,15 @@
pathPattern = append(pathPattern, chunk)
}
}
- if pathPattern[0] != "" {
- matchingPaths = ctx.findMatchingPaths(pathPattern)
- } else {
- // Heuristics -- if pattern starts from top, restrict it to the directories where
- // we know inherit-product uses dynamically calculated path. Restrict it even further
- // for certain path which would yield too many useless matches
- if len(varPath.chunks) == 2 && varPath.chunks[1] == "/BoardConfigVendor.mk" {
- pathPattern[0] = "vendor/google_devices"
- matchingPaths = ctx.findMatchingPaths(pathPattern)
- } else {
- for _, t := range []string{"vendor/qcom", "vendor/google_devices"} {
- pathPattern[0] = t
- matchingPaths = append(matchingPaths, ctx.findMatchingPaths(pathPattern)...)
- }
+ if pathPattern[0] == "" {
+ // If pattern starts from the top. restrict it to the directories where
+ // we know inherit-product uses dynamically calculated path.
+ for _, p := range ctx.includeTops {
+ pathPattern[0] = p
+ matchingPaths = append(matchingPaths, ctx.findMatchingPaths(pathPattern)...)
}
+ } else {
+ matchingPaths = ctx.findMatchingPaths(pathPattern)
}
// Safeguard against $(call inherit-product,$(PRODUCT_PATH))
const maxMatchingFiles = 150
@@ -1133,6 +1144,34 @@
list: &variableRefExpr{ctx.addVariable(s + "_BOARD_PLATFORMS"), true},
isNot: negate,
}, true
+
+ case "is-board-platform2", "is-board-platform-in-list2":
+ if s, ok := maybeString(xValue); !ok || s != "" {
+ return ctx.newBadExpr(directive,
+ fmt.Sprintf("the result of %s can be compared only to empty", x.name)), true
+ }
+ if len(x.args) != 1 {
+ return ctx.newBadExpr(directive, "%s requires an argument", x.name), true
+ }
+ cc := &callExpr{
+ name: x.name,
+ args: []starlarkExpr{x.args[0]},
+ returnType: starlarkTypeBool,
+ }
+ if !negate {
+ return ¬Expr{cc}, true
+ }
+ return cc, true
+ case "is-vendor-board-qcom":
+ if s, ok := maybeString(xValue); !ok || s != "" {
+ return ctx.newBadExpr(directive,
+ fmt.Sprintf("the result of %s can be compared only to empty", x.name)), true
+ }
+ return &inExpr{
+ expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
+ list: &variableRefExpr{ctx.addVariable("QCOM_BOARD_PLATFORMS"), true},
+ isNot: negate,
+ }, true
default:
return ctx.newBadExpr(directive, "Unknown function in ifeq: %s", x.name), true
}
@@ -1162,17 +1201,21 @@
}
// Either pattern or text should be const, and the
// non-const one should be varRefExpr
- if xInList, ok = xPattern.(*stringLiteralExpr); ok {
+ if xInList, ok = xPattern.(*stringLiteralExpr); ok && !strings.ContainsRune(xInList.literal, '%') && xText.typ() == starlarkTypeList {
expr = xText
} else if xInList, ok = xText.(*stringLiteralExpr); ok {
expr = xPattern
} else {
- return &callExpr{
+ expr = &callExpr{
object: nil,
name: filterFuncCall.name,
args: filterFuncCall.args,
returnType: starlarkTypeBool,
}
+ if negate {
+ expr = ¬Expr{expr: expr}
+ }
+ return expr
}
case *variableRefExpr:
if v, ok := xPattern.(*variableRefExpr); ok {
@@ -1273,6 +1316,10 @@
returnType: starlarkTypeUnknown,
}
}
+ if strings.HasPrefix(refDump, soongNsPrefix) {
+ // TODO (asmundak): if we find many, maybe handle them.
+ return ctx.newBadExpr(node, "SOONG_CONFIG_ variables cannot be referenced: %s", refDump)
+ }
if v := ctx.addVariable(refDump); v != nil {
return &variableRefExpr{v, ctx.lastAssignment(v.name()) != nil}
}
@@ -1434,6 +1481,7 @@
handled := true
switch x := node.(type) {
case *mkparser.Comment:
+ ctx.maybeHandleAnnotation(x)
ctx.insertComment("#" + x.Comment)
case *mkparser.Assignment:
ctx.handleAssignment(x)
@@ -1449,11 +1497,33 @@
handled = false
}
default:
- ctx.errorf(x, "unsupported line %s", x.Dump())
+ ctx.errorf(x, "unsupported line %s", strings.ReplaceAll(x.Dump(), "\n", "\n#"))
}
return handled
}
+// Processes annotation. An annotation is a comment that starts with #RBC# and provides
+// a conversion hint -- say, where to look for the dynamically calculated inherit/include
+// paths.
+func (ctx *parseContext) maybeHandleAnnotation(cnode *mkparser.Comment) {
+ maybeTrim := func(s, prefix string) (string, bool) {
+ if strings.HasPrefix(s, prefix) {
+ return strings.TrimSpace(strings.TrimPrefix(s, prefix)), true
+ }
+ return s, false
+ }
+ annotation, ok := maybeTrim(cnode.Comment, annotationCommentPrefix)
+ if !ok {
+ return
+ }
+ if p, ok := maybeTrim(annotation, "include_top"); ok {
+ ctx.includeTops = append(ctx.includeTops, p)
+ return
+ }
+ ctx.errorf(cnode, "unsupported annotation %s", cnode.Comment)
+
+}
+
func (ctx *parseContext) insertComment(s string) {
ctx.receiver.newNode(&commentNode{strings.TrimSpace(s)})
}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 434500b..511bb0f 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -360,20 +360,27 @@
endif
ifneq (,$(filter true, $(v1)$(v2)))
endif
+ifeq (,$(filter barbet coral%,$(TARGET_PRODUCT)))
+else ifneq (,$(filter barbet%,$(TARGET_PRODUCT)))
+endif
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
- if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]:
+ if not rblf.filter("userdebug eng", g["TARGET_BUILD_VARIANT"]):
pass
- if g["TARGET_BUILD_VARIANT"] == "userdebug":
+ if rblf.filter("userdebug", g["TARGET_BUILD_VARIANT"]):
pass
if "plaf" in g.get("PLATFORM_LIST", []):
pass
if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]:
pass
- if "%s%s" % (_v1, _v2) == "true":
+ if rblf.filter("true", "%s%s" % (_v1, _v2)):
+ pass
+ if not rblf.filter("barbet coral%", g["TARGET_PRODUCT"]):
+ pass
+ elif rblf.filter("barbet%", g["TARGET_PRODUCT"]):
pass
`,
},
@@ -556,6 +563,27 @@
`,
},
{
+ desc: "new is-board calls",
+ mkname: "product.mk",
+ in: `
+ifneq (,$(call is-board-platform-in-list2,msm8998 $(X))
+else ifeq (,$(call is-board-platform2,copper)
+else ifneq (,$(call is-vendor-board-qcom))
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if rblf.board_platform_in(g, "msm8998 %s" % g.get("X", "")):
+ pass
+ elif not rblf.board_platform_is(g, "copper"):
+ pass
+ elif g.get("TARGET_BOARD_PLATFORM", "") not in g["QCOM_BOARD_PLATFORMS"]:
+ pass
+`,
+ },
+ {
desc: "findstring call",
mkname: "product.mk",
in: `
@@ -674,6 +702,8 @@
$(info $(notdir foo/bar))
$(call add_soong_config_namespace,snsconfig)
$(call add_soong_config_var_value,snsconfig,imagetype,odm_image)
+$(call soong_config_set, snsconfig, foo, foo_value)
+$(call soong_config_append, snsconfig, bar, bar_value)
PRODUCT_COPY_FILES := $(call copy-files,$(wildcard foo*.mk),etc)
PRODUCT_COPY_FILES := $(call product-copy-files-by-pattern,from/%,to/%,a b c)
`,
@@ -693,8 +723,10 @@
rblf.mkinfo("product.mk", rblf.dir((_foobar).split()[-1]))
rblf.mkinfo("product.mk", rblf.abspath("foo/bar"))
rblf.mkinfo("product.mk", rblf.notdir("foo/bar"))
- rblf.add_soong_config_namespace(g, "snsconfig")
- rblf.add_soong_config_var_value(g, "snsconfig", "imagetype", "odm_image")
+ rblf.soong_config_namespace(g, "snsconfig")
+ rblf.soong_config_set(g, "snsconfig", "imagetype", "odm_image")
+ rblf.soong_config_set(g, "snsconfig", "foo", "foo_value")
+ rblf.soong_config_append(g, "snsconfig", "bar", "bar_value")
cfg["PRODUCT_COPY_FILES"] = rblf.copy_files(rblf.expand_wildcard("foo*.mk"), "etc")
cfg["PRODUCT_COPY_FILES"] = rblf.product_copy_files_by_pattern("from/%", "to/%", "a b c")
`,
@@ -777,17 +809,21 @@
in: `
SOONG_CONFIG_NAMESPACES += cvd
SOONG_CONFIG_cvd += launch_configs
-SOONG_CONFIG_cvd_launch_configs += cvd_config_auto.json
+SOONG_CONFIG_cvd_launch_configs = cvd_config_auto.json
SOONG_CONFIG_cvd += grub_config
SOONG_CONFIG_cvd_grub_config += grub.cfg
+x := $(SOONG_CONFIG_cvd_grub_config)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
- rblf.add_soong_config_namespace(g, "cvd")
- rblf.add_soong_config_var_value(g, "cvd", "launch_configs", "cvd_config_auto.json")
- rblf.add_soong_config_var_value(g, "cvd", "grub_config", "grub.cfg")
+ rblf.soong_config_namespace(g, "cvd")
+ rblf.soong_config_set(g, "cvd", "launch_configs", "cvd_config_auto.json")
+ rblf.soong_config_append(g, "cvd", "grub_config", "grub.cfg")
+ # MK2RBC TRANSLATION ERROR: SOONG_CONFIG_ variables cannot be referenced: SOONG_CONFIG_cvd_grub_config
+ # x := $(SOONG_CONFIG_cvd_grub_config)
+ rblf.warning("product.mk", "partially successful conversion")
`,
},
{
@@ -904,7 +940,7 @@
desc: "Dynamic inherit path",
mkname: "product.mk",
in: `
-MY_PATH=foo
+MY_PATH:=foo
$(call inherit-product,vendor/$(MY_PATH)/cfg.mk)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -924,6 +960,47 @@
rblf.inherit(handle, _varmod, _varmod_init)
`,
},
+ {
+ desc: "Dynamic inherit with hint",
+ mkname: "product.mk",
+ in: `
+MY_PATH:=foo
+#RBC# include_top vendor/foo1
+$(call inherit-product,$(MY_PATH)/cfg.mk)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["MY_PATH"] = "foo"
+ #RBC# include_top vendor/foo1
+ _entry = {
+ "vendor/foo1/cfg.mk": ("_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("cannot")
+ rblf.inherit(handle, _varmod, _varmod_init)
+`,
+ },
+ {
+ desc: "Ignore make rules",
+ mkname: "product.mk",
+ in: `
+foo: foo.c
+ gcc -o $@ $*`,
+ expected: `# MK2RBC TRANSLATION ERROR: unsupported line rule: foo: foo.c
+#gcc -o $@ $*
+# rule: foo: foo.c
+# gcc -o $@ $*
+load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ rblf.warning("product.mk", "partially successful conversion")
+`,
+ },
}
var known_variables = []struct {
diff --git a/mk2rbc/version_defaults.go b/mk2rbc/version_defaults.go
index 27e8198..64645d7 100644
--- a/mk2rbc/version_defaults.go
+++ b/mk2rbc/version_defaults.go
@@ -15,7 +15,6 @@
package mk2rbc
import (
- mkparser "android/soong/androidmk/parser"
"bytes"
"fmt"
"io/ioutil"
@@ -23,6 +22,8 @@
"sort"
"strconv"
"strings"
+
+ mkparser "android/soong/androidmk/parser"
)
const codenamePrefix = "PLATFORM_VERSION_CODENAME."
@@ -97,7 +98,10 @@
strings.ToLower(name), genericValue(value)))
}
}
+
sort.Strings(lines)
+ sort.Strings(codenames)
+
sink.WriteString("version_defaults = struct(\n")
for _, l := range lines {
sink.WriteString(l)
diff --git a/python/binary.go b/python/binary.go
index bc2768c..bf6167c 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -37,7 +37,6 @@
type bazelPythonBinaryAttributes struct {
Main string
Srcs bazel.LabelListAttribute
- Data bazel.LabelListAttribute
Deps bazel.LabelListAttribute
Python_version string
}
@@ -63,6 +62,7 @@
}
}
}
+
// TODO(b/182306917): this doesn't fully handle all nested props versioned
// by the python version, which would have been handled by the version split
// mutator. This is sufficient for very simple python_binary_host modules
@@ -80,15 +80,11 @@
// do nothing, since python_version defaults to PY3.
}
- srcs := android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
- data := android.BazelLabelForModuleSrc(ctx, m.properties.Data)
- deps := android.BazelLabelForModuleDeps(ctx, m.properties.Libs)
-
+ baseAttrs := m.makeArchVariantBaseAttributes(ctx)
attrs := &bazelPythonBinaryAttributes{
Main: main,
- Srcs: bazel.MakeLabelListAttribute(srcs),
- Data: bazel.MakeLabelListAttribute(data),
- Deps: bazel.MakeLabelListAttribute(deps),
+ Srcs: baseAttrs.Srcs,
+ Deps: baseAttrs.Deps,
Python_version: python_version,
}
@@ -97,7 +93,10 @@
Rule_class: "py_binary",
}
- ctx.CreateBazelTargetModule(m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+ Name: m.Name(),
+ Data: baseAttrs.Data,
+ }, attrs)
}
type BinaryProperties struct {
diff --git a/python/library.go b/python/library.go
index a132216..d136a4e 100644
--- a/python/library.go
+++ b/python/library.go
@@ -45,7 +45,6 @@
type bazelPythonLibraryAttributes struct {
Srcs bazel.LabelListAttribute
- Data bazel.LabelListAttribute
Deps bazel.LabelListAttribute
Srcs_version string
}
@@ -88,14 +87,10 @@
// do nothing, since python_version defaults to PY2ANDPY3
}
- srcs := android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
- data := android.BazelLabelForModuleSrc(ctx, m.properties.Data)
- deps := android.BazelLabelForModuleDeps(ctx, m.properties.Libs)
-
+ baseAttrs := m.makeArchVariantBaseAttributes(ctx)
attrs := &bazelPythonLibraryAttributes{
- Srcs: bazel.MakeLabelListAttribute(srcs),
- Data: bazel.MakeLabelListAttribute(data),
- Deps: bazel.MakeLabelListAttribute(deps),
+ Srcs: baseAttrs.Srcs,
+ Deps: baseAttrs.Deps,
Srcs_version: python_version,
}
@@ -104,7 +99,10 @@
Rule_class: "py_library",
}
- ctx.CreateBazelTargetModule(m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+ Name: m.Name(),
+ Data: baseAttrs.Data,
+ }, attrs)
}
func PythonLibraryFactory() android.Module {
diff --git a/python/python.go b/python/python.go
index f900172..401d91f 100644
--- a/python/python.go
+++ b/python/python.go
@@ -22,6 +22,7 @@
"regexp"
"strings"
+ "android/soong/bazel"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -120,6 +121,18 @@
Embedded_launcher *bool `blueprint:"mutated"`
}
+type baseAttributes struct {
+ // TODO(b/200311466): Probably not translate b/c Bazel has no good equiv
+ //Pkg_path bazel.StringAttribute
+ // TODO: Related to Pkg_bath and similarLy gated
+ //Is_internal bazel.BoolAttribute
+ // Combines Srcs and Exclude_srcs
+ Srcs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ // Combines Data and Java_data (invariant)
+ Data bazel.LabelListAttribute
+}
+
// Used to store files of current module after expanding dependencies
type pathMapping struct {
dest string
@@ -177,6 +190,25 @@
}
}
+func (m *Module) makeArchVariantBaseAttributes(ctx android.TopDownMutatorContext) baseAttributes {
+ var attrs baseAttributes
+ archVariantBaseProps := m.GetArchVariantProperties(ctx, &BaseProperties{})
+ for axis, configToProps := range archVariantBaseProps {
+ for config, props := range configToProps {
+ if baseProps, ok := props.(*BaseProperties); ok {
+ attrs.Srcs.SetSelectValue(axis, config,
+ android.BazelLabelForModuleSrcExcludes(ctx, baseProps.Srcs, baseProps.Exclude_srcs))
+ attrs.Deps.SetSelectValue(axis, config,
+ android.BazelLabelForModuleDeps(ctx, baseProps.Libs))
+ data := android.BazelLabelForModuleSrc(ctx, baseProps.Data)
+ data.Append(android.BazelLabelForModuleSrc(ctx, baseProps.Java_data))
+ attrs.Data.SetSelectValue(axis, config, data)
+ }
+ }
+ }
+ return attrs
+}
+
// bootstrapper interface should be implemented for runnable modules, e.g. binary and test
type bootstrapper interface {
bootstrapperProps() []interface{}
diff --git a/rust/builder.go b/rust/builder.go
index 426a569..f79cf9b 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -95,7 +95,7 @@
func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto")
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "bin")
}
@@ -112,13 +112,13 @@
func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto")
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "staticlib")
}
func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto")
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "cdylib")
}
diff --git a/rust/compiler.go b/rust/compiler.go
index 1ce71f6..cada985 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -449,6 +449,10 @@
// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs.
func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
+ if len(srcs) == 0 {
+ ctx.PropertyErrorf("srcs", "srcs must not be empty")
+ }
+
// The srcs can contain strings with prefix ":".
// They are dependent modules of this module, with android.SourceDepTag.
// They are not the main source file compiled by rustc.
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index f589b69..ec6829a 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -98,6 +98,41 @@
}`)
}
+// Test that we reject _no_ source files.
+func TestEnforceMissingSourceFiles(t *testing.T) {
+
+ singleSrcError := "srcs must not be empty"
+
+ // Test libraries
+ testRustError(t, singleSrcError, `
+ rust_library_host {
+ name: "foo-bar-library",
+ crate_name: "foo",
+ }`)
+
+ // Test binaries
+ testRustError(t, singleSrcError, `
+ rust_binary_host {
+ name: "foo-bar-binary",
+ crate_name: "foo",
+ }`)
+
+ // Test proc_macros
+ testRustError(t, singleSrcError, `
+ rust_proc_macro {
+ name: "foo-bar-proc-macro",
+ crate_name: "foo",
+ }`)
+
+ // Test prebuilts
+ testRustError(t, singleSrcError, `
+ rust_prebuilt_dylib {
+ name: "foo-bar-prebuilt",
+ crate_name: "foo",
+ host_supported: true,
+ }`)
+}
+
// Test environment vars for Cargo compat are set.
func TestCargoCompat(t *testing.T) {
ctx := testRust(t, `
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 47ca3a7..8182c32 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -18,6 +18,7 @@
"frameworks/native/libs/binder/rust",
"frameworks/proto_logging/stats",
"packages/modules/DnsResolver",
+ "packages/modules/Uwb",
"packages/modules/Virtualization",
"prebuilts/rust",
"system/bt",
@@ -32,6 +33,7 @@
"system/security",
"system/tools/aidl",
"tools/security/fuzzing/example_rust_fuzzer",
+ "tools/security/fuzzing/orphans",
"vendor/",
}
diff --git a/rust/fuzz.go b/rust/fuzz.go
index 5fb56ff..a628b61 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -111,6 +111,10 @@
// List of individual fuzz targets.
s.FuzzTargets = make(map[string]bool)
+ // Map tracking whether each shared library has an install rule to avoid duplicate install rules from
+ // multiple fuzzers that depend on the same shared library.
+ sharedLibraryInstalled := make(map[string]bool)
+
ctx.VisitAllModules(func(module android.Module) {
// Discard non-fuzz targets.
rustModule, ok := module.(*Module)
@@ -145,6 +149,12 @@
// The executable.
files = append(files, fuzz.FileToZip{rustModule.unstrippedOutputFile.Path(), ""})
+ // Grab the list of required shared libraries.
+ sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, cc.UnstrippedOutputFile, cc.IsValidSharedDependency)
+
+ // Package shared libraries
+ files = append(files, cc.GetSharedLibsToZip(sharedLibraries, rustModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...)
+
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok {
return
diff --git a/rust/project_json.go b/rust/project_json.go
index faa7db5..ae48312 100644
--- a/rust/project_json.go
+++ b/rust/project_json.go
@@ -51,6 +51,7 @@
Deps []rustProjectDep `json:"deps"`
Cfg []string `json:"cfg"`
Env map[string]string `json:"env"`
+ ProcMacro bool `json:"is_proc_macro"`
}
type rustProjectJson struct {
@@ -208,6 +209,8 @@
comp = c.baseCompiler
case *testDecorator:
comp = c.binaryDecorator.baseCompiler
+ case *procMacroDecorator:
+ comp = c.baseCompiler
default:
return nil, nil, false
}
@@ -224,6 +227,8 @@
return 0, false
}
+ _, procMacro := rModule.compiler.(*procMacroDecorator)
+
crate := rustProjectCrate{
DisplayName: rModule.Name(),
RootModule: rootModule,
@@ -231,6 +236,7 @@
Deps: make([]rustProjectDep, 0),
Cfg: make([]string, 0),
Env: make(map[string]string),
+ ProcMacro: procMacro,
}
if comp.CargoOutDir().Valid() {
diff --git a/rust/project_json_test.go b/rust/project_json_test.go
index f7b6681..255b2e5 100644
--- a/rust/project_json_test.go
+++ b/rust/project_json_test.go
@@ -117,6 +117,58 @@
validateJsonCrates(t, jsonContent)
}
+func TestProjectJsonProcMacroDep(t *testing.T) {
+ bp := `
+ rust_proc_macro {
+ name: "libproc_macro",
+ srcs: ["a/src/lib.rs"],
+ crate_name: "proc_macro"
+ }
+ rust_library {
+ name: "librust",
+ srcs: ["b/src/lib.rs"],
+ crate_name: "rust",
+ proc_macros: ["libproc_macro"],
+ }
+ `
+ jsonContent := testProjectJson(t, bp)
+ crates := validateJsonCrates(t, jsonContent)
+ libproc_macro_count := 0
+ librust_count := 0
+ for _, c := range crates {
+ crate := validateCrate(t, c)
+ procMacro, ok := crate["is_proc_macro"].(bool)
+ if !ok {
+ t.Fatalf("Unexpected type for is_proc_macro: %v", crate["is_proc_macro"])
+ }
+
+ name, ok := crate["display_name"].(string)
+ if !ok {
+ t.Fatalf("Unexpected type for display_name: %v", crate["display_name"])
+ }
+
+ switch name {
+ case "libproc_macro":
+ libproc_macro_count += 1
+ if !procMacro {
+ t.Fatalf("'libproc_macro' is marked with is_proc_macro=false")
+ }
+ case "librust":
+ librust_count += 1
+ if procMacro {
+ t.Fatalf("'librust' is not a proc macro crate, but is marked with is_proc_macro=true")
+ }
+ default:
+ break
+ }
+ }
+
+ if libproc_macro_count != 1 || librust_count != 1 {
+ t.Fatalf("Unexpected crate counts: libproc_macro_count: %v, librust_count: %v",
+ libproc_macro_count, librust_count)
+ }
+}
+
func TestProjectJsonFeature(t *testing.T) {
bp := `
rust_library {
diff --git a/rust/rust.go b/rust/rust.go
index 0a7d68d..13169f1 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -130,9 +130,10 @@
// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
Min_sdk_version *string
- PreventInstall bool
- HideFromMake bool
- Installable *bool
+ HideFromMake bool `blueprint:"mutated"`
+ PreventInstall bool `blueprint:"mutated"`
+
+ Installable *bool
}
type Module struct {
@@ -177,8 +178,8 @@
mod.Properties.HideFromMake = true
}
-func (c *Module) HiddenFromMake() bool {
- return c.Properties.HideFromMake
+func (mod *Module) HiddenFromMake() bool {
+ return mod.Properties.HideFromMake
}
func (mod *Module) SanitizePropDefined() bool {
@@ -526,10 +527,6 @@
return mod.Properties.PreventInstall
}
-func (mod *Module) HideFromMake() {
- mod.Properties.HideFromMake = true
-}
-
func (mod *Module) MarkAsCoverageVariant(coverage bool) {
mod.coverage.Properties.IsCoverageVariant = coverage
}
@@ -597,6 +594,13 @@
return false
}
+func (mod *Module) UnstrippedOutputFile() android.Path {
+ if mod.unstrippedOutputFile.Valid() {
+ return mod.unstrippedOutputFile.Path()
+ }
+ return nil
+}
+
func (mod *Module) IncludeDirs() android.Paths {
if mod.compiler != nil {
if library, ok := mod.compiler.(*libraryDecorator); ok {
@@ -663,7 +667,7 @@
}
func (mod *Module) installable(apexInfo android.ApexInfo) bool {
- if !mod.EverInstallable() {
+ if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) {
return false
}
@@ -898,8 +902,24 @@
}
apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
- if mod.installable(apexInfo) {
+ if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) {
+ // If the module has been specifically configure to not be installed then
+ // hide from make as otherwise it will break when running inside make as the
+ // output path to install will not be specified. Not all uninstallable
+ // modules can be hidden from make as some are needed for resolving make
+ // side dependencies.
+ mod.HideFromMake()
+ } else if !mod.installable(apexInfo) {
+ mod.SkipInstall()
+ }
+
+ // Still call install though, the installs will be stored as PackageSpecs to allow
+ // using the outputs in a genrule.
+ if mod.OutputFile().Valid() {
mod.compiler.install(ctx)
+ if ctx.Failed() {
+ return
+ }
}
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
diff --git a/scripts/build-aml-prebuilts.sh b/scripts/build-aml-prebuilts.sh
index 8a5513e..1a16f7c 100755
--- a/scripts/build-aml-prebuilts.sh
+++ b/scripts/build-aml-prebuilts.sh
@@ -23,10 +23,10 @@
export OUT_DIR=${OUT_DIR:-out}
if [ -e ${OUT_DIR}/soong/.soong.kati_enabled ]; then
- # If ${OUT_DIR} has been created without --skip-make, Soong will create an
+ # If ${OUT_DIR} has been created without --soong-only, Soong will create an
# ${OUT_DIR}/soong/build.ninja that leaves out many targets which are
# expected to be supplied by the .mk files, and that might cause errors in
- # "m --skip-make" below. We therefore default to a different out dir
+ # "m --soong-only" below. We therefore default to a different out dir
# location in that case.
AML_OUT_DIR=out/aml
echo "Avoiding in-make OUT_DIR '${OUT_DIR}' - building in '${AML_OUT_DIR}' instead"
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index b05861b..f183c05 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -17,6 +17,7 @@
MODULES_SDK_AND_EXPORTS=(
art-module-sdk
art-module-test-exports
+ compos-module-sdk
conscrypt-module-host-exports
conscrypt-module-sdk
conscrypt-module-test-exports
@@ -98,7 +99,7 @@
export FORCE_BUILD_LLVM_COMPONENTS=true
# Create multi-archs SDKs in a different out directory. The multi-arch script
-# uses Soong in --skip-make mode which cannot use the same directory as normal
+# uses Soong in --soong-only mode which cannot use the same directory as normal
# mode with make.
export OUT_DIR=${OUT_DIR}/aml
echo_and_run build/soong/scripts/build-aml-prebuilts.sh \
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index a1fa48d..4783037 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -64,7 +64,7 @@
"MissingUsesLibraries": ${MISSING_USES_LIBRARIES}
}
EOF
-m --skip-make ${SOONG_OUT}/ndk.timestamp
+m --soong-only --skip-config ${SOONG_OUT}/ndk.timestamp
if [ -n "${DIST_DIR}" ]; then
mkdir -p ${DIST_DIR} || true
diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt
index 9aae2a9..b1b1e7e 100644
--- a/scripts/check_boot_jars/package_allowed_list.txt
+++ b/scripts/check_boot_jars/package_allowed_list.txt
@@ -71,6 +71,7 @@
javax\.xml\.xpath
jdk\.internal\.math
jdk\.internal\.misc
+jdk\.internal\.reflect
jdk\.internal\.util
jdk\.internal\.vm\.annotation
jdk\.net
diff --git a/scripts/gen_ndk_backedby_apex.sh b/scripts/gen_ndk_backedby_apex.sh
index 4abaaba..212362e 100755
--- a/scripts/gen_ndk_backedby_apex.sh
+++ b/scripts/gen_ndk_backedby_apex.sh
@@ -21,52 +21,29 @@
# After the parse function below "dlopen" would be write to the output file.
printHelp() {
echo "**************************** Usage Instructions ****************************"
- echo "This script is used to generate the Mainline modules backed-by NDK symbols."
+ echo "This script is used to generate the native libraries backed by Mainline modules."
echo ""
- echo "To run this script use: ./gen_ndk_backed_by_apex.sh \$OUTPUT_FILE_PATH \$NDK_LIB_NAME_LIST \$MODULE_LIB1 \$MODULE_LIB2..."
+ echo "To run this script use: ./gen_ndk_backed_by_apex.sh \$OUTPUT_FILE_PATH \$MODULE_LIB1 \$MODULE_LIB2..."
echo "For example: If output write to /backedby.txt then the command would be:"
- echo "./gen_ndk_backed_by_apex.sh /backedby.txt /ndkLibList.txt lib1.so lib2.so"
+ echo "./gen_ndk_backed_by_apex.sh /backedby.txt lib1.so lib2.so"
echo "If the module1 is backing lib1 then the backedby.txt would contains: "
- echo "lib1"
+ echo "lib1.so lib2.so"
}
-contains() {
- val="$1"
- shift
- for x in "$@"; do
- if [ "$x" = "$val" ]; then
- return 0
- fi
- done
- return 1
-}
-
-
-genBackedByList() {
+genAllBackedByList() {
out="$1"
shift
- ndk_list="$1"
- shift
rm -f "$out"
touch "$out"
- while IFS= read -r line
- do
- soFileName=$(echo "$line" | sed 's/\(.*so\).*/\1/')
- if [[ ! -z "$soFileName" && "$soFileName" != *"#"* ]]
- then
- if contains "$soFileName" "$@"; then
- echo "$soFileName" >> "$out"
- fi
- fi
- done < "$ndk_list"
+ echo "$@" >> "$out"
}
if [[ "$1" == "help" ]]
then
printHelp
-elif [[ "$#" -lt 2 ]]
+elif [[ "$#" -lt 1 ]]
then
- echo "Wrong argument length. Expecting at least 2 argument representing output path, path to ndk library list, followed by a list of libraries in the Mainline module."
+ echo "Wrong argument length. Expecting at least 1 argument representing output path, followed by a list of libraries in the Mainline module."
else
- genBackedByList "$@"
+ genAllBackedByList "$@"
fi
diff --git a/scripts/get_clang_version.py b/scripts/get_clang_version.py
index 64d922a..691c45d 100755
--- a/scripts/get_clang_version.py
+++ b/scripts/get_clang_version.py
@@ -34,7 +34,7 @@
with open(global_go) as infile:
contents = infile.read()
- regex_rev = r'\tClangDefaultVersion\s+= "(?P<rev>clang-r\d+[a-z]?\d?)"'
+ regex_rev = r'\tClangDefaultVersion\s+= "(?P<rev>clang-.*)"'
match_rev = re.search(regex_rev, contents)
if match_rev is None:
raise RuntimeError('Parsing clang info failed')
diff --git a/scripts/hiddenapi/signature_patterns.py b/scripts/hiddenapi/signature_patterns.py
index 0acb2a0..e75ee95 100755
--- a/scripts/hiddenapi/signature_patterns.py
+++ b/scripts/hiddenapi/signature_patterns.py
@@ -13,8 +13,10 @@
# 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.
-"""Generate a set of signature patterns from the modular flags generated by a
-bootclasspath_fragment that can be used to select a subset of monolithic flags
+"""Generate a set of signature patterns for a bootclasspath_fragment.
+
+The patterns are generated from the modular flags produced by the
+bootclasspath_fragment and are used to select a subset of the monolithic flags
against which the modular flags can be compared.
"""
@@ -22,33 +24,122 @@
import csv
import sys
+
def dict_reader(csvfile):
return csv.DictReader(
- csvfile, delimiter=',', quotechar='|', fieldnames=['signature']
- )
+ csvfile, delimiter=',', quotechar='|', fieldnames=['signature'])
-def produce_patterns_from_file(file):
+def dotPackageToSlashPackage(pkg):
+ return pkg.replace('.', '/')
+
+
+def slashPackageToDotPackage(pkg):
+ return pkg.replace('/', '.')
+
+
+def isSplitPackage(splitPackages, pkg):
+ return splitPackages and (pkg in splitPackages or '*' in splitPackages)
+
+
+def matchedByPackagePrefixPattern(packagePrefixes, prefix):
+ for packagePrefix in packagePrefixes:
+ if prefix == packagePrefix:
+ return packagePrefix
+ elif prefix.startswith(packagePrefix) and prefix[len(
+ packagePrefix)] == '/':
+ return packagePrefix
+ return False
+
+
+def validate_package_prefixes(splitPackages, packagePrefixes):
+ # If there are no package prefixes then there is no possible conflict
+ # between them and the split packages.
+ if len(packagePrefixes) == 0:
+ return
+
+ # Check to make sure that the split packages and package prefixes do not
+ # overlap.
+ errors = []
+ for splitPackage in splitPackages:
+ if splitPackage == '*':
+ # A package prefix matches a split package.
+ packagePrefixesForOutput = ', '.join(
+ map(slashPackageToDotPackage, packagePrefixes))
+ errors.append(
+ 'split package "*" conflicts with all package prefixes %s\n'
+ ' add split_packages:[] to fix' % packagePrefixesForOutput)
+ else:
+ packagePrefix = matchedByPackagePrefixPattern(
+ packagePrefixes, splitPackage)
+ if packagePrefix:
+ # A package prefix matches a split package.
+ splitPackageForOutput = slashPackageToDotPackage(splitPackage)
+ packagePrefixForOutput = slashPackageToDotPackage(packagePrefix)
+ errors.append(
+ 'split package %s is matched by package prefix %s' %
+ (splitPackageForOutput, packagePrefixForOutput))
+ return errors
+
+
+def validate_split_packages(splitPackages):
+ errors = []
+ if '*' in splitPackages and len(splitPackages) > 1:
+ errors.append('split packages are invalid as they contain both the'
+ ' wildcard (*) and specific packages, use the wildcard or'
+ ' specific packages, not a mixture')
+ return errors
+
+
+def produce_patterns_from_file(file, splitPackages=None, packagePrefixes=None):
with open(file, 'r') as f:
- return produce_patterns_from_stream(f)
+ return produce_patterns_from_stream(f, splitPackages, packagePrefixes)
-def produce_patterns_from_stream(stream):
- # Read in all the signatures into a list and remove member names.
+def produce_patterns_from_stream(stream,
+ splitPackages=None,
+ packagePrefixes=None):
+ splitPackages = set(splitPackages or [])
+ packagePrefixes = list(packagePrefixes or [])
+ # Read in all the signatures into a list and remove any unnecessary class
+ # and member names.
patterns = set()
for row in dict_reader(stream):
signature = row['signature']
- text = signature.removeprefix("L")
+ text = signature.removeprefix('L')
# Remove the class specific member signature
- pieces = text.split(";->")
+ pieces = text.split(';->')
qualifiedClassName = pieces[0]
- # Remove inner class names as they cannot be separated
- # from the containing outer class.
- pieces = qualifiedClassName.split("$", maxsplit=1)
- pattern = pieces[0]
+ pieces = qualifiedClassName.rsplit('/', maxsplit=1)
+ pkg = pieces[0]
+ # If the package is split across multiple modules then it cannot be used
+ # to select the subset of the monolithic flags that this module
+ # produces. In that case we need to keep the name of the class but can
+ # discard any nested class names as an outer class cannot be split
+ # across modules.
+ #
+ # If the package is not split then every class in the package must be
+ # provided by this module so there is no need to list the classes
+ # explicitly so just use the package name instead.
+ if isSplitPackage(splitPackages, pkg):
+ # Remove inner class names.
+ pieces = qualifiedClassName.split('$', maxsplit=1)
+ pattern = pieces[0]
+ else:
+ # Add a * to ensure that the pattern matches the classes in that
+ # package.
+ pattern = pkg + '/*'
patterns.add(pattern)
- patterns = list(patterns) #pylint: disable=redefined-variable-type
+ # Remove any patterns that would be matched by a package prefix pattern.
+ patterns = list(
+ filter(lambda p: not matchedByPackagePrefixPattern(packagePrefixes, p),
+ patterns))
+ # Add the package prefix patterns to the list. Add a ** to ensure that each
+ # package prefix pattern will match the classes in that package and all
+ # sub-packages.
+ patterns = patterns + list(map(lambda x: x + '/**', packagePrefixes))
+ # Sort the patterns.
patterns.sort()
return patterns
@@ -56,24 +147,47 @@
def main(args):
args_parser = argparse.ArgumentParser(
description='Generate a set of signature patterns '
- 'that select a subset of monolithic hidden API files.'
- )
+ 'that select a subset of monolithic hidden API files.')
args_parser.add_argument(
'--flags',
help='The stub flags file which contains an entry for every dex member',
)
+ args_parser.add_argument(
+ '--split-package',
+ action='append',
+ help='A package that is split across multiple bootclasspath_fragment modules'
+ )
+ args_parser.add_argument(
+ '--package-prefix',
+ action='append',
+ help='A package prefix unique to this set of flags')
args_parser.add_argument('--output', help='Generated signature prefixes')
args = args_parser.parse_args(args)
+ splitPackages = set(map(dotPackageToSlashPackage, args.split_package or []))
+ errors = validate_split_packages(splitPackages)
+
+ packagePrefixes = list(
+ map(dotPackageToSlashPackage, args.package_prefix or []))
+
+ if not errors:
+ errors = validate_package_prefixes(splitPackages, packagePrefixes)
+
+ if errors:
+ for error in errors:
+ print(error)
+ sys.exit(1)
+
# Read in all the patterns into a list.
- patterns = produce_patterns_from_file(args.flags)
+ patterns = produce_patterns_from_file(args.flags, splitPackages,
+ packagePrefixes)
# Write out all the patterns.
with open(args.output, 'w') as outputFile:
for pattern in patterns:
outputFile.write(pattern)
- outputFile.write("\n")
+ outputFile.write('\n')
-if __name__ == "__main__":
+if __name__ == '__main__':
main(sys.argv[1:])
diff --git a/scripts/hiddenapi/signature_patterns_test.py b/scripts/hiddenapi/signature_patterns_test.py
index 3babe54..b59dfd7 100755
--- a/scripts/hiddenapi/signature_patterns_test.py
+++ b/scripts/hiddenapi/signature_patterns_test.py
@@ -13,37 +13,99 @@
# 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.
-
"""Unit tests for signature_patterns.py."""
import io
import unittest
-from signature_patterns import * #pylint: disable=unused-wildcard-import,wildcard-import
+from signature_patterns import * #pylint: disable=unused-wildcard-import,wildcard-import
class TestGeneratedPatterns(unittest.TestCase):
- def produce_patterns_from_string(self, csvdata):
- with io.StringIO(csvdata) as f:
- return produce_patterns_from_stream(f)
- def test_generate(self):
- #pylint: disable=line-too-long
- patterns = self.produce_patterns_from_string(
- '''
+ csvFlags = """
Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V,blocked
Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;,public-api
Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
-'''
- )
- #pylint: enable=line-too-long
+"""
+
+ def produce_patterns_from_string(self,
+ csv,
+ splitPackages=None,
+ packagePrefixes=None):
+ with io.StringIO(csv) as f:
+ return produce_patterns_from_stream(f, splitPackages,
+ packagePrefixes)
+
+ def test_generate_default(self):
+ patterns = self.produce_patterns_from_string(
+ TestGeneratedPatterns.csvFlags)
expected = [
- "java/lang/Character",
- "java/lang/Object",
- "java/lang/ProcessBuilder",
+ 'java/lang/*',
]
self.assertEqual(expected, patterns)
+ def test_generate_split_package(self):
+ patterns = self.produce_patterns_from_string(
+ TestGeneratedPatterns.csvFlags, splitPackages={'java/lang'})
+ expected = [
+ 'java/lang/Character',
+ 'java/lang/Object',
+ 'java/lang/ProcessBuilder',
+ ]
+ self.assertEqual(expected, patterns)
+
+ def test_generate_split_package_wildcard(self):
+ patterns = self.produce_patterns_from_string(
+ TestGeneratedPatterns.csvFlags, splitPackages={'*'})
+ expected = [
+ 'java/lang/Character',
+ 'java/lang/Object',
+ 'java/lang/ProcessBuilder',
+ ]
+ self.assertEqual(expected, patterns)
+
+ def test_generate_package_prefix(self):
+ patterns = self.produce_patterns_from_string(
+ TestGeneratedPatterns.csvFlags, packagePrefixes={'java/lang'})
+ expected = [
+ 'java/lang/**',
+ ]
+ self.assertEqual(expected, patterns)
+
+ def test_generate_package_prefix_top_package(self):
+ patterns = self.produce_patterns_from_string(
+ TestGeneratedPatterns.csvFlags, packagePrefixes={'java'})
+ expected = [
+ 'java/**',
+ ]
+ self.assertEqual(expected, patterns)
+
+ def test_split_package_wildcard_conflicts_with_other_split_packages(self):
+ errors = validate_split_packages({'*', 'java'})
+ expected = [
+ 'split packages are invalid as they contain both the wildcard (*)'
+ ' and specific packages, use the wildcard or specific packages,'
+ ' not a mixture'
+ ]
+ self.assertEqual(expected, errors)
+
+ def test_split_package_wildcard_conflicts_with_package_prefixes(self):
+ errors = validate_package_prefixes({'*'}, packagePrefixes={'java'})
+ expected = [
+ 'split package "*" conflicts with all package prefixes java\n'
+ ' add split_packages:[] to fix',
+ ]
+ self.assertEqual(expected, errors)
+
+ def test_split_package_conflict(self):
+ errors = validate_package_prefixes({'java/split'},
+ packagePrefixes={'java'})
+ expected = [
+ 'split package java.split is matched by package prefix java',
+ ]
+ self.assertEqual(expected, errors)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/scripts/package-check.sh b/scripts/package-check.sh
index d7e602f..9f4a9da 100755
--- a/scripts/package-check.sh
+++ b/scripts/package-check.sh
@@ -42,7 +42,7 @@
fi
# Transform to a slash-separated path and add a trailing slash to enforce
# package name boundary.
- prefixes+=("${package//\./\/}/")
+ prefixes+=("${package//\.//}/")
shift
done
diff --git a/scripts/rbc-run b/scripts/rbc-run
index e2fa6d1..a0907cf 100755
--- a/scripts/rbc-run
+++ b/scripts/rbc-run
@@ -1,16 +1,15 @@
#! /bin/bash
# Convert and run one configuration
-# Args: <product>-<variant>
-[[ $# -eq 1 && "$1" =~ ^(.*)-(.*)$ ]] || { echo Usage: ${0##*/} PRODUCT-VARIANT >&2; exit 1; }
-declare -r product="${BASH_REMATCH[1]:-aosp_arm}"
-declare -r variant="${BASH_REMATCH[2]:-eng}"
+# Args: a product/board makefile optionally followed by additional arguments
+# that will be passed to rbcrun.
+[[ $# -gt 0 && -f "$1" ]] || { echo "Usage: ${0##*/} product.mk [Additional rbcrun arguments]" >&2; exit 1; }
set -eu
declare -r output_root=${OUT_DIR:-out}
declare -r runner="$output_root/soong/.bootstrap/bin/rbcrun"
declare -r converter="$output_root/soong/.bootstrap/bin/mk2rbc"
declare -r launcher=$output_root/launchers/run.rbc
-$converter -mode=write -r --outdir $output_root --launcher=$launcher $product
-printf "#TARGET_PRODUCT=$product TARGET_BUILD_VARIANT=$variant\n"
-env TARGET_PRODUCT=$product TARGET_BUILD_VARIANT=$variant \
- $runner RBC_OUT="make,global" RBC_DEBUG="${RBC_DEBUG:-}" $launcher
+declare -r makefile=$1
+shift
+$converter -mode=write -r --outdir $output_root --launcher=$launcher $makefile
+$runner RBC_OUT="make,global" RBC_DEBUG="${RBC_DEBUG:-}" $@ $launcher
diff --git a/sdk/Android.bp b/sdk/Android.bp
index c6544d6..f42b478 100644
--- a/sdk/Android.bp
+++ b/sdk/Android.bp
@@ -11,10 +11,12 @@
"soong-android",
"soong-apex",
"soong-cc",
+ "soong-dexpreopt",
"soong-java",
],
srcs: [
"bp.go",
+ "build_release.go",
"exports.go",
"member_trait.go",
"member_type.go",
@@ -24,6 +26,7 @@
testSrcs: [
"bootclasspath_fragment_sdk_test.go",
"bp_test.go",
+ "build_release_test.go",
"cc_sdk_test.go",
"compat_config_sdk_test.go",
"exports_test.go",
@@ -31,6 +34,7 @@
"license_sdk_test.go",
"member_trait_test.go",
"sdk_test.go",
+ "systemserverclasspath_fragment_sdk_test.go",
"testing.go",
],
pluginFor: ["soong_build"],
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index e1ae474..ff2af43 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -138,8 +138,8 @@
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
signature_patterns: "hiddenapi/signature-patterns.csv",
- stub_flags: "hiddenapi/filtered-stub-flags.csv",
- all_flags: "hiddenapi/filtered-flags.csv",
+ filtered_stub_flags: "hiddenapi/filtered-stub-flags.csv",
+ filtered_flags: "hiddenapi/filtered-flags.csv",
},
}
@@ -166,8 +166,8 @@
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
signature_patterns: "hiddenapi/signature-patterns.csv",
- stub_flags: "hiddenapi/filtered-stub-flags.csv",
- all_flags: "hiddenapi/filtered-flags.csv",
+ filtered_stub_flags: "hiddenapi/filtered-stub-flags.csv",
+ filtered_flags: "hiddenapi/filtered-flags.csv",
},
}
@@ -339,8 +339,8 @@
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
signature_patterns: "hiddenapi/signature-patterns.csv",
- stub_flags: "hiddenapi/filtered-stub-flags.csv",
- all_flags: "hiddenapi/filtered-flags.csv",
+ filtered_stub_flags: "hiddenapi/filtered-stub-flags.csv",
+ filtered_flags: "hiddenapi/filtered-flags.csv",
},
}
@@ -424,8 +424,8 @@
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
signature_patterns: "hiddenapi/signature-patterns.csv",
- stub_flags: "hiddenapi/filtered-stub-flags.csv",
- all_flags: "hiddenapi/filtered-flags.csv",
+ filtered_stub_flags: "hiddenapi/filtered-stub-flags.csv",
+ filtered_flags: "hiddenapi/filtered-flags.csv",
},
}
@@ -649,8 +649,8 @@
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
signature_patterns: "hiddenapi/signature-patterns.csv",
- stub_flags: "hiddenapi/filtered-stub-flags.csv",
- all_flags: "hiddenapi/filtered-flags.csv",
+ filtered_stub_flags: "hiddenapi/filtered-stub-flags.csv",
+ filtered_flags: "hiddenapi/filtered-flags.csv",
},
}
@@ -852,8 +852,8 @@
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
signature_patterns: "hiddenapi/signature-patterns.csv",
- stub_flags: "hiddenapi/filtered-stub-flags.csv",
- all_flags: "hiddenapi/filtered-flags.csv",
+ filtered_stub_flags: "hiddenapi/filtered-stub-flags.csv",
+ filtered_flags: "hiddenapi/filtered-flags.csv",
},
}
diff --git a/sdk/build_release.go b/sdk/build_release.go
new file mode 100644
index 0000000..a3f0899
--- /dev/null
+++ b/sdk/build_release.go
@@ -0,0 +1,324 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sdk
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+// Supports customizing sdk snapshot output based on target build release.
+
+// buildRelease represents the version of a build system used to create a specific release.
+//
+// The name of the release, is the same as the code for the dessert release, e.g. S, T, etc.
+type buildRelease struct {
+ // The name of the release, e.g. S, T, etc.
+ name string
+
+ // The index of this structure within the buildReleases list.
+ ordinal int
+}
+
+// String returns the name of the build release.
+func (s *buildRelease) String() string {
+ return s.name
+}
+
+// buildReleaseSet represents a set of buildRelease objects.
+type buildReleaseSet struct {
+ // Set of *buildRelease represented as a map from *buildRelease to struct{}.
+ contents map[*buildRelease]struct{}
+}
+
+// addItem adds a build release to the set.
+func (s *buildReleaseSet) addItem(release *buildRelease) {
+ s.contents[release] = struct{}{}
+}
+
+// addRange adds all the build releases from start (inclusive) to end (inclusive).
+func (s *buildReleaseSet) addRange(start *buildRelease, end *buildRelease) {
+ for i := start.ordinal; i <= end.ordinal; i += 1 {
+ s.addItem(buildReleases[i])
+ }
+}
+
+// contains returns true if the set contains the specified build release.
+func (s *buildReleaseSet) contains(release *buildRelease) bool {
+ _, ok := s.contents[release]
+ return ok
+}
+
+// String returns a string representation of the set, sorted from earliest to latest release.
+func (s *buildReleaseSet) String() string {
+ list := []string{}
+ for _, release := range buildReleases {
+ if _, ok := s.contents[release]; ok {
+ list = append(list, release.name)
+ }
+ }
+ return fmt.Sprintf("[%s]", strings.Join(list, ","))
+}
+
+var (
+ // nameToBuildRelease contains a map from name to build release.
+ nameToBuildRelease = map[string]*buildRelease{}
+
+ // buildReleases lists all the available build releases.
+ buildReleases = []*buildRelease{}
+
+ // allBuildReleaseSet is the set of all build releases.
+ allBuildReleaseSet = &buildReleaseSet{contents: map[*buildRelease]struct{}{}}
+
+ // Add the build releases from oldest to newest.
+ buildReleaseS = initBuildRelease("S")
+ buildReleaseT = initBuildRelease("T")
+)
+
+// initBuildRelease creates a new build release with the specified name.
+func initBuildRelease(name string) *buildRelease {
+ ordinal := len(nameToBuildRelease)
+ release := &buildRelease{name: name, ordinal: ordinal}
+ nameToBuildRelease[name] = release
+ buildReleases = append(buildReleases, release)
+ allBuildReleaseSet.addItem(release)
+ return release
+}
+
+// latestBuildRelease returns the latest build release, i.e. the last one added.
+func latestBuildRelease() *buildRelease {
+ return buildReleases[len(buildReleases)-1]
+}
+
+// nameToRelease maps from build release name to the corresponding build release (if it exists) or
+// the error if it does not.
+func nameToRelease(name string) (*buildRelease, error) {
+ if r, ok := nameToBuildRelease[name]; ok {
+ return r, nil
+ }
+
+ return nil, fmt.Errorf("unknown release %q, expected one of %s", name, allBuildReleaseSet)
+}
+
+// parseBuildReleaseSet parses a build release set string specification into a build release set.
+//
+// The specification consists of one of the following:
+// * a single build release name, e.g. S, T, etc.
+// * a closed range (inclusive to inclusive), e.g. S-T
+// * an open range, e.g. T+.
+//
+// This returns the set if the specification was valid or an error.
+func parseBuildReleaseSet(specification string) (*buildReleaseSet, error) {
+ set := &buildReleaseSet{contents: map[*buildRelease]struct{}{}}
+
+ if strings.HasSuffix(specification, "+") {
+ rangeStart := strings.TrimSuffix(specification, "+")
+ start, err := nameToRelease(rangeStart)
+ if err != nil {
+ return nil, err
+ }
+ end := latestBuildRelease()
+ set.addRange(start, end)
+ } else if strings.Contains(specification, "-") {
+ limits := strings.SplitN(specification, "-", 2)
+ start, err := nameToRelease(limits[0])
+ if err != nil {
+ return nil, err
+ }
+
+ end, err := nameToRelease(limits[1])
+ if err != nil {
+ return nil, err
+ }
+
+ if start.ordinal > end.ordinal {
+ return nil, fmt.Errorf("invalid closed range, start release %q is later than end release %q", start.name, end.name)
+ }
+
+ set.addRange(start, end)
+ } else {
+ release, err := nameToRelease(specification)
+ if err != nil {
+ return nil, err
+ }
+ set.addItem(release)
+ }
+
+ return set, nil
+}
+
+// Given a set of properties (struct value), set the value of a field within that struct (or one of
+// its embedded structs) to its zero value.
+type fieldPrunerFunc func(structValue reflect.Value)
+
+// A property that can be cleared by a propertyPruner.
+type prunerProperty struct {
+ // The name of the field for this property. It is a "."-separated path for fields in non-anonymous
+ // sub-structs.
+ name string
+
+ // Sets the associated field to its zero value.
+ prunerFunc fieldPrunerFunc
+}
+
+// propertyPruner provides support for pruning (i.e. setting to their zero value) properties from
+// a properties structure.
+type propertyPruner struct {
+ // The properties that the pruner will clear.
+ properties []prunerProperty
+}
+
+// gatherFields recursively processes the supplied structure and a nested structures, selecting the
+// fields that require pruning and populates the propertyPruner.properties with the information
+// needed to prune those fields.
+//
+// containingStructAccessor is a func that if given an object will return a field whose value is
+// of the supplied structType. It is nil on initial entry to this method but when this method is
+// called recursively on a field that is a nested structure containingStructAccessor is set to a
+// func that provides access to the field's value.
+//
+// namePrefix is the prefix to the fields that are being visited. It is "" on initial entry to this
+// method but when this method is called recursively on a field that is a nested structure
+// namePrefix is the result of appending the field name (plus a ".") to the previous name prefix.
+// Unless the field is anonymous in which case it is passed through unchanged.
+//
+// selector is a func that will select whether the supplied field requires pruning or not. If it
+// returns true then the field will be added to those to be pruned, otherwise it will not.
+func (p *propertyPruner) gatherFields(structType reflect.Type, containingStructAccessor fieldAccessorFunc, namePrefix string, selector fieldSelectorFunc) {
+ for f := 0; f < structType.NumField(); f++ {
+ field := structType.Field(f)
+ if field.PkgPath != "" {
+ // Ignore unexported fields.
+ continue
+ }
+
+ // Save a copy of the field index for use in the function.
+ fieldIndex := f
+
+ name := namePrefix + field.Name
+
+ fieldGetter := func(container reflect.Value) reflect.Value {
+ if containingStructAccessor != nil {
+ // This is an embedded structure so first access the field for the embedded
+ // structure.
+ container = containingStructAccessor(container)
+ }
+
+ // Skip through interface and pointer values to find the structure.
+ container = getStructValue(container)
+
+ defer func() {
+ if r := recover(); r != nil {
+ panic(fmt.Errorf("%s for fieldIndex %d of field %s of container %#v", r, fieldIndex, name, container.Interface()))
+ }
+ }()
+
+ // Return the field.
+ return container.Field(fieldIndex)
+ }
+
+ zeroValue := reflect.Zero(field.Type)
+ fieldPruner := func(container reflect.Value) {
+ if containingStructAccessor != nil {
+ // This is an embedded structure so first access the field for the embedded
+ // structure.
+ container = containingStructAccessor(container)
+ }
+
+ // Skip through interface and pointer values to find the structure.
+ container = getStructValue(container)
+
+ defer func() {
+ if r := recover(); r != nil {
+ panic(fmt.Errorf("%s for fieldIndex %d of field %s of container %#v", r, fieldIndex, name, container.Interface()))
+ }
+ }()
+
+ // Set the field.
+ container.Field(fieldIndex).Set(zeroValue)
+ }
+
+ if selector(name, field) {
+ property := prunerProperty{
+ name,
+ fieldPruner,
+ }
+ p.properties = append(p.properties, property)
+ } else if field.Type.Kind() == reflect.Struct {
+ // Gather fields from the nested or embedded structure.
+ var subNamePrefix string
+ if field.Anonymous {
+ subNamePrefix = namePrefix
+ } else {
+ subNamePrefix = name + "."
+ }
+ p.gatherFields(field.Type, fieldGetter, subNamePrefix, selector)
+ }
+ }
+}
+
+// pruneProperties will prune (set to zero value) any properties in the supplied struct.
+//
+// The struct must be of the same type as was originally passed to newPropertyPruner to create this
+// propertyPruner.
+func (p *propertyPruner) pruneProperties(propertiesStruct interface{}) {
+ structValue := reflect.ValueOf(propertiesStruct)
+ for _, property := range p.properties {
+ property.prunerFunc(structValue)
+ }
+}
+
+// fieldSelectorFunc is called to select whether a specific field should be pruned or not.
+// name is the name of the field, including any prefixes from containing str
+type fieldSelectorFunc func(name string, field reflect.StructField) bool
+
+// newPropertyPruner creates a new property pruner for the structure type for the supplied
+// properties struct.
+//
+// The returned pruner can be used on any properties structure of the same type as the supplied set
+// of properties.
+func newPropertyPruner(propertiesStruct interface{}, selector fieldSelectorFunc) *propertyPruner {
+ structType := getStructValue(reflect.ValueOf(propertiesStruct)).Type()
+ pruner := &propertyPruner{}
+ pruner.gatherFields(structType, nil, "", selector)
+ return pruner
+}
+
+// newPropertyPrunerByBuildRelease creates a property pruner that will clear any properties in the
+// structure which are not supported by the specified target build release.
+//
+// A property is pruned if its field has a tag of the form:
+// `supported_build_releases:"<build-release-set>"`
+// and the resulting build release set does not contain the target build release. Properties that
+// have no such tag are assumed to be supported by all releases.
+func newPropertyPrunerByBuildRelease(propertiesStruct interface{}, targetBuildRelease *buildRelease) *propertyPruner {
+ return newPropertyPruner(propertiesStruct, func(name string, field reflect.StructField) bool {
+ if supportedBuildReleases, ok := field.Tag.Lookup("supported_build_releases"); ok {
+ set, err := parseBuildReleaseSet(supportedBuildReleases)
+ if err != nil {
+ panic(fmt.Errorf("invalid `supported_build_releases` tag on %s of %T: %s", name, propertiesStruct, err))
+ }
+
+ // If the field does not support tha target release then prune it.
+ return !set.contains(targetBuildRelease)
+
+ } else {
+ // Any untagged fields are assumed to be supported by all build releases so should never be
+ // pruned.
+ return false
+ }
+ })
+}
diff --git a/sdk/build_release_test.go b/sdk/build_release_test.go
new file mode 100644
index 0000000..dff276d
--- /dev/null
+++ b/sdk/build_release_test.go
@@ -0,0 +1,185 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sdk
+
+import (
+ "fmt"
+ "testing"
+
+ "android/soong/android"
+)
+
+// Tests for build_release.go
+
+var (
+ // Some additional test specific releases that are added after the currently supported ones and
+ // so are treated as being for future releases.
+ buildReleaseFuture1 = initBuildRelease("F1")
+ buildReleaseFuture2 = initBuildRelease("F2")
+)
+
+func TestNameToRelease(t *testing.T) {
+ t.Run("single release", func(t *testing.T) {
+ release, err := nameToRelease("S")
+ android.AssertDeepEquals(t, "errors", nil, err)
+ android.AssertDeepEquals(t, "release", buildReleaseS, release)
+ })
+ t.Run("invalid release", func(t *testing.T) {
+ release, err := nameToRelease("A")
+ android.AssertDeepEquals(t, "release", (*buildRelease)(nil), release)
+ // Uses a wildcard in the error message to allow for additional build releases to be added to
+ // the supported set without breaking this test.
+ android.FailIfNoMatchingErrors(t, `unknown release "A", expected one of \[S,T.*,F1,F2\]`, []error{err})
+ })
+}
+
+func TestParseBuildReleaseSet(t *testing.T) {
+ t.Run("single release", func(t *testing.T) {
+ set, err := parseBuildReleaseSet("S")
+ android.AssertDeepEquals(t, "errors", nil, err)
+ android.AssertStringEquals(t, "set", "[S]", set.String())
+ })
+ t.Run("open range", func(t *testing.T) {
+ set, err := parseBuildReleaseSet("F1+")
+ android.AssertDeepEquals(t, "errors", nil, err)
+ android.AssertStringEquals(t, "set", "[F1,F2]", set.String())
+ })
+ t.Run("closed range", func(t *testing.T) {
+ set, err := parseBuildReleaseSet("S-F1")
+ android.AssertDeepEquals(t, "errors", nil, err)
+ android.AssertStringEquals(t, "set", "[S,T,F1]", set.String())
+ })
+ invalidAReleaseMessage := `unknown release "A", expected one of ` + allBuildReleaseSet.String()
+ t.Run("invalid release", func(t *testing.T) {
+ set, err := parseBuildReleaseSet("A")
+ android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
+ android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage)
+ })
+ t.Run("invalid release in open range", func(t *testing.T) {
+ set, err := parseBuildReleaseSet("A+")
+ android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
+ android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage)
+ })
+ t.Run("invalid release in closed range start", func(t *testing.T) {
+ set, err := parseBuildReleaseSet("A-S")
+ android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
+ android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage)
+ })
+ t.Run("invalid release in closed range end", func(t *testing.T) {
+ set, err := parseBuildReleaseSet("T-A")
+ android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
+ android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), invalidAReleaseMessage)
+ })
+ t.Run("invalid closed range reversed", func(t *testing.T) {
+ set, err := parseBuildReleaseSet("F1-S")
+ android.AssertDeepEquals(t, "set", (*buildReleaseSet)(nil), set)
+ android.AssertStringDoesContain(t, "errors", fmt.Sprint(err), `invalid closed range, start release "F1" is later than end release "S"`)
+ })
+}
+
+func TestBuildReleaseSetContains(t *testing.T) {
+ t.Run("contains", func(t *testing.T) {
+ set, _ := parseBuildReleaseSet("F1-F2")
+ android.AssertBoolEquals(t, "set contains F1", true, set.contains(buildReleaseFuture1))
+ android.AssertBoolEquals(t, "set does not contain S", false, set.contains(buildReleaseS))
+ android.AssertBoolEquals(t, "set contains F2", true, set.contains(buildReleaseFuture2))
+ android.AssertBoolEquals(t, "set does not contain T", false, set.contains(buildReleaseT))
+ })
+}
+
+func TestPropertyPrunerInvalidTag(t *testing.T) {
+ type brokenStruct struct {
+ Broken string `supported_build_releases:"A"`
+ }
+ type containingStruct struct {
+ Nested brokenStruct
+ }
+
+ t.Run("broken struct", func(t *testing.T) {
+ android.AssertPanicMessageContains(t, "error", "invalid `supported_build_releases` tag on Broken of *sdk.brokenStruct: unknown release \"A\"", func() {
+ newPropertyPrunerByBuildRelease(&brokenStruct{}, buildReleaseS)
+ })
+ })
+
+ t.Run("nested broken struct", func(t *testing.T) {
+ android.AssertPanicMessageContains(t, "error", "invalid `supported_build_releases` tag on Nested.Broken of *sdk.containingStruct: unknown release \"A\"", func() {
+ newPropertyPrunerByBuildRelease(&containingStruct{}, buildReleaseS)
+ })
+ })
+}
+
+func TestPropertyPrunerByBuildRelease(t *testing.T) {
+ type nested struct {
+ F1_only string `supported_build_releases:"F1"`
+ }
+
+ type testBuildReleasePruner struct {
+ Default string
+ S_and_T_only string `supported_build_releases:"S-T"`
+ T_later string `supported_build_releases:"T+"`
+ Nested nested
+ }
+
+ input := testBuildReleasePruner{
+ Default: "Default",
+ S_and_T_only: "S_and_T_only",
+ T_later: "T_later",
+ Nested: nested{
+ F1_only: "F1_only",
+ },
+ }
+
+ t.Run("target S", func(t *testing.T) {
+ testStruct := input
+ pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseS)
+ pruner.pruneProperties(&testStruct)
+
+ expected := input
+ expected.T_later = ""
+ expected.Nested.F1_only = ""
+ android.AssertDeepEquals(t, "test struct", expected, testStruct)
+ })
+
+ t.Run("target T", func(t *testing.T) {
+ testStruct := input
+ pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseT)
+ pruner.pruneProperties(&testStruct)
+
+ expected := input
+ expected.Nested.F1_only = ""
+ android.AssertDeepEquals(t, "test struct", expected, testStruct)
+ })
+
+ t.Run("target F1", func(t *testing.T) {
+ testStruct := input
+ pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseFuture1)
+ pruner.pruneProperties(&testStruct)
+
+ expected := input
+ expected.S_and_T_only = ""
+ android.AssertDeepEquals(t, "test struct", expected, testStruct)
+ })
+
+ t.Run("target F2", func(t *testing.T) {
+ testStruct := input
+ pruner := newPropertyPrunerByBuildRelease(&testStruct, buildReleaseFuture2)
+ pruner.pruneProperties(&testStruct)
+
+ expected := input
+ expected.S_and_T_only = ""
+ expected.Nested.F1_only = ""
+ android.AssertDeepEquals(t, "test struct", expected, testStruct)
+ })
+}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 2b53739..0d9b4a0 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -482,6 +482,71 @@
)
}
+func TestSnapshotWithJavaSystemserverLibrary(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ android.FixtureAddFile("aidl", nil),
+ android.FixtureAddFile("resource.txt", nil),
+ ).RunTestWithBp(t, `
+ module_exports {
+ name: "myexports",
+ java_systemserver_libs: ["myjavalib"],
+ }
+
+ java_library {
+ name: "myjavalib",
+ srcs: ["Test.java"],
+ java_resources: ["resource.txt"],
+ // The aidl files should not be copied to the snapshot because a java_systemserver_libs member
+ // is not intended to be used for compiling Java, only for accessing the dex implementation
+ // jar.
+ aidl: {
+ export_include_dirs: ["aidl"],
+ },
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ permitted_packages: ["pkg.myjavalib"],
+ }
+ `)
+
+ CheckSnapshot(t, result, "myexports", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "myjavalib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"],
+ permitted_packages: ["pkg.myjavalib"],
+}
+`),
+ checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "myexports_myjavalib@current",
+ sdk_member_name: "myjavalib",
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"],
+ permitted_packages: ["pkg.myjavalib"],
+}
+
+module_exports_snapshot {
+ name: "myexports@current",
+ visibility: ["//visibility:public"],
+ java_systemserver_libs: ["myexports_myjavalib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/myexports/common_os/empty -> java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar
+`),
+ )
+}
+
func TestHostSnapshotWithJavaImplLibrary(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 85e3d87..83294f6 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -21,6 +21,7 @@
"testing"
"android/soong/android"
+ "android/soong/java"
"github.com/google/blueprint/proptools"
)
@@ -706,4 +707,86 @@
snapshotTestPreparer(checkSnapshotWithoutSource, android.FixtureWithRootAndroidBp(bp)),
)
})
+
+ t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ java.PrepareForTestWithJavaDefaultModules,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("mysdklibrary"),
+ android.FixtureWithRootAndroidBp(`
+ sdk {
+ name: "mysdk",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ apex_available: ["myapex"],
+ contents: ["mysdklibrary"],
+ }
+
+ java_sdk_library {
+ name: "mysdklibrary",
+ srcs: ["Test.java"],
+ compile_dex: true,
+ public: {enabled: true},
+ permitted_packages: ["mysdklibrary"],
+ }
+ `),
+ android.FixtureMergeEnv(map[string]string{
+ "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S",
+ }),
+ ).RunTest(t)
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ contents: ["mysdklibrary"],
+ hidden_api: {
+ annotation_flags: "hiddenapi/annotation-flags.csv",
+ metadata: "hiddenapi/metadata.csv",
+ index: "hiddenapi/index.csv",
+ stub_flags: "hiddenapi/stub-flags.csv",
+ all_flags: "hiddenapi/all-flags.csv",
+ },
+}
+
+java_sdk_library_import {
+ name: "mysdklibrary",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ shared_library: true,
+ compile_dex: true,
+ permitted_packages: ["mysdklibrary"],
+ public: {
+ jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
+ current_api: "sdk_library/public/mysdklibrary.txt",
+ removed_api: "sdk_library/public/mysdklibrary-removed.txt",
+ sdk_version: "current",
+ },
+}
+`),
+
+ checkAllCopyRules(`
+.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv
+.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv
+.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv
+.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv
+.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv
+.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar
+.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
+.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt
+`),
+ )
+ })
+
}
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
new file mode 100644
index 0000000..16e3e7f
--- /dev/null
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -0,0 +1,171 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sdk
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
+ "android/soong/java"
+)
+
+func TestSnapshotWithSystemServerClasspathFragment(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ java.PrepareForTestWithJavaDefaultModules,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("mysdklibrary"),
+ dexpreopt.FixtureSetApexSystemServerJars("myapex:mylib", "myapex:mysdklibrary"),
+ prepareForSdkTestWithApex,
+
+ android.FixtureWithRootAndroidBp(`
+ sdk {
+ name: "mysdk",
+ systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+ java_sdk_libs: [
+ // This is not strictly needed as it should be automatically added to the sdk_snapshot as
+ // a java_sdk_libs module because it is used in the mysystemserverclasspathfragment's
+ // contents property. However, it is specified here to ensure that duplicates are
+ // correctly deduped.
+ "mysdklibrary",
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ min_sdk_version: "2",
+ systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ apex_available: ["myapex"],
+ contents: [
+ "mylib",
+ "mysdklibrary",
+ ],
+ }
+
+ java_library {
+ name: "mylib",
+ apex_available: ["myapex"],
+ srcs: ["Test.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ min_sdk_version: "2",
+ compile_dex: true,
+ permitted_packages: ["mylib"],
+ }
+
+ java_sdk_library {
+ name: "mysdklibrary",
+ apex_available: ["myapex"],
+ srcs: ["Test.java"],
+ shared_library: false,
+ public: {enabled: true},
+ min_sdk_version: "2",
+ }
+ `),
+ ).RunTest(t)
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+ name: "mysdklibrary",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ shared_library: false,
+ public: {
+ jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
+ current_api: "sdk_library/public/mysdklibrary.txt",
+ removed_api: "sdk_library/public/mysdklibrary-removed.txt",
+ sdk_version: "current",
+ },
+}
+
+java_import {
+ name: "mylib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
+ permitted_packages: ["mylib"],
+}
+
+prebuilt_systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ contents: [
+ "mylib",
+ "mysdklibrary",
+ ],
+}
+`),
+ checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+ name: "mysdk_mysdklibrary@current",
+ sdk_member_name: "mysdklibrary",
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ shared_library: false,
+ public: {
+ jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
+ current_api: "sdk_library/public/mysdklibrary.txt",
+ removed_api: "sdk_library/public/mysdklibrary-removed.txt",
+ sdk_version: "current",
+ },
+}
+
+java_import {
+ name: "mysdk_mylib@current",
+ sdk_member_name: "mylib",
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
+ permitted_packages: ["mylib"],
+}
+
+prebuilt_systemserverclasspath_fragment {
+ name: "mysdk_mysystemserverclasspathfragment@current",
+ sdk_member_name: "mysystemserverclasspathfragment",
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ contents: [
+ "mysdk_mylib@current",
+ "mysdk_mysdklibrary@current",
+ ],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ visibility: ["//visibility:public"],
+ java_sdk_libs: ["mysdk_mysdklibrary@current"],
+ java_systemserver_libs: ["mysdk_mylib@current"],
+ systemserverclasspath_fragments: ["mysdk_mysystemserverclasspathfragment@current"],
+}
+`),
+ )
+}
diff --git a/sdk/testing.go b/sdk/testing.go
index 3254cf9..294f1a5 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -136,6 +136,7 @@
androidUnversionedBpContents: sdk.GetUnversionedAndroidBpContentsForTests(),
androidVersionedBpContents: sdk.GetVersionedAndroidBpContentsForTests(),
snapshotTestCustomizations: map[snapshotTest]*snapshotTestCustomization{},
+ targetBuildRelease: sdk.builderForTests.targetBuildRelease,
}
buildParams := sdk.BuildParamsForTests()
@@ -253,6 +254,13 @@
}
fs[filepath.Join(snapshotSubDir, "Android.bp")] = []byte(snapshotBuildInfo.androidBpContents)
+ // If the generated snapshot builders not for the current release then it cannot be loaded by
+ // the current release.
+ currentBuildRelease := latestBuildRelease()
+ if snapshotBuildInfo.targetBuildRelease != currentBuildRelease {
+ return
+ }
+
// The preparers from the original source fixture.
sourcePreparers := result.Preparer()
@@ -476,6 +484,9 @@
// The final output zip.
outputZip string
+ // The target build release.
+ targetBuildRelease *buildRelease
+
// The test specific customizations for each snapshot test.
snapshotTestCustomizations map[snapshotTest]*snapshotTestCustomization
}
diff --git a/sdk/update.go b/sdk/update.go
index 3246832..389e845 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -81,6 +81,19 @@
// snapshot module only. The zip file containing the generated snapshot will be
// <sdk-name>-<number>.zip.
//
+// SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE
+// This allows the target build release (i.e. the release version of the build within which
+// the snapshot will be used) of the snapshot to be specified. If unspecified then it defaults
+// to the current build release version. Otherwise, it must be the name of one of the build
+// releases defined in nameToBuildRelease, e.g. S, T, etc..
+//
+// The generated snapshot must only be used in the specified target release. If the target
+// build release is not the current build release then the generated Android.bp file not be
+// checked for compatibility.
+//
+// e.g. if setting SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S will cause the generated snapshot
+// to be compatible with S.
+//
var pctx = android.NewPackageContext("android/soong/sdk")
@@ -358,6 +371,14 @@
snapshotZipFileSuffix = "-" + version
}
+ currentBuildRelease := latestBuildRelease()
+ targetBuildReleaseEnv := config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", currentBuildRelease.name)
+ targetBuildRelease, err := nameToRelease(targetBuildReleaseEnv)
+ if err != nil {
+ ctx.ModuleErrorf("invalid SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE: %s", err)
+ targetBuildRelease = currentBuildRelease
+ }
+
builder := &snapshotBuilder{
ctx: ctx,
sdk: s,
@@ -369,6 +390,7 @@
prebuiltModules: make(map[string]*bpModule),
allMembersByName: allMembersByName,
exportedMembersByName: exportedMembersByName,
+ targetBuildRelease: targetBuildRelease,
}
s.builderForTests = builder
@@ -449,7 +471,11 @@
generateBpContents(&bp.generatedContents, bpFile)
contents := bp.content.String()
- syntaxCheckSnapshotBpFile(ctx, contents)
+ // If the snapshot is being generated for the current build release then check the syntax to make
+ // sure that it is compatible.
+ if targetBuildRelease == currentBuildRelease {
+ syntaxCheckSnapshotBpFile(ctx, contents)
+ }
bp.build(pctx, ctx, nil)
@@ -1051,6 +1077,9 @@
// The set of exported members by name.
exportedMembersByName map[string]struct{}
+
+ // The target build release for which the snapshot is to be generated.
+ targetBuildRelease *buildRelease
}
func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
@@ -1426,6 +1455,16 @@
return osInfo
}
+func (osInfo *osTypeSpecificInfo) pruneUnsupportedProperties(pruner *propertyPruner) {
+ if len(osInfo.archInfos) == 0 {
+ pruner.pruneProperties(osInfo.Properties)
+ } else {
+ for _, archInfo := range osInfo.archInfos {
+ archInfo.pruneUnsupportedProperties(pruner)
+ }
+ }
+}
+
// Optimize the properties by extracting common properties from arch type specific
// properties into os type specific properties.
func (osInfo *osTypeSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
@@ -1635,6 +1674,16 @@
return linkType
}
+func (archInfo *archTypeSpecificInfo) pruneUnsupportedProperties(pruner *propertyPruner) {
+ if len(archInfo.imageVariantInfos) == 0 {
+ pruner.pruneProperties(archInfo.Properties)
+ } else {
+ for _, imageVariantInfo := range archInfo.imageVariantInfos {
+ imageVariantInfo.pruneUnsupportedProperties(pruner)
+ }
+ }
+}
+
// Optimize the properties by extracting common properties from link type specific
// properties into arch type specific properties.
func (archInfo *archTypeSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
@@ -1732,6 +1781,16 @@
return imageInfo
}
+func (imageInfo *imageVariantSpecificInfo) pruneUnsupportedProperties(pruner *propertyPruner) {
+ if len(imageInfo.linkInfos) == 0 {
+ pruner.pruneProperties(imageInfo.Properties)
+ } else {
+ for _, linkInfo := range imageInfo.linkInfos {
+ linkInfo.pruneUnsupportedProperties(pruner)
+ }
+ }
+}
+
// Optimize the properties by extracting common properties from link type specific
// properties into arch type specific properties.
func (imageInfo *imageVariantSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
@@ -1798,6 +1857,10 @@
addSdkMemberPropertiesToSet(ctx, l.Properties, linkPropertySet)
}
+func (l *linkTypeSpecificInfo) pruneUnsupportedProperties(pruner *propertyPruner) {
+ pruner.pruneProperties(l.Properties)
+}
+
func (l *linkTypeSpecificInfo) String() string {
return fmt.Sprintf("LinkType{%s}", l.linkType)
}
@@ -1837,12 +1900,12 @@
memberType := member.memberType
// Do not add the prefer property if the member snapshot module is a source module type.
+ config := ctx.sdkMemberContext.Config()
if !memberType.UsesSourceModuleTypeInSnapshot() {
// Set the prefer based on the environment variable. This is a temporary work around to allow a
// snapshot to be created that sets prefer: true.
// TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
// dynamically at build time not at snapshot generation time.
- config := ctx.sdkMemberContext.Config()
prefer := config.IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
// Set prefer. Setting this to false is not strictly required as that is the default but it does
@@ -1884,6 +1947,11 @@
commonProperties := variantPropertiesFactory()
commonProperties.Base().Os = android.CommonOS
+ // Create a property pruner that will prune any properties unsupported by the target build
+ // release.
+ targetBuildRelease := ctx.builder.targetBuildRelease
+ unsupportedPropertyPruner := newPropertyPrunerByBuildRelease(commonProperties, targetBuildRelease)
+
// Create common value extractor that can be used to optimize the properties.
commonValueExtractor := newCommonValueExtractor(commonProperties)
@@ -1898,6 +1966,8 @@
// independent properties structs.
osSpecificPropertiesContainers = append(osSpecificPropertiesContainers, osInfo)
+ osInfo.pruneUnsupportedProperties(unsupportedPropertyPruner)
+
// Optimize the properties across all the variants for a specific os type.
osInfo.optimizeProperties(ctx, commonValueExtractor)
}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index db66ae2..b22a5b7 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -548,7 +548,7 @@
Rule_class: "sh_binary",
}
- ctx.CreateBazelTargetModule(m.Name(), props, attrs)
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
}
var Bool = proptools.Bool
diff --git a/soong.bash b/soong.bash
index 8cf2ec6..db7af7c 100755
--- a/soong.bash
+++ b/soong.bash
@@ -15,8 +15,8 @@
# limitations under the License.
echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
-echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
+echo 'Use `m --soong-only` with a standalone OUT_DIR instead.' >&2
echo 'Without envsetup.sh, use:' >&2
-echo ' build/soong/soong_ui.bash --make-mode --skip-make' >&2
+echo ' build/soong/soong_ui.bash --make-mode --soong-only' >&2
echo '======================================================' >&2
exit 1
diff --git a/tests/lib.sh b/tests/lib.sh
index e777820..e6074f8 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -105,7 +105,7 @@
}
function run_soong() {
- build/soong/soong_ui.bash --make-mode --skip-ninja --skip-make --skip-soong-tests "$@"
+ build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
}
function create_mock_bazel() {
@@ -125,7 +125,7 @@
}
run_ninja() {
- build/soong/soong_ui.bash --make-mode --skip-make --skip-soong-tests "$@"
+ build/soong/soong_ui.bash --make-mode --skip-config --soong-only --skip-soong-tests "$@"
}
info "Starting Soong integration test suite $(basename $0)"
diff --git a/ui/build/config.go b/ui/build/config.go
index 35dacf2..07ffb44 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -83,6 +83,8 @@
// Set by multiproduct_kati
emptyNinjaFile bool
+
+ metricsUploader string
}
const srcDirFileCheck = "build/soong/root.bp"
@@ -237,7 +239,8 @@
// Precondition: the current directory is the top of the source tree
checkTopDir(ctx)
- if srcDir := absPath(ctx, "."); strings.ContainsRune(srcDir, ' ') {
+ srcDir := absPath(ctx, ".")
+ if strings.ContainsRune(srcDir, ' ') {
ctx.Println("You are building in a directory whose absolute path contains a space character:")
ctx.Println()
ctx.Printf("%q\n", srcDir)
@@ -245,6 +248,8 @@
ctx.Fatalln("Directory names containing spaces are not supported")
}
+ ret.metricsUploader = GetMetricsUploader(srcDir, ret.environ)
+
if outDir := ret.OutDir(); strings.ContainsRune(outDir, ' ') {
ctx.Println("The absolute path of your output directory ($OUT_DIR) contains a space character:")
ctx.Println()
@@ -355,13 +360,16 @@
}
func buildConfig(config Config) *smpb.BuildConfig {
- return &smpb.BuildConfig{
+ c := &smpb.BuildConfig{
ForceUseGoma: proto.Bool(config.ForceUseGoma()),
UseGoma: proto.Bool(config.UseGoma()),
UseRbe: proto.Bool(config.UseRBE()),
BazelAsNinja: proto.Bool(config.UseBazel()),
BazelMixedBuild: proto.Bool(config.bazelBuildMode() == mixedBuild),
}
+ c.Targets = append(c.Targets, config.arguments...)
+
+ return c
}
// getConfigArgs processes the command arguments based on the build action and creates a set of new
@@ -788,10 +796,6 @@
return shared.JoinPath(c.SoongOutDir(), usedEnvFile+"."+tag)
}
-func (c *configImpl) MainNinjaFile() string {
- return shared.JoinPath(c.SoongOutDir(), "build.ninja")
-}
-
func (c *configImpl) Bp2BuildMarkerFile() string {
return shared.JoinPath(c.SoongOutDir(), ".bootstrap/bp2build_workspace_marker")
}
@@ -1243,10 +1247,7 @@
}
func (c *configImpl) MetricsUploaderApp() string {
- if p, ok := c.environ.Get("ANDROID_ENABLE_METRICS_UPLOAD"); ok {
- return p
- }
- return ""
+ return c.metricsUploader
}
// LogsDir returns the logs directory where build log and metrics
@@ -1274,3 +1275,14 @@
func (c *configImpl) EmptyNinjaFile() bool {
return c.emptyNinjaFile
}
+
+func GetMetricsUploader(topDir string, env *Environment) string {
+ if p, ok := env.Get("METRICS_UPLOADER"); ok {
+ metricsUploader := filepath.Join(topDir, p)
+ if _, err := os.Stat(metricsUploader); err == nil {
+ return metricsUploader
+ }
+ }
+
+ return ""
+}
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index 1f2158b..e293275 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -1003,6 +1003,7 @@
tests := []struct {
name string
environ Environment
+ arguments []string
useBazel bool
expectedBuildConfig *smpb.BuildConfig
}{
@@ -1074,6 +1075,20 @@
},
},
{
+ name: "specified targets",
+ environ: Environment{},
+ useBazel: true,
+ arguments: []string{"droid", "dist"},
+ expectedBuildConfig: &smpb.BuildConfig{
+ ForceUseGoma: proto.Bool(false),
+ UseGoma: proto.Bool(false),
+ UseRbe: proto.Bool(false),
+ BazelAsNinja: proto.Bool(true),
+ BazelMixedBuild: proto.Bool(false),
+ Targets: []string{"droid", "dist"},
+ },
+ },
+ {
name: "all set",
environ: Environment{
"FORCE_USE_GOMA=1",
@@ -1095,8 +1110,9 @@
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
c := &configImpl{
- environ: &tc.environ,
- useBazel: tc.useBazel,
+ environ: &tc.environ,
+ useBazel: tc.useBazel,
+ arguments: tc.arguments,
}
config := Config{c}
actualBuildConfig := buildConfig(config)
@@ -1106,3 +1122,65 @@
})
}
}
+
+func TestGetMetricsUploaderApp(t *testing.T) {
+
+ metricsUploaderDir := "metrics_uploader_dir"
+ metricsUploaderBinary := "metrics_uploader_binary"
+ metricsUploaderPath := filepath.Join(metricsUploaderDir, metricsUploaderBinary)
+ tests := []struct {
+ description string
+ environ Environment
+ createFiles bool
+ expected string
+ }{{
+ description: "Uploader binary exist",
+ environ: Environment{"METRICS_UPLOADER=" + metricsUploaderPath},
+ createFiles: true,
+ expected: metricsUploaderPath,
+ }, {
+ description: "Uploader binary not exist",
+ environ: Environment{"METRICS_UPLOADER=" + metricsUploaderPath},
+ createFiles: false,
+ expected: "",
+ }, {
+ description: "Uploader binary variable not set",
+ createFiles: true,
+ expected: "",
+ }}
+
+ for _, tt := range tests {
+ t.Run(tt.description, func(t *testing.T) {
+ defer logger.Recover(func(err error) {
+ t.Fatalf("got unexpected error: %v", err)
+ })
+
+ // Create the root source tree.
+ topDir, err := ioutil.TempDir("", "")
+ if err != nil {
+ t.Fatalf("failed to create temp dir: %v", err)
+ }
+ defer os.RemoveAll(topDir)
+
+ expected := tt.expected
+ if len(expected) > 0 {
+ expected = filepath.Join(topDir, expected)
+ }
+
+ if tt.createFiles {
+ if err := os.MkdirAll(filepath.Join(topDir, metricsUploaderDir), 0755); err != nil {
+ t.Errorf("failed to create %s directory: %v", metricsUploaderDir, err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(topDir, metricsUploaderPath), []byte{}, 0644); err != nil {
+ t.Errorf("failed to create file %s: %v", expected, err)
+ }
+ }
+
+ actual := GetMetricsUploader(topDir, &tt.environ)
+
+ if actual != expected {
+ t.Errorf("expecting: %s, actual: %s", expected, actual)
+ }
+ })
+ }
+}
diff --git a/ui/build/context.go b/ui/build/context.go
index f5e987e..4a4352c 100644
--- a/ui/build/context.go
+++ b/ui/build/context.go
@@ -71,9 +71,9 @@
realTime := end - begin
c.Metrics.SetTimeMetrics(
soong_metrics_proto.PerfInfo{
- Desc: &desc,
- Name: &name,
- StartTime: &begin,
- RealTime: &realTime})
+ Description: &desc,
+ Name: &name,
+ StartTime: &begin,
+ RealTime: &realTime})
}
}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 3d16073..afec829 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -163,6 +163,7 @@
"AUX_OS_VARIANT_LIST",
"PRODUCT_SOONG_NAMESPACES",
"SOONG_SDK_SNAPSHOT_PREFER",
+ "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
"SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR",
"SOONG_SDK_SNAPSHOT_VERSION",
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 617d293..a0f223b 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -170,7 +170,7 @@
ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap")
defer ctx.EndTrace()
- mainSoongBuildExtraArgs := []string{"-o", config.MainNinjaFile()}
+ mainSoongBuildExtraArgs := []string{"-o", config.SoongNinjaFile()}
if config.EmptyNinjaFile() {
mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--empty-ninja-file")
}
@@ -178,7 +178,7 @@
mainSoongBuildInvocation := primaryBuilderInvocation(
config,
soongBuildTag,
- config.MainNinjaFile(),
+ config.SoongNinjaFile(),
mainSoongBuildExtraArgs)
if config.bazelBuildMode() == mixedBuild {
@@ -401,7 +401,7 @@
if config.SoongBuildInvocationNeeded() {
// This build generates <builddir>/build.ninja, which is used later by build/soong/ui/build/build.go#Build().
- targets = append(targets, config.MainNinjaFile())
+ targets = append(targets, config.SoongNinjaFile())
}
ninja("bootstrap", ".bootstrap/build.ninja", targets...)
diff --git a/ui/build/upload.go b/ui/build/upload.go
index 55ada33..687f519 100644
--- a/ui/build/upload.go
+++ b/ui/build/upload.go
@@ -70,12 +70,11 @@
return metricsFiles
}
-// UploadMetrics uploads a set of metrics files to a server for analysis. An
-// uploader full path is specified in ANDROID_ENABLE_METRICS_UPLOAD environment
-// variable in order to upload the set of metrics files. The metrics files are
-// first copied to a temporary directory and the uploader is then executed in
-// the background to allow the user/system to continue working. Soong communicates
-// to the uploader through the upload_proto raw protobuf file.
+// UploadMetrics uploads a set of metrics files to a server for analysis.
+// The metrics files are first copied to a temporary directory
+// and the uploader is then executed in the background to allow the user/system
+// to continue working. Soong communicates to the uploader through the
+// upload_proto raw protobuf file.
func UploadMetrics(ctx Context, config Config, simpleOutput bool, buildStarted time.Time, paths ...string) {
ctx.BeginTrace(metrics.RunSetupTool, "upload_metrics")
defer ctx.EndTrace()
diff --git a/ui/build/upload_test.go b/ui/build/upload_test.go
index b740c11..764a1e1 100644
--- a/ui/build/upload_test.go
+++ b/ui/build/upload_test.go
@@ -80,13 +80,10 @@
createFiles bool
files []string
}{{
- description: "ANDROID_ENABLE_METRICS_UPLOAD not set",
- }, {
- description: "no metrics files to upload",
- uploader: "fake",
+ description: "no metrics uploader",
}, {
description: "non-existent metrics files no upload",
- uploader: "fake",
+ uploader: "echo",
files: []string{"metrics_file_1", "metrics_file_2", "metrics_file_3"},
}, {
description: "trigger upload",
@@ -137,9 +134,9 @@
config := Config{&configImpl{
environ: &Environment{
"OUT_DIR=" + outDir,
- "ANDROID_ENABLE_METRICS_UPLOAD=" + tt.uploader,
},
- buildDateTime: strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10),
+ buildDateTime: strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10),
+ metricsUploader: tt.uploader,
}}
UploadMetrics(ctx, config, false, time.Now(), metricsFiles...)
@@ -192,9 +189,10 @@
config := Config{&configImpl{
environ: &Environment{
- "ANDROID_ENABLE_METRICS_UPLOAD=fake",
"OUT_DIR=/bad",
- }}}
+ },
+ metricsUploader: "echo",
+ }}
UploadMetrics(ctx, config, true, time.Now(), metricsFile)
t.Errorf("got nil, expecting %q as a failure", tt.expectedErr)
diff --git a/ui/metrics/event.go b/ui/metrics/event.go
index c3367e3..ebe664f 100644
--- a/ui/metrics/event.go
+++ b/ui/metrics/event.go
@@ -69,7 +69,7 @@
func (e event) perfInfo() soong_metrics_proto.PerfInfo {
realTime := uint64(_now().Sub(e.start).Nanoseconds())
return soong_metrics_proto.PerfInfo{
- Desc: proto.String(e.desc),
+ Description: proto.String(e.desc),
Name: proto.String(e.name),
StartTime: proto.Uint64(uint64(e.start.UnixNano())),
RealTime: proto.Uint64(realTime),
diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go
index ccf9bd8..f1bb862 100644
--- a/ui/metrics/metrics.go
+++ b/ui/metrics/metrics.go
@@ -25,16 +25,11 @@
// that captures the metrics and is them added as a perfInfo into the set
// of the collected metrics. Finally, when soong_ui has finished the build,
// the defer Dump function is invoked to store the collected metrics to the
-// raw protobuf file in the $OUT directory.
-//
-// There is one additional step that occurs after the raw protobuf file is written.
-// If the configuration environment variable ANDROID_ENABLE_METRICS_UPLOAD is
-// set with the path, the raw protobuf file is uploaded to the destination. See
-// ui/build/upload.go for more details. The filename of the raw protobuf file
-// and the list of files to be uploaded is defined in cmd/soong_ui/main.go.
-//
-// See ui/metrics/event.go for the explanation of what an event is and how
-// the metrics system is a stack based system.
+// raw protobuf file in the $OUT directory and this raw protobuf file will be
+// uploaded to the destination. See ui/build/upload.go for more details. The
+// filename of the raw protobuf file and the list of files to be uploaded is
+// defined in cmd/soong_ui/main.go. See ui/metrics/event.go for the explanation
+// of what an event is and how the metrics system is a stack based system.
import (
"io/ioutil"
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index 697e954..2e530b0 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -14,7 +14,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.26.0
+// protoc-gen-go v1.27.1
// protoc v3.9.1
// source: metrics.proto
@@ -518,6 +518,9 @@
// Whether build is occurring in a mixed build mode, where Bazel maintains the
// definition and build of some modules in cooperation with Soong.
BazelMixedBuild *bool `protobuf:"varint,5,opt,name=bazel_mixed_build,json=bazelMixedBuild" json:"bazel_mixed_build,omitempty"`
+ // These are the targets soong passes to ninja, these targets include special
+ // targets such as droid as well as the regular build targets.
+ Targets []string `protobuf:"bytes,6,rep,name=targets" json:"targets,omitempty"`
}
func (x *BuildConfig) Reset() {
@@ -587,6 +590,13 @@
return false
}
+func (x *BuildConfig) GetTargets() []string {
+ if x != nil {
+ return x.Targets
+ }
+ return nil
+}
+
type SystemResourceInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -650,7 +660,7 @@
unknownFields protoimpl.UnknownFields
// The description for the phase/action/part while the tool running.
- Desc *string `protobuf:"bytes,1,opt,name=desc" json:"desc,omitempty"`
+ Description *string `protobuf:"bytes,1,opt,name=description" json:"description,omitempty"`
// The name for the running phase/action/part.
Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
// The absolute start time.
@@ -699,9 +709,9 @@
return file_metrics_proto_rawDescGZIP(), []int{3}
}
-func (x *PerfInfo) GetDesc() string {
- if x != nil && x.Desc != nil {
- return *x.Desc
+func (x *PerfInfo) GetDescription() string {
+ if x != nil && x.Description != nil {
+ return *x.Description
}
return ""
}
@@ -1238,7 +1248,7 @@
0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x52, 0x4d, 0x10, 0x01, 0x12,
0x09, 0x0a, 0x05, 0x41, 0x52, 0x4d, 0x36, 0x34, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x58, 0x38,
0x36, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x58, 0x38, 0x36, 0x5f, 0x36, 0x34, 0x10, 0x04, 0x22,
- 0xb9, 0x01, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0xd3, 0x01, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
0x08, 0x52, 0x07, 0x75, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73,
0x65, 0x5f, 0x72, 0x62, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x73, 0x65,
@@ -1249,100 +1259,102 @@
0x08, 0x52, 0x0c, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x41, 0x73, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x12,
0x2a, 0x0a, 0x11, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62,
0x75, 0x69, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x62, 0x61, 0x7a, 0x65,
- 0x6c, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x22, 0x6f, 0x0a, 0x12, 0x53,
- 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66,
- 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x68, 0x79, 0x73, 0x69,
- 0x63, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
- 0x52, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x4d,
- 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62,
- 0x6c, 0x65, 0x5f, 0x63, 0x70, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61,
- 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x70, 0x75, 0x73, 0x22, 0xf3, 0x01, 0x0a,
- 0x08, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73,
- 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x73, 0x63, 0x12, 0x12, 0x0a,
- 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
- 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
- 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65,
- 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20,
- 0x01, 0x28, 0x04, 0x52, 0x08, 0x72, 0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a,
- 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x75, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x04, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x65,
- 0x12, 0x60, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65,
- 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
- 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52,
- 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x15, 0x70, 0x72, 0x6f,
- 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e,
- 0x66, 0x6f, 0x22, 0xb9, 0x03, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65,
- 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
- 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28,
- 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72,
- 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x54, 0x69,
- 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x79, 0x73, 0x74,
- 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x69, 0x6d, 0x65,
- 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x1c, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73,
- 0x73, 0x5f, 0x6b, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x52,
- 0x73, 0x73, 0x4b, 0x62, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70, 0x61,
- 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52,
- 0x0f, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73,
- 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66,
- 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x6a,
- 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0b,
- 0x69, 0x6f, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28,
- 0x04, 0x52, 0x09, 0x69, 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c,
- 0x69, 0x6f, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x08, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6f, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x3c,
- 0x0a, 0x1a, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74,
- 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x18, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e,
- 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x1c,
- 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74,
- 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01,
- 0x28, 0x04, 0x52, 0x1a, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43,
- 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0xe5,
- 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x66,
- 0x6f, 0x12, 0x5b, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65,
- 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
- 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x6f,
- 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x42, 0x75, 0x69,
- 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x3a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
- 0x4e, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1f,
- 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12,
- 0x24, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x5f, 0x6f, 0x66, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
- 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6e, 0x75, 0x6d, 0x4f, 0x66, 0x4d, 0x6f,
- 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79,
- 0x73, 0x74, 0x65, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10,
- 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x4f, 0x4f, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04,
- 0x4d, 0x41, 0x4b, 0x45, 0x10, 0x02, 0x22, 0x6c, 0x0a, 0x1a, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63,
- 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x4d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x6c, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x73, 0x22, 0x6f, 0x0a, 0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52,
+ 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x74,
+ 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x6d, 0x65,
+ 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x74, 0x6f, 0x74, 0x61,
+ 0x6c, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12,
+ 0x25, 0x0a, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x70, 0x75,
+ 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62,
+ 0x6c, 0x65, 0x43, 0x70, 0x75, 0x73, 0x22, 0x81, 0x02, 0x0a, 0x08, 0x50, 0x65, 0x72, 0x66, 0x49,
+ 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61,
+ 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x6c,
+ 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x72, 0x65, 0x61,
+ 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f,
+ 0x75, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6d,
+ 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63,
+ 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69,
+ 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
- 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42, 0x61, 0x73, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x74,
- 0x72, 0x69, 0x63, 0x73, 0x22, 0x62, 0x0a, 0x1b, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c,
- 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x73, 0x4d, 0x65, 0x74, 0x72,
- 0x69, 0x63, 0x73, 0x12, 0x43, 0x0a, 0x04, 0x63, 0x75, 0x6a, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
- 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c,
- 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x73, 0x52, 0x04, 0x63, 0x75, 0x6a, 0x73, 0x22, 0xc3, 0x01, 0x0a, 0x11, 0x53, 0x6f, 0x6f,
- 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x18,
- 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
- 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x61, 0x72, 0x69,
- 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x76, 0x61, 0x72, 0x69,
- 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6c,
- 0x6c, 0x6f, 0x63, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
- 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x43, 0x6f, 0x75, 0x6e, 0x74,
- 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f,
- 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61,
- 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6d, 0x61,
- 0x78, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x04, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x48, 0x65, 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x28,
- 0x5a, 0x26, 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, 0x65, 0x74, 0x72, 0x69,
- 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49,
+ 0x6e, 0x66, 0x6f, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65,
+ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xb9, 0x03, 0x0a, 0x13, 0x50,
+ 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e,
+ 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74,
+ 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
+ 0x52, 0x0e, 0x75, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73,
+ 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f,
+ 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x73, 0x79,
+ 0x73, 0x74, 0x65, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x1c,
+ 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f, 0x6b, 0x62, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x52, 0x73, 0x73, 0x4b, 0x62, 0x12, 0x2a, 0x0a, 0x11,
+ 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74,
+ 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x50, 0x61,
+ 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x61, 0x6a, 0x6f,
+ 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x06, 0x20,
+ 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61,
+ 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x6f, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74,
+ 0x5f, 0x6b, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69, 0x6f, 0x49, 0x6e, 0x70,
+ 0x75, 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x6f, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75,
+ 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x69, 0x6f, 0x4f, 0x75,
+ 0x74, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x3c, 0x0a, 0x1a, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74,
+ 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74,
+ 0x63, 0x68, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x76, 0x6f, 0x6c, 0x75,
+ 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74,
+ 0x63, 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74,
+ 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74,
+ 0x63, 0x68, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x69, 0x6e, 0x76, 0x6f,
+ 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x77,
+ 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x75, 0x6c,
+ 0x65, 0x54, 0x79, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x5b, 0x0a, 0x0c, 0x62, 0x75, 0x69,
+ 0x6c, 0x64, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65,
+ 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
+ 0x3a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64,
+ 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
+ 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64,
+ 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x5f, 0x6f,
+ 0x66, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
+ 0x0c, 0x6e, 0x75, 0x6d, 0x4f, 0x66, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x2f, 0x0a,
+ 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x0b, 0x0a, 0x07,
+ 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x4f, 0x4f,
+ 0x4e, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x41, 0x4b, 0x45, 0x10, 0x02, 0x22, 0x6c,
+ 0x0a, 0x1a, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f,
+ 0x75, 0x72, 0x6e, 0x65, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x12, 0x3a, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
+ 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x42,
+ 0x61, 0x73, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x62, 0x0a, 0x1b,
+ 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72,
+ 0x6e, 0x65, 0x79, 0x73, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x43, 0x0a, 0x04, 0x63,
+ 0x75, 0x6a, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
+ 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x72, 0x4a, 0x6f, 0x75, 0x72,
+ 0x6e, 0x65, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x04, 0x63, 0x75, 0x6a, 0x73,
+ 0x22, 0xc3, 0x01, 0x0a, 0x11, 0x53, 0x6f, 0x6f, 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73,
+ 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x08, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11,
+ 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
+ 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c,
+ 0x6c, 0x6f, 0x63, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61,
+ 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x53, 0x69,
+ 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x5f, 0x73,
+ 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x48, 0x65,
+ 0x61, 0x70, 0x53, 0x69, 0x7a, 0x65, 0x42, 0x28, 0x5a, 0x26, 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, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
}
var (
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index ef42f54..db0a14a 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -123,6 +123,10 @@
// Whether build is occurring in a mixed build mode, where Bazel maintains the
// definition and build of some modules in cooperation with Soong.
optional bool bazel_mixed_build = 5;
+
+ // These are the targets soong passes to ninja, these targets include special
+ // targets such as droid as well as the regular build targets.
+ repeated string targets = 6;
}
message SystemResourceInfo {
@@ -135,7 +139,7 @@
message PerfInfo {
// The description for the phase/action/part while the tool running.
- optional string desc = 1;
+ optional string description = 1;
// The name for the running phase/action/part.
optional string name = 2;