Merge "Use prebuild modules even when coverage is enabled." into sc-dev am: fe1d6c535c
Original change: https://googleplex-android-review.googlesource.com/c/platform/build/soong/+/15472697
Change-Id: If8bc890561f17a5179a8d655043be1ac36d165f2
diff --git a/Android.bp b/Android.bp
index 8f7f3e2..d6260b4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -92,7 +92,7 @@
}
cc_genrule {
- name: "host_bionic_linker_flags",
+ name: "host_bionic_linker_script",
host_supported: true,
device_supported: false,
target: {
@@ -107,12 +107,22 @@
},
},
tools: ["extract_linker"],
- cmd: "$(location) -f $(out) $(in)",
+ cmd: "$(location) -T $(out) $(in)",
srcs: [":linker"],
- out: ["linker.flags"],
+ out: ["linker.script"],
}
// Instantiate the dex_bootjars singleton module.
dex_bootjars {
name: "dex_bootjars",
}
+
+// Pseudo-test that's run on checkbuilds to ensure that get_clang_version can
+// parse cc/config/global.go.
+genrule {
+ name: "get_clang_version_test",
+ cmd: "$(location get_clang_version) > $(out)",
+ tools: ["get_clang_version"],
+ srcs: ["cc/config/global.go"],
+ out: ["clang-prebuilts-version.txt"],
+}
diff --git a/OWNERS b/OWNERS
index e851bf7..f15bd32 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,18 +1,22 @@
# This file is included by several other projects as the list of people
# approving build related projects.
+# AMER
ahumesky@google.com
asmundak@google.com
ccross@android.com
cparsons@google.com
dwillemsen@google.com
eakammer@google.com
-jingwen@google.com
joeo@google.com
-jungjw@google.com
-lberki@google.com
+spandandas@google.com
+yuntaoxu@google.com
+
+# APAC
+jingwen@google.com
ruperts@google.com
-# To expedite LON reviews
+# EMEA
hansson@google.com
+lberki@google.com
paulduffin@google.com
diff --git a/README.md b/README.md
index b7e93f4..10ddd73 100644
--- a/README.md
+++ b/README.md
@@ -213,8 +213,8 @@
A module name's **scope** is the smallest namespace containing it. Suppose a
source tree has `device/my` and `device/my/display` namespaces. If `libfoo`
-module is defined in `device/co/display/lib/Android.bp`, its namespace is
-`device/co/display`.
+module is defined in `device/my/display/lib/Android.bp`, its namespace is
+`device/my/display`.
The name uniqueness thus means that module's name is unique within its scope. In
other words, "//_scope_:_name_" is globally unique module reference, e.g,
diff --git a/android/Android.bp b/android/Android.bp
index 5d0f2b9..1bccd7b 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -17,6 +17,8 @@
"soong-response",
"soong-shared",
"soong-ui-metrics_proto",
+ "golang-protobuf-proto",
+ "golang-protobuf-encoding-prototext",
],
srcs: [
"androidmk.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index 557e7ba..f032f1b 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -486,9 +486,9 @@
if a.Include == "" {
a.Include = "$(BUILD_PREBUILT)"
}
- a.Required = append(a.Required, amod.commonProperties.Required...)
- a.Host_required = append(a.Host_required, amod.commonProperties.Host_required...)
- a.Target_required = append(a.Target_required, amod.commonProperties.Target_required...)
+ 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()...)
for _, distString := range a.GetDistForGoals(mod) {
fmt.Fprintf(&a.header, distString)
diff --git a/android/apex.go b/android/apex.go
index 4618fe9..b9efe4e 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -54,6 +54,10 @@
// True if this module comes from an updatable apexBundle.
Updatable bool
+ // True if this module can use private platform APIs. Only non-updatable APEX can set this
+ // to true.
+ UsePlatformApis bool
+
// The list of SDK modules that the containing apexBundle depends on.
RequiredSdks SdkRefs
@@ -87,16 +91,31 @@
var ApexInfoProvider = blueprint.NewMutatorProvider(ApexInfo{}, "apex")
+func (i ApexInfo) AddJSONData(d *map[string]interface{}) {
+ (*d)["Apex"] = map[string]interface{}{
+ "ApexVariationName": i.ApexVariationName,
+ "MinSdkVersion": i.MinSdkVersion,
+ "InApexModules": i.InApexModules,
+ "InApexVariants": i.InApexVariants,
+ "ForPrebuiltApex": i.ForPrebuiltApex,
+ }
+}
+
// mergedName gives the name of the alias variation that will be used when multiple apex variations
// of a module can be deduped into one variation. For example, if libfoo is included in both apex.a
// and apex.b, and if the two APEXes have the same min_sdk_version (say 29), then libfoo doesn't
// have to be built twice, but only once. In that case, the two apex variations apex.a and apex.b
-// are configured to have the same alias variation named apex29.
+// are configured to have the same alias variation named apex29. Whether platform APIs is allowed
+// or not also matters; if two APEXes don't have the same allowance, they get different names and
+// thus wouldn't be merged.
func (i ApexInfo) mergedName(ctx PathContext) string {
name := "apex" + strconv.Itoa(i.MinSdkVersion.FinalOrFutureInt())
for _, sdk := range i.RequiredSdks {
name += "_" + sdk.Name + "_" + sdk.Version
}
+ if i.UsePlatformApis {
+ name += "_private"
+ }
return name
}
@@ -527,6 +546,10 @@
merged[index].InApexModules = append(merged[index].InApexModules, apexInfo.InApexModules...)
merged[index].ApexContents = append(merged[index].ApexContents, apexInfo.ApexContents...)
merged[index].Updatable = merged[index].Updatable || apexInfo.Updatable
+ if merged[index].UsePlatformApis != apexInfo.UsePlatformApis {
+ panic(fmt.Errorf("variants having different UsePlatformApis can't be merged"))
+ }
+ merged[index].UsePlatformApis = apexInfo.UsePlatformApis
} else {
seen[mergedName] = len(merged)
apexInfo.ApexVariationName = mergedName
diff --git a/android/apex_test.go b/android/apex_test.go
index e112369..60a639b 100644
--- a/android/apex_test.go
+++ b/android/apex_test.go
@@ -33,10 +33,10 @@
{
name: "single",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"foo", FutureApiLevel, false, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"apex10000", FutureApiLevel, false, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
},
wantAliases: [][2]string{
{"foo", "apex10000"},
@@ -45,11 +45,11 @@
{
name: "merge",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, SdkRefs{{"baz", "1"}}, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
- {"bar", FutureApiLevel, false, SdkRefs{{"baz", "1"}}, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ {"foo", FutureApiLevel, false, false, SdkRefs{{"baz", "1"}}, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"bar", FutureApiLevel, false, false, SdkRefs{{"baz", "1"}}, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
},
wantMerged: []ApexInfo{
- {"apex10000_baz_1", FutureApiLevel, false, SdkRefs{{"baz", "1"}}, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, false}},
+ {"apex10000_baz_1", FutureApiLevel, false, false, SdkRefs{{"baz", "1"}}, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, false}},
wantAliases: [][2]string{
{"bar", "apex10000_baz_1"},
{"foo", "apex10000_baz_1"},
@@ -58,12 +58,12 @@
{
name: "don't merge version",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
- {"bar", uncheckedFinalApiLevel(30), false, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ {"foo", FutureApiLevel, false, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"bar", uncheckedFinalApiLevel(30), false, false, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
},
wantMerged: []ApexInfo{
- {"apex30", uncheckedFinalApiLevel(30), false, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
- {"apex10000", FutureApiLevel, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"apex30", uncheckedFinalApiLevel(30), false, false, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ {"apex10000", FutureApiLevel, false, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
},
wantAliases: [][2]string{
{"bar", "apex30"},
@@ -73,11 +73,11 @@
{
name: "merge updatable",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
- {"bar", FutureApiLevel, true, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ {"foo", FutureApiLevel, false, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"bar", FutureApiLevel, true, false, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, true, nil, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
+ {"apex10000", FutureApiLevel, true, false, nil, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
},
wantAliases: [][2]string{
{"bar", "apex10000"},
@@ -87,12 +87,12 @@
{
name: "don't merge sdks",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, SdkRefs{{"baz", "1"}}, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
- {"bar", FutureApiLevel, false, SdkRefs{{"baz", "2"}}, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ {"foo", FutureApiLevel, false, false, SdkRefs{{"baz", "1"}}, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"bar", FutureApiLevel, false, false, SdkRefs{{"baz", "2"}}, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
},
wantMerged: []ApexInfo{
- {"apex10000_baz_2", FutureApiLevel, false, SdkRefs{{"baz", "2"}}, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
- {"apex10000_baz_1", FutureApiLevel, false, SdkRefs{{"baz", "1"}}, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"apex10000_baz_2", FutureApiLevel, false, false, SdkRefs{{"baz", "2"}}, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ {"apex10000_baz_1", FutureApiLevel, false, false, SdkRefs{{"baz", "1"}}, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
},
wantAliases: [][2]string{
{"bar", "apex10000_baz_2"},
@@ -102,21 +102,36 @@
{
name: "don't merge when for prebuilt_apex",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
- {"bar", FutureApiLevel, true, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ {"foo", FutureApiLevel, false, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"bar", FutureApiLevel, true, false, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
// This one should not be merged in with the others because it is for
// a prebuilt_apex.
- {"baz", FutureApiLevel, true, nil, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex},
+ {"baz", FutureApiLevel, true, false, nil, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex},
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, true, nil, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
- {"baz", FutureApiLevel, true, nil, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex},
+ {"apex10000", FutureApiLevel, true, false, nil, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
+ {"baz", FutureApiLevel, true, false, nil, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex},
},
wantAliases: [][2]string{
{"bar", "apex10000"},
{"foo", "apex10000"},
},
},
+ {
+ name: "don't merge different UsePlatformApis",
+ in: []ApexInfo{
+ {"foo", FutureApiLevel, false, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"bar", FutureApiLevel, false, true, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ },
+ wantMerged: []ApexInfo{
+ {"apex10000_private", FutureApiLevel, false, true, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ {"apex10000", FutureApiLevel, false, false, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ },
+ wantAliases: [][2]string{
+ {"bar", "apex10000_private"},
+ {"foo", "apex10000"},
+ },
+ },
}
for _, tt := range tests {
diff --git a/android/arch.go b/android/arch.go
index bb1b613..7ca7336 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -21,6 +21,8 @@
"runtime"
"strings"
+ "android/soong/bazel"
+
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/proptools"
@@ -253,7 +255,7 @@
// Linux returns true if the OS uses the Linux kernel, i.e. if the OS is Android or is Linux
// with or without the Bionic libc runtime.
func (os OsType) Linux() bool {
- return os == Android || os == Linux || os == LinuxBionic
+ return os == Android || os == Linux || os == LinuxBionic || os == LinuxMusl
}
// newOsType constructs an OsType and adds it to the global lists.
@@ -289,28 +291,6 @@
return NoOsType
}
-// BuildOs returns the OsType for the OS that the build is running on.
-var BuildOs = func() OsType {
- switch runtime.GOOS {
- case "linux":
- return Linux
- case "darwin":
- return Darwin
- default:
- panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
- }
-}()
-
-// BuildArch returns the ArchType for the CPU that the build is running on.
-var BuildArch = func() ArchType {
- switch runtime.GOARCH {
- case "amd64":
- return X86_64
- default:
- panic(fmt.Sprintf("unsupported Arch: %s", runtime.GOARCH))
- }
-}()
-
var (
// osTypeList contains a list of all the supported OsTypes, including ones not supported
// by the current build host or the target device.
@@ -325,6 +305,8 @@
NoOsType OsType
// Linux is the OS for the Linux kernel plus the glibc runtime.
Linux = newOsType("linux_glibc", Host, false, X86, X86_64)
+ // LinuxMusl is the OS for the Linux kernel plus the musl runtime.
+ LinuxMusl = newOsType("linux_musl", Host, false, X86, X86_64)
// Darwin is the OS for MacOS/Darwin host machines.
Darwin = newOsType("darwin", Host, false, X86_64)
// LinuxBionic is the OS for the Linux kernel plus the Bionic libc runtime, but without the
@@ -335,8 +317,6 @@
// Android is the OS for target devices that run all of Android, including the Linux kernel
// and the Bionic libc runtime.
Android = newOsType("android", Device, false, Arm, Arm64, X86, X86_64)
- // Fuchsia is the OS for target devices that run Fuchsia.
- Fuchsia = newOsType("fuchsia", Device, false, Arm64, X86_64)
// CommonOS is a pseudo OSType for a common OS variant, which is OsType agnostic and which
// has dependencies on all the OS variants.
@@ -885,6 +865,8 @@
"Android64",
"Android32",
"Bionic",
+ "Glibc",
+ "Musl",
"Linux",
"Not_windows",
"Arm_on_x86",
@@ -897,7 +879,7 @@
// Add the OS/Arch combinations, e.g. "android_arm64".
for _, archType := range osArchTypeMap[os] {
- targets = append(targets, os.Field+"_"+archType.Name)
+ targets = append(targets, GetCompoundTargetField(os, archType))
// Also add the special "linux_<arch>" and "bionic_<arch>" property structs.
if os.Linux() {
@@ -1055,24 +1037,28 @@
// Returns the immediate child of the input property struct that corresponds to
// the sub-property "field".
func getChildPropertyStruct(ctx ArchVariantContext,
- src reflect.Value, field, userFriendlyField string) reflect.Value {
+ src reflect.Value, field, userFriendlyField string) (reflect.Value, bool) {
// Step into non-nil pointers to structs in the src value.
if src.Kind() == reflect.Ptr {
if src.IsNil() {
- return src
+ return reflect.Value{}, false
}
src = src.Elem()
}
// Find the requested field in the src struct.
- src = src.FieldByName(proptools.FieldNameForProperty(field))
- if !src.IsValid() {
+ child := src.FieldByName(proptools.FieldNameForProperty(field))
+ if !child.IsValid() {
ctx.ModuleErrorf("field %q does not exist", userFriendlyField)
- return src
+ return reflect.Value{}, false
}
- return src
+ if child.IsZero() {
+ return reflect.Value{}, false
+ }
+
+ return child, true
}
// Squash the appropriate OS-specific property structs into the matching top level property structs
@@ -1099,8 +1085,9 @@
if os.Class == Host {
field := "Host"
prefix := "target.host"
- hostProperties := getChildPropertyStruct(ctx, targetProp, field, prefix)
- mergePropertyStruct(ctx, genProps, hostProperties)
+ if hostProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, hostProperties)
+ }
}
// Handle target OS generalities of the form:
@@ -1112,15 +1099,41 @@
if os.Linux() {
field := "Linux"
prefix := "target.linux"
- linuxProperties := getChildPropertyStruct(ctx, targetProp, field, prefix)
- mergePropertyStruct(ctx, genProps, linuxProperties)
+ if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, linuxProperties)
+ }
}
if os.Bionic() {
field := "Bionic"
prefix := "target.bionic"
- bionicProperties := getChildPropertyStruct(ctx, targetProp, field, prefix)
- mergePropertyStruct(ctx, genProps, bionicProperties)
+ if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, bionicProperties)
+ }
+ }
+
+ if os == Linux {
+ field := "Glibc"
+ prefix := "target.glibc"
+ if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, bionicProperties)
+ }
+ }
+
+ if os == LinuxMusl {
+ field := "Musl"
+ prefix := "target.musl"
+ if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, bionicProperties)
+ }
+
+ // Special case: to ease the transition from glibc to musl, apply linux_glibc
+ // properties (which has historically mean host linux) to musl variants.
+ field = "Linux_glibc"
+ prefix = "target.linux_glibc"
+ if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, bionicProperties)
+ }
}
// Handle target OS properties in the form:
@@ -1137,14 +1150,16 @@
// },
field := os.Field
prefix := "target." + os.Name
- osProperties := getChildPropertyStruct(ctx, targetProp, field, prefix)
- mergePropertyStruct(ctx, genProps, osProperties)
+ if osProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, osProperties)
+ }
if os.Class == Host && os != Windows {
field := "Not_windows"
prefix := "target.not_windows"
- notWindowsProperties := getChildPropertyStruct(ctx, targetProp, field, prefix)
- mergePropertyStruct(ctx, genProps, notWindowsProperties)
+ if notWindowsProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, notWindowsProperties)
+ }
}
// Handle 64-bit device properties in the form:
@@ -1164,13 +1179,15 @@
if ctx.Config().Android64() {
field := "Android64"
prefix := "target.android64"
- android64Properties := getChildPropertyStruct(ctx, targetProp, field, prefix)
- mergePropertyStruct(ctx, genProps, android64Properties)
+ if android64Properties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, android64Properties)
+ }
} else {
field := "Android32"
prefix := "target.android32"
- android32Properties := getChildPropertyStruct(ctx, targetProp, field, prefix)
- mergePropertyStruct(ctx, genProps, android32Properties)
+ if android32Properties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
+ mergePropertyStruct(ctx, genProps, android32Properties)
+ }
}
}
}
@@ -1186,12 +1203,11 @@
// },
// This struct will also contain sub-structs containing to the architecture/CPU
// variants and features that themselves contain properties specific to those.
-func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) reflect.Value {
+func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) {
archPropValues := reflect.ValueOf(archProperties).Elem()
archProp := archPropValues.FieldByName("Arch").Elem()
prefix := "arch." + archType.Name
- archStruct := getChildPropertyStruct(ctx, archProp, archType.Name, prefix)
- return archStruct
+ return getChildPropertyStruct(ctx, archProp, archType.Name, prefix)
}
// Returns the struct containing the properties specific to a given multilib
@@ -1201,11 +1217,14 @@
// key: value,
// },
// },
-func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) reflect.Value {
+func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) {
archPropValues := reflect.ValueOf(archProperties).Elem()
multilibProp := archPropValues.FieldByName("Multilib").Elem()
- multilibProperties := getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib)
- return multilibProperties
+ return getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib)
+}
+
+func GetCompoundTargetField(os OsType, arch ArchType) string {
+ return os.Field + "_" + arch.Name
}
// Returns the structs corresponding to the properties specific to the given
@@ -1219,58 +1238,64 @@
archType := arch.ArchType
if arch.ArchType != Common {
- archStruct := getArchTypeStruct(ctx, archProperties, arch.ArchType)
- result = append(result, archStruct)
+ archStruct, ok := getArchTypeStruct(ctx, archProperties, arch.ArchType)
+ if ok {
+ result = append(result, archStruct)
- // Handle arch-variant-specific properties in the form:
- // arch: {
- // arm: {
- // variant: {
- // key: value,
- // },
- // },
- // },
- v := variantReplacer.Replace(arch.ArchVariant)
- if v != "" {
- prefix := "arch." + archType.Name + "." + v
- variantProperties := getChildPropertyStruct(ctx, archStruct, v, prefix)
- result = append(result, variantProperties)
- }
+ // Handle arch-variant-specific properties in the form:
+ // arch: {
+ // arm: {
+ // variant: {
+ // key: value,
+ // },
+ // },
+ // },
+ v := variantReplacer.Replace(arch.ArchVariant)
+ if v != "" {
+ prefix := "arch." + archType.Name + "." + v
+ if variantProperties, ok := getChildPropertyStruct(ctx, archStruct, v, prefix); ok {
+ result = append(result, variantProperties)
+ }
+ }
- // Handle cpu-variant-specific properties in the form:
- // arch: {
- // arm: {
- // variant: {
- // key: value,
- // },
- // },
- // },
- if arch.CpuVariant != arch.ArchVariant {
- c := variantReplacer.Replace(arch.CpuVariant)
- if c != "" {
- prefix := "arch." + archType.Name + "." + c
- cpuVariantProperties := getChildPropertyStruct(ctx, archStruct, c, prefix)
- result = append(result, cpuVariantProperties)
+ // Handle cpu-variant-specific properties in the form:
+ // arch: {
+ // arm: {
+ // variant: {
+ // key: value,
+ // },
+ // },
+ // },
+ if arch.CpuVariant != arch.ArchVariant {
+ c := variantReplacer.Replace(arch.CpuVariant)
+ if c != "" {
+ prefix := "arch." + archType.Name + "." + c
+ if cpuVariantProperties, ok := getChildPropertyStruct(ctx, archStruct, c, prefix); ok {
+ result = append(result, cpuVariantProperties)
+ }
+ }
+ }
+
+ // Handle arch-feature-specific properties in the form:
+ // arch: {
+ // arm: {
+ // feature: {
+ // key: value,
+ // },
+ // },
+ // },
+ for _, feature := range arch.ArchFeatures {
+ prefix := "arch." + archType.Name + "." + feature
+ if featureProperties, ok := getChildPropertyStruct(ctx, archStruct, feature, prefix); ok {
+ result = append(result, featureProperties)
+ }
}
}
- // Handle arch-feature-specific properties in the form:
- // arch: {
- // arm: {
- // feature: {
- // key: value,
- // },
- // },
- // },
- for _, feature := range arch.ArchFeatures {
- prefix := "arch." + archType.Name + "." + feature
- featureProperties := getChildPropertyStruct(ctx, archStruct, feature, prefix)
- result = append(result, featureProperties)
+ if multilibProperties, ok := getMultilibStruct(ctx, archProperties, archType); ok {
+ result = append(result, multilibProperties)
}
- multilibProperties := getMultilibStruct(ctx, archProperties, archType)
- result = append(result, multilibProperties)
-
// Handle combined OS-feature and arch specific properties in the form:
// target: {
// bionic_x86: {
@@ -1280,15 +1305,17 @@
if os.Linux() {
field := "Linux_" + arch.ArchType.Name
userFriendlyField := "target.linux_" + arch.ArchType.Name
- linuxProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField)
- result = append(result, linuxProperties)
+ if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
+ result = append(result, linuxProperties)
+ }
}
if os.Bionic() {
field := "Bionic_" + archType.Name
userFriendlyField := "target.bionic_" + archType.Name
- bionicProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField)
- result = append(result, bionicProperties)
+ if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
+ result = append(result, bionicProperties)
+ }
}
// Handle combined OS and arch specific properties in the form:
@@ -1306,10 +1333,21 @@
// key: value,
// },
// },
- field := os.Field + "_" + archType.Name
+ field := GetCompoundTargetField(os, archType)
userFriendlyField := "target." + os.Name + "_" + archType.Name
- osArchProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField)
- result = append(result, osArchProperties)
+ if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
+ result = append(result, osArchProperties)
+ }
+
+ if os == LinuxMusl {
+ // Special case: to ease the transition from glibc to musl, apply linux_glibc
+ // properties (which has historically mean host linux) to musl variants.
+ field := "Linux_glibc_" + archType.Name
+ userFriendlyField := "target.linux_glibc_" + archType.Name
+ if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
+ result = append(result, osArchProperties)
+ }
+ }
}
// Handle arm on x86 properties in the form:
@@ -1326,21 +1364,24 @@
hasArmAndroidArch(ctx.Config().Targets[Android])) {
field := "Arm_on_x86"
userFriendlyField := "target.arm_on_x86"
- armOnX86Properties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField)
- result = append(result, armOnX86Properties)
+ if armOnX86Properties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
+ result = append(result, armOnX86Properties)
+ }
}
if arch.ArchType == X86_64 && (hasArmAbi(arch) ||
hasArmAndroidArch(ctx.Config().Targets[Android])) {
field := "Arm_on_x86_64"
userFriendlyField := "target.arm_on_x86_64"
- armOnX8664Properties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField)
- result = append(result, armOnX8664Properties)
+ if armOnX8664Properties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
+ result = append(result, armOnX8664Properties)
+ }
}
if os == Android && nativeBridgeEnabled {
userFriendlyField := "Native_bridge"
prefix := "target.native_bridge"
- nativeBridgeProperties := getChildPropertyStruct(ctx, targetProp, userFriendlyField, prefix)
- result = append(result, nativeBridgeProperties)
+ if nativeBridgeProperties, ok := getChildPropertyStruct(ctx, targetProp, userFriendlyField, prefix); ok {
+ result = append(result, nativeBridgeProperties)
+ }
}
}
@@ -1371,6 +1412,34 @@
}
}
+// determineBuildOS stores the OS and architecture used for host targets used during the build into
+// config based on the runtime OS and architecture determined by Go and the product configuration.
+func determineBuildOS(config *config) {
+ config.BuildOS = func() OsType {
+ switch runtime.GOOS {
+ case "linux":
+ if Bool(config.productVariables.HostMusl) {
+ return LinuxMusl
+ }
+ return Linux
+ case "darwin":
+ return Darwin
+ default:
+ panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
+ }
+ }()
+
+ config.BuildArch = func() ArchType {
+ switch runtime.GOARCH {
+ case "amd64":
+ return X86_64
+ default:
+ panic(fmt.Sprintf("unsupported Arch: %s", runtime.GOARCH))
+ }
+ }()
+
+}
+
// Convert the arch product variables into a list of targets for each OsType.
func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) {
variables := config.productVariables
@@ -1404,9 +1473,9 @@
hostCross := false
if os.Class == Host {
var osSupported bool
- if os == BuildOs {
+ if os == config.BuildOS {
osSupported = true
- } else if BuildOs.Linux() && os.Linux() {
+ } else if config.BuildOS.Linux() && os.Linux() {
// LinuxBionic and Linux are compatible
osSupported = true
} else {
@@ -1444,11 +1513,11 @@
}
// The primary host target, which must always exist.
- addTarget(BuildOs, *variables.HostArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
+ addTarget(config.BuildOS, *variables.HostArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
// An optional secondary host target.
if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" {
- addTarget(BuildOs, *variables.HostSecondaryArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
+ addTarget(config.BuildOS, *variables.HostSecondaryArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
}
// Optional cross-compiled host targets, generally Windows.
@@ -1473,13 +1542,8 @@
// Optional device targets
if variables.DeviceArch != nil && *variables.DeviceArch != "" {
- var target = Android
- if Bool(variables.Fuchsia) {
- target = Fuchsia
- }
-
// The primary device target.
- addTarget(target, *variables.DeviceArch, variables.DeviceArchVariant,
+ addTarget(Android, *variables.DeviceArch, variables.DeviceArchVariant,
variables.DeviceCpuVariant, variables.DeviceAbi, NativeBridgeDisabled, nil, nil)
// An optional secondary device target.
@@ -1540,23 +1604,26 @@
abi []string
}
-// getNdkAbisConfig returns a list of archConfigs for the ABIs supported by the NDK.
+// getNdkAbisConfig returns the list of archConfigs that are used for bulding
+// the API stubs and static libraries that are included in the NDK. These are
+// built *without Neon*, because non-Neon is still supported and building these
+// with Neon will break those users.
func getNdkAbisConfig() []archConfig {
return []archConfig{
- {"arm", "armv7-a", "", []string{"armeabi-v7a"}},
{"arm64", "armv8-a-branchprot", "", []string{"arm64-v8a"}},
- {"x86", "", "", []string{"x86"}},
+ {"arm", "armv7-a", "", []string{"armeabi-v7a"}},
{"x86_64", "", "", []string{"x86_64"}},
+ {"x86", "", "", []string{"x86"}},
}
}
// getAmlAbisConfig returns a list of archConfigs for the ABIs supported by mainline modules.
func getAmlAbisConfig() []archConfig {
return []archConfig{
- {"arm", "armv7-a-neon", "", []string{"armeabi-v7a"}},
{"arm64", "armv8-a", "", []string{"arm64-v8a"}},
- {"x86", "", "", []string{"x86"}},
+ {"arm", "armv7-a-neon", "", []string{"armeabi-v7a"}},
{"x86_64", "", "", []string{"x86_64"}},
+ {"x86", "", "", []string{"x86"}},
}
}
@@ -1857,25 +1924,38 @@
PropertyErrorf(property, fmt string, args ...interface{})
}
-// GetArchProperties returns a map of architectures to the values of the
-// properties of the 'propertySet' struct that are specific to that architecture.
+// ArchVariantProperties represents a map of arch-variant config strings to a property interface{}.
+type ArchVariantProperties map[string]interface{}
+
+// ConfigurationAxisToArchVariantProperties represents a map of bazel.ConfigurationAxis to
+// ArchVariantProperties, such that each independent arch-variant axis maps to the
+// configs/properties for that axis.
+type ConfigurationAxisToArchVariantProperties map[bazel.ConfigurationAxis]ArchVariantProperties
+
+// GetArchVariantProperties returns a ConfigurationAxisToArchVariantProperties where the
+// arch-variant properties correspond to the values of the properties of the 'propertySet' struct
+// that are specific to that axis/configuration. Each axis is independent, containing
+// non-overlapping configs that correspond to the various "arch-variant" support, at this time:
+// arches (including multilib)
+// oses
+// arch+os combinations
//
-// For example, passing a struct { Foo bool, Bar string } will return an
-// interface{} that can be type asserted back into the same struct, containing
-// the arch specific property value specified by the module if defined.
+// For example, passing a struct { Foo bool, Bar string } will return an interface{} that can be
+// type asserted back into the same struct, containing the config-specific property value specified
+// by the module if defined.
//
// Arch-specific properties may come from an arch stanza or a multilib stanza; properties
// in these stanzas are combined.
// For example: `arch: { x86: { Foo: ["bar"] } }, multilib: { lib32: {` Foo: ["baz"] } }`
// will result in `Foo: ["bar", "baz"]` being returned for architecture x86, if the given
// propertyset contains `Foo []string`.
-func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet interface{}) map[ArchType]interface{} {
+func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySet interface{}) ConfigurationAxisToArchVariantProperties {
// Return value of the arch types to the prop values for that arch.
- archToProp := map[ArchType]interface{}{}
+ axisToProps := ConfigurationAxisToArchVariantProperties{}
// Nothing to do for non-arch-specific modules.
if !m.ArchSpecific() {
- return archToProp
+ return axisToProps
}
dstType := reflect.ValueOf(propertySet).Type()
@@ -1893,9 +1973,10 @@
if archProperties == nil {
// This module does not have the property set requested
- return archToProp
+ return axisToProps
}
+ archToProp := ArchVariantProperties{}
// For each arch type (x86, arm64, etc.)
for _, arch := range ArchTypeList() {
// Arch properties are sometimes sharded (see createArchPropTypeDesc() ).
@@ -1903,9 +1984,14 @@
// input one that contains the data specific to that arch.
propertyStructs := make([]reflect.Value, 0)
for _, archProperty := range archProperties {
- archTypeStruct := getArchTypeStruct(ctx, archProperty, arch)
- multilibStruct := getMultilibStruct(ctx, archProperty, arch)
- propertyStructs = append(propertyStructs, archTypeStruct, multilibStruct)
+ archTypeStruct, ok := getArchTypeStruct(ctx, archProperty, arch)
+ if ok {
+ propertyStructs = append(propertyStructs, archTypeStruct)
+ }
+ multilibStruct, ok := getMultilibStruct(ctx, archProperty, arch)
+ if ok {
+ propertyStructs = append(propertyStructs, multilibStruct)
+ }
}
// Create a new instance of the requested property set
@@ -1916,95 +2002,68 @@
mergePropertyStruct(ctx, value, propertyStruct)
}
- archToProp[arch] = value
+ archToProp[arch.Name] = value
}
+ axisToProps[bazel.ArchConfigurationAxis] = archToProp
- return archToProp
-}
-
-// GetTargetProperties returns a map of OS target (e.g. android, windows) to the
-// values of the properties of the 'dst' struct that are specific to that OS
-// target.
-//
-// For example, passing a struct { Foo bool, Bar string } will return an
-// interface{} that can be type asserted back into the same struct, containing
-// the os-specific property value specified by the module if defined.
-//
-// While this looks similar to GetArchProperties, the internal representation of
-// the properties have a slightly different layout to warrant a standalone
-// lookup function.
-func (m *ModuleBase) GetTargetProperties(dst interface{}) map[OsType]interface{} {
- // Return value of the arch types to the prop values for that arch.
- osToProp := map[OsType]interface{}{}
-
- // Nothing to do for non-OS/arch-specific modules.
- if !m.ArchSpecific() {
- return osToProp
- }
-
- // archProperties has the type of [][]interface{}. Looks complicated, so
- // let's explain this step by step.
- //
- // Loop over the outer index, which determines the property struct that
- // contains a matching set of properties in dst that we're interested in.
- // For example, BaseCompilerProperties or BaseLinkerProperties.
- for i := range m.archProperties {
- if m.archProperties[i] == nil {
+ osToProp := ArchVariantProperties{}
+ archOsToProp := ArchVariantProperties{}
+ // For android, linux, ...
+ for _, os := range osTypeList {
+ if os == CommonOS {
+ // It looks like this OS value is not used in Blueprint files
continue
}
-
- // Iterate over the supported OS types
- for _, os := range osTypeList {
- // e.g android, linux_bionic
- field := os.Field
-
- // If it's not nil, loop over the inner index, which determines the arch variant
- // of the prop type. In an Android.bp file, this is like looping over:
- //
- // target: { android: { key: value, ... }, linux_bionic: { key: value, ... } }
- for _, archProperties := range m.archProperties[i] {
- archPropValues := reflect.ValueOf(archProperties).Elem()
-
- // This is the archPropRoot struct. Traverse into the Targetnested struct.
- src := archPropValues.FieldByName("Target").Elem()
-
- // Step into non-nil pointers to structs in the src value.
- if src.Kind() == reflect.Ptr {
- if src.IsNil() {
- continue
- }
- src = src.Elem()
- }
-
- // Find the requested field (e.g. android, linux_bionic) in the src struct.
- src = src.FieldByName(field)
-
- // Validation steps. We want valid non-nil pointers to structs.
- if !src.IsValid() || src.IsNil() {
- continue
- }
-
- if src.Kind() != reflect.Ptr || src.Elem().Kind() != reflect.Struct {
- continue
- }
-
- // Clone the destination prop, since we want a unique prop struct per arch.
- dstClone := reflect.New(reflect.ValueOf(dst).Elem().Type()).Interface()
-
- // Copy the located property struct into the cloned destination property struct.
- err := proptools.ExtendMatchingProperties([]interface{}{dstClone}, src.Interface(), nil, proptools.OrderReplace)
- if err != nil {
- // This is fine, it just means the src struct doesn't match.
- continue
- }
-
- // Found the prop for the os, you have.
- osToProp[os] = dstClone
-
- // Go to the next prop.
- break
- }
+ osToProp[os.Name] = getTargetStruct(ctx, propertySet, archProperties, os.Field)
+ // For arm, x86, ...
+ for _, arch := range osArchTypeMap[os] {
+ targetField := GetCompoundTargetField(os, arch)
+ targetName := fmt.Sprintf("%s_%s", os.Name, arch.Name)
+ archOsToProp[targetName] = getTargetStruct(ctx, propertySet, archProperties, targetField)
}
}
- return osToProp
+ axisToProps[bazel.OsConfigurationAxis] = osToProp
+ axisToProps[bazel.OsArchConfigurationAxis] = archOsToProp
+
+ axisToProps[bazel.BionicConfigurationAxis] = map[string]interface{}{
+ "bionic": getTargetStruct(ctx, propertySet, archProperties, "Bionic"),
+ }
+
+ return axisToProps
+}
+
+// Returns a struct matching the propertySet interface, containing properties specific to the targetName
+// For example, given these arguments:
+// propertySet = BaseCompilerProperties
+// targetName = "android_arm"
+// And given this Android.bp fragment:
+// target:
+// android_arm: {
+// srcs: ["foo.c"],
+// }
+// android_arm64: {
+// srcs: ["bar.c"],
+// }
+// }
+// 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)
+ 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)
+ }
+ }
+
+ // 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)
+ }
+
+ return value
}
diff --git a/android/arch_test.go b/android/arch_test.go
index 3aa4779..a828321 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -473,3 +473,186 @@
})
}
}
+
+type testArchPropertiesModule struct {
+ ModuleBase
+ properties struct {
+ A []string `android:"arch_variant"`
+ }
+}
+
+func (testArchPropertiesModule) GenerateAndroidBuildActions(ctx ModuleContext) {}
+
+func TestArchProperties(t *testing.T) {
+ bp := `
+ module {
+ name: "foo",
+ a: ["root"],
+ arch: {
+ arm: {
+ a: ["arm"],
+ armv7_a_neon: { a: ["armv7_a_neon"] },
+ },
+ arm64: {
+ a: ["arm64"],
+ armv8_a: { a: ["armv8_a"] },
+ },
+ x86: { a: ["x86"] },
+ x86_64: { a: ["x86_64"] },
+ },
+ multilib: {
+ lib32: { a: ["lib32"] },
+ lib64: { a: ["lib64"] },
+ },
+ target: {
+ bionic: { a: ["bionic"] },
+ host: { a: ["host"] },
+ android: { a: ["android"] },
+ glibc: { a: ["glibc"] },
+ musl: { a: ["musl"] },
+ linux_bionic: { a: ["linux_bionic"] },
+ linux: { a: ["linux"] },
+ linux_glibc: { a: ["linux_glibc"] },
+ linux_musl: { a: ["linux_musl"] },
+ windows: { a: ["windows"], enabled: true },
+ darwin: { a: ["darwin"] },
+ not_windows: { a: ["not_windows"] },
+ android32: { a: ["android32"] },
+ android64: { a: ["android64"] },
+ android_arm: { a: ["android_arm"] },
+ android_arm64: { a: ["android_arm64"] },
+ linux_x86: { a: ["linux_x86"] },
+ linux_x86_64: { a: ["linux_x86_64"] },
+ linux_glibc_x86: { a: ["linux_glibc_x86"] },
+ linux_glibc_x86_64: { a: ["linux_glibc_x86_64"] },
+ linux_musl_x86: { a: ["linux_musl_x86"] },
+ linux_musl_x86_64: { a: ["linux_musl_x86_64"] },
+ darwin_x86_64: { a: ["darwin_x86_64"] },
+ windows_x86: { a: ["windows_x86"] },
+ windows_x86_64: { a: ["windows_x86_64"] },
+ },
+ }
+ `
+
+ type result struct {
+ module string
+ variant string
+ property []string
+ }
+
+ testCases := []struct {
+ name string
+ goOS string
+ preparer FixturePreparer
+ results []result
+ }{
+ {
+ name: "default",
+ results: []result{
+ {
+ module: "foo",
+ variant: "android_arm64_armv8-a",
+ property: []string{"root", "linux", "bionic", "android", "android64", "arm64", "armv8_a", "lib64", "android_arm64"},
+ },
+ {
+ module: "foo",
+ variant: "android_arm_armv7-a-neon",
+ property: []string{"root", "linux", "bionic", "android", "android64", "arm", "armv7_a_neon", "lib32", "android_arm"},
+ },
+ },
+ },
+ {
+ name: "linux",
+ goOS: "linux",
+ results: []result{
+ {
+ module: "foo",
+ variant: "linux_glibc_x86_64",
+ property: []string{"root", "host", "linux", "glibc", "linux_glibc", "not_windows", "x86_64", "lib64", "linux_x86_64", "linux_glibc_x86_64"},
+ },
+ {
+ module: "foo",
+ variant: "linux_glibc_x86",
+ property: []string{"root", "host", "linux", "glibc", "linux_glibc", "not_windows", "x86", "lib32", "linux_x86", "linux_glibc_x86"},
+ },
+ },
+ },
+ {
+ name: "windows",
+ goOS: "linux",
+ preparer: FixtureModifyConfig(func(config Config) {
+ config.Targets[Windows] = []Target{
+ {Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", true},
+ {Windows, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", true},
+ }
+ }),
+ results: []result{
+ {
+ module: "foo",
+ variant: "windows_x86_64",
+ property: []string{"root", "host", "windows", "x86_64", "lib64", "windows_x86_64"},
+ },
+ {
+ module: "foo",
+ variant: "windows_x86",
+ property: []string{"root", "host", "windows", "x86", "lib32", "windows_x86"},
+ },
+ },
+ },
+ {
+ name: "linux_musl",
+ goOS: "linux",
+ preparer: FixtureModifyConfig(modifyTestConfigForMusl),
+ results: []result{
+ {
+ module: "foo",
+ variant: "linux_musl_x86_64",
+ property: []string{"root", "host", "linux", "musl", "linux_glibc", "linux_musl", "not_windows", "x86_64", "lib64", "linux_x86_64", "linux_musl_x86_64", "linux_glibc_x86_64"},
+ },
+ {
+ module: "foo",
+ variant: "linux_musl_x86",
+ property: []string{"root", "host", "linux", "musl", "linux_glibc", "linux_musl", "not_windows", "x86", "lib32", "linux_x86", "linux_musl_x86", "linux_glibc_x86"},
+ },
+ },
+ },
+ {
+ name: "darwin",
+ goOS: "darwin",
+ results: []result{
+ {
+ module: "foo",
+ variant: "darwin_x86_64",
+ property: []string{"root", "host", "darwin", "not_windows", "x86_64", "lib64", "darwin_x86_64"},
+ },
+ },
+ },
+ }
+
+ for _, tt := range testCases {
+ t.Run(tt.name, func(t *testing.T) {
+ if tt.goOS != "" && tt.goOS != runtime.GOOS {
+ t.Skipf("test requires runtime.GOOS==%s, got %s", tt.goOS, runtime.GOOS)
+ }
+ result := GroupFixturePreparers(
+ PrepareForTestWithArchMutator,
+ OptionalFixturePreparer(tt.preparer),
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("module", func() Module {
+ module := &testArchPropertiesModule{}
+ module.AddProperties(&module.properties)
+ InitAndroidArchModule(module, HostAndDeviceDefault, MultilibBoth)
+ return module
+ })
+ }),
+ ).RunTestWithBp(t, bp)
+
+ for _, want := range tt.results {
+ t.Run(want.module+"_"+want.variant, func(t *testing.T) {
+ got := result.ModuleForTests(want.module, want.variant).Module().(*testArchPropertiesModule).properties.A
+ AssertArrayString(t, "arch mutator property", want.property, got)
+ })
+ }
+ })
+ }
+}
diff --git a/android/bazel.go b/android/bazel.go
index 9621f3e..7123ed2 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -126,67 +126,56 @@
)
var (
- // Do not write BUILD files for these directories
- // NOTE: this is not recursive
- bp2buildDoNotWriteBuildFileList = []string{
- // Don't generate these BUILD files - because external BUILD files already exist
- "external/boringssl",
- "external/brotli",
- "external/dagger2",
- "external/flatbuffers",
- "external/gflags",
- "external/google-fruit",
- "external/grpc-grpc",
- "external/grpc-grpc/test/core/util",
- "external/grpc-grpc/test/cpp/common",
- "external/grpc-grpc/third_party/address_sorting",
- "external/nanopb-c",
- "external/nos/host/generic",
- "external/nos/host/generic/libnos",
- "external/nos/host/generic/libnos/generator",
- "external/nos/host/generic/libnos_datagram",
- "external/nos/host/generic/libnos_transport",
- "external/nos/host/generic/nugget/proto",
- "external/perfetto",
- "external/protobuf",
- "external/rust/cxx",
- "external/rust/cxx/demo",
- "external/ruy",
- "external/tensorflow",
- "external/tensorflow/tensorflow/lite",
- "external/tensorflow/tensorflow/lite/java",
- "external/tensorflow/tensorflow/lite/kernels",
- "external/tflite-support",
- "external/tinyalsa_new",
- "external/wycheproof",
- "external/libyuv",
+ // Keep any existing BUILD files (and do not generate new BUILD files) for these directories
+ // in the synthetic Bazel workspace.
+ bp2buildKeepExistingBuildFile = map[string]bool{
+ // This is actually build/bazel/build.BAZEL symlinked to ./BUILD
+ ".":/*recursive = */ false,
+
+ // build/bazel/examples/apex/... BUILD files should be generated, so
+ // build/bazel is not recursive. Instead list each subdirectory under
+ // build/bazel explicitly.
+ "build/bazel":/* recursive = */ false,
+ "build/bazel/examples/android_app":/* recursive = */ true,
+ "build/bazel/bazel_skylib":/* recursive = */ true,
+ "build/bazel/rules":/* recursive = */ true,
+ "build/bazel/rules_cc":/* recursive = */ true,
+ "build/bazel/tests":/* recursive = */ true,
+ "build/bazel/platforms":/* recursive = */ true,
+ "build/bazel/product_variables":/* recursive = */ true,
+ "build/pesto":/* recursive = */ true,
+
+ // external/bazelbuild-rules_android/... is needed by mixed builds, otherwise mixed builds analysis fails
+ // e.g. ERROR: Analysis of target '@soong_injection//mixed_builds:buildroot' failed
+ "external/bazelbuild-rules_android":/* recursive = */ true,
+
+ "prebuilts/sdk":/* recursive = */ false,
+ "prebuilts/sdk/tools":/* recursive = */ false,
+ "prebuilts/r8":/* recursive = */ false,
+ "packages/apps/Music":/* recursive = */ false,
}
// Configure modules in these directories to enable bp2build_available: true or false by default.
bp2buildDefaultConfig = Bp2BuildConfig{
- "bionic": Bp2BuildDefaultTrueRecursively,
- "external/gwp_asan": Bp2BuildDefaultTrueRecursively,
- "system/core/libcutils": Bp2BuildDefaultTrueRecursively,
+ "bionic": Bp2BuildDefaultTrueRecursively,
+ "build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
+ "external/gwp_asan": Bp2BuildDefaultTrueRecursively,
+ "system/core/libcutils": Bp2BuildDefaultTrueRecursively,
"system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively,
"system/libbase": Bp2BuildDefaultTrueRecursively,
"system/logging/liblog": Bp2BuildDefaultTrueRecursively,
+ "system/timezone/apex": Bp2BuildDefaultTrueRecursively,
+ "system/timezone/output_data": Bp2BuildDefaultTrueRecursively,
"external/jemalloc_new": Bp2BuildDefaultTrueRecursively,
"external/fmtlib": Bp2BuildDefaultTrueRecursively,
"external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
"external/scudo": Bp2BuildDefaultTrueRecursively,
+ "prebuilts/clang/host/linux-x86": 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.
- "libc_nopthread", // http://b/186821550, cc_library_static, depends on //bionic/libc:libc_bionic_ndk (http://b/186822256)
- // also depends on //bionic/libc:libc_tzcode (http://b/186822591)
- // also depends on //bionic/libc:libstdc++ (http://b/186822597)
- "libc_common", // http://b/186821517, cc_library_static, depends on //bionic/libc:libc_nopthread (http://b/186821550)
- "libc_common_static", // http://b/186824119, cc_library_static, depends on //bionic/libc:libc_common (http://b/186821517)
- "libc_common_shared", // http://b/186824118, cc_library_static, depends on //bionic/libc:libc_common (http://b/186821517)
- "libc_nomalloc", // http://b/186825031, cc_library_static, depends on //bionic/libc:libc_common (http://b/186821517)
-
"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)
@@ -205,12 +194,8 @@
"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_jemalloc_wrapper", // http://b/187012490, cc_library_static, depends on //external/jemalloc_new:libjemalloc5 (http://b/186828626)
- "libc_ndk", // http://b/187013218, cc_library_static, depends on //bionic/libm:libm (http://b/183064661)
- "libc", // http://b/183064430, cc_library, depends on //external/jemalloc_new:libjemalloc5 (http://b/186828626)
- "libc_bionic_ndk", // http://b/186822256, cc_library_static, fatal error: 'generated_android_ids.h' file not found
- "libc_malloc_hooks", // http://b/187016307, cc_library, ld.lld: error: undefined symbol: __malloc_hook
- "libm", // http://b/183064661, cc_library, math.h:25:16: error: unexpected token in argument list
+ "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
@@ -218,7 +203,8 @@
// libcxx
"libBionicBenchmarksUtils", // cc_library_static, fatal error: 'map' file not found, from libcxx
"fmtlib", // cc_library_static, fatal error: 'cassert' file not found, from libcxx
- "libbase", // http://b/186826479, cc_library, fatal error: 'memory' file not found, from libcxx
+ "fmtlib_ndk", // cc_library_static, fatal error: 'cassert' file not found
+ "libbase", // Requires liblog. http://b/186826479, cc_library, fatal error: 'memory' file not found, from libcxx.
// http://b/186024507: Includes errors because of the system_shared_libs default value.
// Missing -isystem bionic/libc/include through the libc/libm/libdl
@@ -229,42 +215,36 @@
"note_memtag_heap_async", // http://b/185127353: cc_library_static, error: feature.h not found
"note_memtag_heap_sync", // http://b/185127353: cc_library_static, error: feature.h not found
+ "gwp_asan_crash_handler", // cc_library, ld.lld: error: undefined symbol: memset
+
// Tests. Handle later.
"libbionic_tests_headers_posix", // http://b/186024507, cc_library_static, sched.h, time.h not found
"libjemalloc5_integrationtest",
"libjemalloc5_stresstestlib",
"libjemalloc5_unittest",
+
+ // APEX support
+ "com.android.runtime", // http://b/194746715, apex, depends on 'libc_malloc_debug' and 'libc_malloc_hooks'
}
// Per-module denylist of cc_library modules to only generate the static
// variant if their shared variant isn't ready or buildable by Bazel.
bp2buildCcLibraryStaticOnlyList = []string{
- "libstdc++", // http://b/186822597, cc_library, ld.lld: error: undefined symbol: __errno
+ "libstdc++", // http://b/186822597, cc_library, ld.lld: error: undefined symbol: __errno
+ "libjemalloc5", // http://b/188503688, cc_library, `target: { android: { enabled: false } }` for android targets.
}
// Per-module denylist to opt modules out of mixed builds. Such modules will
// still be generated via bp2build.
- mixedBuildsDisabledList = []string{
- "libc_netbsd", // lberki@, cc_library_static, version script assignment of 'LIBC_PRIVATE' to symbol 'SHA1Final' failed: symbol not defined
- "libc_openbsd", // ruperts@, cc_library_static, OK for bp2build but error: duplicate symbol: strcpy for mixed builds
- "libsystemproperties", // cparsons@, cc_library_static, wrong include paths
- "libpropertyinfoparser", // cparsons@, cc_library_static, wrong include paths
- "libarm-optimized-routines-string", // jingwen@, cc_library_static, OK for bp2build but b/186615213 (asflags not handled in bp2build), version script assignment of 'LIBC' to symbol 'memcmp' failed: symbol not defined (also for memrchr, strnlen)
- "fmtlib_ndk", // http://b/187040371, cc_library_static, OK for bp2build but format-inl.h:11:10: fatal error: 'cassert' file not found for mixed builds
- }
+ mixedBuildsDisabledList = []string{}
// Used for quicker lookups
- bp2buildDoNotWriteBuildFile = map[string]bool{}
bp2buildModuleDoNotConvert = map[string]bool{}
bp2buildCcLibraryStaticOnly = map[string]bool{}
mixedBuildsDisabled = map[string]bool{}
)
func init() {
- for _, moduleName := range bp2buildDoNotWriteBuildFileList {
- bp2buildDoNotWriteBuildFile[moduleName] = true
- }
-
for _, moduleName := range bp2buildModuleDoNotConvertList {
bp2buildModuleDoNotConvert[moduleName] = true
}
@@ -282,12 +262,21 @@
return bp2buildCcLibraryStaticOnly[ctx.Module().Name()]
}
-func ShouldWriteBuildFileForDir(dir string) bool {
- if _, ok := bp2buildDoNotWriteBuildFile[dir]; ok {
- return false
- } else {
+func ShouldKeepExistingBuildFileForDir(dir string) bool {
+ if _, ok := bp2buildKeepExistingBuildFile[dir]; ok {
+ // Exact dir match
return true
}
+ // Check if subtree match
+ for prefix, recursive := range bp2buildKeepExistingBuildFile {
+ if recursive {
+ if strings.HasPrefix(dir, prefix+"/") {
+ return true
+ }
+ }
+ }
+ // Default
+ return false
}
// MixedBuildsEnabled checks that a module is ready to be replaced by a
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 8cddbb2..341d500 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -205,7 +205,7 @@
func NewBazelContext(c *config) (BazelContext, error) {
// TODO(cparsons): Assess USE_BAZEL=1 instead once "mixed Soong/Bazel builds"
// are production ready.
- if c.Getenv("USE_BAZEL_ANALYSIS") != "1" {
+ if !c.IsEnvTrue("USE_BAZEL_ANALYSIS") {
return noopBazelContext{}, nil
}
@@ -333,7 +333,7 @@
// The actual platform values here may be overridden by configuration
// transitions from the buildroot.
cmdFlags = append(cmdFlags,
- fmt.Sprintf("--platforms=%s", "//build/bazel/platforms:android_x86_64"))
+ fmt.Sprintf("--platforms=%s", "//build/bazel/platforms:android_target"))
cmdFlags = append(cmdFlags,
fmt.Sprintf("--extra_toolchains=%s", "//prebuilts/clang/host/linux-x86:all"))
// This should be parameterized on the host OS, but let's restrict to linux
@@ -351,6 +351,9 @@
"HOME="+paths.homeDir,
pwdPrefix(),
"BUILD_DIR="+absolutePath(paths.buildDir),
+ // Make OUT_DIR absolute here so tools/bazel.sh uses the correct
+ // OUT_DIR at <root>/out, instead of <root>/out/soong/workspace/out.
+ "OUT_DIR="+absolutePath(paths.outDir()),
// Disables local host detection of gcc; toolchain information is defined
// explicitly in BUILD files.
"BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1")
@@ -539,10 +542,13 @@
platform_name = build_options(target)["//command_line_option:platforms"][0].name
if platform_name == "host":
return "HOST"
- elif not platform_name.startswith("android_"):
- fail("expected platform name of the form 'android_<arch>', but was " + str(platforms))
+ elif platform_name.startswith("android_"):
+ return platform_name[len("android_"):]
+ elif platform_name.startswith("linux_"):
+ return platform_name[len("linux_"):]
+ else:
+ fail("expected platform name of the form 'android_<arch>' or 'linux_<arch>', but was " + str(platforms))
return "UNKNOWN"
- return platform_name[len("android_"):]
def format(target):
id_string = str(target.label) + "|" + get_arch(target)
@@ -567,7 +573,7 @@
// Returns the path where the contents of the @soong_injection repository live.
// It is used by Soong to tell Bazel things it cannot over the command line.
func (p *bazelPaths) injectedFilesDir() string {
- return filepath.Join(p.buildDir, "soong_injection")
+ return filepath.Join(p.buildDir, bazel.SoongInjectionDirName)
}
// Returns the path of the synthetic Bazel workspace that contains a symlink
@@ -576,6 +582,11 @@
return filepath.Join(p.buildDir, "workspace")
}
+// Returns the path to the top level out dir ($OUT_DIR).
+func (p *bazelPaths) outDir() string {
+ return filepath.Dir(p.buildDir)
+}
+
// Issues commands to Bazel to receive results for all cquery requests
// queued in the BazelContext.
func (context *bazelContext) InvokeBazel() error {
@@ -734,8 +745,17 @@
}
rule := NewRuleBuilder(pctx, ctx)
cmd := rule.Command()
- cmd.Text(fmt.Sprintf("cd %s/execroot/__main__ && %s",
- ctx.Config().BazelContext.OutputBase(), buildStatement.Command))
+
+ // cd into Bazel's execution root, which is the action cwd.
+ cmd.Text(fmt.Sprintf("cd %s/execroot/__main__ && ", ctx.Config().BazelContext.OutputBase()))
+
+ for _, pair := range buildStatement.Env {
+ // Set per-action env variables, if any.
+ cmd.Flag(pair.Key + "=" + pair.Value)
+ }
+
+ // The actual Bazel action.
+ cmd.Text(" " + buildStatement.Command)
for _, outputPath := range buildStatement.OutputPaths {
cmd.ImplicitOutput(PathForBazelOut(ctx, outputPath))
@@ -748,6 +768,10 @@
cmd.ImplicitDepFile(PathForBazelOut(ctx, *depfile))
}
+ for _, symlinkPath := range buildStatement.SymlinkPaths {
+ cmd.ImplicitSymlinkOutput(PathForBazelOut(ctx, symlinkPath))
+ }
+
// This is required to silence warnings pertaining to unexpected timestamps. Particularly,
// some Bazel builtins (such as files in the bazel_tools directory) have far-future
// timestamps. Without restat, Ninja would emit warnings that the input files of a
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index f4b2a7c..b050774 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -73,6 +73,7 @@
EarlyModulePathContext
GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
+ ModuleFromName(name string) (blueprint.Module, bool)
Module() Module
ModuleType() string
OtherModuleName(m blueprint.Module) string
@@ -83,6 +84,36 @@
// or ":<module>") and returns a Bazel-compatible label which corresponds to dependencies on the
// module within the given ctx.
func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList {
+ return bazelLabelForModuleDeps(ctx, modules, false)
+}
+
+// BazelLabelForModuleWholeDeps expects a list of references to other modules, ("<module>"
+// or ":<module>") and returns a Bazel-compatible label which corresponds to dependencies on the
+// module within the given ctx, where prebuilt dependencies will be appended with _alwayslink so
+// they can be handled as whole static libraries.
+func BazelLabelForModuleWholeDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList {
+ return bazelLabelForModuleDeps(ctx, modules, true)
+}
+
+// BazelLabelForModuleDepsExcludes expects two lists: modules (containing modules to include in the
+// list), and excludes (modules to exclude from the list). Both of these should contain references
+// to other modules, ("<module>" or ":<module>"). It returns a Bazel-compatible label list which
+// corresponds to dependencies on the module within the given ctx, and the excluded dependencies.
+func BazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+ return bazelLabelForModuleDepsExcludes(ctx, modules, excludes, false)
+}
+
+// BazelLabelForModuleWholeDepsExcludes expects two lists: modules (containing modules to include in
+// the list), and excludes (modules to exclude from the list). Both of these should contain
+// references to other modules, ("<module>" or ":<module>"). It returns a Bazel-compatible label
+// list which corresponds to dependencies on the module within the given ctx, and the excluded
+// dependencies. Prebuilt dependencies will be appended with _alwayslink so they can be handled as
+// whole static libraries.
+func BazelLabelForModuleWholeDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+ return bazelLabelForModuleDepsExcludes(ctx, modules, excludes, true)
+}
+
+func bazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string, isWholeLibs bool) bazel.LabelList {
var labels bazel.LabelList
for _, module := range modules {
bpText := module
@@ -90,7 +121,7 @@
module = ":" + module
}
if m, t := SrcIsModuleWithTag(module); m != "" {
- l := getOtherModuleLabel(ctx, m, t)
+ l := getOtherModuleLabel(ctx, m, t, isWholeLibs)
l.OriginalModuleName = bpText
labels.Includes = append(labels.Includes, l)
} else {
@@ -100,10 +131,26 @@
return labels
}
+func bazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string, isWholeLibs bool) bazel.LabelList {
+ moduleLabels := bazelLabelForModuleDeps(ctx, RemoveListFromList(modules, excludes), isWholeLibs)
+ if len(excludes) == 0 {
+ return moduleLabels
+ }
+ excludeLabels := bazelLabelForModuleDeps(ctx, excludes, isWholeLibs)
+ return bazel.LabelList{
+ Includes: moduleLabels.Includes,
+ Excludes: excludeLabels.Includes,
+ }
+}
+
func BazelLabelForModuleSrcSingle(ctx BazelConversionPathContext, path string) bazel.Label {
return BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes[0]
}
+func BazelLabelForModuleDepSingle(ctx BazelConversionPathContext, path string) bazel.Label {
+ return BazelLabelForModuleDepsExcludes(ctx, []string{path}, []string(nil)).Includes[0]
+}
+
// BazelLabelForModuleSrc expects a list of path (relative to local module directory) and module
// references (":<module>") and returns a bazel.LabelList{} containing the resolved references in
// paths, relative to the local module, or Bazel-labels (absolute if in a different package or
@@ -257,7 +304,7 @@
for _, p := range paths {
if m, tag := SrcIsModuleWithTag(p); m != "" {
- l := getOtherModuleLabel(ctx, m, tag)
+ l := getOtherModuleLabel(ctx, m, tag, false)
if !InList(l.Label, expandedExcludes) {
l.OriginalModuleName = fmt.Sprintf(":%s", m)
labels.Includes = append(labels.Includes, l)
@@ -288,15 +335,18 @@
// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the
// module. The label will be relative to the current directory if appropriate. The dependency must
// already be resolved by either deps mutator or path deps mutator.
-func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string) bazel.Label {
- m, _ := ctx.GetDirectDep(dep)
+func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string, isWholeLibs bool) bazel.Label {
+ m, _ := ctx.ModuleFromName(dep)
if m == nil {
- panic(fmt.Errorf(`Cannot get direct dep %q of %q.
- This is likely because it was not added via AddDependency().
- This may be due a mutator skipped during bp2build.`, dep, ctx.Module().Name()))
+ panic(fmt.Errorf("No module named %q found, but was a direct dep of %q", dep, ctx.Module().Name()))
}
otherLabel := bazelModuleLabel(ctx, m, tag)
label := bazelModuleLabel(ctx, ctx.Module(), "")
+ if isWholeLibs {
+ if m, ok := m.(Module); ok && IsModulePrebuilt(m) {
+ otherLabel += "_alwayslink"
+ }
+ }
if samePackage(label, otherLabel) {
otherLabel = bazelShortLabel(otherLabel)
}
diff --git a/android/config.go b/android/config.go
index 24fc522..b3b8f3c 100644
--- a/android/config.go
+++ b/android/config.go
@@ -35,6 +35,7 @@
"github.com/google/blueprint/proptools"
"android/soong/android/soongconfig"
+ "android/soong/bazel"
"android/soong/remoteexec"
)
@@ -107,6 +108,12 @@
ProductVariablesFileName string
+ // BuildOS stores the OsType for the OS that the build is running on.
+ BuildOS OsType
+
+ // BuildArch stores the ArchType for the CPU that the build is running on.
+ BuildArch ArchType
+
Targets map[OsType][]Target
BuildOSTarget Target // the Target for tools run on the build machine
BuildOSCommonTarget Target // the Target for common (java) tools run on the build machine
@@ -169,7 +176,7 @@
// loadFromConfigFile loads and decodes configuration options from a JSON file
// in the current working directory.
-func loadFromConfigFile(configurable jsonConfigurable, filename string) error {
+func loadFromConfigFile(configurable *productVariables, filename string) error {
// Try to open the file
configFileReader, err := os.Open(filename)
defer configFileReader.Close()
@@ -194,13 +201,20 @@
}
}
- // No error
- return nil
+ if Bool(configurable.GcovCoverage) && Bool(configurable.ClangCoverage) {
+ return fmt.Errorf("GcovCoverage and ClangCoverage cannot both be set")
+ }
+
+ configurable.Native_coverage = proptools.BoolPtr(
+ Bool(configurable.GcovCoverage) ||
+ Bool(configurable.ClangCoverage))
+
+ return saveToBazelConfigFile(configurable, filepath.Dir(filename))
}
// atomically writes the config file in case two copies of soong_build are running simultaneously
// (for example, docs generation and ninja manifest generation)
-func saveToConfigFile(config jsonConfigurable, filename string) error {
+func saveToConfigFile(config *productVariables, filename string) error {
data, err := json.MarshalIndent(&config, "", " ")
if err != nil {
return fmt.Errorf("cannot marshal config data: %s", err.Error())
@@ -229,6 +243,35 @@
return nil
}
+func saveToBazelConfigFile(config *productVariables, outDir string) error {
+ dir := filepath.Join(outDir, bazel.SoongInjectionDirName, "product_config")
+ err := createDirIfNonexistent(dir, os.ModePerm)
+ if err != nil {
+ return fmt.Errorf("Could not create dir %s: %s", dir, err)
+ }
+
+ data, err := json.MarshalIndent(&config, "", " ")
+ if err != nil {
+ return fmt.Errorf("cannot marshal config data: %s", err.Error())
+ }
+
+ bzl := []string{
+ bazel.GeneratedBazelFileWarning,
+ fmt.Sprintf(`_product_vars = json.decode("""%s""")`, data),
+ "product_vars = _product_vars\n",
+ }
+ err = ioutil.WriteFile(filepath.Join(dir, "product_variables.bzl"), []byte(strings.Join(bzl, "\n")), 0644)
+ if err != nil {
+ return fmt.Errorf("Could not write .bzl config file %s", err)
+ }
+ err = ioutil.WriteFile(filepath.Join(dir, "BUILD"), []byte(bazel.GeneratedBazelFileWarning), 0644)
+ if err != nil {
+ return fmt.Errorf("Could not write BUILD config file %s", err)
+ }
+
+ return nil
+}
+
// NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that
// use the android package.
func NullConfig(buildDir string) Config {
@@ -289,41 +332,28 @@
return Config{config}
}
-func fuchsiaTargets() map[OsType][]Target {
- return map[OsType][]Target{
- Fuchsia: {
- {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
- },
- BuildOs: {
- {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
- },
- }
-}
-
-var PrepareForTestSetDeviceToFuchsia = FixtureModifyConfig(func(config Config) {
- config.Targets = fuchsiaTargets()
-})
-
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},
{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false},
},
- BuildOs: []Target{
- {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
- {BuildOs, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
+ config.BuildOS: []Target{
+ {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
+ {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
},
}
if runtime.GOOS == "darwin" {
- config.Targets[BuildOs] = config.Targets[BuildOs][:1]
+ config.Targets[config.BuildOS] = config.Targets[config.BuildOS][:1]
}
- config.BuildOSTarget = config.Targets[BuildOs][0]
- config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0]
+ config.BuildOSTarget = config.Targets[config.BuildOS][0]
+ config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0]
config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
@@ -332,6 +362,19 @@
config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon")
}
+func modifyTestConfigForMusl(config Config) {
+ delete(config.Targets, config.BuildOS)
+ config.productVariables.HostMusl = boolPtr(true)
+ determineBuildOS(config.config)
+ config.Targets[config.BuildOS] = []Target{
+ {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
+ {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
+ }
+
+ config.BuildOSTarget = config.Targets[config.BuildOS][0]
+ config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
+}
+
// TestArchConfig returns a Config object suitable for using for tests that
// need to run the arch mutator.
func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
@@ -402,6 +445,8 @@
config.katiEnabled = true
}
+ determineBuildOS(config)
+
// Sets up the map of target OSes to the finer grained compilation targets
// that are configured from the product variables.
targets, err := decodeTargetProductVariables(config)
@@ -439,8 +484,8 @@
config.Targets = targets
// Compilation targets for host tools.
- config.BuildOSTarget = config.Targets[BuildOs][0]
- config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0]
+ config.BuildOSTarget = config.Targets[config.BuildOS][0]
+ config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
// Compilation targets for Android.
if len(config.Targets[Android]) > 0 {
@@ -448,14 +493,6 @@
config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0]
}
- if Bool(config.productVariables.GcovCoverage) && Bool(config.productVariables.ClangCoverage) {
- return Config{}, fmt.Errorf("GcovCoverage and ClangCoverage cannot both be set")
- }
-
- config.productVariables.Native_coverage = proptools.BoolPtr(
- Bool(config.productVariables.GcovCoverage) ||
- Bool(config.productVariables.ClangCoverage))
-
config.BazelContext, err = NewBazelContext(config)
config.bp2buildPackageConfig = bp2buildDefaultConfig
config.bp2buildModuleTypeConfig = make(map[string]bool)
@@ -792,6 +829,12 @@
return Bool(c.productVariables.Unbundled_build_apps)
}
+// Returns true if building image that aren't bundled with the platform.
+// UnbundledBuild() is always true when this is true.
+func (c *config) UnbundledBuildImage() bool {
+ return Bool(c.productVariables.Unbundled_build_image)
+}
+
// Returns true if building modules against prebuilt SDKs.
func (c *config) AlwaysUsePrebuiltSdks() bool {
return Bool(c.productVariables.Always_use_prebuilt_sdks)
@@ -802,10 +845,6 @@
return Bool(c.productVariables.Skip_boot_jars_check)
}
-func (c *config) Fuchsia() bool {
- return Bool(c.productVariables.Fuchsia)
-}
-
func (c *config) MinimizeJavaDebugInfo() bool {
return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng)
}
@@ -1812,16 +1851,16 @@
func (c *config) BootJars() []string {
return c.Once(earlyBootJarsKey, func() interface{} {
list := c.productVariables.BootJars.CopyOfJars()
- return append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...)
+ return append(list, c.productVariables.ApexBootJars.CopyOfJars()...)
}).([]string)
}
-func (c *config) NonUpdatableBootJars() ConfiguredJarList {
+func (c *config) NonApexBootJars() ConfiguredJarList {
return c.productVariables.BootJars
}
-func (c *config) UpdatableBootJars() ConfiguredJarList {
- return c.productVariables.UpdatableBootJars
+func (c *config) ApexBootJars() ConfiguredJarList {
+ return c.productVariables.ApexBootJars
}
func (c *config) RBEWrapper() string {
diff --git a/android/defaults.go b/android/defaults.go
index aacfbac..be80cf1 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -104,6 +104,7 @@
EarlyModuleContext
CreateModule(ModuleFactory, ...interface{}) Module
+ AddMissingDependencies(missingDeps []string)
}
type DefaultableHook func(ctx DefaultableHookContext)
diff --git a/android/filegroup.go b/android/filegroup.go
index fc6850e..e207412 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -63,7 +63,10 @@
Srcs: srcs,
}
- props := bazel.BazelTargetModuleProperties{Rule_class: "filegroup"}
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "filegroup",
+ Bzl_load_location: "//build/bazel/rules:filegroup.bzl",
+ }
ctx.CreateBazelTargetModule(BazelFileGroupFactory, fg.Name(), props, attrs)
}
diff --git a/android/image.go b/android/image.go
index 66101be..bc6b8cd 100644
--- a/android/image.go
+++ b/android/image.go
@@ -43,10 +43,9 @@
// its variation.
ExtraImageVariations(ctx BaseModuleContext) []string
- // SetImageVariation will be passed a newly created recovery variant of the module. ModuleBase implements
- // SetImageVariation, most module types will not need to override it, and those that do must call the
- // overridden method. Implementors of SetImageVariation must be careful to modify the module argument
- // and not the receiver.
+ // SetImageVariation is called for each newly created image variant. The receiver is the original
+ // module, "variation" is the name of the newly created variant and "module" is the newly created
+ // variant itself.
SetImageVariation(ctx BaseModuleContext, variation string, module Module)
}
diff --git a/android/metrics.go b/android/metrics.go
index b7aee54..2cd5efa 100644
--- a/android/metrics.go
+++ b/android/metrics.go
@@ -18,7 +18,7 @@
"io/ioutil"
"runtime"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
)
diff --git a/android/module.go b/android/module.go
index f745a4a..5e2e06a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -223,6 +223,8 @@
// the first DependencyTag.
GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
+ ModuleFromName(name string) (blueprint.Module, bool)
+
// VisitDirectDepsBlueprint calls visit for each direct dependency. If there are multiple
// direct dependencies on the same module visit will be called multiple times on that module
// and OtherModuleDependencyTag will return a different tag for each.
@@ -325,7 +327,6 @@
Host() bool
Device() bool
Darwin() bool
- Fuchsia() bool
Windows() bool
Debug() bool
PrimaryArch() bool
@@ -344,8 +345,18 @@
// Deprecated: use ModuleContext.Build instead.
ModuleBuild(pctx PackageContext, params ModuleBuildParams)
+ // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
+ // be tagged with `android:"path" to support automatic source module dependency resolution.
+ //
+ // Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
ExpandSources(srcFiles, excludes []string) Paths
+
+ // Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
+ // be tagged with `android:"path" to support automatic source module dependency resolution.
+ //
+ // Deprecated: use PathForModuleSrc instead.
ExpandSource(srcFile, prop string) Path
+
ExpandOptionalSource(srcFile *string, prop string) OptionalPath
// InstallExecutable creates a rule to copy srcPath to name in the installPath directory,
@@ -403,6 +414,7 @@
InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
+ InstallInVendor() bool
InstallBypassMake() bool
InstallForceOS() (*OsType, *ArchType)
@@ -461,6 +473,7 @@
InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
+ InstallInVendor() bool
InstallBypassMake() bool
InstallForceOS() (*OsType, *ArchType)
HideFromMake()
@@ -473,6 +486,7 @@
InitRc() Paths
VintfFragments() Paths
NoticeFiles() Paths
+ EffectiveLicenseFiles() Paths
AddProperties(props ...interface{})
GetProperties() []interface{}
@@ -1190,6 +1204,10 @@
vintfFragmentsPaths Paths
}
+func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
+ (*d)["Android"] = map[string]interface{}{}
+}
+
func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
@@ -1501,13 +1519,17 @@
return m.commonProperties.NamespaceExportedToMake
}
+func (m *ModuleBase) EffectiveLicenseFiles() Paths {
+ return m.commonProperties.Effective_license_text
+}
+
// computeInstallDeps finds the installed paths of all dependencies that have a dependency
// tag that is annotated as needing installation via the IsInstallDepNeeded method.
func (m *ModuleBase) computeInstallDeps(ctx ModuleContext) ([]*installPathsDepSet, []*packagingSpecsDepSet) {
var installDeps []*installPathsDepSet
var packagingSpecs []*packagingSpecsDepSet
ctx.VisitDirectDeps(func(dep Module) {
- if IsInstallDepNeeded(ctx.OtherModuleDependencyTag(dep)) && !dep.IsHideFromMake() {
+ if IsInstallDepNeeded(ctx.OtherModuleDependencyTag(dep)) && !dep.IsHideFromMake() && !dep.IsSkipInstall() {
installDeps = append(installDeps, dep.base().installFilesDepSet)
packagingSpecs = append(packagingSpecs, dep.base().packagingSpecsDepSet)
}
@@ -1560,6 +1582,10 @@
return Bool(m.commonProperties.Recovery)
}
+func (m *ModuleBase) InstallInVendor() bool {
+ return Bool(m.commonProperties.Vendor)
+}
+
func (m *ModuleBase) InstallInRoot() bool {
return false
}
@@ -2013,8 +2039,13 @@
tagPath []blueprint.DependencyTag
strictVisitDeps bool // If true, enforce that all dependencies are enabled
+
+ bazelConversionMode bool
}
+func (b *baseModuleContext) BazelConversionMode() bool {
+ return b.bazelConversionMode
+}
func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
return b.bp.OtherModuleName(m)
}
@@ -2354,6 +2385,17 @@
return b.getDirectDepFirstTag(name)
}
+func (b *baseModuleContext) ModuleFromName(name string) (blueprint.Module, bool) {
+ if !b.BazelConversionMode() {
+ panic("cannot call ModuleFromName if not in bazel conversion mode")
+ }
+ if moduleName, _ := SrcIsModuleWithTag(name); moduleName != "" {
+ return b.bp.ModuleFromName(moduleName)
+ } else {
+ return b.bp.ModuleFromName(name)
+ }
+}
+
func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
b.bp.VisitDirectDeps(visit)
}
@@ -2544,10 +2586,6 @@
return b.os == Darwin
}
-func (b *baseModuleContext) Fuchsia() bool {
- return b.os == Fuchsia
-}
-
func (b *baseModuleContext) Windows() bool {
return b.os == Windows
}
@@ -2626,6 +2664,10 @@
return m.module.InstallForceOS()
}
+func (m *moduleContext) InstallInVendor() bool {
+ return m.module.InstallInVendor()
+}
+
func (m *moduleContext) skipInstall() bool {
if m.module.base().commonProperties.SkipInstall {
return true
@@ -2793,42 +2835,101 @@
return m.bp
}
-// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
-// was not a module reference.
+// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name"
+// into the module name, or empty string if the input was not a module reference.
func SrcIsModule(s string) (module string) {
- if len(s) > 1 && s[0] == ':' {
- return s[1:]
+ if len(s) > 1 {
+ if s[0] == ':' {
+ module = s[1:]
+ if !isUnqualifiedModuleName(module) {
+ // The module name should be unqualified but is not so do not treat it as a module.
+ module = ""
+ }
+ } else if s[0] == '/' && s[1] == '/' {
+ module = s
+ }
}
- return ""
+ return module
}
-// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the
-// module name and an empty string for the tag, or empty strings if the input was not a module reference.
+// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or
+// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name"
+// into the module name and an empty string for the tag, or empty strings if the input was not a
+// module reference.
func SrcIsModuleWithTag(s string) (module, tag string) {
- if len(s) > 1 && s[0] == ':' {
- module = s[1:]
- if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
- if module[len(module)-1] == '}' {
- tag = module[tagStart+1 : len(module)-1]
- module = module[:tagStart]
- return module, tag
+ if len(s) > 1 {
+ if s[0] == ':' {
+ module = s[1:]
+ } else if s[0] == '/' && s[1] == '/' {
+ module = s
+ }
+
+ if module != "" {
+ if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
+ if module[len(module)-1] == '}' {
+ tag = module[tagStart+1 : len(module)-1]
+ module = module[:tagStart]
+ }
+ }
+
+ if s[0] == ':' && !isUnqualifiedModuleName(module) {
+ // The module name should be unqualified but is not so do not treat it as a module.
+ module = ""
+ tag = ""
}
}
- return module, ""
}
- return "", ""
+
+ return module, tag
}
+// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e.
+// does not contain any /.
+func isUnqualifiedModuleName(module string) bool {
+ return strings.IndexByte(module, '/') == -1
+}
+
+// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any
+// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps
+// or ExtractSourcesDeps.
+//
+// If uniquely identifies the dependency that was added as it contains both the module name used to
+// add the dependency as well as the tag. That makes it very simple to find the matching dependency
+// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag
+// used to add it. It does not need to check that the module name as returned by one of
+// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the
+// name supplied in the tag. That means it does not need to handle differences in module names
+// caused by prebuilt_ prefix, or fully qualified module names.
type sourceOrOutputDependencyTag struct {
blueprint.BaseDependencyTag
+
+ // The name of the module.
+ moduleName string
+
+ // The tag that will be passed to the module's OutputFileProducer.OutputFiles(tag) method.
tag string
}
-func sourceOrOutputDepTag(tag string) blueprint.DependencyTag {
- return sourceOrOutputDependencyTag{tag: tag}
+func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag {
+ return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag}
}
-var SourceDepTag = sourceOrOutputDepTag("")
+// IsSourceDepTag returns true if the supplied blueprint.DependencyTag is one that was used to add
+// dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for properties
+// tagged with `android:"path"`.
+func IsSourceDepTag(depTag blueprint.DependencyTag) bool {
+ _, ok := depTag.(sourceOrOutputDependencyTag)
+ return ok
+}
+
+// IsSourceDepTagWithOutputTag returns true if the supplied blueprint.DependencyTag is one that was
+// used to add dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for
+// properties tagged with `android:"path"` AND it was added using a module reference of
+// :moduleName{outputTag}.
+func IsSourceDepTagWithOutputTag(depTag blueprint.DependencyTag, outputTag string) bool {
+ t, ok := depTag.(sourceOrOutputDependencyTag)
+ return ok && t.tag == outputTag
+}
// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
// using ":module" syntax, if any.
@@ -2843,7 +2944,7 @@
ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
} else {
set[s] = true
- ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
+ ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
}
}
}
@@ -2856,7 +2957,7 @@
func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
if s != nil {
if m, t := SrcIsModuleWithTag(*s); m != "" {
- ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
+ ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
}
}
}
diff --git a/android/module_test.go b/android/module_test.go
index 9ac9291..9e2b0ca 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -55,6 +55,27 @@
},
wantModule: "foo:bar",
},
+ {
+ name: "fully qualified",
+ args: args{
+ s: "//foo:bar",
+ },
+ wantModule: "//foo:bar",
+ },
+ {
+ name: "fully qualified with tag",
+ args: args{
+ s: "//foo:bar{.tag}",
+ },
+ wantModule: "//foo:bar{.tag}",
+ },
+ {
+ name: "invalid unqualified name",
+ args: args{
+ s: ":foo/bar",
+ },
+ wantModule: "",
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -128,6 +149,35 @@
},
wantModule: "foo.bar}",
},
+ {
+ name: "fully qualified",
+ args: args{
+ s: "//foo:bar",
+ },
+ wantModule: "//foo:bar",
+ },
+ {
+ name: "fully qualified with tag",
+ args: args{
+ s: "//foo:bar{.tag}",
+ },
+ wantModule: "//foo:bar",
+ wantTag: ".tag",
+ },
+ {
+ name: "invalid unqualified name",
+ args: args{
+ s: ":foo/bar",
+ },
+ wantModule: "",
+ },
+ {
+ name: "invalid unqualified name with tag",
+ args: args{
+ s: ":foo/bar{.tag}",
+ },
+ wantModule: "",
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
diff --git a/android/mutator.go b/android/mutator.go
index 365bf29..d895669 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -19,6 +19,7 @@
"fmt"
"reflect"
"strings"
+ "sync"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -34,7 +35,7 @@
// continue on to GenerateAndroidBuildActions
// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
-func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) {
+func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators, bp2buildMutators []RegisterMutatorFunc) {
mctx := ®isterMutatorsContext{
bazelConversionMode: true,
}
@@ -52,16 +53,6 @@
f(mctx)
}
- bp2buildDepsMutators = append([]RegisterMutatorFunc{
- registerDepsMutatorBp2Build,
- registerPathDepsMutator,
- registerBp2buildArchPathDepsMutator,
- }, depsMutators...)
-
- for _, f := range bp2buildDepsMutators {
- f(mctx)
- }
-
// Register bp2build mutators
for _, f := range bp2buildMutators {
f(mctx)
@@ -226,9 +217,11 @@
}
var bp2buildPreArchMutators = []RegisterMutatorFunc{}
-var bp2buildDepsMutators = []RegisterMutatorFunc{}
var bp2buildMutators = map[string]RegisterMutatorFunc{}
+// See http://b/192523357
+var bp2buildLock sync.Mutex
+
// RegisterBp2BuildMutator registers specially crafted mutators for
// converting Blueprint/Android modules into special modules that can
// be code-generated into Bazel BUILD targets.
@@ -238,6 +231,9 @@
f := func(ctx RegisterMutatorsContext) {
ctx.TopDown(moduleType, m)
}
+ // Use a lock to avoid a concurrent map write if RegisterBp2BuildMutator is called in parallel
+ bp2buildLock.Lock()
+ defer bp2buildLock.Unlock()
bp2buildMutators[moduleType] = f
}
@@ -247,12 +243,6 @@
bp2buildPreArchMutators = append(bp2buildPreArchMutators, f)
}
-// DepsBp2BuildMutators adds mutators to be register for converting Android Blueprint modules into
-// Bazel BUILD targets that should run prior to conversion to resolve dependencies.
-func DepsBp2BuildMutators(f RegisterMutatorFunc) {
- bp2buildDepsMutators = append(bp2buildDepsMutators, f)
-}
-
type BaseMutatorContext interface {
BaseModuleContext
@@ -262,6 +252,9 @@
// Rename all variants of a module. The new name is not visible to calls to ModuleName,
// AddDependency or OtherModuleName until after this mutator pass is complete.
Rename(name string)
+
+ // BazelConversionMode returns whether this mutator is being run as part of Bazel Conversion.
+ BazelConversionMode() bool
}
type TopDownMutator func(TopDownMutatorContext)
@@ -403,26 +396,24 @@
// variant of the current module. The value should not be modified after being passed to
// SetVariationProvider.
SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{})
-
- // BazelConversionMode returns whether this mutator is being run as part of Bazel Conversion.
- BazelConversionMode() bool
}
type bottomUpMutatorContext struct {
bp blueprint.BottomUpMutatorContext
baseModuleContext
- finalPhase bool
- bazelConversionMode bool
+ finalPhase bool
}
func bottomUpMutatorContextFactory(ctx blueprint.BottomUpMutatorContext, a Module,
finalPhase, bazelConversionMode bool) BottomUpMutatorContext {
+ moduleContext := a.base().baseModuleContextFactory(ctx)
+ moduleContext.bazelConversionMode = bazelConversionMode
+
return &bottomUpMutatorContext{
- bp: ctx,
- baseModuleContext: a.base().baseModuleContextFactory(ctx),
- finalPhase: finalPhase,
- bazelConversionMode: bazelConversionMode,
+ bp: ctx,
+ baseModuleContext: a.base().baseModuleContextFactory(ctx),
+ finalPhase: finalPhase,
}
}
@@ -455,9 +446,11 @@
func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) MutatorHandle {
f := func(ctx blueprint.TopDownMutatorContext) {
if a, ok := ctx.Module().(Module); ok {
+ moduleContext := a.base().baseModuleContextFactory(ctx)
+ moduleContext.bazelConversionMode = x.bazelConversionMode
actx := &topDownMutatorContext{
bp: ctx,
- baseModuleContext: a.base().baseModuleContextFactory(ctx),
+ baseModuleContext: moduleContext,
}
m(actx)
}
@@ -726,7 +719,3 @@
func (b *bottomUpMutatorContext) SetVariationProvider(module blueprint.Module, provider blueprint.ProviderKey, value interface{}) {
b.bp.SetVariationProvider(module, provider, value)
}
-
-func (b *bottomUpMutatorContext) BazelConversionMode() bool {
- return b.bazelConversionMode
-}
diff --git a/android/namespace.go b/android/namespace.go
index d137636..4f727e1 100644
--- a/android/namespace.go
+++ b/android/namespace.go
@@ -27,7 +27,11 @@
)
func init() {
- RegisterModuleType("soong_namespace", NamespaceFactory)
+ registerNamespaceBuildComponents(InitRegistrationContext)
+}
+
+func registerNamespaceBuildComponents(ctx RegistrationContext) {
+ ctx.RegisterModuleType("soong_namespace", NamespaceFactory)
}
// threadsafe sorted list
diff --git a/android/namespace_test.go b/android/namespace_test.go
index 08e221a..ea399da 100644
--- a/android/namespace_test.go
+++ b/android/namespace_test.go
@@ -636,13 +636,12 @@
result := GroupFixturePreparers(
FixtureModifyContext(func(ctx *TestContext) {
ctx.RegisterModuleType("test_module", newTestModule)
- ctx.RegisterModuleType("soong_namespace", NamespaceFactory)
ctx.Context.RegisterModuleType("blueprint_test_module", newBlueprintTestModule)
- ctx.PreArchMutators(RegisterNamespaceMutator)
ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
ctx.BottomUp("rename", renameMutator)
})
}),
+ PrepareForTestWithNamespace,
bps.AddToFixture(),
).
// Ignore errors for now so tests can check them later.
diff --git a/android/neverallow.go b/android/neverallow.go
index af072cd..fa19009 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -55,6 +55,7 @@
AddNeverAllowRules(createCcSdkVariantRules()...)
AddNeverAllowRules(createUncompressDexRules()...)
AddNeverAllowRules(createMakefileGoalRules()...)
+ AddNeverAllowRules(createInitFirstStageRules()...)
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -217,6 +218,15 @@
}
}
+func createInitFirstStageRules() []Rule {
+ return []Rule{
+ NeverAllow().
+ Without("name", "init_first_stage").
+ With("install_in_root", "true").
+ Because("install_in_root is only for init_first_stage."),
+ }
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
diff --git a/android/override_module.go b/android/override_module.go
index 0a7e294..e72cb78 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -213,7 +213,6 @@
// to keep them in this order and not put any order mutators between them.
func RegisterOverridePostDepsMutators(ctx RegisterMutatorsContext) {
ctx.BottomUp("override_deps", overrideModuleDepsMutator).Parallel()
- ctx.TopDown("register_override", registerOverrideMutator).Parallel()
ctx.BottomUp("perform_override", performOverrideMutator).Parallel()
// overridableModuleDepsMutator calls OverridablePropertiesDepsMutator so that overridable modules can
// add deps from overridable properties.
@@ -253,20 +252,11 @@
return
}
})
- ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base)
- }
-}
-
-// Visits the base module added as a dependency above, checks the module type, and registers the
-// overriding module.
-func registerOverrideMutator(ctx TopDownMutatorContext) {
- ctx.VisitDirectDepsWithTag(overrideBaseDepTag, func(base Module) {
- if o, ok := base.(OverridableModule); ok {
+ baseModule := ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base)[0]
+ if o, ok := baseModule.(OverridableModule); ok {
o.addOverride(ctx.Module().(OverrideModule))
- } else {
- ctx.PropertyErrorf("base", "unsupported base module type")
}
- })
+ }
}
// Now, goes through all overridable modules, finds all modules overriding them, creates a local
diff --git a/android/packaging_test.go b/android/packaging_test.go
index f91dc5d..ff7446c 100644
--- a/android/packaging_test.go
+++ b/android/packaging_test.go
@@ -18,13 +18,15 @@
"testing"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
// Module to be packaged
type componentTestModule struct {
ModuleBase
props struct {
- Deps []string
+ Deps []string
+ Skip_install *bool
}
}
@@ -49,6 +51,9 @@
builtFile := PathForModuleOut(ctx, m.Name())
dir := ctx.Target().Arch.ArchType.Multilib
installDir := PathForModuleInstall(ctx, dir)
+ if proptools.Bool(m.props.Skip_install) {
+ m.SkipInstall()
+ }
ctx.InstallFile(installDir, m.Name(), builtFile)
}
@@ -365,3 +370,31 @@
}
`, []string{"lib64/foo"})
}
+
+func TestPackagingWithSkipInstallDeps(t *testing.T) {
+ // package -[dep]-> foo -[dep]-> bar -[dep]-> baz
+ // OK SKIPPED
+ multiTarget := false
+ runPackagingTest(t, multiTarget,
+ `
+ component {
+ name: "foo",
+ deps: ["bar"],
+ }
+
+ component {
+ name: "bar",
+ deps: ["baz"],
+ skip_install: true,
+ }
+
+ component {
+ name: "baz",
+ }
+
+ package_module {
+ name: "package",
+ deps: ["foo"],
+ }
+ `, []string{"lib64/foo"})
+}
diff --git a/android/path_properties.go b/android/path_properties.go
index 4446773..3976880 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -51,7 +51,7 @@
// Add dependencies to anything that is a module reference.
for _, s := range pathProperties {
if m, t := SrcIsModuleWithTag(s); m != "" {
- ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
+ ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
}
}
}
diff --git a/android/path_properties_test.go b/android/path_properties_test.go
index 568f868..07b4869 100644
--- a/android/path_properties_test.go
+++ b/android/path_properties_test.go
@@ -63,7 +63,8 @@
if p.props.Foo != "" {
// Make sure there is only one dependency on a module listed in a property present in multiple property structs
- if ctx.GetDirectDepWithTag(SrcIsModule(p.props.Foo), sourceOrOutputDepTag("")) == nil {
+ m := SrcIsModule(p.props.Foo)
+ if GetModuleFromPathDep(ctx, m, "") == nil {
ctx.ModuleErrorf("GetDirectDepWithTag failed")
}
}
diff --git a/android/paths.go b/android/paths.go
index fb75117..9c9914e 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -20,6 +20,7 @@
"os"
"path/filepath"
"reflect"
+ "regexp"
"sort"
"strings"
@@ -88,7 +89,8 @@
// the Path methods that rely on module dependencies having been resolved.
type ModuleWithDepsPathContext interface {
EarlyModulePathContext
- GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
+ VisitDirectDepsBlueprint(visit func(blueprint.Module))
+ OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
}
// ModuleMissingDepsPathContext is a subset of *ModuleContext methods required by
@@ -446,7 +448,7 @@
// 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.
func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag string) (Paths, error) {
- module := ctx.GetDirectDepWithTag(moduleName, sourceOrOutputDepTag(tag))
+ module := GetModuleFromPathDep(ctx, moduleName, tag)
if module == nil {
return nil, missingDependencyError{[]string{moduleName}}
}
@@ -474,6 +476,39 @@
}
}
+// GetModuleFromPathDep will return the module that was added as a dependency automatically for
+// properties tagged with `android:"path"` or manually using ExtractSourceDeps or
+// ExtractSourcesDeps.
+//
+// The moduleName and tag supplied to this should be the values returned from SrcIsModuleWithTag.
+// Or, if no tag is expected then the moduleName should be the value returned by SrcIsModule and
+// the tag must be "".
+//
+// If tag is "" then the returned module will be the dependency that was added for ":moduleName".
+// Otherwise, it is the dependency that was added for ":moduleName{tag}".
+func GetModuleFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag string) blueprint.Module {
+ var found blueprint.Module
+ // The sourceOrOutputDepTag uniquely identifies the module dependency as it contains both the
+ // module name and the tag. Dependencies added automatically for properties tagged with
+ // `android:"path"` are deduped so are guaranteed to be unique. It is possible for duplicate
+ // dependencies to be added manually using ExtractSourcesDeps or ExtractSourceDeps but even then
+ // it will always be the case that the dependencies will be identical, i.e. the same tag and same
+ // moduleName referring to the same dependency module.
+ //
+ // It does not matter whether the moduleName is a fully qualified name or if the module
+ // dependency is a prebuilt module. All that matters is the same information is supplied to
+ // create the tag here as was supplied to create the tag when the dependency was added so that
+ // this finds the matching dependency module.
+ expectedTag := sourceOrOutputDepTag(moduleName, tag)
+ ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
+ depTag := ctx.OtherModuleDependencyTag(module)
+ if depTag == expectedTag {
+ found = module
+ }
+ })
+ return found
+}
+
// PathsAndMissingDepsForModuleSrcExcludes returns a Paths{} containing the resolved references in
// paths, minus those listed in excludes. Elements of paths and excludes are resolved as:
// * filepath, relative to local module directory, resolves as a filepath relative to the local
@@ -1252,10 +1287,11 @@
// PathForModuleSrc returns a Path representing the paths... under the
// module's local source directory.
func PathForModuleSrc(ctx ModuleMissingDepsPathContext, pathComponents ...string) Path {
- p, err := validatePath(pathComponents...)
- if err != nil {
- reportPathError(ctx, err)
- }
+ // Just join the components textually just to make sure that it does not corrupt a fully qualified
+ // module reference, e.g. if the pathComponents is "://other:foo" then using filepath.Join() or
+ // validatePath() will corrupt it, e.g. replace "//" with "/". If the path is not a module
+ // reference then it will be validated by expandOneSrcPath anyway when it calls expandOneSrcPath.
+ p := strings.Join(pathComponents, string(filepath.Separator))
paths, err := expandOneSrcPath(ctx, p, nil)
if err != nil {
if depErr, ok := err.(missingDependencyError); ok {
@@ -1591,6 +1627,18 @@
// PathForModuleInstall returns a Path representing the install path for the
// module appended with paths...
func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string) InstallPath {
+ os, arch := osAndArch(ctx)
+ partition := modulePartition(ctx, os)
+ return makePathForInstall(ctx, os, arch, partition, ctx.Debug(), pathComponents...)
+}
+
+// PathForModuleInPartitionInstall is similar to PathForModuleInstall but partition is provided by the caller
+func PathForModuleInPartitionInstall(ctx ModuleInstallPathContext, partition string, pathComponents ...string) InstallPath {
+ os, arch := osAndArch(ctx)
+ return makePathForInstall(ctx, os, arch, partition, ctx.Debug(), pathComponents...)
+}
+
+func osAndArch(ctx ModuleInstallPathContext) (OsType, ArchType) {
os := ctx.Os()
arch := ctx.Arch().ArchType
forceOS, forceArch := ctx.InstallForceOS()
@@ -1600,14 +1648,14 @@
if forceArch != nil {
arch = *forceArch
}
- partition := modulePartition(ctx, os)
+ return os, arch
+}
- ret := pathForInstall(ctx, os, arch, partition, ctx.Debug(), pathComponents...)
-
+func makePathForInstall(ctx ModuleInstallPathContext, os OsType, arch ArchType, partition string, debug bool, pathComponents ...string) InstallPath {
+ ret := pathForInstall(ctx, os, arch, partition, debug, pathComponents...)
if ctx.InstallBypassMake() && ctx.Config().KatiEnabled() {
ret = ret.ToMakePath()
}
-
return ret
}
@@ -1620,7 +1668,7 @@
partionPaths = []string{"target", "product", ctx.Config().DeviceName(), partition}
} else {
osName := os.String()
- if os == Linux {
+ if os == Linux || os == LinuxMusl {
// instead of linux_glibc
osName = "linux"
}
@@ -1990,6 +2038,10 @@
func CreateOutputDirIfNonexistent(path WritablePath, perm os.FileMode) error {
dir := absolutePath(path.String())
+ return createDirIfNonexistent(dir, perm)
+}
+
+func createDirIfNonexistent(dir string, perm os.FileMode) error {
if _, err := os.Stat(dir); os.IsNotExist(err) {
return os.MkdirAll(dir, os.ModePerm)
} else {
@@ -1997,6 +2049,9 @@
}
}
+// absolutePath is deliberately private so that Soong's Go plugins can't use it to find and
+// read arbitrary files without going through the methods in the current package that track
+// dependencies.
func absolutePath(path string) string {
if filepath.IsAbs(path) {
return path
@@ -2040,3 +2095,25 @@
}
return ret
}
+
+var thirdPartyDirPrefixExceptions = []*regexp.Regexp{
+ regexp.MustCompile("^vendor/[^/]*google[^/]*/"),
+ regexp.MustCompile("^hardware/google/"),
+ regexp.MustCompile("^hardware/interfaces/"),
+ regexp.MustCompile("^hardware/libhardware[^/]*/"),
+ regexp.MustCompile("^hardware/ril/"),
+}
+
+func IsThirdPartyPath(path string) bool {
+ thirdPartyDirPrefixes := []string{"external/", "vendor/", "hardware/"}
+
+ if HasAnyPrefix(path, thirdPartyDirPrefixes) {
+ for _, prefix := range thirdPartyDirPrefixExceptions {
+ if prefix.MatchString(path) {
+ return false
+ }
+ }
+ return true
+ }
+ return false
+}
diff --git a/android/paths_test.go b/android/paths_test.go
index 6f5d79e..f4e4ce1 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -1125,6 +1125,12 @@
rels []string
src string
rel string
+
+ // Make test specific preparations to the test fixture.
+ preparer FixturePreparer
+
+ // A test specific error handler.
+ errorHandler FixtureErrorHandler
}
func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) {
@@ -1157,14 +1163,23 @@
"foo/src_special/$": nil,
}
+ errorHandler := test.errorHandler
+ if errorHandler == nil {
+ errorHandler = FixtureExpectsNoErrors
+ }
+
result := GroupFixturePreparers(
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory)
ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory)
- ctx.RegisterModuleType("filegroup", FileGroupFactory)
}),
+ PrepareForTestWithFilegroup,
+ PrepareForTestWithNamespace,
mockFS.AddToFixture(),
- ).RunTest(t)
+ OptionalFixturePreparer(test.preparer),
+ ).
+ ExtendWithErrorHandler(errorHandler).
+ RunTest(t)
m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
@@ -1333,6 +1348,73 @@
src: "foo/src_special/$",
rel: "src_special/$",
},
+ {
+ // This test makes sure that an unqualified module name cannot contain characters that make
+ // it appear as a qualified module name.
+ name: "output file provider, invalid fully qualified name",
+ bp: `
+ test {
+ name: "foo",
+ src: "://other:b",
+ srcs: ["://other:c"],
+ }`,
+ preparer: FixtureAddTextFile("other/Android.bp", `
+ soong_namespace {}
+
+ output_file_provider {
+ name: "b",
+ outs: ["gen/b"],
+ }
+
+ output_file_provider {
+ name: "c",
+ outs: ["gen/c"],
+ }
+ `),
+ src: "foo/:/other:b",
+ rel: ":/other:b",
+ srcs: []string{"foo/:/other:c"},
+ rels: []string{":/other:c"},
+ },
+ {
+ name: "output file provider, missing fully qualified name",
+ bp: `
+ test {
+ name: "foo",
+ src: "//other:b",
+ srcs: ["//other:c"],
+ }`,
+ errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{
+ `"foo" depends on undefined module "//other:b"`,
+ `"foo" depends on undefined module "//other:c"`,
+ }),
+ },
+ {
+ name: "output file provider, fully qualified name",
+ bp: `
+ test {
+ name: "foo",
+ src: "//other:b",
+ srcs: ["//other:c"],
+ }`,
+ src: "out/soong/.intermediates/other/b/gen/b",
+ rel: "gen/b",
+ srcs: []string{"out/soong/.intermediates/other/c/gen/c"},
+ rels: []string{"gen/c"},
+ preparer: FixtureAddTextFile("other/Android.bp", `
+ soong_namespace {}
+
+ output_file_provider {
+ name: "b",
+ outs: ["gen/b"],
+ }
+
+ output_file_provider {
+ name: "c",
+ outs: ["gen/c"],
+ }
+ `),
+ },
}
testPathForModuleSrc(t, tests)
diff --git a/android/prebuilt.go b/android/prebuilt.go
index f3493bd..e611502 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -61,6 +61,16 @@
// a matching name.
Prefer *bool `android:"arch_variant"`
+ // When specified this names a Soong config variable that controls the prefer property.
+ //
+ // If the value of the named Soong config variable is true then prefer is set to false and vice
+ // versa. If the Soong config variable is not set then it defaults to false, so prefer defaults
+ // to true.
+ //
+ // If specified then the prefer property is ignored in favor of the value of the Soong config
+ // variable.
+ Use_source_config_var *ConfigVarProperties
+
SourceExists bool `blueprint:"mutated"`
UsePrebuilt bool `blueprint:"mutated"`
@@ -68,6 +78,22 @@
PrebuiltRenamedToSource bool `blueprint:"mutated"`
}
+// Properties that can be used to select a Soong config variable.
+type ConfigVarProperties struct {
+ // Allow instances of this struct to be used as a property value in a BpPropertySet.
+ BpPrintableBase
+
+ // The name of the configuration namespace.
+ //
+ // As passed to add_soong_config_namespace in Make.
+ Config_namespace *string
+
+ // The name of the configuration variable.
+ //
+ // As passed to add_soong_config_var_value in Make.
+ Var_name *string
+}
+
type Prebuilt struct {
properties PrebuiltProperties
@@ -364,12 +390,18 @@
return false
}
- // TODO: use p.Properties.Name and ctx.ModuleDir to override preference
- if Bool(p.properties.Prefer) {
+ // If source is not available or is disabled then always use the prebuilt.
+ if source == nil || !source.Enabled() {
return true
}
- return source == nil || !source.Enabled()
+ // If the use_source_config_var property is set then it overrides the prefer property setting.
+ if configVar := p.properties.Use_source_config_var; configVar != nil {
+ return !ctx.Config().VendorConfig(proptools.String(configVar.Config_namespace)).Bool(proptools.String(configVar.Var_name))
+ }
+
+ // TODO: use p.Properties.Name and ctx.ModuleDir to override preference
+ return Bool(p.properties.Prefer)
}
func (p *Prebuilt) SourceExists() bool {
diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go
index 516d042..e5edf91 100644
--- a/android/prebuilt_build_tool.go
+++ b/android/prebuilt_build_tool.go
@@ -86,7 +86,7 @@
func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) {
if makeVar := String(t.properties.Export_to_make_var); makeVar != "" {
- if t.Target().Os != BuildOs {
+ if t.Target().Os != ctx.Config().BuildOS {
return
}
ctx.StrictRaw(makeVar, t.toolPath.String())
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 23524a5..a1f8e63 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -21,279 +21,362 @@
"github.com/google/blueprint"
)
-var prebuiltsTests = []struct {
- name string
- replaceBp bool // modules is added to default bp boilerplate if false.
- modules string
- prebuilt []OsType
-}{
- {
- name: "no prebuilt",
- modules: `
- source {
- name: "bar",
- }`,
- prebuilt: nil,
- },
- {
- name: "no source prebuilt not preferred",
- modules: `
- prebuilt {
- name: "bar",
- prefer: false,
- srcs: ["prebuilt_file"],
- }`,
- prebuilt: []OsType{Android, BuildOs},
- },
- {
- name: "no source prebuilt preferred",
- modules: `
- prebuilt {
- name: "bar",
- prefer: true,
- srcs: ["prebuilt_file"],
- }`,
- prebuilt: []OsType{Android, BuildOs},
- },
- {
- name: "prebuilt not preferred",
- modules: `
- source {
- name: "bar",
- }
+func TestPrebuilts(t *testing.T) {
+ buildOS := TestArchConfig(t.TempDir(), nil, "", nil).BuildOS
- prebuilt {
- name: "bar",
- prefer: false,
- srcs: ["prebuilt_file"],
- }`,
- prebuilt: nil,
- },
- {
- name: "prebuilt preferred",
- modules: `
- source {
- name: "bar",
- }
+ var prebuiltsTests = []struct {
+ name string
+ replaceBp bool // modules is added to default bp boilerplate if false.
+ modules string
+ prebuilt []OsType
+ preparer FixturePreparer
+ }{
+ {
+ name: "no prebuilt",
+ modules: `
+ source {
+ name: "bar",
+ }`,
+ prebuilt: nil,
+ },
+ {
+ name: "no source prebuilt not preferred",
+ modules: `
+ prebuilt {
+ name: "bar",
+ prefer: false,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "no source prebuilt preferred",
+ modules: `
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "prebuilt not preferred",
+ modules: `
+ source {
+ name: "bar",
+ }
- prebuilt {
- name: "bar",
- prefer: true,
- srcs: ["prebuilt_file"],
- }`,
- prebuilt: []OsType{Android, BuildOs},
- },
- {
- name: "prebuilt no file not preferred",
- modules: `
- source {
- name: "bar",
- }
+ prebuilt {
+ name: "bar",
+ prefer: false,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: nil,
+ },
+ {
+ name: "prebuilt preferred",
+ modules: `
+ source {
+ name: "bar",
+ }
- prebuilt {
- name: "bar",
- prefer: false,
- }`,
- prebuilt: nil,
- },
- {
- name: "prebuilt no file preferred",
- modules: `
- source {
- name: "bar",
- }
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "prebuilt no file not preferred",
+ modules: `
+ source {
+ name: "bar",
+ }
- prebuilt {
- name: "bar",
- prefer: true,
- }`,
- prebuilt: nil,
- },
- {
- name: "prebuilt file from filegroup preferred",
- modules: `
- filegroup {
- name: "fg",
- srcs: ["prebuilt_file"],
- }
- prebuilt {
- name: "bar",
- prefer: true,
- srcs: [":fg"],
- }`,
- prebuilt: []OsType{Android, BuildOs},
- },
- {
- name: "prebuilt module for device only",
- modules: `
- source {
- name: "bar",
- }
+ prebuilt {
+ name: "bar",
+ prefer: false,
+ }`,
+ prebuilt: nil,
+ },
+ {
+ name: "prebuilt no file preferred",
+ modules: `
+ source {
+ name: "bar",
+ }
- prebuilt {
- name: "bar",
- host_supported: false,
- prefer: true,
- srcs: ["prebuilt_file"],
- }`,
- prebuilt: []OsType{Android},
- },
- {
- name: "prebuilt file for host only",
- modules: `
- source {
- name: "bar",
- }
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ }`,
+ prebuilt: nil,
+ },
+ {
+ name: "prebuilt file from filegroup preferred",
+ modules: `
+ filegroup {
+ name: "fg",
+ srcs: ["prebuilt_file"],
+ }
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ srcs: [":fg"],
+ }`,
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "prebuilt module for device only",
+ modules: `
+ source {
+ name: "bar",
+ }
- prebuilt {
- name: "bar",
- prefer: true,
- target: {
- host: {
- srcs: ["prebuilt_file"],
- },
- },
- }`,
- prebuilt: []OsType{BuildOs},
- },
- {
- name: "prebuilt override not preferred",
- modules: `
- source {
- name: "baz",
- }
+ prebuilt {
+ name: "bar",
+ host_supported: false,
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: []OsType{Android},
+ },
+ {
+ name: "prebuilt file for host only",
+ modules: `
+ source {
+ name: "bar",
+ }
- override_source {
- name: "bar",
- base: "baz",
- }
-
- prebuilt {
- name: "bar",
- prefer: false,
- srcs: ["prebuilt_file"],
- }`,
- prebuilt: nil,
- },
- {
- name: "prebuilt override preferred",
- modules: `
- source {
- name: "baz",
- }
-
- override_source {
- name: "bar",
- base: "baz",
- }
-
- prebuilt {
- name: "bar",
- prefer: true,
- srcs: ["prebuilt_file"],
- }`,
- prebuilt: []OsType{Android, BuildOs},
- },
- {
- name: "prebuilt including default-disabled OS",
- replaceBp: true,
- modules: `
- source {
- name: "foo",
- deps: [":bar"],
- target: {
- windows: {
- enabled: true,
- },
- },
- }
-
- source {
- name: "bar",
- target: {
- windows: {
- enabled: true,
- },
- },
- }
-
- prebuilt {
- name: "bar",
- prefer: true,
- srcs: ["prebuilt_file"],
- target: {
- windows: {
- enabled: true,
- },
- },
- }`,
- prebuilt: []OsType{Android, BuildOs, Windows},
- },
- {
- name: "fall back to source for default-disabled OS",
- replaceBp: true,
- modules: `
- source {
- name: "foo",
- deps: [":bar"],
- target: {
- windows: {
- enabled: true,
- },
- },
- }
-
- source {
- name: "bar",
- target: {
- windows: {
- enabled: true,
- },
- },
- }
-
- prebuilt {
- name: "bar",
- prefer: true,
- srcs: ["prebuilt_file"],
- }`,
- prebuilt: []OsType{Android, BuildOs},
- },
- {
- name: "prebuilt properties customizable",
- replaceBp: true,
- modules: `
- source {
- name: "foo",
- deps: [":bar"],
- }
-
- soong_config_module_type {
- name: "prebuilt_with_config",
- module_type: "prebuilt",
- config_namespace: "any_namespace",
- bool_variables: ["bool_var"],
- properties: ["prefer"],
- }
-
- prebuilt_with_config {
- name: "bar",
- prefer: true,
- srcs: ["prebuilt_file"],
- soong_config_variables: {
- bool_var: {
- prefer: false,
- conditions_default: {
- prefer: true,
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ target: {
+ host: {
+ srcs: ["prebuilt_file"],
},
},
- },
- }`,
- prebuilt: []OsType{Android, BuildOs},
- },
-}
+ }`,
+ prebuilt: []OsType{buildOS},
+ },
+ {
+ name: "prebuilt override not preferred",
+ modules: `
+ source {
+ name: "baz",
+ }
-func TestPrebuilts(t *testing.T) {
+ override_source {
+ name: "bar",
+ base: "baz",
+ }
+
+ prebuilt {
+ name: "bar",
+ prefer: false,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: nil,
+ },
+ {
+ name: "prebuilt override preferred",
+ modules: `
+ source {
+ name: "baz",
+ }
+
+ override_source {
+ name: "bar",
+ base: "baz",
+ }
+
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "prebuilt including default-disabled OS",
+ replaceBp: true,
+ modules: `
+ source {
+ name: "foo",
+ deps: [":bar"],
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+ }
+
+ source {
+ name: "bar",
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+ }
+
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+ }`,
+ prebuilt: []OsType{Android, buildOS, Windows},
+ },
+ {
+ name: "fall back to source for default-disabled OS",
+ replaceBp: true,
+ modules: `
+ source {
+ name: "foo",
+ deps: [":bar"],
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+ }
+
+ source {
+ name: "bar",
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
+ }
+
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "prebuilt properties customizable",
+ replaceBp: true,
+ modules: `
+ source {
+ name: "foo",
+ deps: [":bar"],
+ }
+
+ soong_config_module_type {
+ name: "prebuilt_with_config",
+ module_type: "prebuilt",
+ config_namespace: "any_namespace",
+ bool_variables: ["bool_var"],
+ properties: ["prefer"],
+ }
+
+ prebuilt_with_config {
+ name: "bar",
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ soong_config_variables: {
+ bool_var: {
+ prefer: false,
+ conditions_default: {
+ prefer: true,
+ },
+ },
+ },
+ }`,
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "prebuilt use_source_config_var={acme, use_source} - no var specified",
+ modules: `
+ source {
+ name: "bar",
+ }
+
+ prebuilt {
+ name: "bar",
+ use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+ srcs: ["prebuilt_file"],
+ }`,
+ // When use_source_env is specified then it will use the prebuilt by default if the environment
+ // variable is not set.
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=false",
+ modules: `
+ source {
+ name: "bar",
+ }
+
+ prebuilt {
+ name: "bar",
+ use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+ srcs: ["prebuilt_file"],
+ }`,
+ preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.VendorVars = map[string]map[string]string{
+ "acme": {
+ "use_source": "false",
+ },
+ }
+ }),
+ // Setting the environment variable named in use_source_env to false will cause the prebuilt to
+ // be used.
+ prebuilt: []OsType{Android, buildOS},
+ },
+ {
+ name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true",
+ modules: `
+ source {
+ name: "bar",
+ }
+
+ prebuilt {
+ name: "bar",
+ use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+ srcs: ["prebuilt_file"],
+ }`,
+ preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.VendorVars = map[string]map[string]string{
+ "acme": {
+ "use_source": "true",
+ },
+ }
+ }),
+ // Setting the environment variable named in use_source_env to true will cause the source to be
+ // used.
+ prebuilt: nil,
+ },
+ {
+ name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true, no source",
+ modules: `
+ prebuilt {
+ name: "bar",
+ use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
+ srcs: ["prebuilt_file"],
+ }`,
+ preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.VendorVars = map[string]map[string]string{
+ "acme": {
+ "use_source": "true",
+ },
+ }
+ }),
+ // Although the environment variable says to use source there is no source available.
+ prebuilt: []OsType{Android, buildOS},
+ },
+ }
+
fs := MockFS{
"prebuilt_file": nil,
"source_file": nil,
@@ -329,6 +412,7 @@
}),
fs.AddToFixture(),
FixtureRegisterWithContext(registerTestPrebuiltModules),
+ OptionalFixturePreparer(test.preparer),
).RunTestWithBp(t, bp)
for _, variant := range result.ModuleVariantsForTests("foo") {
diff --git a/android/register.go b/android/register.go
index 4c8088d..5984862 100644
--- a/android/register.go
+++ b/android/register.go
@@ -180,7 +180,7 @@
bp2buildMutatorList = append(bp2buildMutatorList, f)
}
- RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutatorList)
+ RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators, bp2buildMutatorList)
}
// Register the pipeline of singletons, module types, and mutators for
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 2507c4c..6605869 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -22,9 +22,10 @@
"strings"
"testing"
- "github.com/golang/protobuf/proto"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
+ "google.golang.org/protobuf/encoding/prototext"
+ "google.golang.org/protobuf/proto"
"android/soong/cmd/sbox/sbox_proto"
"android/soong/remoteexec"
@@ -621,7 +622,11 @@
}
// Create a rule to write the manifest as a the textproto.
- WriteFileRule(r.ctx, r.sboxManifestPath, proto.MarshalTextString(&manifest))
+ pbText, err := prototext.Marshal(&manifest)
+ if err != nil {
+ ReportPathErrorf(r.ctx, "sbox manifest failed to marshal: %q", err)
+ }
+ WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText))
// Generate a new string to use as the command line of the sbox rule. This uses
// a RuleBuilderCommand as a convenience method of building the command line, then
@@ -1266,7 +1271,7 @@
t.Helper()
content := ContentFromFileRuleForTests(t, params)
manifest := sbox_proto.Manifest{}
- err := proto.UnmarshalText(content, &manifest)
+ err := prototext.Unmarshal([]byte(content), &manifest)
if err != nil {
t.Fatalf("failed to unmarshal manifest: %s", err.Error())
}
diff --git a/android/sdk.go b/android/sdk.go
index 42c8ffa..da740f3 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -239,6 +239,12 @@
// to the zip
CopyToSnapshot(src Path, dest string)
+ // Return the path to an empty file.
+ //
+ // This can be used by sdk member types that need to create an empty file in the snapshot, simply
+ // pass the value returned from this to the CopyToSnapshot() method.
+ EmptyFile() Path
+
// Unzip the supplied zip into the snapshot relative directory destDir.
UnzipToSnapshot(zipPath Path, destDir string)
@@ -342,6 +348,22 @@
Name() string
}
+// BpPrintable is a marker interface that must be implemented by any struct that is added as a
+// property value.
+type BpPrintable interface {
+ bpPrintable()
+}
+
+// BpPrintableBase must be embedded within any struct that is added as a
+// property value.
+type BpPrintableBase struct {
+}
+
+func (b BpPrintableBase) bpPrintable() {
+}
+
+var _ BpPrintable = BpPrintableBase{}
+
// An individual member of the SDK, includes all of the variants that the SDK
// requires.
type SdkMember interface {
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index 8f252d9..b2f8eaa 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -313,6 +313,51 @@
})
}
+func TestNonExistentPropertyInSoongConfigModule(t *testing.T) {
+ bp := `
+ soong_config_module_type {
+ name: "acme_test",
+ module_type: "test",
+ config_namespace: "acme",
+ bool_variables: ["feature1"],
+ properties: ["made_up_property"],
+ }
+
+ acme_test {
+ name: "foo",
+ cflags: ["-DGENERIC"],
+ soong_config_variables: {
+ feature1: {
+ made_up_property: true,
+ },
+ },
+ }
+ `
+
+ fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer {
+ return FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.VendorVars = vars
+ })
+ }
+
+ GroupFixturePreparers(
+ fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}),
+ PrepareForTestWithDefaults,
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("soong_config_module_type_import", soongConfigModuleTypeImportFactory)
+ ctx.RegisterModuleType("soong_config_module_type", soongConfigModuleTypeFactory)
+ ctx.RegisterModuleType("soong_config_string_variable", soongConfigStringVariableDummyFactory)
+ ctx.RegisterModuleType("soong_config_bool_variable", soongConfigBoolVariableDummyFactory)
+ ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory)
+ ctx.RegisterModuleType("test", soongConfigTestModuleFactory)
+ }),
+ FixtureWithRootAndroidBp(bp),
+ ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{
+ // TODO(b/171232169): improve the error message for non-existent properties
+ `unrecognized property "soong_config_variables`,
+ })).RunTest(t)
+}
+
func testConfigWithVendorVars(buildDir, bp string, fs map[string][]byte, vendorVars map[string]map[string]string) Config {
config := TestConfig(buildDir, nil, bp, fs)
diff --git a/android/test_suites.go b/android/test_suites.go
index 6b7b909..22f6cf2 100644
--- a/android/test_suites.go
+++ b/android/test_suites.go
@@ -60,7 +60,7 @@
for _, module := range SortedStringKeys(files) {
installedPaths = append(installedPaths, files[module]...)
}
- testCasesDir := pathForInstall(ctx, BuildOs, X86, "testcases", false).ToMakePath()
+ testCasesDir := pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases", false).ToMakePath()
outputFile := PathForOutput(ctx, "packaging", "robolectric-tests.zip")
rule := NewRuleBuilder(pctx, ctx)
diff --git a/android/testing.go b/android/testing.go
index b36f62c..6ba8e3c 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -110,6 +110,11 @@
FixtureAddFile("build/soong/licenses/LICENSE", nil),
)
+var PrepareForTestWithNamespace = FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ registerNamespaceBuildComponents(ctx)
+ ctx.PreArchMutators(RegisterNamespaceMutator)
+})
+
// Test fixture preparer that will register most java build components.
//
// Singletons and mutators should only be added here if they are needed for a majority of java
@@ -166,9 +171,9 @@
type TestContext struct {
*Context
- preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc
- bp2buildPreArch, bp2buildDeps, bp2buildMutators []RegisterMutatorFunc
- NameResolver *NameResolver
+ preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc
+ bp2buildPreArch, bp2buildMutators []RegisterMutatorFunc
+ NameResolver *NameResolver
// The list of pre-singletons and singletons registered for the test.
preSingletons, singletons sortableComponents
@@ -219,12 +224,6 @@
ctx.bp2buildPreArch = append(ctx.bp2buildPreArch, f)
}
-// DepsBp2BuildMutators adds mutators to be register for converting Android Blueprint modules into
-// Bazel BUILD targets that should run prior to conversion to resolve dependencies.
-func (ctx *TestContext) DepsBp2BuildMutators(f RegisterMutatorFunc) {
- ctx.bp2buildDeps = append(ctx.bp2buildDeps, f)
-}
-
// registeredComponentOrder defines the order in which a sortableComponent type is registered at
// runtime and provides support for reordering the components registered for a test in the same
// way.
@@ -459,7 +458,7 @@
// RegisterForBazelConversion prepares a test context for bp2build conversion.
func (ctx *TestContext) RegisterForBazelConversion() {
- RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators)
+ RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch, ctx.bp2buildMutators)
}
func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) {
diff --git a/android/variable.go b/android/variable.go
index 0dc5262..89ffe46 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -101,6 +101,9 @@
Keep_symbols *bool
Keep_symbols_and_debug_frame *bool
}
+ Static_libs []string
+ Whole_static_libs []string
+ Shared_libs []string
}
// eng is true for -eng builds, and can be used to turn on additionaly heavyweight debugging
@@ -201,6 +204,7 @@
HostArch *string `json:",omitempty"`
HostSecondaryArch *string `json:",omitempty"`
+ HostMusl *bool `json:",omitempty"`
CrossHost *string `json:",omitempty"`
CrossHostArch *string `json:",omitempty"`
@@ -223,6 +227,7 @@
Allow_missing_dependencies *bool `json:",omitempty"`
Unbundled_build *bool `json:",omitempty"`
Unbundled_build_apps *bool `json:",omitempty"`
+ Unbundled_build_image *bool `json:",omitempty"`
Always_use_prebuilt_sdks *bool `json:",omitempty"`
Skip_boot_jars_check *bool `json:",omitempty"`
Malloc_not_svelte *bool `json:",omitempty"`
@@ -249,8 +254,8 @@
UncompressPrivAppDex *bool `json:",omitempty"`
ModulesLoadedByPrivilegedModules []string `json:",omitempty"`
- BootJars ConfiguredJarList `json:",omitempty"`
- UpdatableBootJars ConfiguredJarList `json:",omitempty"`
+ BootJars ConfiguredJarList `json:",omitempty"`
+ ApexBootJars ConfiguredJarList `json:",omitempty"`
IntegerOverflowExcludePaths []string `json:",omitempty"`
@@ -283,7 +288,7 @@
NativeCoverageExcludePaths []string `json:",omitempty"`
// Set by NewConfig
- Native_coverage *bool
+ Native_coverage *bool `json:",omitempty"`
SanitizeHost []string `json:",omitempty"`
SanitizeDevice []string `json:",omitempty"`
@@ -296,8 +301,6 @@
Override_rs_driver *string `json:",omitempty"`
- Fuchsia *bool `json:",omitempty"`
-
DeviceKernelHeaders []string `json:",omitempty"`
ExtraVndkVersions []string `json:",omitempty"`
@@ -439,8 +442,8 @@
Malloc_pattern_fill_contents: boolPtr(false),
Safestack: boolPtr(false),
- BootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}},
- UpdatableBootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}},
+ BootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}},
+ ApexBootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}},
}
if runtime.GOOS == "linux" {
@@ -459,16 +462,17 @@
// with the appropriate ProductConfigVariable.
type ProductConfigProperty struct {
ProductConfigVariable string
+ FullConfig string
Property interface{}
}
// ProductConfigProperties is a map of property name to a slice of ProductConfigProperty such that
// all it all product variable-specific versions of a property are easily accessed together
-type ProductConfigProperties map[string][]ProductConfigProperty
+type ProductConfigProperties map[string]map[string]ProductConfigProperty
// ProductVariableProperties returns a ProductConfigProperties containing only the properties which
// have been set for the module in the given context.
-func ProductVariableProperties(ctx ProductConfigContext) ProductConfigProperties {
+func ProductVariableProperties(ctx BaseMutatorContext) ProductConfigProperties {
module := ctx.Module()
moduleBase := module.base()
@@ -478,7 +482,24 @@
return productConfigProperties
}
- variableValues := reflect.ValueOf(moduleBase.variableProperties).Elem().FieldByName("Product_variables")
+ productVariableValues(moduleBase.variableProperties, "", &productConfigProperties)
+
+ for _, configToProps := range moduleBase.GetArchVariantProperties(ctx, moduleBase.variableProperties) {
+ for config, props := range configToProps {
+ // GetArchVariantProperties is creating an instance of the requested type
+ // and productVariablesValues expects an interface, so no need to cast
+ productVariableValues(props, config, &productConfigProperties)
+ }
+ }
+
+ return productConfigProperties
+}
+
+func productVariableValues(variableProps interface{}, suffix string, productConfigProperties *ProductConfigProperties) {
+ if suffix != "" {
+ suffix = "-" + suffix
+ }
+ variableValues := reflect.ValueOf(variableProps).Elem().FieldByName("Product_variables")
for i := 0; i < variableValues.NumField(); i++ {
variableValue := variableValues.Field(i)
// Check if any properties were set for the module
@@ -496,15 +517,17 @@
// e.g. Asflags, Cflags, Enabled, etc.
propertyName := variableValue.Type().Field(j).Name
- productConfigProperties[propertyName] = append(productConfigProperties[propertyName],
- ProductConfigProperty{
- ProductConfigVariable: productVariableName,
- Property: property.Interface(),
- })
+ if (*productConfigProperties)[propertyName] == nil {
+ (*productConfigProperties)[propertyName] = make(map[string]ProductConfigProperty)
+ }
+ config := productVariableName + suffix
+ (*productConfigProperties)[propertyName][config] = ProductConfigProperty{
+ ProductConfigVariable: productVariableName,
+ FullConfig: config,
+ Property: property.Interface(),
+ }
}
}
-
- return productConfigProperties
}
func VariableMutator(mctx BottomUpMutatorContext) {
diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go
index 5316d7b..08616a9 100644
--- a/androidmk/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -104,6 +104,7 @@
"LOCAL_NDK_STL_VARIANT": "stl",
"LOCAL_JAR_MANIFEST": "manifest",
"LOCAL_CERTIFICATE": "certificate",
+ "LOCAL_CERTIFICATE_LINEAGE": "lineage",
"LOCAL_PACKAGE_NAME": "name",
"LOCAL_MODULE_RELATIVE_PATH": "relative_install_path",
"LOCAL_PROTOC_OPTIMIZE_TYPE": "proto.type",
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index 439f45d..02ab89d 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -794,7 +794,7 @@
include $(BUILD_CTS_SUPPORT_PACKAGE)
`,
expected: `
-android_test {
+android_test_helper_app {
name: "FooTest",
defaults: ["cts_support_defaults"],
test_suites: ["cts"],
@@ -1463,6 +1463,22 @@
}
`,
},
+ {
+ desc: "LOCAL_CERTIFICATE_LINEAGE",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_TAGS := tests
+LOCAL_CERTIFICATE_LINEAGE := lineage
+include $(BUILD_PACKAGE)
+`,
+ expected: `
+android_test {
+ name: "foo",
+ lineage: "lineage",
+}
+`,
+ },
}
func TestEndToEnd(t *testing.T) {
diff --git a/androidmk/parser/make_strings.go b/androidmk/parser/make_strings.go
index 3c4815e..aac4c4e 100644
--- a/androidmk/parser/make_strings.go
+++ b/androidmk/parser/make_strings.go
@@ -278,6 +278,15 @@
}
}
+// If MakeString is $(var) after trimming, returns var
+func (ms *MakeString) SingleVariable() (*MakeString, bool) {
+ if len(ms.Strings) != 2 || strings.TrimSpace(ms.Strings[0]) != "" ||
+ strings.TrimSpace(ms.Strings[1]) != "" {
+ return nil, false
+ }
+ return ms.Variables[0].Name, true
+}
+
func splitAnyN(s, sep string, n int) []string {
ret := []string{}
for n == -1 || n > 1 {
diff --git a/androidmk/parser/parser.go b/androidmk/parser/parser.go
index 5afef65..d24efc1 100644
--- a/androidmk/parser/parser.go
+++ b/androidmk/parser/parser.go
@@ -216,13 +216,14 @@
// Nothing
case "else":
p.ignoreSpaces()
- if p.tok != '\n' {
+ if p.tok != '\n' && p.tok != '#' {
d = p.scanner.TokenText()
p.accept(scanner.Ident)
if d == "ifdef" || d == "ifndef" || d == "ifeq" || d == "ifneq" {
d = "el" + d
p.ignoreSpaces()
expression = p.parseExpression()
+ expression.TrimRightSpaces()
} else {
p.errorf("expected ifdef/ifndef/ifeq/ifneq, found %s", d)
}
diff --git a/apex/Android.bp b/apex/Android.bp
index 6269757..b9b5428 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -9,6 +9,7 @@
"blueprint",
"soong",
"soong-android",
+ "soong-bazel",
"soong-bpf",
"soong-cc",
"soong-filesystem",
diff --git a/apex/apex.go b/apex/apex.go
index bea54bc..8c42a3f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -27,6 +27,7 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/bpf"
"android/soong/cc"
prebuilt_etc "android/soong/etc"
@@ -53,6 +54,8 @@
ctx.PreArchMutators(registerPreArchMutators)
ctx.PreDepsMutators(RegisterPreDepsMutators)
ctx.PostDepsMutators(RegisterPostDepsMutators)
+
+ android.RegisterBp2BuildMutator("apex", ApexBundleBp2Build)
}
func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
@@ -130,6 +133,10 @@
// symlinking to the system libs. Default is true.
Updatable *bool
+ // Whether this APEX can use platform APIs or not. Can be set to true only when `updatable:
+ // false`. Default is false.
+ Platform_apis *bool
+
// Whether this APEX is installable to one of the partitions like system, vendor, etc.
// Default: true.
Installable *bool
@@ -318,6 +325,7 @@
android.DefaultableModuleBase
android.OverridableModuleBase
android.SdkBase
+ android.BazelModuleBase
// Properties
properties apexBundleProperties
@@ -415,6 +423,9 @@
// Path of API coverage generate file
apisUsedByModuleFile android.ModuleOutPath
apisBackedByModuleFile android.ModuleOutPath
+
+ // Collect the module directory for IDE info in java/jdeps.go.
+ modulePaths []string
}
// apexFileClass represents a type of file that can be included in APEX.
@@ -736,20 +747,22 @@
}
}
- // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
- // regardless of the TARGET_PREFER_* setting. See b/144532908
- archForPrebuiltEtc := config.Arches()[0]
- for _, arch := range config.Arches() {
- // Prefer 64-bit arch if there is any
- if arch.ArchType.Multilib == "lib64" {
- archForPrebuiltEtc = arch
- break
+ if prebuilts := a.properties.Prebuilts; len(prebuilts) > 0 {
+ // For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
+ // regardless of the TARGET_PREFER_* setting. See b/144532908
+ archForPrebuiltEtc := config.Arches()[0]
+ for _, arch := range config.Arches() {
+ // Prefer 64-bit arch if there is any
+ if arch.ArchType.Multilib == "lib64" {
+ archForPrebuiltEtc = arch
+ break
+ }
}
+ ctx.AddFarVariationDependencies([]blueprint.Variation{
+ {Mutator: "os", Variation: ctx.Os().String()},
+ {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
+ }, prebuiltTag, prebuilts...)
}
- ctx.AddFarVariationDependencies([]blueprint.Variation{
- {Mutator: "os", Variation: ctx.Os().String()},
- {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
- }, prebuiltTag, a.properties.Prebuilts...)
// Common-arch dependencies come next
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
@@ -913,6 +926,7 @@
MinSdkVersion: minSdkVersion,
RequiredSdks: a.RequiredSdks(),
Updatable: a.Updatable(),
+ UsePlatformApis: a.UsePlatformApis(),
InApexVariants: []string{apexVariationName},
InApexModules: []string{a.Name()}, // could be com.mycompany.android.foo
ApexContents: []*android.ApexContents{apexContents},
@@ -1277,6 +1291,10 @@
return proptools.BoolDefault(a.properties.Updatable, true)
}
+func (a *apexBundle) UsePlatformApis() bool {
+ return proptools.BoolDefault(a.properties.Platform_apis, false)
+}
+
// getCertString returns the name of the cert that should be used to sign this APEX. This is
// basically from the "certificate" property, but could be overridden by the device config.
func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
@@ -1631,6 +1649,7 @@
a.checkUpdatable(ctx)
a.checkMinSdkVersion(ctx)
a.checkStaticLinkingToStubLibraries(ctx)
+ a.checkStaticExecutables(ctx)
if len(a.properties.Tests) > 0 && !a.testApex {
ctx.PropertyErrorf("tests", "property allowed only in apex_test module type")
return
@@ -1648,6 +1667,9 @@
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
+ // Collect the module directory for IDE info in java/jdeps.go.
+ a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
+
// TODO(jiyong): do this using WalkPayloadDeps
// TODO(jiyong): make this clean!!!
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
@@ -1714,7 +1736,9 @@
ctx.PropertyErrorf("systemserverclasspath_fragments", "%q is not a systemserverclasspath_fragment module", depName)
return false
}
- filesInfo = append(filesInfo, apexClasspathFragmentProtoFile(ctx, child))
+ if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
+ filesInfo = append(filesInfo, *af)
+ }
return true
}
case javaLibTag:
@@ -1996,7 +2020,7 @@
a.filesInfo = filesInfo
// Set suffix and primaryApexType depending on the ApexType
- buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuildApps()
+ buildFlattenedAsDefault := ctx.Config().FlattenApex()
switch a.properties.ApexType {
case imageApex:
if buildFlattenedAsDefault {
@@ -2111,17 +2135,23 @@
}
// Add classpaths.proto config.
- filesToAdd = append(filesToAdd, apexClasspathFragmentProtoFile(ctx, module))
+ if af := apexClasspathFragmentProtoFile(ctx, module); af != nil {
+ filesToAdd = append(filesToAdd, *af)
+ }
return filesToAdd
}
-// apexClasspathFragmentProtoFile returns apexFile structure defining the classpath.proto config that
-// the module contributes to the apex.
-func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) apexFile {
- fragmentInfo := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
- classpathProtoOutput := fragmentInfo.ClasspathFragmentProtoOutput
- return newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), fragmentInfo.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
+// apexClasspathFragmentProtoFile returns *apexFile structure defining the classpath.proto config that
+// the module contributes to the apex; or nil if the proto config was not generated.
+func apexClasspathFragmentProtoFile(ctx android.ModuleContext, module blueprint.Module) *apexFile {
+ info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
+ if !info.ClasspathFragmentProtoGenerated {
+ return nil
+ }
+ classpathProtoOutput := info.ClasspathFragmentProtoOutput
+ af := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), info.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
+ return &af
}
// apexFileForBootclasspathFragmentContentModule creates an apexFile for a bootclasspath_fragment
@@ -2158,6 +2188,7 @@
android.InitDefaultableModule(module)
android.InitSdkAwareModule(module)
android.InitOverridableModule(module, &module.overridableProperties.Overrides)
+ android.InitBazelModule(module)
return module
}
@@ -2303,16 +2334,33 @@
})
}
-// Enforce that Java deps of the apex are using stable SDKs to compile
+// checkUpdatable enforces APEX and its transitive dep properties to have desired values for updatable APEXes.
func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) {
if a.Updatable() {
if String(a.properties.Min_sdk_version) == "" {
ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
}
+ if a.UsePlatformApis() {
+ ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
+ }
a.checkJavaStableSdkVersion(ctx)
+ a.checkClasspathFragments(ctx)
}
}
+// checkClasspathFragments enforces that all classpath fragments in deps generate classpaths.proto config.
+func (a *apexBundle) checkClasspathFragments(ctx android.ModuleContext) {
+ ctx.VisitDirectDeps(func(module android.Module) {
+ if tag := ctx.OtherModuleDependencyTag(module); tag == bcpfTag || tag == sscpfTag {
+ info := ctx.OtherModuleProvider(module, java.ClasspathFragmentProtoContentInfoProvider).(java.ClasspathFragmentProtoContentInfo)
+ if !info.ClasspathFragmentProtoGenerated {
+ ctx.OtherModuleErrorf(module, "is included in updatable apex %v, it must not set generate_classpaths_proto to false", ctx.ModuleName())
+ }
+ }
+ })
+}
+
+// checkJavaStableSdkVersion enforces that all Java deps are using stable SDKs to compile.
func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
// Visit direct deps only. As long as we guarantee top-level deps are using stable SDKs,
// java's checkLinkType guarantees correct usage for transitive deps
@@ -2331,7 +2379,7 @@
})
}
-// Ensures that the all the dependencies are marked as available for this APEX
+// checkApexAvailability ensures that the all the dependencies are marked as available for this APEX.
func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
// Let's be practical. Availability for test, host, and the VNDK apex isn't important
if ctx.Host() || a.testApex || a.vndkApex {
@@ -2383,6 +2431,49 @@
})
}
+// checkStaticExecutable ensures that executables in an APEX are not static.
+func (a *apexBundle) checkStaticExecutables(ctx android.ModuleContext) {
+ // No need to run this for host APEXes
+ if ctx.Host() {
+ return
+ }
+
+ ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
+ if ctx.OtherModuleDependencyTag(module) != executableTag {
+ return
+ }
+
+ if l, ok := module.(cc.LinkableInterface); ok && l.StaticExecutable() {
+ apex := a.ApexVariationName()
+ exec := ctx.OtherModuleName(module)
+ if isStaticExecutableAllowed(apex, exec) {
+ return
+ }
+ ctx.ModuleErrorf("executable %s is static", ctx.OtherModuleName(module))
+ }
+ })
+}
+
+// A small list of exceptions where static executables are allowed in APEXes.
+func isStaticExecutableAllowed(apex string, exec string) bool {
+ m := map[string][]string{
+ "com.android.runtime": []string{
+ "linker",
+ "linkerconfig",
+ },
+ }
+ execNames, ok := m[apex]
+ return ok && android.InList(exec, execNames)
+}
+
+// Collect information for opening IDE project files in java/jdeps.go.
+func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
+ dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
+ dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
+ dpInfo.Deps = append(dpInfo.Deps, a.properties.Systemserverclasspath_fragments...)
+ dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
+}
+
var (
apexAvailBaseline = makeApexAvailableBaseline()
inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
@@ -3070,3 +3161,127 @@
},
}
}
+
+// For Bazel / bp2build
+
+type bazelApexBundleAttributes struct {
+ Manifest bazel.LabelAttribute
+ Android_manifest bazel.LabelAttribute
+ File_contexts bazel.LabelAttribute
+ Key bazel.LabelAttribute
+ Certificate bazel.LabelAttribute
+ Min_sdk_version string
+ Updatable bazel.BoolAttribute
+ Installable bazel.BoolAttribute
+ Native_shared_libs bazel.LabelListAttribute
+ Binaries bazel.StringListAttribute
+ Prebuilts bazel.LabelListAttribute
+}
+
+type bazelApexBundle struct {
+ android.BazelTargetModuleBase
+ bazelApexBundleAttributes
+}
+
+func BazelApexBundleFactory() android.Module {
+ module := &bazelApexBundle{}
+ module.AddProperties(&module.bazelApexBundleAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+func ApexBundleBp2Build(ctx android.TopDownMutatorContext) {
+ module, ok := ctx.Module().(*apexBundle)
+ if !ok {
+ // Not an APEX bundle
+ return
+ }
+ if !module.ConvertWithBp2build(ctx) {
+ return
+ }
+ if ctx.ModuleType() != "apex" {
+ return
+ }
+
+ apexBundleBp2BuildInternal(ctx, module)
+}
+
+func apexBundleBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexBundle) {
+ var manifestLabelAttribute bazel.LabelAttribute
+ if module.properties.Manifest != nil {
+ manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.Manifest))
+ }
+
+ var androidManifestLabelAttribute bazel.LabelAttribute
+ if module.properties.AndroidManifest != nil {
+ androidManifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.AndroidManifest))
+ }
+
+ var fileContextsLabelAttribute bazel.LabelAttribute
+ if module.properties.File_contexts != nil {
+ fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.properties.File_contexts))
+ }
+
+ var minSdkVersion string
+ if module.properties.Min_sdk_version != nil {
+ minSdkVersion = *module.properties.Min_sdk_version
+ }
+
+ var keyLabelAttribute bazel.LabelAttribute
+ if module.overridableProperties.Key != nil {
+ keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.overridableProperties.Key))
+ }
+
+ var certificateLabelAttribute bazel.LabelAttribute
+ if module.overridableProperties.Certificate != nil {
+ certificateLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.overridableProperties.Certificate))
+ }
+
+ nativeSharedLibs := module.properties.ApexNativeDependencies.Native_shared_libs
+ nativeSharedLibsLabelList := android.BazelLabelForModuleDeps(ctx, nativeSharedLibs)
+ nativeSharedLibsLabelListAttribute := bazel.MakeLabelListAttribute(nativeSharedLibsLabelList)
+
+ prebuilts := module.properties.Prebuilts
+ prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
+ prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
+
+ binaries := module.properties.ApexNativeDependencies.Binaries
+ binariesStringListAttribute := bazel.MakeStringListAttribute(binaries)
+
+ var updatableAttribute bazel.BoolAttribute
+ if module.properties.Updatable != nil {
+ updatableAttribute.Value = module.properties.Updatable
+ }
+
+ var installableAttribute bazel.BoolAttribute
+ if module.properties.Installable != nil {
+ installableAttribute.Value = module.properties.Installable
+ }
+
+ attrs := &bazelApexBundleAttributes{
+ Manifest: manifestLabelAttribute,
+ Android_manifest: androidManifestLabelAttribute,
+ File_contexts: fileContextsLabelAttribute,
+ Min_sdk_version: minSdkVersion,
+ Key: keyLabelAttribute,
+ Certificate: certificateLabelAttribute,
+ Updatable: updatableAttribute,
+ Installable: installableAttribute,
+ Native_shared_libs: nativeSharedLibsLabelListAttribute,
+ Binaries: binariesStringListAttribute,
+ Prebuilts: prebuiltsLabelListAttribute,
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "apex",
+ Bzl_load_location: "//build/bazel/rules:apex.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(BazelApexBundleFactory, module.Name(), props, attrs)
+}
+
+func (m *bazelApexBundle) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelApexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index 9823842..6faed70 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -59,8 +59,15 @@
echo "******************************";
echo "Detected changes to allowed dependencies in updatable modules.";
echo "To fix and update packages/modules/common/build/allowed_deps.txt, please run:";
- echo "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)";
- echo "Members of mainline-modularization@google.com will review the changes.";
+ echo -e "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)\n";
+ echo "When submitting the generated CL, you must include the following information";
+ echo "in the commit message if you are adding a new dependency:";
+ echo "Apex-Size-Increase:";
+ echo "Previous-Platform-Support:";
+ echo "Aosp-First:";
+ echo "Test-Info:";
+ echo "You do not need OWNERS approval to submit the change, but mainline-modularization@";
+ echo "will periodically review additions and may require changes.";
echo -e "******************************\n";
exit 1;
fi;
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 7b01b94..39db1f0 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -374,7 +374,6 @@
symlinks: ["foo_link_"],
symlink_preferred_arch: true,
system_shared_libs: [],
- static_executable: true,
stl: "none",
apex_available: [ "myapex", "com.android.gki.*" ],
}
@@ -709,6 +708,79 @@
}
}
+func TestApexManifestMinSdkVersion(t *testing.T) {
+ ctx := testApex(t, `
+ apex_defaults {
+ name: "my_defaults",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: ":my-file-contexts",
+ updatable: false,
+ }
+ apex {
+ name: "myapex_30",
+ min_sdk_version: "30",
+ defaults: ["my_defaults"],
+ }
+
+ apex {
+ name: "myapex_current",
+ min_sdk_version: "current",
+ defaults: ["my_defaults"],
+ }
+
+ apex {
+ name: "myapex_none",
+ defaults: ["my_defaults"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ filegroup {
+ name: "my-file-contexts",
+ srcs: ["product_specific_file_contexts"],
+ }
+ `, withFiles(map[string][]byte{
+ "product_specific_file_contexts": nil,
+ }), android.FixtureModifyProductVariables(
+ func(variables android.FixtureProductVariables) {
+ variables.Unbundled_build = proptools.BoolPtr(true)
+ variables.Always_use_prebuilt_sdks = proptools.BoolPtr(false)
+ }), android.FixtureMergeEnv(map[string]string{
+ "UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT": "true",
+ }))
+
+ testCases := []struct {
+ module string
+ minSdkVersion string
+ }{
+ {
+ module: "myapex_30",
+ minSdkVersion: "30",
+ },
+ {
+ module: "myapex_current",
+ minSdkVersion: "Q.$$(cat out/soong/api_fingerprint.txt)",
+ },
+ {
+ module: "myapex_none",
+ minSdkVersion: "Q.$$(cat out/soong/api_fingerprint.txt)",
+ },
+ }
+ for _, tc := range testCases {
+ module := ctx.ModuleForTests(tc.module, "android_common_"+tc.module+"_image")
+ args := module.Rule("apexRule").Args
+ optFlags := args["opt_flags"]
+ if !strings.Contains(optFlags, "--min_sdk_version "+tc.minSdkVersion) {
+ t.Errorf("%s: Expected min_sdk_version=%s, got: %s", tc.module, tc.minSdkVersion, optFlags)
+ }
+ }
+}
+
func TestBasicZipApex(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -766,6 +838,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib", "mylib3"],
+ binaries: ["foo.rust"],
updatable: false,
}
@@ -814,6 +887,25 @@
stl: "none",
apex_available: [ "myapex" ],
}
+
+ rust_binary {
+ name: "foo.rust",
+ srcs: ["foo.rs"],
+ shared_libs: ["libfoo.shared_from_rust"],
+ prefer_rlib: true,
+ apex_available: ["myapex"],
+ }
+
+ cc_library_shared {
+ name: "libfoo.shared_from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: {
+ versions: ["10", "11", "12"],
+ },
+ }
+
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
@@ -851,7 +943,90 @@
"lib64/mylib.so",
"lib64/mylib3.so",
"lib64/mylib4.so",
+ "bin/foo.rust",
+ "lib64/libc++.so", // by the implicit dependency from foo.rust
+ "lib64/liblog.so", // by the implicit dependency from foo.rust
})
+
+ // Ensure that stub dependency from a rust module is not included
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
+ // The rust module is linked to the stub cc library
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
+ ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
+ ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
+}
+
+func TestApexCanUsePrivateApis(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["mylib"],
+ binaries: ["foo.rust"],
+ updatable: false,
+ platform_apis: true,
+ }
+
+ 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: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
+
+ cc_library {
+ name: "mylib2",
+ srcs: ["mylib.cpp"],
+ cflags: ["-include mylib.h"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ }
+
+ rust_binary {
+ name: "foo.rust",
+ srcs: ["foo.rs"],
+ shared_libs: ["libfoo.shared_from_rust"],
+ prefer_rlib: true,
+ apex_available: ["myapex"],
+ }
+
+ cc_library_shared {
+ name: "libfoo.shared_from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: {
+ versions: ["10", "11", "12"],
+ },
+ }
+ `)
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+
+ // Ensure that indirect stubs dep is not included
+ ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
+
+ // Ensure that we are using non-stub variants of mylib2 and libfoo.shared_from_rust (because
+ // of the platform_apis: true)
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000_private").Rule("ld").Args["libFlags"]
+ ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
+ ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000_private").Rule("rustc").Args["linkFlags"]
+ ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
+ ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
}
func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
@@ -1620,6 +1795,36 @@
expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
+func TestApexMinSdkVersion_SupportsCodeNames_JavaLibs(t *testing.T) {
+ testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["libx"],
+ min_sdk_version: "S",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "libx",
+ srcs: ["a.java"],
+ apex_available: [ "myapex" ],
+ sdk_version: "current",
+ min_sdk_version: "S", // should be okay
+ }
+ `,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_version_active_codenames = []string{"S"}
+ variables.Platform_sdk_codename = proptools.StringPtr("S")
+ }),
+ )
+}
+
func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -2286,7 +2491,6 @@
srcs: ["mylib.cpp"],
relative_install_path: "foo/bar",
system_shared_libs: [],
- static_executable: true,
stl: "none",
apex_available: [ "myapex" ],
}
@@ -2346,7 +2550,6 @@
name: "mybin",
relative_install_path: "foo/bar",
system_shared_libs: [],
- static_executable: true,
stl: "none",
apex_available: [ "myapex" ],
native_bridge_supported: true,
@@ -3115,60 +3318,109 @@
}
func TestVndkApexCurrent(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- updatable: false,
- }
-
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
-
- cc_library {
- name: "libvndksp",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- `+vndkLibrariesTxtFiles("current"))
-
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{
- "lib/libvndk.so",
- "lib/libvndksp.so",
+ commonFiles := []string{
"lib/libc++.so",
- "lib64/libvndk.so",
- "lib64/libvndksp.so",
"lib64/libc++.so",
"etc/llndk.libraries.29.txt",
"etc/vndkcore.libraries.29.txt",
"etc/vndksp.libraries.29.txt",
"etc/vndkprivate.libraries.29.txt",
"etc/vndkproduct.libraries.29.txt",
- })
+ }
+ testCases := []struct {
+ vndkVersion string
+ expectedFiles []string
+ }{
+ {
+ vndkVersion: "current",
+ expectedFiles: append(commonFiles,
+ "lib/libvndk.so",
+ "lib/libvndksp.so",
+ "lib64/libvndk.so",
+ "lib64/libvndksp.so"),
+ },
+ {
+ vndkVersion: "",
+ expectedFiles: append(commonFiles,
+ // Legacy VNDK APEX contains only VNDK-SP files (of core variant)
+ "lib/libvndksp.so",
+ "lib64/libvndksp.so"),
+ },
+ }
+ for _, tc := range testCases {
+ t.Run("VNDK.current with DeviceVndkVersion="+tc.vndkVersion, func(t *testing.T) {
+ ctx := testApex(t, `
+ apex_vndk {
+ name: "com.android.vndk.current",
+ key: "com.android.vndk.current.key",
+ updatable: false,
+ }
+
+ apex_key {
+ name: "com.android.vndk.current.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libvndk",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "com.android.vndk.current" ],
+ }
+
+ cc_library {
+ name: "libvndksp",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "com.android.vndk.current" ],
+ }
+
+ // VNDK-Ext should not cause any problems
+
+ cc_library {
+ name: "libvndk.ext",
+ srcs: ["mylib2.cpp"],
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libvndksp.ext",
+ srcs: ["mylib2.cpp"],
+ vendor: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ extends: "libvndksp",
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `+vndkLibrariesTxtFiles("current"), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.DeviceVndkVersion = proptools.StringPtr(tc.vndkVersion)
+ }))
+ ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", tc.expectedFiles)
+ })
+ }
}
func TestVndkApexWithPrebuilt(t *testing.T) {
@@ -4262,6 +4514,13 @@
prebuilt_bootclasspath_fragment {
name: "art-bootclasspath-fragment",
contents: ["core-oj"],
+ hidden_api: {
+ 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",
+ },
}
java_import {
@@ -4282,16 +4541,26 @@
p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
dexJarBuildPath := p.DexJarBuildPath()
stem := android.RemoveOptionalPrebuiltPrefix(name)
- if expected, actual := ".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar", android.NormalizePathForTesting(dexJarBuildPath); actual != expected {
- t.Errorf("Incorrect DexJarBuildPath value '%s', expected '%s'", actual, expected)
- }
+ android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.",
+ ".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar",
+ android.NormalizePathForTesting(dexJarBuildPath))
+ }
+
+ checkDexJarInstallPath := func(t *testing.T, ctx *android.TestContext, name string) {
+ // Make sure the import has been given the correct path to the dex jar.
+ p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
+ dexJarBuildPath := p.DexJarInstallPath()
+ stem := android.RemoveOptionalPrebuiltPrefix(name)
+ android.AssertStringEquals(t, "DexJarInstallPath should be apex-related path.",
+ "target/product/test_device/apex/myapex/javalib/"+stem+".jar",
+ android.NormalizePathForTesting(dexJarBuildPath))
}
ensureNoSourceVariant := func(t *testing.T, ctx *android.TestContext, name string) {
// Make sure that an apex variant is not created for the source module.
- if expected, actual := []string{"android_common"}, ctx.ModuleVariantsForTests(name); !reflect.DeepEqual(expected, actual) {
- t.Errorf("invalid set of variants for %q: expected %q, found %q", "libfoo", expected, actual)
- }
+ android.AssertArrayString(t, "Check if there is no source variant",
+ []string{"android_common"},
+ ctx.ModuleVariantsForTests(name))
}
t.Run("prebuilt only", func(t *testing.T) {
@@ -4340,8 +4609,10 @@
}
checkDexJarBuildPath(t, ctx, "libfoo")
+ checkDexJarInstallPath(t, ctx, "libfoo")
checkDexJarBuildPath(t, ctx, "libbar")
+ checkDexJarInstallPath(t, ctx, "libbar")
})
t.Run("prebuilt with source preferred", func(t *testing.T) {
@@ -4387,9 +4658,11 @@
ctx := testDexpreoptWithApexes(t, bp, "", transform)
checkDexJarBuildPath(t, ctx, "prebuilt_libfoo")
+ checkDexJarInstallPath(t, ctx, "prebuilt_libfoo")
ensureNoSourceVariant(t, ctx, "libfoo")
checkDexJarBuildPath(t, ctx, "prebuilt_libbar")
+ checkDexJarInstallPath(t, ctx, "prebuilt_libbar")
ensureNoSourceVariant(t, ctx, "libbar")
})
@@ -4437,9 +4710,11 @@
ctx := testDexpreoptWithApexes(t, bp, "", transform)
checkDexJarBuildPath(t, ctx, "prebuilt_libfoo")
+ checkDexJarInstallPath(t, ctx, "prebuilt_libfoo")
ensureNoSourceVariant(t, ctx, "libfoo")
checkDexJarBuildPath(t, ctx, "prebuilt_libbar")
+ checkDexJarInstallPath(t, ctx, "prebuilt_libbar")
ensureNoSourceVariant(t, ctx, "libbar")
})
}
@@ -4469,7 +4744,7 @@
}
}
- checkHiddenAPIIndexInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
+ checkHiddenAPIIndexFromClassesInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
t.Helper()
platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
var rule android.TestingBuildParams
@@ -4478,6 +4753,15 @@
java.CheckHiddenAPIRuleInputs(t, "intermediate index", expectedIntermediateInputs, rule)
}
+ checkHiddenAPIIndexFromFlagsInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
+ t.Helper()
+ platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
+ var rule android.TestingBuildParams
+
+ rule = platformBootclasspath.Output("hiddenapi-index.csv")
+ java.CheckHiddenAPIRuleInputs(t, "monolithic index", expectedIntermediateInputs, rule)
+ }
+
fragment := java.ApexVariantReference{
Apex: proptools.StringPtr("myapex"),
Module: proptools.StringPtr("my-bootclasspath-fragment"),
@@ -4502,6 +4786,13 @@
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
+ hidden_api: {
+ 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",
+ },
}
java_import {
@@ -4525,9 +4816,10 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexInputs(t, ctx, `
- out/soong/.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar
- out/soong/.intermediates/libfoo/android_common_myapex/combined/libfoo.jar
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
+ my-bootclasspath-fragment/index.csv
+ out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
`)
})
@@ -4543,6 +4835,13 @@
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
+ hidden_api: {
+ 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",
+ },
}
java_import {
@@ -4566,9 +4865,10 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexInputs(t, ctx, `
- out/soong/.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar
- out/soong/.intermediates/libfoo/android_common_myapex/combined/libfoo.jar
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
+ my-bootclasspath-fragment/index.csv
+ out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
`)
})
@@ -4591,6 +4891,13 @@
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
+ hidden_api: {
+ 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",
+ },
}
java_import {
@@ -4649,6 +4956,13 @@
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
+ hidden_api: {
+ 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",
+ },
}
java_import {
@@ -4687,9 +5001,10 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexInputs(t, ctx, `
- out/soong/.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar
- out/soong/.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
+ my-bootclasspath-fragment/index.csv
+ out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
`)
})
@@ -4725,6 +5040,13 @@
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
+ hidden_api: {
+ 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",
+ },
}
java_import {
@@ -4761,9 +5083,10 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexInputs(t, ctx, `
- out/soong/.intermediates/libbar/android_common_myapex/javac/libbar.jar
- out/soong/.intermediates/libfoo/android_common_apex10000/javac/libfoo.jar
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
+ my-bootclasspath-fragment/index.csv
+ out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
`)
})
@@ -4799,6 +5122,13 @@
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
+ hidden_api: {
+ 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",
+ },
}
java_import {
@@ -4837,9 +5167,10 @@
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexInputs(t, ctx, `
- out/soong/.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar
- out/soong/.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar
+ checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
+ checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
+ my-bootclasspath-fragment/index.csv
+ out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
`)
})
}
@@ -6568,73 +6899,6 @@
return result.TestContext
}
-func TestDuplicateDeapexeresFromPrebuiltApexes(t *testing.T) {
- preparers := android.GroupFixturePreparers(
- java.PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithApexBuildComponents,
- ).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
- `Ambiguous duplicate deapexer module dependencies "com.android.myapex.deapexer" and "com.mycompany.android.myapex.deapexer"`))
-
- bpBase := `
- apex_set {
- name: "com.android.myapex",
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- set: "myapex.apks",
- }
-
- apex_set {
- name: "com.mycompany.android.myapex",
- apex_name: "com.android.myapex",
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- set: "company-myapex.apks",
- }
-
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- apex_available: ["com.android.myapex"],
- %s
- }
- `
-
- t.Run("java_import", func(t *testing.T) {
- _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- apex_available: ["com.android.myapex"],
- }
- `)
- })
-
- t.Run("java_sdk_library_import", func(t *testing.T) {
- _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
- java_sdk_library_import {
- name: "libfoo",
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["com.android.myapex"],
- }
- `)
- })
-
- t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) {
- _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `
- image_name: "art",
- contents: ["libfoo"],
- `)+`
- java_sdk_library_import {
- name: "libfoo",
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["com.android.myapex"],
- }
- `)
- })
-}
-
func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
apex {
@@ -6666,6 +6930,47 @@
`)
}
+func TestUpdatable_should_not_set_generate_classpaths_proto(t *testing.T) {
+ testApexError(t, `"mysystemserverclasspathfragment" .* it must not set generate_classpaths_proto to false`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ systemserverclasspath_fragments: [
+ "mysystemserverclasspathfragment",
+ ],
+ min_sdk_version: "29",
+ updatable: true,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["b.java"],
+ min_sdk_version: "29",
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ generate_classpaths_proto: false,
+ contents: [
+ "foo",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ `)
+}
+
func TestNoUpdatableJarsInBootImage(t *testing.T) {
// Set the BootJars in dexpreopt.GlobalConfig and productVariables to the same value. This can
// result in an invalid configuration as it does not set the ArtApexJars and allows art apex
@@ -6788,6 +7093,13 @@
name: "my-bootclasspath-fragment",
contents: ["libfoo"],
apex_available: ["myapex"],
+ hidden_api: {
+ 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",
+ },
}
java_import {
@@ -6799,7 +7111,7 @@
})
}
-func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJars []string, rules []android.Rule) {
+func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, bootJars []string, rules []android.Rule) {
t.Helper()
bp += `
apex_key {
@@ -6824,11 +7136,11 @@
PrepareForTestWithApexBuildComponents,
android.PrepareForTestWithNeverallowRules(rules),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- updatableBootJars := make([]string, 0, len(apexBootJars))
- for _, apexBootJar := range apexBootJars {
- updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
+ apexBootJars := make([]string, 0, len(bootJars))
+ for _, apexBootJar := range bootJars {
+ apexBootJars = append(apexBootJars, "myapex:"+apexBootJar)
}
- variables.UpdatableBootJars = android.CreateTestConfiguredJarList(updatableBootJars)
+ variables.ApexBootJars = android.CreateTestConfiguredJarList(apexBootJars)
}),
fs.AddToFixture(),
).
@@ -7627,6 +7939,28 @@
}
}
+func TestHostApexInHostOnlyBuild(t *testing.T) {
+ testApex(t, `
+ apex {
+ name: "myapex",
+ host_supported: true,
+ key: "myapex.key",
+ updatable: false,
+ payload_type: "zip",
+ }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `,
+ android.FixtureModifyConfig(func(config android.Config) {
+ // We may not have device targets in all builds, e.g. in
+ // prebuilts/build-tools/build-prebuilts.sh
+ config.Targets[android.Android] = []android.Target{}
+ }))
+}
+
func TestApexJavaCoverage(t *testing.T) {
bp := `
apex {
@@ -7701,6 +8035,57 @@
}
}
+func TestProhibitStaticExecutable(t *testing.T) {
+ testApexError(t, `executable mybin is static`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ binaries: ["mybin"],
+ min_sdk_version: "29",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_binary {
+ name: "mybin",
+ srcs: ["mylib.cpp"],
+ relative_install_path: "foo/bar",
+ static_executable: true,
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ min_sdk_version: "29",
+ }
+ `)
+
+ testApexError(t, `executable mybin.rust is static`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ binaries: ["mybin.rust"],
+ min_sdk_version: "29",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ rust_binary {
+ name: "mybin.rust",
+ srcs: ["foo.rs"],
+ static_executable: true,
+ apex_available: ["myapex"],
+ min_sdk_version: "29",
+ }
+ `)
+}
+
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 4b1600e..6098989 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -383,6 +383,13 @@
apex_available: [
"com.android.art",
],
+ hidden_api: {
+ annotation_flags: "mybootclasspathfragment/annotation-flags.csv",
+ metadata: "mybootclasspathfragment/metadata.csv",
+ index: "mybootclasspathfragment/index.csv",
+ stub_flags: "mybootclasspathfragment/stub-flags.csv",
+ all_flags: "mybootclasspathfragment/all-flags.csv",
+ },
}
`, contentsInsert(contents), prefer)
return android.FixtureAddTextFile("prebuilts/module_sdk/art/Android.bp", text)
@@ -582,6 +589,13 @@
apex_available: [
"com.android.art",
],
+ hidden_api: {
+ annotation_flags: "mybootclasspathfragment/annotation-flags.csv",
+ metadata: "mybootclasspathfragment/metadata.csv",
+ index: "mybootclasspathfragment/index.csv",
+ stub_flags: "mybootclasspathfragment/stub-flags.csv",
+ all_flags: "mybootclasspathfragment/all-flags.csv",
+ },
}
`)
@@ -734,7 +748,7 @@
prepareForTestWithMyapex,
// Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
- java.FixtureConfigureUpdatableBootJars("myapex:foo", "myapex:bar"),
+ java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
// is disabled.
android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
diff --git a/apex/builder.go b/apex/builder.go
index d2e6ad8..148f42f 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -602,6 +602,11 @@
// codename
if moduleMinSdkVersion.IsCurrent() || moduleMinSdkVersion.IsNone() {
minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
+
+ if java.UseApiFingerprint(ctx) {
+ minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
+ implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
+ }
}
// apex module doesn't have a concept of target_sdk_version, hence for the time
// being targetSdkVersion == default targetSdkVersion of the branch.
@@ -611,10 +616,6 @@
targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
}
- if java.UseApiFingerprint(ctx) {
- minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
- implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
- }
optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion)
optFlags = append(optFlags, "--min_sdk_version "+minSdkVersion)
@@ -760,7 +761,7 @@
rule := java.Signapk
args := map[string]string{
"certificates": pem.String() + " " + key.String(),
- "flags": "-a 4096", //alignment
+ "flags": "-a 4096 --align-file-size", //alignment
}
implicits := android.Paths{pem, key}
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
diff --git a/apex/key.go b/apex/key.go
index 8b33b59..32a7ce1 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -20,6 +20,7 @@
"strings"
"android/soong/android"
+ "android/soong/bazel"
"github.com/google/blueprint/proptools"
)
@@ -33,10 +34,13 @@
func registerApexKeyBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("apex_key", ApexKeyFactory)
ctx.RegisterSingletonType("apex_keys_text", apexKeysTextFactory)
+
+ android.RegisterBp2BuildMutator("apex_key", ApexKeyBp2Build)
}
type apexKey struct {
android.ModuleBase
+ android.BazelModuleBase
properties apexKeyProperties
@@ -61,6 +65,7 @@
module := &apexKey{}
module.AddProperties(&module.properties)
android.InitAndroidArchModule(module, android.HostAndDeviceDefault, android.MultilibCommon)
+ android.InitBazelModule(module)
return module
}
@@ -190,3 +195,68 @@
func (s *apexKeysText) MakeVars(ctx android.MakeVarsContext) {
ctx.Strict("SOONG_APEX_KEYS_FILE", s.output.String())
}
+
+// For Bazel / bp2build
+
+type bazelApexKeyAttributes struct {
+ Public_key bazel.LabelAttribute
+ Private_key bazel.LabelAttribute
+}
+
+type bazelApexKey struct {
+ android.BazelTargetModuleBase
+ bazelApexKeyAttributes
+}
+
+func BazelApexKeyFactory() android.Module {
+ module := &bazelApexKey{}
+ module.AddProperties(&module.bazelApexKeyAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+func ApexKeyBp2Build(ctx android.TopDownMutatorContext) {
+ module, ok := ctx.Module().(*apexKey)
+ if !ok {
+ // Not an APEX key
+ return
+ }
+ if !module.ConvertWithBp2build(ctx) {
+ return
+ }
+ if ctx.ModuleType() != "apex_key" {
+ return
+ }
+
+ apexKeyBp2BuildInternal(ctx, module)
+}
+
+func apexKeyBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexKey) {
+ var privateKeyLabelAttribute bazel.LabelAttribute
+ if module.properties.Private_key != nil {
+ privateKeyLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.Private_key))
+ }
+
+ var publicKeyLabelAttribute bazel.LabelAttribute
+ if module.properties.Public_key != nil {
+ publicKeyLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.Public_key))
+ }
+
+ attrs := &bazelApexKeyAttributes{
+ Private_key: privateKeyLabelAttribute,
+ Public_key: publicKeyLabelAttribute,
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "apex_key",
+ Bzl_load_location: "//build/bazel/rules:apex_key.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(BazelApexKeyFactory, module.Name(), props, attrs)
+}
+
+func (m *bazelApexKey) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelApexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index bc35479..3066c79 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -159,11 +159,12 @@
android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category])
}
- android.AssertPathsRelativeToTopEquals(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/stub-flags.csv"}, info.StubFlagsPaths)
android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/index.csv"}, info.IndexPaths)
- android.AssertPathsRelativeToTopEquals(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/all-flags.csv"}, info.AllFlagsPaths)
+
+ android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
+ android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/all-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex10000/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
}
func TestPlatformBootclasspathDependencies(t *testing.T) {
@@ -173,7 +174,7 @@
prepareForTestWithMyapex,
// Configure some libraries in the art and framework boot images.
java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"),
- java.FixtureConfigureUpdatableBootJars("myapex:bar"),
+ java.FixtureConfigureApexBootJars("myapex:bar"),
java.PrepareForTestWithJavaSdkLibraryFiles,
java.FixtureWithLastReleaseApis("foo"),
).RunTestWithBp(t, `
@@ -288,7 +289,7 @@
"com.android.art:quuz",
"platform:foo",
- // The configured contents of UpdatableBootJars.
+ // The configured contents of ApexBootJars.
"myapex:bar",
})
@@ -313,7 +314,7 @@
`com.android.art:quuz`,
`platform:foo`,
- // The configured contents of UpdatableBootJars.
+ // The configured contents of ApexBootJars.
`myapex:bar`,
// The fragments.
@@ -348,7 +349,7 @@
// if the dependency on myapex:foo is filtered out because of either of those conditions then
// the dependencies resolved by the platform_bootclasspath will not match the configured list
// and so will fail the test.
- java.FixtureConfigureUpdatableBootJars("myapex:foo", "myapex:bar"),
+ java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
java.PrepareForTestWithJavaSdkLibraryFiles,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
@@ -482,3 +483,62 @@
pairs := java.ApexNamePairsFromModules(ctx, modules)
android.AssertDeepEquals(t, "module dependencies", expected, pairs)
}
+
+// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in
+// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config
+// by setting generate_classpaths_proto property to false.
+func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ prepareForTestWithMyapex,
+ java.FixtureConfigureApexBootJars("myapex:foo"),
+ android.FixtureWithRootAndroidBp(`
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ fragments: [
+ {
+ apex: "myapex",
+ module:"foo-fragment",
+ },
+ ],
+ }
+
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: ["foo-fragment"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ bootclasspath_fragment {
+ name: "foo-fragment",
+ generate_classpaths_proto: false,
+ contents: ["foo"],
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["foo"],
+ }
+ `),
+ ).RunTest(t)
+
+ java.CheckClasspathFragmentProtoContentInfoProvider(t, result,
+ true, // proto should be generated
+ "myapex:foo", // apex doesn't generate its own config, so must be in platform_bootclasspath
+ "bootclasspath.pb",
+ "out/soong/target/product/test_device/system/etc/classpaths",
+ )
+}
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index 95b6e23..537f51d 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -76,3 +76,54 @@
`mysystemserverclasspathfragment`,
})
}
+
+func TestSystemserverclasspathFragmentNoGeneratedProto(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForTestWithSystemserverclasspathFragment,
+ prepareForTestWithMyapex,
+ ).RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ systemserverclasspath_fragments: [
+ "mysystemserverclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ generate_classpaths_proto: false,
+ contents: [
+ "foo",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ `)
+
+ ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
+ "javalib/foo.jar",
+ })
+
+ java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
+ `myapex.key`,
+ `mysystemserverclasspathfragment`,
+ })
+}
diff --git a/bazel/Android.bp b/bazel/Android.bp
index b7c185a..b68d65b 100644
--- a/bazel/Android.bp
+++ b/bazel/Android.bp
@@ -7,6 +7,7 @@
pkgPath: "android/soong/bazel",
srcs: [
"aquery.go",
+ "configurability.go",
"constants.go",
"properties.go",
],
diff --git a/bazel/aquery.go b/bazel/aquery.go
index 555f1dc..8741afb 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -73,31 +73,39 @@
// BuildStatement contains information to register a build statement corresponding (one to one)
// with a Bazel action from Bazel's action graph.
type BuildStatement struct {
- Command string
- Depfile *string
- OutputPaths []string
- InputPaths []string
- Env []KeyValuePair
- Mnemonic string
+ Command string
+ Depfile *string
+ OutputPaths []string
+ InputPaths []string
+ SymlinkPaths []string
+ Env []KeyValuePair
+ Mnemonic string
}
-// AqueryBuildStatements returns an array of BuildStatements which should be registered (and output
-// to a ninja file) to correspond one-to-one with the given action graph json proto (from a bazel
-// aquery invocation).
-func AqueryBuildStatements(aqueryJsonProto []byte) ([]BuildStatement, error) {
- buildStatements := []BuildStatement{}
+// A helper type for aquery processing which facilitates retrieval of path IDs from their
+// less readable Bazel structures (depset and path fragment).
+type aqueryArtifactHandler struct {
+ // Maps middleman artifact Id to input artifact depset ID.
+ // Middleman artifacts are treated as "substitute" artifacts for mixed builds. For example,
+ // if we find a middleman action which has outputs [foo, bar], and output [baz_middleman], then,
+ // for each other action which has input [baz_middleman], we add [foo, bar] to the inputs for
+ // that action instead.
+ middlemanIdToDepsetIds map[int][]int
+ // Maps depset Id to depset struct.
+ depsetIdToDepset map[int]depSetOfFiles
+ // depsetIdToArtifactIdsCache is a memoization of depset flattening, because flattening
+ // may be an expensive operation.
+ depsetIdToArtifactIdsCache map[int][]int
+ // Maps artifact Id to fully expanded path.
+ artifactIdToPath map[int]string
+}
- var aqueryResult actionGraphContainer
- err := json.Unmarshal(aqueryJsonProto, &aqueryResult)
-
- if err != nil {
- return nil, err
- }
-
+func newAqueryHandler(aqueryResult actionGraphContainer) (*aqueryArtifactHandler, error) {
pathFragments := map[int]pathFragment{}
for _, pathFragment := range aqueryResult.PathFragments {
pathFragments[pathFragment.Id] = pathFragment
}
+
artifactIdToPath := map[int]string{}
for _, artifact := range aqueryResult.Artifacts {
artifactPath, err := expandPathFragment(artifact.PathFragmentId, pathFragments)
@@ -112,22 +120,87 @@
depsetIdToDepset[depset.Id] = depset
}
- // depsetIdToArtifactIdsCache is a memoization of depset flattening, because flattening
- // may be an expensive operation.
- depsetIdToArtifactIdsCache := map[int][]int{}
-
// Do a pass through all actions to identify which artifacts are middleman artifacts.
- // These will be omitted from the inputs of other actions.
- // TODO(b/180945500): Handle middleman actions; without proper handling, depending on generated
- // headers may cause build failures.
- middlemanArtifactIds := map[int]bool{}
+ middlemanIdToDepsetIds := map[int][]int{}
for _, actionEntry := range aqueryResult.Actions {
if actionEntry.Mnemonic == "Middleman" {
for _, outputId := range actionEntry.OutputIds {
- middlemanArtifactIds[outputId] = true
+ middlemanIdToDepsetIds[outputId] = actionEntry.InputDepSetIds
}
}
}
+ return &aqueryArtifactHandler{
+ middlemanIdToDepsetIds: middlemanIdToDepsetIds,
+ depsetIdToDepset: depsetIdToDepset,
+ depsetIdToArtifactIdsCache: map[int][]int{},
+ artifactIdToPath: artifactIdToPath,
+ }, nil
+}
+
+func (a *aqueryArtifactHandler) getInputPaths(depsetIds []int) ([]string, error) {
+ inputPaths := []string{}
+
+ for _, inputDepSetId := range depsetIds {
+ inputArtifacts, err := a.artifactIdsFromDepsetId(inputDepSetId)
+ if err != nil {
+ return nil, err
+ }
+ for _, inputId := range inputArtifacts {
+ if middlemanInputDepsetIds, isMiddlemanArtifact := a.middlemanIdToDepsetIds[inputId]; isMiddlemanArtifact {
+ // Add all inputs from middleman actions which created middleman artifacts which are
+ // in the inputs for this action.
+ swappedInputPaths, err := a.getInputPaths(middlemanInputDepsetIds)
+ if err != nil {
+ return nil, err
+ }
+ inputPaths = append(inputPaths, swappedInputPaths...)
+ } else {
+ inputPath, exists := a.artifactIdToPath[inputId]
+ if !exists {
+ return nil, fmt.Errorf("undefined input artifactId %d", inputId)
+ }
+ inputPaths = append(inputPaths, inputPath)
+ }
+ }
+ }
+ return inputPaths, nil
+}
+
+func (a *aqueryArtifactHandler) artifactIdsFromDepsetId(depsetId int) ([]int, error) {
+ if result, exists := a.depsetIdToArtifactIdsCache[depsetId]; exists {
+ return result, nil
+ }
+ if depset, exists := a.depsetIdToDepset[depsetId]; exists {
+ result := depset.DirectArtifactIds
+ for _, childId := range depset.TransitiveDepSetIds {
+ childArtifactIds, err := a.artifactIdsFromDepsetId(childId)
+ if err != nil {
+ return nil, err
+ }
+ result = append(result, childArtifactIds...)
+ }
+ a.depsetIdToArtifactIdsCache[depsetId] = result
+ return result, nil
+ } else {
+ return nil, fmt.Errorf("undefined input depsetId %d", depsetId)
+ }
+}
+
+// AqueryBuildStatements returns an array of BuildStatements which should be registered (and output
+// to a ninja file) to correspond one-to-one with the given action graph json proto (from a bazel
+// aquery invocation).
+func AqueryBuildStatements(aqueryJsonProto []byte) ([]BuildStatement, error) {
+ buildStatements := []BuildStatement{}
+
+ var aqueryResult actionGraphContainer
+ err := json.Unmarshal(aqueryJsonProto, &aqueryResult)
+ if err != nil {
+ return nil, err
+ }
+ aqueryHandler, err := newAqueryHandler(aqueryResult)
+ if err != nil {
+ return nil, err
+ }
for _, actionEntry := range aqueryResult.Actions {
if shouldSkipAction(actionEntry) {
@@ -136,7 +209,7 @@
outputPaths := []string{}
var depfile *string
for _, outputId := range actionEntry.OutputIds {
- outputPath, exists := artifactIdToPath[outputId]
+ outputPath, exists := aqueryHandler.artifactIdToPath[outputId]
if !exists {
return nil, fmt.Errorf("undefined outputId %d", outputId)
}
@@ -151,35 +224,32 @@
outputPaths = append(outputPaths, outputPath)
}
}
- inputPaths := []string{}
- for _, inputDepSetId := range actionEntry.InputDepSetIds {
- inputArtifacts, err :=
- artifactIdsFromDepsetId(depsetIdToDepset, depsetIdToArtifactIdsCache, inputDepSetId)
- if err != nil {
- return nil, err
- }
- for _, inputId := range inputArtifacts {
- if _, isMiddlemanArtifact := middlemanArtifactIds[inputId]; isMiddlemanArtifact {
- // Omit middleman artifacts.
- continue
- }
- inputPath, exists := artifactIdToPath[inputId]
- if !exists {
- return nil, fmt.Errorf("undefined input artifactId %d", inputId)
- }
- inputPaths = append(inputPaths, inputPath)
- }
+ inputPaths, err := aqueryHandler.getInputPaths(actionEntry.InputDepSetIds)
+ if err != nil {
+ return nil, err
}
+
buildStatement := BuildStatement{
Command: strings.Join(proptools.ShellEscapeList(actionEntry.Arguments), " "),
Depfile: depfile,
OutputPaths: outputPaths,
InputPaths: inputPaths,
Env: actionEntry.EnvironmentVariables,
- Mnemonic: actionEntry.Mnemonic}
- if len(actionEntry.Arguments) < 1 {
+ Mnemonic: actionEntry.Mnemonic,
+ }
+
+ if isSymlinkAction(actionEntry) {
+ if len(inputPaths) != 1 || len(outputPaths) != 1 {
+ return nil, fmt.Errorf("Expect 1 input and 1 output to symlink action, got: input %q, output %q", inputPaths, outputPaths)
+ }
+ out := outputPaths[0]
+ 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)
+ buildStatement.SymlinkPaths = outputPaths[:]
+ } else if len(actionEntry.Arguments) < 1 {
return nil, fmt.Errorf("received action with no command: [%v]", buildStatement)
- continue
}
buildStatements = append(buildStatements, buildStatement)
}
@@ -187,13 +257,18 @@
return buildStatements, nil
}
+func isSymlinkAction(a action) bool {
+ return a.Mnemonic == "Symlink" || a.Mnemonic == "SolibSymlink"
+}
+
func shouldSkipAction(a action) bool {
- // TODO(b/180945121): Handle symlink actions.
- if a.Mnemonic == "Symlink" || a.Mnemonic == "SourceSymlinkManifest" || a.Mnemonic == "SymlinkTree" {
+ // TODO(b/180945121): Handle complex symlink actions.
+ if a.Mnemonic == "SymlinkTree" || a.Mnemonic == "SourceSymlinkManifest" {
return true
}
- // TODO(b/180945500): Handle middleman actions; without proper handling, depending on generated
- // headers may cause build failures.
+ // Middleman actions are not handled like other actions; they are handled separately as a
+ // preparatory step so that their inputs may be relayed to actions depending on middleman
+ // artifacts.
if a.Mnemonic == "Middleman" {
return true
}
@@ -209,28 +284,6 @@
return false
}
-func artifactIdsFromDepsetId(depsetIdToDepset map[int]depSetOfFiles,
- depsetIdToArtifactIdsCache map[int][]int, depsetId int) ([]int, error) {
- if result, exists := depsetIdToArtifactIdsCache[depsetId]; exists {
- return result, nil
- }
- if depset, exists := depsetIdToDepset[depsetId]; exists {
- result := depset.DirectArtifactIds
- for _, childId := range depset.TransitiveDepSetIds {
- childArtifactIds, err :=
- artifactIdsFromDepsetId(depsetIdToDepset, depsetIdToArtifactIdsCache, childId)
- if err != nil {
- return nil, err
- }
- result = append(result, childArtifactIds...)
- }
- depsetIdToArtifactIdsCache[depsetId] = result
- return result, nil
- } else {
- return nil, fmt.Errorf("undefined input depsetId %d", depsetId)
- }
-}
-
func expandPathFragment(id int, pathFragmentsMap map[int]pathFragment) (string, error) {
labels := []string{}
currId := id
@@ -241,6 +294,9 @@
return "", fmt.Errorf("undefined path fragment id %d", currId)
}
labels = append([]string{currFragment.Label}, labels...)
+ if currId == currFragment.ParentId {
+ return "", fmt.Errorf("Fragment cannot refer to itself as parent %#v", currFragment)
+ }
currId = currFragment.ParentId
}
return filepath.Join(labels...), nil
diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go
index fa8810f..43e4155 100644
--- a/bazel/aquery_test.go
+++ b/bazel/aquery_test.go
@@ -718,17 +718,316 @@
assertBuildStatements(t, expectedBuildStatements, actualbuildStatements)
}
+func TestMiddlemenAction(t *testing.T) {
+ const inputString = `
+{
+ "artifacts": [{
+ "id": 1,
+ "pathFragmentId": 1
+ }, {
+ "id": 2,
+ "pathFragmentId": 2
+ }, {
+ "id": 3,
+ "pathFragmentId": 3
+ }, {
+ "id": 4,
+ "pathFragmentId": 4
+ }, {
+ "id": 5,
+ "pathFragmentId": 5
+ }, {
+ "id": 6,
+ "pathFragmentId": 6
+ }],
+ "pathFragments": [{
+ "id": 1,
+ "label": "middleinput_one"
+ }, {
+ "id": 2,
+ "label": "middleinput_two"
+ }, {
+ "id": 3,
+ "label": "middleman_artifact"
+ }, {
+ "id": 4,
+ "label": "maininput_one"
+ }, {
+ "id": 5,
+ "label": "maininput_two"
+ }, {
+ "id": 6,
+ "label": "output"
+ }],
+ "depSetOfFiles": [{
+ "id": 1,
+ "directArtifactIds": [1, 2]
+ }, {
+ "id": 2,
+ "directArtifactIds": [3, 4, 5]
+ }],
+ "actions": [{
+ "targetId": 1,
+ "actionKey": "x",
+ "mnemonic": "Middleman",
+ "arguments": ["touch", "foo"],
+ "inputDepSetIds": [1],
+ "outputIds": [3],
+ "primaryOutputId": 3
+ }, {
+ "targetId": 2,
+ "actionKey": "y",
+ "mnemonic": "Main action",
+ "arguments": ["touch", "foo"],
+ "inputDepSetIds": [2],
+ "outputIds": [6],
+ "primaryOutputId": 6
+ }]
+}`
+
+ actual, err := AqueryBuildStatements([]byte(inputString))
+ if err != nil {
+ t.Errorf("Unexpected error %q", err)
+ }
+ if expected := 1; len(actual) != expected {
+ t.Fatalf("Expected %d build statements, got %d", expected, len(actual))
+ }
+
+ bs := actual[0]
+ expectedInputs := []string{"middleinput_one", "middleinput_two", "maininput_one", "maininput_two"}
+ if !reflect.DeepEqual(bs.InputPaths, expectedInputs) {
+ t.Errorf("Expected main action inputs %q, but got %q", expectedInputs, bs.InputPaths)
+ }
+
+ expectedOutputs := []string{"output"}
+ if !reflect.DeepEqual(bs.OutputPaths, expectedOutputs) {
+ t.Errorf("Expected main action outputs %q, but got %q", expectedOutputs, bs.OutputPaths)
+ }
+}
+
+func TestSimpleSymlink(t *testing.T) {
+ const inputString = `
+{
+ "artifacts": [{
+ "id": 1,
+ "pathFragmentId": 3
+ }, {
+ "id": 2,
+ "pathFragmentId": 5
+ }],
+ "actions": [{
+ "targetId": 1,
+ "actionKey": "x",
+ "mnemonic": "Symlink",
+ "inputDepSetIds": [1],
+ "outputIds": [2],
+ "primaryOutputId": 2
+ }],
+ "depSetOfFiles": [{
+ "id": 1,
+ "directArtifactIds": [1]
+ }],
+ "pathFragments": [{
+ "id": 1,
+ "label": "one"
+ }, {
+ "id": 2,
+ "label": "file_subdir",
+ "parentId": 1
+ }, {
+ "id": 3,
+ "label": "file",
+ "parentId": 2
+ }, {
+ "id": 4,
+ "label": "symlink_subdir",
+ "parentId": 1
+ }, {
+ "id": 5,
+ "label": "symlink",
+ "parentId": 4
+ }]
+}`
+
+ actual, err := AqueryBuildStatements([]byte(inputString))
+
+ if err != nil {
+ t.Errorf("Unexpected error %q", err)
+ }
+
+ expectedBuildStatements := []BuildStatement{
+ BuildStatement{
+ Command: "mkdir -p one/symlink_subdir && " +
+ "rm -f one/symlink_subdir/symlink && " +
+ "ln -rsf 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"},
+ Mnemonic: "Symlink",
+ },
+ }
+ assertBuildStatements(t, actual, expectedBuildStatements)
+}
+
+func TestSymlinkQuotesPaths(t *testing.T) {
+ const inputString = `
+{
+ "artifacts": [{
+ "id": 1,
+ "pathFragmentId": 3
+ }, {
+ "id": 2,
+ "pathFragmentId": 5
+ }],
+ "actions": [{
+ "targetId": 1,
+ "actionKey": "x",
+ "mnemonic": "SolibSymlink",
+ "inputDepSetIds": [1],
+ "outputIds": [2],
+ "primaryOutputId": 2
+ }],
+ "depSetOfFiles": [{
+ "id": 1,
+ "directArtifactIds": [1]
+ }],
+ "pathFragments": [{
+ "id": 1,
+ "label": "one"
+ }, {
+ "id": 2,
+ "label": "file subdir",
+ "parentId": 1
+ }, {
+ "id": 3,
+ "label": "file",
+ "parentId": 2
+ }, {
+ "id": 4,
+ "label": "symlink subdir",
+ "parentId": 1
+ }, {
+ "id": 5,
+ "label": "symlink",
+ "parentId": 4
+ }]
+}`
+
+ actual, err := AqueryBuildStatements([]byte(inputString))
+
+ if err != nil {
+ t.Errorf("Unexpected error %q", err)
+ }
+
+ expectedBuildStatements := []BuildStatement{
+ BuildStatement{
+ Command: "mkdir -p 'one/symlink subdir' && " +
+ "rm -f 'one/symlink subdir/symlink' && " +
+ "ln -rsf '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"},
+ Mnemonic: "SolibSymlink",
+ },
+ }
+ assertBuildStatements(t, actual, expectedBuildStatements)
+}
+
+func TestSymlinkMultipleInputs(t *testing.T) {
+ const inputString = `
+{
+ "artifacts": [{
+ "id": 1,
+ "pathFragmentId": 1
+ }, {
+ "id": 2,
+ "pathFragmentId": 2
+ }, {
+ "id": 3,
+ "pathFragmentId": 3
+ }],
+ "actions": [{
+ "targetId": 1,
+ "actionKey": "x",
+ "mnemonic": "Symlink",
+ "inputDepSetIds": [1],
+ "outputIds": [3],
+ "primaryOutputId": 3
+ }],
+ "depSetOfFiles": [{
+ "id": 1,
+ "directArtifactIds": [1,2]
+ }],
+ "pathFragments": [{
+ "id": 1,
+ "label": "file"
+ }, {
+ "id": 2,
+ "label": "other_file"
+ }, {
+ "id": 3,
+ "label": "symlink"
+ }]
+}`
+
+ _, err := AqueryBuildStatements([]byte(inputString))
+ assertError(t, err, `Expect 1 input and 1 output to symlink action, got: input ["file" "other_file"], output ["symlink"]`)
+}
+
+func TestSymlinkMultipleOutputs(t *testing.T) {
+ const inputString = `
+{
+ "artifacts": [{
+ "id": 1,
+ "pathFragmentId": 1
+ }, {
+ "id": 2,
+ "pathFragmentId": 2
+ }, {
+ "id": 3,
+ "pathFragmentId": 3
+ }],
+ "actions": [{
+ "targetId": 1,
+ "actionKey": "x",
+ "mnemonic": "Symlink",
+ "inputDepSetIds": [1],
+ "outputIds": [2,3],
+ "primaryOutputId": 2
+ }],
+ "depSetOfFiles": [{
+ "id": 1,
+ "directArtifactIds": [1]
+ }],
+ "pathFragments": [{
+ "id": 1,
+ "label": "file"
+ }, {
+ "id": 2,
+ "label": "symlink"
+ }, {
+ "id": 3,
+ "label": "other_symlink"
+ }]
+}`
+
+ _, err := AqueryBuildStatements([]byte(inputString))
+ assertError(t, err, `Expect 1 input and 1 output to symlink action, got: input ["file"], output ["symlink" "other_symlink"]`)
+}
+
func assertError(t *testing.T, err error, expected string) {
+ t.Helper()
if err == nil {
t.Errorf("expected error '%s', but got no error", expected)
} else if err.Error() != expected {
- t.Errorf("expected error '%s', but got: %s", expected, err.Error())
+ t.Errorf("expected error:\n\t'%s', but got:\n\t'%s'", expected, err.Error())
}
}
// Asserts that the given actual build statements match the given expected build statements.
// Build statement equivalence is determined using buildStatementEquals.
func assertBuildStatements(t *testing.T, expected []BuildStatement, actual []BuildStatement) {
+ t.Helper()
if len(expected) != len(actual) {
t.Errorf("expected %d build statements, but got %d,\n expected: %v,\n actual: %v",
len(expected), len(actual), expected, actual)
@@ -765,6 +1064,12 @@
if !reflect.DeepEqual(stringSet(first.OutputPaths), stringSet(second.OutputPaths)) {
return false
}
+ if !reflect.DeepEqual(stringSet(first.SymlinkPaths), stringSet(second.SymlinkPaths)) {
+ return false
+ }
+ if first.Depfile != second.Depfile {
+ return false
+ }
return true
}
diff --git a/bazel/configurability.go b/bazel/configurability.go
new file mode 100644
index 0000000..f5f0913
--- /dev/null
+++ b/bazel/configurability.go
@@ -0,0 +1,228 @@
+// 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 bazel
+
+import (
+ "fmt"
+ "strings"
+)
+
+const (
+ // ArchType names in arch.go
+ archArm = "arm"
+ archArm64 = "arm64"
+ archX86 = "x86"
+ archX86_64 = "x86_64"
+
+ // OsType names in arch.go
+ osAndroid = "android"
+ osDarwin = "darwin"
+ osLinux = "linux_glibc"
+ osLinuxMusl = "linux_musl"
+ osLinuxBionic = "linux_bionic"
+ osWindows = "windows"
+
+ // Targets in arch.go
+ osArchAndroidArm = "android_arm"
+ osArchAndroidArm64 = "android_arm64"
+ osArchAndroidX86 = "android_x86"
+ osArchAndroidX86_64 = "android_x86_64"
+ osArchDarwinX86_64 = "darwin_x86_64"
+ osArchLinuxX86 = "linux_glibc_x86"
+ osArchLinuxX86_64 = "linux_glibc_x86_64"
+ osArchLinuxMuslX86 = "linux_musl_x86"
+ osArchLinuxMuslX86_64 = "linux_musl_x86_64"
+ osArchLinuxBionicArm64 = "linux_bionic_arm64"
+ osArchLinuxBionicX86_64 = "linux_bionic_x86_64"
+ osArchWindowsX86 = "windows_x86"
+ osArchWindowsX86_64 = "windows_x86_64"
+
+ // This is the string representation of the default condition wherever a
+ // configurable attribute is used in a select statement, i.e.
+ // //conditions:default for Bazel.
+ //
+ // This is consistently named "conditions_default" to mirror the Soong
+ // config variable default key in an Android.bp file, although there's no
+ // integration with Soong config variables (yet).
+ conditionsDefault = "conditions_default"
+
+ ConditionsDefaultSelectKey = "//conditions:default"
+
+ productVariableBazelPackage = "//build/bazel/product_variables"
+)
+
+var (
+ // These are the list of OSes and architectures with a Bazel config_setting
+ // and constraint value equivalent. These exist in arch.go, but the android
+ // package depends on the bazel package, so a cyclic dependency prevents
+ // using those variables here.
+
+ // A map of architectures to the Bazel label of the constraint_value
+ // for the @platforms//cpu:cpu constraint_setting
+ platformArchMap = map[string]string{
+ archArm: "//build/bazel/platforms/arch:arm",
+ archArm64: "//build/bazel/platforms/arch:arm64",
+ archX86: "//build/bazel/platforms/arch:x86",
+ archX86_64: "//build/bazel/platforms/arch:x86_64",
+ conditionsDefault: ConditionsDefaultSelectKey, // The default condition of as arch select map.
+ }
+
+ // A map of target operating systems to the Bazel label of the
+ // constraint_value for the @platforms//os:os constraint_setting
+ platformOsMap = map[string]string{
+ osAndroid: "//build/bazel/platforms/os:android",
+ osDarwin: "//build/bazel/platforms/os:darwin",
+ osLinux: "//build/bazel/platforms/os:linux",
+ osLinuxMusl: "//build/bazel/platforms/os:linux_musl",
+ osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
+ osWindows: "//build/bazel/platforms/os:windows",
+ conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
+ }
+
+ platformBionicMap = map[string]string{
+ "bionic": "//build/bazel/platforms/os:bionic",
+ conditionsDefault: 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",
+ osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86",
+ osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64",
+ osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
+ osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
+ osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
+ osArchLinuxMuslX86: "//build/bazel/platforms/os_arch:linux_musl_x86",
+ osArchLinuxMuslX86_64: "//build/bazel/platforms/os_arch:linux_musl_x86_64",
+ osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64",
+ osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
+ osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86",
+ osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
+ conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map.
+ }
+)
+
+// basic configuration types
+type configurationType int
+
+const (
+ noConfig configurationType = iota
+ arch
+ os
+ osArch
+ bionic
+ productVariables
+)
+
+func (ct configurationType) String() string {
+ return map[configurationType]string{
+ noConfig: "no_config",
+ arch: "arch",
+ os: "os",
+ osArch: "arch_os",
+ bionic: "bionic",
+ productVariables: "product_variables",
+ }[ct]
+}
+
+func (ct configurationType) validateConfig(config string) {
+ switch ct {
+ case noConfig:
+ if config != "" {
+ panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config))
+ }
+ case arch:
+ if _, ok := platformArchMap[config]; !ok {
+ panic(fmt.Errorf("Unknown arch: %s", config))
+ }
+ case os:
+ if _, ok := platformOsMap[config]; !ok {
+ panic(fmt.Errorf("Unknown os: %s", config))
+ }
+ case osArch:
+ 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:
+ panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
+ }
+}
+
+// SelectKey returns the Bazel select key for a given configurationType and config string.
+func (ct configurationType) SelectKey(config string) string {
+ ct.validateConfig(config)
+ switch ct {
+ case noConfig:
+ panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType "))
+ case arch:
+ return platformArchMap[config]
+ case os:
+ return platformOsMap[config]
+ case osArch:
+ return platformOsArchMap[config]
+ case bionic:
+ return platformBionicMap[config]
+ case productVariables:
+ if config == conditionsDefault {
+ return ConditionsDefaultSelectKey
+ }
+ return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(config))
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct))
+ }
+}
+
+var (
+ // Indicating there is no configuration axis
+ NoConfigAxis = ConfigurationAxis{configurationType: noConfig}
+ // An axis for architecture-specific configurations
+ ArchConfigurationAxis = ConfigurationAxis{configurationType: arch}
+ // An axis for os-specific configurations
+ 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
+func ProductVariableConfigurationAxis(variable string) ConfigurationAxis {
+ return ConfigurationAxis{
+ configurationType: productVariables,
+ subType: variable,
+ }
+}
+
+// ConfigurationAxis is an independent axis for configuration, there should be no overlap between
+// elements within an axis.
+type ConfigurationAxis struct {
+ configurationType
+ // some configuration types (e.g. productVariables) have multiple independent axes, subType helps
+ // distinguish between them without needing to list all 17 product variables.
+ subType string
+}
+
+func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
+ if ca.configurationType < other.configurationType {
+ return true
+ }
+ return ca.subType < other.subType
+}
diff --git a/bazel/constants.go b/bazel/constants.go
index 15c75cf..6beb496 100644
--- a/bazel/constants.go
+++ b/bazel/constants.go
@@ -18,6 +18,10 @@
// Run bazel as a ninja executer
BazelNinjaExecRunName = RunName("bazel-ninja-exec")
+
+ SoongInjectionDirName = "soong_injection"
+
+ GeneratedBazelFileWarning = "# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT"
)
// String returns the name of the run.
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index c30abeb..52c6c2f 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -16,6 +16,14 @@
CcStaticLibraryFiles []string
Includes []string
SystemIncludes []string
+ // Archives owned by the current target (not by its dependencies). These will
+ // be a subset of OutputFiles. (or static libraries, this will be equal to OutputFiles,
+ // but general cc_library will also have dynamic libraries in output files).
+ RootStaticArchives []string
+ // Dynamic libraries (.so files) created by the current target. These will
+ // be a subset of OutputFiles. (or shared libraries, this will be equal to OutputFiles,
+ // but general cc_library will also have dynamic libraries in output files).
+ RootDynamicLibraries []string
}
type getOutputFilesRequestType struct{}
@@ -70,6 +78,7 @@
ccObjectFiles = []
staticLibraries = []
+rootStaticArchives = []
linker_inputs = providers(target)["CcInfo"].linking_context.linker_inputs.to_list()
for linker_input in linker_inputs:
@@ -78,6 +87,15 @@
ccObjectFiles += [object.path]
if library.static_library:
staticLibraries.append(library.static_library.path)
+ if linker_input.owner == target.label:
+ rootStaticArchives.append(library.static_library.path)
+
+rootDynamicLibraries = []
+
+if "@rules_cc//examples:experimental_cc_shared_library.bzl%CcSharedLibraryInfo" in providers(target):
+ shared_info = providers(target)["@rules_cc//examples:experimental_cc_shared_library.bzl%CcSharedLibraryInfo"]
+ for lib in shared_info.linker_input.libraries:
+ rootDynamicLibraries += [lib.dynamic_library.path]
returns = [
outputFiles,
@@ -85,6 +103,8 @@
ccObjectFiles,
includes,
system_includes,
+ rootStaticArchives,
+ rootDynamicLibraries
]
return "|".join([", ".join(r) for r in returns])`
@@ -98,7 +118,7 @@
var ccObjects []string
splitString := strings.Split(rawString, "|")
- if expectedLen := 5; len(splitString) != expectedLen {
+ if expectedLen := 7; len(splitString) != expectedLen {
return CcInfo{}, fmt.Errorf("Expected %d items, got %q", expectedLen, splitString)
}
outputFilesString := splitString[0]
@@ -109,12 +129,16 @@
ccObjects = splitOrEmpty(ccObjectsString, ", ")
includes := splitOrEmpty(splitString[3], ", ")
systemIncludes := splitOrEmpty(splitString[4], ", ")
+ rootStaticArchives := splitOrEmpty(splitString[5], ", ")
+ rootDynamicLibraries := splitOrEmpty(splitString[6], ", ")
return CcInfo{
OutputFiles: outputFiles,
CcObjectFiles: ccObjects,
CcStaticLibraryFiles: ccStaticLibraries,
Includes: includes,
SystemIncludes: systemIncludes,
+ RootStaticArchives: rootStaticArchives,
+ RootDynamicLibraries: rootDynamicLibraries,
}, nil
}
diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go
index 6369999..035544e 100644
--- a/bazel/cquery/request_type_test.go
+++ b/bazel/cquery/request_type_test.go
@@ -46,48 +46,54 @@
}{
{
description: "no result",
- input: "||||",
+ input: "||||||",
expectedOutput: CcInfo{
OutputFiles: []string{},
CcObjectFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
+ RootStaticArchives: []string{},
+ RootDynamicLibraries: []string{},
},
},
{
description: "only output",
- input: "test||||",
+ input: "test||||||",
expectedOutput: CcInfo{
OutputFiles: []string{"test"},
CcObjectFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
+ RootStaticArchives: []string{},
+ RootDynamicLibraries: []string{},
},
},
{
description: "all items set",
- input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir",
+ input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir|rootstaticarchive1|rootdynamiclibrary1",
expectedOutput: CcInfo{
OutputFiles: []string{"out1", "out2"},
CcObjectFiles: []string{"object1", "object2"},
CcStaticLibraryFiles: []string{"static_lib1", "static_lib2"},
Includes: []string{".", "dir/subdir"},
SystemIncludes: []string{"system/dir", "system/other/dir"},
+ RootStaticArchives: []string{"rootstaticarchive1"},
+ RootDynamicLibraries: []string{"rootdynamiclibrary1"},
},
},
{
description: "too few result splits",
input: "|",
expectedOutput: CcInfo{},
- expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 5, []string{"", ""}),
+ expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 7, []string{"", ""}),
},
{
description: "too many result splits",
input: strings.Repeat("|", 8),
expectedOutput: CcInfo{},
- expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 5, make([]string, 9)),
+ expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 7, make([]string, 9)),
},
}
for _, tc := range testCases {
diff --git a/bazel/properties.go b/bazel/properties.go
index a71b12b..2656bad 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -19,6 +19,7 @@
"path/filepath"
"regexp"
"sort"
+ "strings"
)
// BazelTargetModuleProperties contain properties and metadata used for
@@ -33,6 +34,10 @@
const BazelTargetModuleNamePrefix = "__bp2build__"
+func StripNamePrefix(moduleName string) string {
+ return strings.TrimPrefix(moduleName, BazelTargetModuleNamePrefix)
+}
+
var productVariableSubstitutionPattern = regexp.MustCompile("%(d|s)")
// Label is used to represent a Bazel compatible Label. Also stores the original
@@ -64,6 +69,17 @@
Excludes []Label
}
+func (ll *LabelList) IsNil() bool {
+ return ll.Includes == nil && ll.Excludes == nil
+}
+
+func (ll *LabelList) deepCopy() LabelList {
+ return LabelList{
+ Includes: ll.Includes[:],
+ Excludes: ll.Excludes[:],
+ }
+}
+
// uniqueParentDirectories returns a list of the unique parent directories for
// all files in ll.Includes.
func (ll *LabelList) uniqueParentDirectories() []string {
@@ -105,7 +121,27 @@
return uniqueLabels
}
-func UniqueBazelLabelList(originalLabelList LabelList) LabelList {
+func FirstUniqueBazelLabels(originalLabels []Label) []Label {
+ var labels []Label
+ found := make(map[Label]bool, len(originalLabels))
+ for _, l := range originalLabels {
+ if _, ok := found[l]; ok {
+ continue
+ }
+ labels = append(labels, l)
+ found[l] = true
+ }
+ return labels
+}
+
+func FirstUniqueBazelLabelList(originalLabelList LabelList) LabelList {
+ var uniqueLabelList LabelList
+ uniqueLabelList.Includes = FirstUniqueBazelLabels(originalLabelList.Includes)
+ uniqueLabelList.Excludes = FirstUniqueBazelLabels(originalLabelList.Excludes)
+ return uniqueLabelList
+}
+
+func UniqueSortedBazelLabelList(originalLabelList LabelList) LabelList {
var uniqueLabelList LabelList
uniqueLabelList.Includes = UniqueSortedBazelLabels(originalLabelList.Includes)
uniqueLabelList.Excludes = UniqueSortedBazelLabels(originalLabelList.Excludes)
@@ -136,6 +172,76 @@
return strings
}
+// Map a function over all labels in a LabelList.
+func MapLabelList(mapOver LabelList, mapFn func(string) string) LabelList {
+ var includes []Label
+ for _, inc := range mapOver.Includes {
+ mappedLabel := Label{Label: mapFn(inc.Label), OriginalModuleName: inc.OriginalModuleName}
+ includes = append(includes, mappedLabel)
+ }
+ // mapFn is not applied over excludes, but they are propagated as-is.
+ return LabelList{Includes: includes, Excludes: mapOver.Excludes}
+}
+
+// Map a function over all Labels in a LabelListAttribute
+func MapLabelListAttribute(mapOver LabelListAttribute, mapFn func(string) string) LabelListAttribute {
+ var result LabelListAttribute
+
+ result.Value = MapLabelList(mapOver.Value, mapFn)
+
+ for axis, configToLabels := range mapOver.ConfigurableValues {
+ for config, value := range configToLabels {
+ result.SetSelectValue(axis, config, MapLabelList(value, mapFn))
+ }
+ }
+
+ return result
+}
+
+// Return all needles in a given haystack, where needleFn is true for needles.
+func FilterLabelList(haystack LabelList, needleFn func(string) bool) LabelList {
+ var includes []Label
+ for _, inc := range haystack.Includes {
+ if needleFn(inc.Label) {
+ includes = append(includes, inc)
+ }
+ }
+ // needleFn is not applied over excludes, but they are propagated as-is.
+ return LabelList{Includes: includes, Excludes: haystack.Excludes}
+}
+
+// Return all needles in a given haystack, where needleFn is true for needles.
+func FilterLabelListAttribute(haystack LabelListAttribute, needleFn func(string) bool) LabelListAttribute {
+ result := MakeLabelListAttribute(FilterLabelList(haystack.Value, needleFn))
+
+ for config, selects := range haystack.ConfigurableValues {
+ newSelects := make(labelListSelectValues, len(selects))
+ for k, v := range selects {
+ newSelects[k] = FilterLabelList(v, needleFn)
+ }
+ result.ConfigurableValues[config] = newSelects
+ }
+
+ return result
+}
+
+// Subtract needle from haystack
+func SubtractBazelLabelListAttribute(haystack LabelListAttribute, needle LabelListAttribute) LabelListAttribute {
+ result := MakeLabelListAttribute(SubtractBazelLabelList(haystack.Value, needle.Value))
+
+ for config, selects := range haystack.ConfigurableValues {
+ newSelects := make(labelListSelectValues, len(selects))
+ needleSelects := needle.ConfigurableValues[config]
+
+ for k, v := range selects {
+ newSelects[k] = SubtractBazelLabelList(v, needleSelects[k])
+ }
+ result.ConfigurableValues[config] = newSelects
+ }
+
+ return result
+}
+
// Subtract needle from haystack
func SubtractBazelLabels(haystack []Label, needle []Label) []Label {
// This is really a set
@@ -160,6 +266,14 @@
return labels
}
+// Appends two LabelLists, returning the combined list.
+func AppendBazelLabelLists(a LabelList, b LabelList) LabelList {
+ var result LabelList
+ result.Includes = append(a.Includes, b.Includes...)
+ result.Excludes = append(a.Excludes, b.Excludes...)
+ return result
+}
+
// Subtract needle from haystack
func SubtractBazelLabelList(haystack LabelList, needle LabelList) LabelList {
var result LabelList
@@ -169,247 +283,325 @@
return result
}
-const (
- // ArchType names in arch.go
- ARCH_ARM = "arm"
- ARCH_ARM64 = "arm64"
- ARCH_X86 = "x86"
- ARCH_X86_64 = "x86_64"
-
- // OsType names in arch.go
- OS_ANDROID = "android"
- OS_DARWIN = "darwin"
- OS_FUCHSIA = "fuchsia"
- OS_LINUX = "linux_glibc"
- OS_LINUX_BIONIC = "linux_bionic"
- OS_WINDOWS = "windows"
-
- // This is the string representation of the default condition wherever a
- // configurable attribute is used in a select statement, i.e.
- // //conditions:default for Bazel.
- //
- // This is consistently named "conditions_default" to mirror the Soong
- // config variable default key in an Android.bp file, although there's no
- // integration with Soong config variables (yet).
- CONDITIONS_DEFAULT = "conditions_default"
-)
-
-var (
- // These are the list of OSes and architectures with a Bazel config_setting
- // and constraint value equivalent. These exist in arch.go, but the android
- // package depends on the bazel package, so a cyclic dependency prevents
- // using those variables here.
-
- // A map of architectures to the Bazel label of the constraint_value
- // for the @platforms//cpu:cpu constraint_setting
- PlatformArchMap = map[string]string{
- ARCH_ARM: "//build/bazel/platforms/arch:arm",
- ARCH_ARM64: "//build/bazel/platforms/arch:arm64",
- ARCH_X86: "//build/bazel/platforms/arch:x86",
- ARCH_X86_64: "//build/bazel/platforms/arch:x86_64",
- CONDITIONS_DEFAULT: "//conditions:default", // The default condition of as arch select map.
- }
-
- // A map of target operating systems to the Bazel label of the
- // constraint_value for the @platforms//os:os constraint_setting
- PlatformOsMap = map[string]string{
- OS_ANDROID: "//build/bazel/platforms/os:android",
- OS_DARWIN: "//build/bazel/platforms/os:darwin",
- OS_FUCHSIA: "//build/bazel/platforms/os:fuchsia",
- OS_LINUX: "//build/bazel/platforms/os:linux",
- OS_LINUX_BIONIC: "//build/bazel/platforms/os:linux_bionic",
- OS_WINDOWS: "//build/bazel/platforms/os:windows",
- CONDITIONS_DEFAULT: "//conditions:default", // The default condition of an os select map.
- }
-)
-
type Attribute interface {
HasConfigurableValues() bool
}
+type labelSelectValues map[string]*Label
+
+type configurableLabels map[ConfigurationAxis]labelSelectValues
+
+func (cl configurableLabels) setValueForAxis(axis ConfigurationAxis, config string, value *Label) {
+ if cl[axis] == nil {
+ cl[axis] = make(labelSelectValues)
+ }
+ cl[axis][config] = value
+}
+
// Represents an attribute whose value is a single label
type LabelAttribute struct {
- Value Label
- X86 Label
- X86_64 Label
- Arm Label
- Arm64 Label
+ Value *Label
+
+ ConfigurableValues configurableLabels
}
-func (attr *LabelAttribute) GetValueForArch(arch string) Label {
- switch arch {
- case ARCH_ARM:
- return attr.Arm
- case ARCH_ARM64:
- return attr.Arm64
- case ARCH_X86:
- return attr.X86
- case ARCH_X86_64:
- return attr.X86_64
- case CONDITIONS_DEFAULT:
- return attr.Value
- default:
- panic("Invalid arch type")
- }
+// HasConfigurableValues returns whether there are configurable values set for this label.
+func (la LabelAttribute) HasConfigurableValues() bool {
+ return len(la.ConfigurableValues) > 0
}
-func (attr *LabelAttribute) SetValueForArch(arch string, value Label) {
- switch arch {
- case ARCH_ARM:
- attr.Arm = value
- case ARCH_ARM64:
- attr.Arm64 = value
- case ARCH_X86:
- attr.X86 = value
- case ARCH_X86_64:
- attr.X86_64 = value
- default:
- panic("Invalid arch type")
- }
+// SetValue sets the base, non-configured value for the Label
+func (la *LabelAttribute) SetValue(value Label) {
+ la.SetSelectValue(NoConfigAxis, "", value)
}
-func (attr LabelAttribute) HasConfigurableValues() bool {
- return attr.Arm.Label != "" || attr.Arm64.Label != "" || attr.X86.Label != "" || attr.X86_64.Label != ""
-}
-
-// Arch-specific label_list typed Bazel attribute values. This should correspond
-// to the types of architectures supported for compilation in arch.go.
-type labelListArchValues struct {
- X86 LabelList
- X86_64 LabelList
- Arm LabelList
- Arm64 LabelList
- Common LabelList
-
- ConditionsDefault LabelList
-}
-
-type labelListOsValues struct {
- Android LabelList
- Darwin LabelList
- Fuchsia LabelList
- Linux LabelList
- LinuxBionic LabelList
- Windows LabelList
-
- ConditionsDefault LabelList
-}
-
-// LabelListAttribute is used to represent a list of Bazel labels as an
-// attribute.
-type LabelListAttribute struct {
- // The non-arch specific attribute label list Value. Required.
- Value LabelList
-
- // The arch-specific attribute label list values. Optional. If used, these
- // are generated in a select statement and appended to the non-arch specific
- // label list Value.
- ArchValues labelListArchValues
-
- // The os-specific attribute label list values. Optional. If used, these
- // are generated in a select statement and appended to the non-os specific
- // label list Value.
- OsValues labelListOsValues
-}
-
-// MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value.
-func MakeLabelListAttribute(value LabelList) LabelListAttribute {
- return LabelListAttribute{Value: UniqueBazelLabelList(value)}
-}
-
-// Append all values, including os and arch specific ones, from another
-// LabelListAttribute to this LabelListAttribute.
-func (attrs *LabelListAttribute) Append(other LabelListAttribute) {
- for arch := range PlatformArchMap {
- this := attrs.GetValueForArch(arch)
- that := other.GetValueForArch(arch)
- this.Append(that)
- attrs.SetValueForArch(arch, this)
- }
-
- for os := range PlatformOsMap {
- this := attrs.GetValueForOS(os)
- that := other.GetValueForOS(os)
- this.Append(that)
- attrs.SetValueForOS(os, this)
- }
-
- attrs.Value.Append(other.Value)
-}
-
-// HasArchSpecificValues returns true if the attribute contains
-// architecture-specific label_list values.
-func (attrs LabelListAttribute) HasConfigurableValues() bool {
- for arch := range PlatformArchMap {
- if len(attrs.GetValueForArch(arch).Includes) > 0 {
- return true
+// SetSelectValue set a value for a bazel select for the given axis, config and value.
+func (la *LabelAttribute) SetSelectValue(axis ConfigurationAxis, config string, value Label) {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ la.Value = &value
+ case arch, os, osArch, bionic, productVariables:
+ if la.ConfigurableValues == nil {
+ la.ConfigurableValues = make(configurableLabels)
}
+ la.ConfigurableValues.setValueForAxis(axis, config, &value)
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SelectValue gets a value for a bazel select for the given axis and config.
+func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) Label {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ return *la.Value
+ case arch, os, osArch, bionic, productVariables:
+ return *la.ConfigurableValues[axis][config]
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
+func (la *LabelAttribute) SortedConfigurationAxes() []ConfigurationAxis {
+ keys := make([]ConfigurationAxis, 0, len(la.ConfigurableValues))
+ for k := range la.ConfigurableValues {
+ keys = append(keys, k)
}
- for os := range PlatformOsMap {
- if len(attrs.GetValueForOS(os).Includes) > 0 {
+ sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
+ return keys
+}
+
+type configToBools map[string]bool
+
+func (ctb configToBools) setValue(config string, value *bool) {
+ if value == nil {
+ if _, ok := ctb[config]; ok {
+ delete(ctb, config)
+ }
+ return
+ }
+ ctb[config] = *value
+}
+
+type configurableBools map[ConfigurationAxis]configToBools
+
+func (cb configurableBools) setValueForAxis(axis ConfigurationAxis, config string, value *bool) {
+ if cb[axis] == nil {
+ cb[axis] = make(configToBools)
+ }
+ cb[axis].setValue(config, value)
+}
+
+// BoolAttribute represents an attribute whose value is a single bool but may be configurable..
+type BoolAttribute struct {
+ Value *bool
+
+ ConfigurableValues configurableBools
+}
+
+// HasConfigurableValues returns whether there are configurable values for this attribute.
+func (ba BoolAttribute) HasConfigurableValues() bool {
+ return len(ba.ConfigurableValues) > 0
+}
+
+// SetSelectValue sets value for the given axis/config.
+func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, value *bool) {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ ba.Value = value
+ case arch, os, osArch, bionic, productVariables:
+ if ba.ConfigurableValues == nil {
+ ba.ConfigurableValues = make(configurableBools)
+ }
+ ba.ConfigurableValues.setValueForAxis(axis, config, value)
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SelectValue gets the value for the given axis/config.
+func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ return ba.Value
+ case arch, os, osArch, bionic, productVariables:
+ if v, ok := ba.ConfigurableValues[axis][config]; ok {
+ return &v
+ } else {
+ return nil
+ }
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
+func (ba *BoolAttribute) SortedConfigurationAxes() []ConfigurationAxis {
+ keys := make([]ConfigurationAxis, 0, len(ba.ConfigurableValues))
+ for k := range ba.ConfigurableValues {
+ keys = append(keys, k)
+ }
+
+ sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
+ return keys
+}
+
+// labelListSelectValues supports config-specific label_list typed Bazel attribute values.
+type labelListSelectValues map[string]LabelList
+
+func (ll labelListSelectValues) appendSelects(other labelListSelectValues) {
+ for k, v := range other {
+ l := ll[k]
+ (&l).Append(v)
+ ll[k] = l
+ }
+}
+
+// HasConfigurableValues returns whether there are configurable values within this set of selects.
+func (ll labelListSelectValues) HasConfigurableValues() bool {
+ for _, v := range ll {
+ if len(v.Includes) > 0 {
return true
}
}
return false
}
-func (attrs *LabelListAttribute) archValuePtrs() map[string]*LabelList {
- return map[string]*LabelList{
- ARCH_X86: &attrs.ArchValues.X86,
- ARCH_X86_64: &attrs.ArchValues.X86_64,
- ARCH_ARM: &attrs.ArchValues.Arm,
- ARCH_ARM64: &attrs.ArchValues.Arm64,
- CONDITIONS_DEFAULT: &attrs.ArchValues.ConditionsDefault,
+// LabelListAttribute is used to represent a list of Bazel labels as an
+// attribute.
+type LabelListAttribute struct {
+ // The non-configured attribute label list Value. Required.
+ Value LabelList
+
+ // The configured attribute label list Values. Optional
+ // a map of independent configurability axes
+ ConfigurableValues configurableLabelLists
+}
+
+type configurableLabelLists map[ConfigurationAxis]labelListSelectValues
+
+func (cll configurableLabelLists) setValueForAxis(axis ConfigurationAxis, config string, list LabelList) {
+ if list.IsNil() {
+ if _, ok := cll[axis][config]; ok {
+ delete(cll[axis], config)
+ }
+ return
+ }
+ if cll[axis] == nil {
+ cll[axis] = make(labelListSelectValues)
+ }
+
+ cll[axis][config] = list
+}
+
+func (cll configurableLabelLists) Append(other configurableLabelLists) {
+ for axis, otherSelects := range other {
+ selects := cll[axis]
+ if selects == nil {
+ selects = make(labelListSelectValues, len(otherSelects))
+ }
+ selects.appendSelects(otherSelects)
+ cll[axis] = selects
}
}
-// GetValueForArch returns the label_list attribute value for an architecture.
-func (attrs *LabelListAttribute) GetValueForArch(arch string) LabelList {
- var v *LabelList
- if v = attrs.archValuePtrs()[arch]; v == nil {
- panic(fmt.Errorf("Unknown arch: %s", arch))
- }
- return *v
-}
-
-// SetValueForArch sets the label_list attribute value for an architecture.
-func (attrs *LabelListAttribute) SetValueForArch(arch string, value LabelList) {
- var v *LabelList
- if v = attrs.archValuePtrs()[arch]; v == nil {
- panic(fmt.Errorf("Unknown arch: %s", arch))
- }
- *v = value
-}
-
-func (attrs *LabelListAttribute) osValuePtrs() map[string]*LabelList {
- return map[string]*LabelList{
- OS_ANDROID: &attrs.OsValues.Android,
- OS_DARWIN: &attrs.OsValues.Darwin,
- OS_FUCHSIA: &attrs.OsValues.Fuchsia,
- OS_LINUX: &attrs.OsValues.Linux,
- OS_LINUX_BIONIC: &attrs.OsValues.LinuxBionic,
- OS_WINDOWS: &attrs.OsValues.Windows,
- CONDITIONS_DEFAULT: &attrs.OsValues.ConditionsDefault,
+// MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value.
+func MakeLabelListAttribute(value LabelList) LabelListAttribute {
+ return LabelListAttribute{
+ Value: value,
+ ConfigurableValues: make(configurableLabelLists),
}
}
-// GetValueForOS returns the label_list attribute value for an OS target.
-func (attrs *LabelListAttribute) GetValueForOS(os string) LabelList {
- var v *LabelList
- if v = attrs.osValuePtrs()[os]; v == nil {
- panic(fmt.Errorf("Unknown os: %s", os))
- }
- return *v
+func (lla *LabelListAttribute) SetValue(list LabelList) {
+ lla.SetSelectValue(NoConfigAxis, "", list)
}
-// SetValueForArch sets the label_list attribute value for an OS target.
-func (attrs *LabelListAttribute) SetValueForOS(os string, value LabelList) {
- var v *LabelList
- if v = attrs.osValuePtrs()[os]; v == nil {
- panic(fmt.Errorf("Unknown os: %s", os))
+// SetSelectValue set a value for a bazel select for the given axis, config and value.
+func (lla *LabelListAttribute) SetSelectValue(axis ConfigurationAxis, config string, list LabelList) {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ lla.Value = list
+ case arch, os, osArch, bionic, productVariables:
+ if lla.ConfigurableValues == nil {
+ lla.ConfigurableValues = make(configurableLabelLists)
+ }
+ lla.ConfigurableValues.setValueForAxis(axis, config, list)
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
}
- *v = value
+}
+
+// SelectValue gets a value for a bazel select for the given axis and config.
+func (lla *LabelListAttribute) SelectValue(axis ConfigurationAxis, config string) LabelList {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ return lla.Value
+ case arch, os, osArch, bionic, productVariables:
+ return lla.ConfigurableValues[axis][config]
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
+func (lla *LabelListAttribute) SortedConfigurationAxes() []ConfigurationAxis {
+ keys := make([]ConfigurationAxis, 0, len(lla.ConfigurableValues))
+ for k := range lla.ConfigurableValues {
+ keys = append(keys, k)
+ }
+
+ sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
+ return keys
+}
+
+// Append all values, including os and arch specific ones, from another
+// LabelListAttribute to this LabelListAttribute.
+func (lla *LabelListAttribute) Append(other LabelListAttribute) {
+ lla.Value.Append(other.Value)
+ if lla.ConfigurableValues == nil {
+ lla.ConfigurableValues = make(configurableLabelLists)
+ }
+ lla.ConfigurableValues.Append(other.ConfigurableValues)
+}
+
+// HasConfigurableValues returns true if the attribute contains axis-specific label list values.
+func (lla LabelListAttribute) HasConfigurableValues() bool {
+ return len(lla.ConfigurableValues) > 0
+}
+
+// IsEmpty returns true if the attribute has no values under any configuration.
+func (lla LabelListAttribute) IsEmpty() bool {
+ if len(lla.Value.Includes) > 0 {
+ return false
+ }
+ for axis, _ := range lla.ConfigurableValues {
+ if lla.ConfigurableValues[axis].HasConfigurableValues() {
+ return false
+ }
+ }
+ return true
+}
+
+// ResolveExcludes handles excludes across the various axes, ensuring that items are removed from
+// the base value and included in default values as appropriate.
+func (lla *LabelListAttribute) ResolveExcludes() {
+ for axis, configToLabels := range lla.ConfigurableValues {
+ baseLabels := lla.Value.deepCopy()
+ for config, val := range configToLabels {
+ // Exclude config-specific excludes from base value
+ lla.Value = SubtractBazelLabelList(lla.Value, LabelList{Includes: val.Excludes})
+
+ // add base values to config specific to add labels excluded by others in this axis
+ // then remove all config-specific excludes
+ allLabels := baseLabels.deepCopy()
+ allLabels.Append(val)
+ lla.ConfigurableValues[axis][config] = SubtractBazelLabelList(allLabels, LabelList{Includes: val.Excludes})
+ }
+
+ // After going through all configs, delete the duplicates in the config
+ // values that are already in the base Value.
+ for config, val := range configToLabels {
+ lla.ConfigurableValues[axis][config] = SubtractBazelLabelList(val, lla.Value)
+ }
+
+ // Now that the Value list is finalized for this axis, compare it with the original
+ // list, and put the difference into the default condition for the axis.
+ lla.ConfigurableValues[axis][conditionsDefault] = SubtractBazelLabelList(baseLabels, lla.Value)
+
+ // if everything ends up without includes, just delete the axis
+ if !lla.ConfigurableValues[axis].HasConfigurableValues() {
+ delete(lla.ConfigurableValues, axis)
+ }
+ }
}
// StringListAttribute corresponds to the string_list Bazel attribute type with
@@ -418,139 +610,110 @@
// The base value of the string list attribute.
Value []string
- // The arch-specific attribute string list values. Optional. If used, these
- // are generated in a select statement and appended to the non-arch specific
- // label list Value.
- ArchValues stringListArchValues
-
- // The os-specific attribute string list values. Optional. If used, these
- // are generated in a select statement and appended to the non-os specific
- // label list Value.
- OsValues stringListOsValues
+ // The configured attribute label list Values. Optional
+ // a map of independent configurability axes
+ ConfigurableValues configurableStringLists
}
-// MakeStringListAttribute initializes a StringListAttribute with the non-arch specific value.
-func MakeStringListAttribute(value []string) StringListAttribute {
- // NOTE: These strings are not necessarily unique or sorted.
- return StringListAttribute{Value: value}
-}
+type configurableStringLists map[ConfigurationAxis]stringListSelectValues
-// Arch-specific string_list typed Bazel attribute values. This should correspond
-// to the types of architectures supported for compilation in arch.go.
-type stringListArchValues struct {
- X86 []string
- X86_64 []string
- Arm []string
- Arm64 []string
- Common []string
-
- ConditionsDefault []string
-}
-
-type stringListOsValues struct {
- Android []string
- Darwin []string
- Fuchsia []string
- Linux []string
- LinuxBionic []string
- Windows []string
-
- ConditionsDefault []string
-}
-
-// HasConfigurableValues returns true if the attribute contains
-// architecture-specific string_list values.
-func (attrs StringListAttribute) HasConfigurableValues() bool {
- for arch := range PlatformArchMap {
- if len(attrs.GetValueForArch(arch)) > 0 {
- return true
+func (csl configurableStringLists) Append(other configurableStringLists) {
+ for axis, otherSelects := range other {
+ selects := csl[axis]
+ if selects == nil {
+ selects = make(stringListSelectValues, len(otherSelects))
}
+ selects.appendSelects(otherSelects)
+ csl[axis] = selects
}
+}
- for os := range PlatformOsMap {
- if len(attrs.GetValueForOS(os)) > 0 {
+func (csl configurableStringLists) setValueForAxis(axis ConfigurationAxis, config string, list []string) {
+ if csl[axis] == nil {
+ csl[axis] = make(stringListSelectValues)
+ }
+ csl[axis][config] = list
+}
+
+type stringListSelectValues map[string][]string
+
+func (sl stringListSelectValues) appendSelects(other stringListSelectValues) {
+ for k, v := range other {
+ sl[k] = append(sl[k], v...)
+ }
+}
+
+func (sl stringListSelectValues) hasConfigurableValues(other stringListSelectValues) bool {
+ for _, val := range sl {
+ if len(val) > 0 {
return true
}
}
return false
}
-func (attrs *StringListAttribute) archValuePtrs() map[string]*[]string {
- return map[string]*[]string{
- ARCH_X86: &attrs.ArchValues.X86,
- ARCH_X86_64: &attrs.ArchValues.X86_64,
- ARCH_ARM: &attrs.ArchValues.Arm,
- ARCH_ARM64: &attrs.ArchValues.Arm64,
- CONDITIONS_DEFAULT: &attrs.ArchValues.ConditionsDefault,
+// MakeStringListAttribute initializes a StringListAttribute with the non-arch specific value.
+func MakeStringListAttribute(value []string) StringListAttribute {
+ // NOTE: These strings are not necessarily unique or sorted.
+ return StringListAttribute{
+ Value: value,
+ ConfigurableValues: make(configurableStringLists),
}
}
-// GetValueForArch returns the string_list attribute value for an architecture.
-func (attrs *StringListAttribute) GetValueForArch(arch string) []string {
- var v *[]string
- if v = attrs.archValuePtrs()[arch]; v == nil {
- panic(fmt.Errorf("Unknown arch: %s", arch))
- }
- return *v
-}
-
-// SetValueForArch sets the string_list attribute value for an architecture.
-func (attrs *StringListAttribute) SetValueForArch(arch string, value []string) {
- var v *[]string
- if v = attrs.archValuePtrs()[arch]; v == nil {
- panic(fmt.Errorf("Unknown arch: %s", arch))
- }
- *v = value
-}
-
-func (attrs *StringListAttribute) osValuePtrs() map[string]*[]string {
- return map[string]*[]string{
- OS_ANDROID: &attrs.OsValues.Android,
- OS_DARWIN: &attrs.OsValues.Darwin,
- OS_FUCHSIA: &attrs.OsValues.Fuchsia,
- OS_LINUX: &attrs.OsValues.Linux,
- OS_LINUX_BIONIC: &attrs.OsValues.LinuxBionic,
- OS_WINDOWS: &attrs.OsValues.Windows,
- CONDITIONS_DEFAULT: &attrs.OsValues.ConditionsDefault,
- }
-}
-
-// GetValueForOS returns the string_list attribute value for an OS target.
-func (attrs *StringListAttribute) GetValueForOS(os string) []string {
- var v *[]string
- if v = attrs.osValuePtrs()[os]; v == nil {
- panic(fmt.Errorf("Unknown os: %s", os))
- }
- return *v
-}
-
-// SetValueForArch sets the string_list attribute value for an OS target.
-func (attrs *StringListAttribute) SetValueForOS(os string, value []string) {
- var v *[]string
- if v = attrs.osValuePtrs()[os]; v == nil {
- panic(fmt.Errorf("Unknown os: %s", os))
- }
- *v = value
+// HasConfigurableValues returns true if the attribute contains axis-specific string_list values.
+func (sla StringListAttribute) HasConfigurableValues() bool {
+ return len(sla.ConfigurableValues) > 0
}
// Append appends all values, including os and arch specific ones, from another
// StringListAttribute to this StringListAttribute
-func (attrs *StringListAttribute) Append(other StringListAttribute) {
- for arch := range PlatformArchMap {
- this := attrs.GetValueForArch(arch)
- that := other.GetValueForArch(arch)
- this = append(this, that...)
- attrs.SetValueForArch(arch, this)
+func (sla *StringListAttribute) Append(other StringListAttribute) {
+ sla.Value = append(sla.Value, other.Value...)
+ if sla.ConfigurableValues == nil {
+ sla.ConfigurableValues = make(configurableStringLists)
+ }
+ sla.ConfigurableValues.Append(other.ConfigurableValues)
+}
+
+// SetSelectValue set a value for a bazel select for the given axis, config and value.
+func (sla *StringListAttribute) SetSelectValue(axis ConfigurationAxis, config string, list []string) {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ sla.Value = list
+ case arch, os, osArch, bionic, productVariables:
+ if sla.ConfigurableValues == nil {
+ sla.ConfigurableValues = make(configurableStringLists)
+ }
+ sla.ConfigurableValues.setValueForAxis(axis, config, list)
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SelectValue gets a value for a bazel select for the given axis and config.
+func (sla *StringListAttribute) SelectValue(axis ConfigurationAxis, config string) []string {
+ axis.validateConfig(config)
+ switch axis.configurationType {
+ case noConfig:
+ return sla.Value
+ case arch, os, osArch, bionic, productVariables:
+ return sla.ConfigurableValues[axis][config]
+ default:
+ panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+ }
+}
+
+// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
+func (sla *StringListAttribute) SortedConfigurationAxes() []ConfigurationAxis {
+ keys := make([]ConfigurationAxis, 0, len(sla.ConfigurableValues))
+ for k := range sla.ConfigurableValues {
+ keys = append(keys, k)
}
- for os := range PlatformOsMap {
- this := attrs.GetValueForOS(os)
- that := other.GetValueForOS(os)
- this = append(this, that...)
- attrs.SetValueForOS(os, this)
- }
-
- attrs.Value = append(attrs.Value, other.Value...)
+ sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
+ return keys
}
// TryVariableSubstitution, replace string substitution formatting within each string in slice with
@@ -569,6 +732,6 @@
// TryVariableSubstitution, replace string substitution formatting within s with Starlark
// string.format compatible tag for productVariable.
func TryVariableSubstitution(s string, productVariable string) (string, bool) {
- sub := productVariableSubstitutionPattern.ReplaceAllString(s, "{"+productVariable+"}")
+ sub := productVariableSubstitutionPattern.ReplaceAllString(s, "$("+productVariable+")")
return sub, s != sub
}
diff --git a/bazel/properties_test.go b/bazel/properties_test.go
index 229a4aa..9464245 100644
--- a/bazel/properties_test.go
+++ b/bazel/properties_test.go
@@ -122,7 +122,7 @@
}
}
}
-func TestUniqueBazelLabelList(t *testing.T) {
+func TestFirstUniqueBazelLabelList(t *testing.T) {
testCases := []struct {
originalLabelList LabelList
expectedUniqueLabelList LabelList
@@ -157,9 +157,139 @@
},
}
for _, tc := range testCases {
- actualUniqueLabelList := UniqueBazelLabelList(tc.originalLabelList)
+ actualUniqueLabelList := FirstUniqueBazelLabelList(tc.originalLabelList)
if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
}
}
}
+
+func TestUniqueSortedBazelLabelList(t *testing.T) {
+ testCases := []struct {
+ originalLabelList LabelList
+ expectedUniqueLabelList LabelList
+ }{
+ {
+ originalLabelList: LabelList{
+ Includes: []Label{
+ {Label: "c"},
+ {Label: "a"},
+ {Label: "a"},
+ {Label: "b"},
+ },
+ Excludes: []Label{
+ {Label: "y"},
+ {Label: "z"},
+ {Label: "x"},
+ {Label: "x"},
+ },
+ },
+ expectedUniqueLabelList: LabelList{
+ Includes: []Label{
+ {Label: "a"},
+ {Label: "b"},
+ {Label: "c"},
+ },
+ Excludes: []Label{
+ {Label: "x"},
+ {Label: "y"},
+ {Label: "z"},
+ },
+ },
+ },
+ }
+ for _, tc := range testCases {
+ actualUniqueLabelList := UniqueSortedBazelLabelList(tc.originalLabelList)
+ if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
+ t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
+ }
+ }
+}
+
+func makeLabels(labels ...string) []Label {
+ var ret []Label
+ for _, l := range labels {
+ ret = append(ret, Label{Label: l})
+ }
+ return ret
+}
+
+func makeLabelList(includes, excludes []string) LabelList {
+ return LabelList{
+ Includes: makeLabels(includes...),
+ Excludes: makeLabels(excludes...),
+ }
+}
+
+func TestResolveExcludes(t *testing.T) {
+ attr := LabelListAttribute{
+ Value: makeLabelList(
+ []string{
+ "all_include",
+ "arm_exclude",
+ "android_exclude",
+ },
+ []string{"all_exclude"},
+ ),
+ ConfigurableValues: configurableLabelLists{
+ ArchConfigurationAxis: labelListSelectValues{
+ "arm": makeLabelList([]string{}, []string{"arm_exclude"}),
+ "x86": makeLabelList([]string{"x86_include"}, []string{}),
+ },
+ OsConfigurationAxis: labelListSelectValues{
+ "android": makeLabelList([]string{}, []string{"android_exclude"}),
+ "linux": makeLabelList([]string{"linux_include"}, []string{}),
+ },
+ OsArchConfigurationAxis: labelListSelectValues{
+ "linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
+ },
+ ProductVariableConfigurationAxis("a"): labelListSelectValues{
+ "a": makeLabelList([]string{}, []string{"not_in_value"}),
+ },
+ },
+ }
+
+ attr.ResolveExcludes()
+
+ expectedBaseIncludes := []Label{Label{Label: "all_include"}}
+ if !reflect.DeepEqual(expectedBaseIncludes, attr.Value.Includes) {
+ t.Errorf("Expected Value includes %q, got %q", attr.Value.Includes, expectedBaseIncludes)
+ }
+ var nilLabels []Label
+ expectedConfiguredIncludes := map[ConfigurationAxis]map[string][]Label{
+ ArchConfigurationAxis: map[string][]Label{
+ "arm": nilLabels,
+ "x86": makeLabels("arm_exclude", "x86_include"),
+ "conditions_default": makeLabels("arm_exclude"),
+ },
+ OsConfigurationAxis: map[string][]Label{
+ "android": nilLabels,
+ "linux": makeLabels("android_exclude", "linux_include"),
+ "conditions_default": makeLabels("android_exclude"),
+ },
+ OsArchConfigurationAxis: map[string][]Label{
+ "linux_x86": makeLabels("linux_x86_include"),
+ "conditions_default": nilLabels,
+ },
+ }
+ for _, axis := range attr.SortedConfigurationAxes() {
+ if _, ok := expectedConfiguredIncludes[axis]; !ok {
+ t.Errorf("Found unexpected axis %s", axis)
+ continue
+ }
+ expectedForAxis := expectedConfiguredIncludes[axis]
+ gotForAxis := attr.ConfigurableValues[axis]
+ if len(expectedForAxis) != len(gotForAxis) {
+ t.Errorf("Expected %d configs for %s, got %d: %s", len(expectedForAxis), axis, len(gotForAxis), gotForAxis)
+ }
+ for config, value := range gotForAxis {
+ if expected, ok := expectedForAxis[config]; ok {
+ if !reflect.DeepEqual(expected, value.Includes) {
+ t.Errorf("For %s, expected: %#v, got %#v", axis, expected, value.Includes)
+ }
+ } else {
+ t.Errorf("Got unexpected config %q for %s", config, axis)
+ }
+ }
+ }
+}
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 3abbc4c..9ec637a 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -11,6 +11,7 @@
"build_conversion.go",
"bzl_conversion.go",
"configurability.go",
+ "compatibility.go",
"constants.go",
"conversion.go",
"metrics.go",
@@ -18,14 +19,19 @@
],
deps: [
"soong-android",
+ "soong-apex",
"soong-bazel",
"soong-cc",
"soong-cc-config",
+ "soong-etc",
"soong-genrule",
"soong-python",
"soong-sh",
],
testSrcs: [
+ "android_app_certificate_conversion_test.go",
+ "apex_conversion_test.go",
+ "apex_key_conversion_test.go",
"build_conversion_test.go",
"bzl_conversion_test.go",
"cc_library_conversion_test.go",
@@ -33,6 +39,7 @@
"cc_library_static_conversion_test.go",
"cc_object_conversion_test.go",
"conversion_test.go",
+ "prebuilt_etc_conversion_test.go",
"python_binary_conversion_test.go",
"sh_conversion_test.go",
"testing.go",
diff --git a/bp2build/android_app_certificate_conversion_test.go b/bp2build/android_app_certificate_conversion_test.go
new file mode 100644
index 0000000..022c687
--- /dev/null
+++ b/bp2build/android_app_certificate_conversion_test.go
@@ -0,0 +1,49 @@
+// 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/java"
+
+ "testing"
+)
+
+func runAndroidAppCertificateTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerAndroidAppCertificateModuleTypes, tc)
+}
+
+func registerAndroidAppCertificateModuleTypes(ctx android.RegistrationContext) {
+}
+
+func TestAndroidAppCertificateSimple(t *testing.T) {
+ runAndroidAppCertificateTestCase(t, bp2buildTestCase{
+ description: "Android app certificate - simple example",
+ moduleTypeUnderTest: "android_app_certificate",
+ moduleTypeUnderTestFactory: java.AndroidAppCertificateFactory,
+ moduleTypeUnderTestBp2BuildMutator: java.AndroidAppCertificateBp2Build,
+ filesystem: map[string]string{},
+ blueprint: `
+android_app_certificate {
+ name: "com.android.apogee.cert",
+ certificate: "chamber_of_secrets_dir",
+}
+`,
+ expectedBazelTargets: []string{`android_app_certificate(
+ name = "com.android.apogee.cert",
+ certificate = "chamber_of_secrets_dir",
+)`}})
+}
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
new file mode 100644
index 0000000..456f18a
--- /dev/null
+++ b/bp2build/apex_conversion_test.go
@@ -0,0 +1,178 @@
+// 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/apex"
+ "android/soong/cc"
+ "android/soong/java"
+
+ "testing"
+)
+
+func runApexTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerApexModuleTypes, tc)
+}
+
+func registerApexModuleTypes(ctx android.RegistrationContext) {
+ // CC module types needed as they can be APEX dependencies
+ cc.RegisterCCBuildComponents(ctx)
+
+ ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+ ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory)
+ ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+}
+
+func TestApexBundleSimple(t *testing.T) {
+ runApexTestCase(t, bp2buildTestCase{
+ description: "apex - simple example",
+ moduleTypeUnderTest: "apex",
+ moduleTypeUnderTestFactory: apex.BundleFactory,
+ moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build,
+ filesystem: map[string]string{},
+ blueprint: `
+apex_key {
+ name: "com.android.apogee.key",
+ public_key: "com.android.apogee.avbpubkey",
+ private_key: "com.android.apogee.pem",
+ bazel_module: { bp2build_available: false },
+}
+
+android_app_certificate {
+ name: "com.android.apogee.certificate",
+ certificate: "com.android.apogee",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "native_shared_lib_1",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "native_shared_lib_2",
+ bazel_module: { bp2build_available: false },
+}
+
+// TODO(b/194878861): Add bp2build support for prebuilt_etc
+cc_library {
+ name: "pretend_prebuilt_1",
+ bazel_module: { bp2build_available: false },
+}
+
+// TODO(b/194878861): Add bp2build support for prebuilt_etc
+cc_library {
+ name: "pretend_prebuilt_2",
+ bazel_module: { bp2build_available: false },
+}
+
+filegroup {
+ name: "com.android.apogee-file_contexts",
+ srcs: [
+ "com.android.apogee-file_contexts",
+ ],
+ bazel_module: { bp2build_available: false },
+}
+
+apex {
+ name: "com.android.apogee",
+ manifest: "apogee_manifest.json",
+ androidManifest: "ApogeeAndroidManifest.xml",
+ file_contexts: "com.android.apogee-file_contexts",
+ min_sdk_version: "29",
+ key: "com.android.apogee.key",
+ certificate: "com.android.apogee.certificate",
+ updatable: false,
+ installable: false,
+ native_shared_libs: [
+ "native_shared_lib_1",
+ "native_shared_lib_2",
+ ],
+ binaries: [
+ "binary_1",
+ "binary_2",
+ ],
+ prebuilts: [
+ "pretend_prebuilt_1",
+ "pretend_prebuilt_2",
+ ],
+}
+`,
+ expectedBazelTargets: []string{`apex(
+ name = "com.android.apogee",
+ android_manifest = "ApogeeAndroidManifest.xml",
+ binaries = [
+ "binary_1",
+ "binary_2",
+ ],
+ certificate = ":com.android.apogee.certificate",
+ file_contexts = ":com.android.apogee-file_contexts",
+ installable = False,
+ key = ":com.android.apogee.key",
+ manifest = "apogee_manifest.json",
+ min_sdk_version = "29",
+ native_shared_libs = [
+ ":native_shared_lib_1",
+ ":native_shared_lib_2",
+ ],
+ prebuilts = [
+ ":pretend_prebuilt_1",
+ ":pretend_prebuilt_2",
+ ],
+ updatable = False,
+)`}})
+}
+
+func TestApexBundleDefaultPropertyValues(t *testing.T) {
+ runApexTestCase(t, bp2buildTestCase{
+ description: "apex - default property values",
+ moduleTypeUnderTest: "apex",
+ moduleTypeUnderTestFactory: apex.BundleFactory,
+ moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build,
+ filesystem: map[string]string{},
+ blueprint: `
+apex {
+ name: "com.android.apogee",
+ manifest: "apogee_manifest.json",
+}
+`,
+ expectedBazelTargets: []string{`apex(
+ name = "com.android.apogee",
+ manifest = "apogee_manifest.json",
+)`}})
+}
+
+func TestApexBundleHasBazelModuleProps(t *testing.T) {
+ runApexTestCase(t, bp2buildTestCase{
+ description: "apex - has bazel module props",
+ moduleTypeUnderTest: "apex",
+ moduleTypeUnderTestFactory: apex.BundleFactory,
+ moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build,
+ filesystem: map[string]string{},
+ blueprint: `
+apex {
+ name: "apogee",
+ manifest: "manifest.json",
+ bazel_module: { bp2build_available: true },
+}
+`,
+ expectedBazelTargets: []string{`apex(
+ name = "apogee",
+ manifest = "manifest.json",
+)`}})
+}
diff --git a/bp2build/apex_key_conversion_test.go b/bp2build/apex_key_conversion_test.go
new file mode 100644
index 0000000..8e1aa09
--- /dev/null
+++ b/bp2build/apex_key_conversion_test.go
@@ -0,0 +1,51 @@
+// 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/apex"
+
+ "testing"
+)
+
+func runApexKeyTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerApexKeyModuleTypes, tc)
+}
+
+func registerApexKeyModuleTypes(ctx android.RegistrationContext) {
+}
+
+func TestApexKeySimple(t *testing.T) {
+ runApexKeyTestCase(t, bp2buildTestCase{
+ description: "apex key - simple example",
+ moduleTypeUnderTest: "apex_key",
+ moduleTypeUnderTestFactory: apex.ApexKeyFactory,
+ moduleTypeUnderTestBp2BuildMutator: apex.ApexKeyBp2Build,
+ filesystem: map[string]string{},
+ blueprint: `
+apex_key {
+ name: "com.android.apogee.key",
+ public_key: "com.android.apogee.avbpubkey",
+ private_key: "com.android.apogee.pem",
+}
+`,
+ expectedBazelTargets: []string{`apex_key(
+ name = "com.android.apogee.key",
+ private_key = "com.android.apogee.pem",
+ public_key = "com.android.apogee.avbpubkey",
+)`}})
+}
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index 59c5acd..06a7306 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "android/soong/bazel"
"fmt"
"os"
)
@@ -28,12 +29,12 @@
bp2buildDir := android.PathForOutput(ctx, "bp2build")
android.RemoveAllOutputDir(bp2buildDir)
- buildToTargets, metrics := GenerateBazelTargets(ctx, true)
+ buildToTargets, metrics, compatLayer := GenerateBazelTargets(ctx, true)
bp2buildFiles := CreateBazelFiles(nil, buildToTargets, ctx.mode)
writeFiles(ctx, bp2buildDir, bp2buildFiles)
- soongInjectionDir := android.PathForOutput(ctx, "soong_injection")
- writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles())
+ soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
+ writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(compatLayer))
return metrics
}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index bddc524..96a8b09 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -19,6 +19,7 @@
"android/soong/bazel"
"fmt"
"reflect"
+ "sort"
"strings"
"github.com/google/blueprint"
@@ -31,9 +32,11 @@
type BazelTarget struct {
name string
+ packageName string
content string
ruleClass string
bzlLoadLocation string
+ handcrafted bool
}
// IsLoadedFromStarlark determines if the BazelTarget's rule class is loaded from a .bzl file,
@@ -42,15 +45,60 @@
return t.bzlLoadLocation != ""
}
+// Label is the fully qualified Bazel label constructed from the BazelTarget's
+// package name and target name.
+func (t BazelTarget) Label() string {
+ if t.packageName == "." {
+ return "//:" + t.name
+ } else {
+ return "//" + t.packageName + ":" + t.name
+ }
+}
+
// BazelTargets is a typedef for a slice of BazelTarget objects.
type BazelTargets []BazelTarget
+// HasHandcraftedTargetsreturns true if a set of bazel targets contain
+// handcrafted ones.
+func (targets BazelTargets) hasHandcraftedTargets() bool {
+ for _, target := range targets {
+ if target.handcrafted {
+ return true
+ }
+ }
+ return false
+}
+
+// sort a list of BazelTargets in-place, by name, and by generated/handcrafted types.
+func (targets BazelTargets) sort() {
+ sort.Slice(targets, func(i, j int) bool {
+ if targets[i].handcrafted != targets[j].handcrafted {
+ // Handcrafted targets will be generated after the bp2build generated targets.
+ return targets[j].handcrafted
+ }
+ // This will cover all bp2build generated targets.
+ return targets[i].name < targets[j].name
+ })
+}
+
// String returns the string representation of BazelTargets, without load
// statements (use LoadStatements for that), since the targets are usually not
// adjacent to the load statements at the top of the BUILD file.
func (targets BazelTargets) String() string {
var res string
for i, target := range targets {
+ // There is only at most 1 handcrafted "target", because its contents
+ // represent the entire BUILD file content from the tree. See
+ // build_conversion.go#getHandcraftedBuildContent for more information.
+ //
+ // Add a header to make it easy to debug where the handcrafted targets
+ // are in a generated BUILD file.
+ if target.handcrafted {
+ res += "# -----------------------------\n"
+ res += "# Section: Handcrafted targets. \n"
+ res += "# -----------------------------\n\n"
+ }
+
res += target.content
if i != len(targets)-1 {
res += "\n\n"
@@ -176,7 +224,7 @@
return attributes
}
-func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[string]BazelTargets, CodegenMetrics) {
+func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[string]BazelTargets, CodegenMetrics, CodegenCompatLayer) {
buildFileToTargets := make(map[string]BazelTargets)
buildFileToAppend := make(map[string]bool)
@@ -185,6 +233,10 @@
RuleClassCount: make(map[string]int),
}
+ compatLayer := CodegenCompatLayer{
+ NameToLabelMap: make(map[string]string),
+ }
+
dirs := make(map[string]bool)
bpCtx := ctx.Context()
@@ -199,6 +251,7 @@
if b, ok := m.(android.Bazelable); ok && b.HasHandcraftedLabel() {
metrics.handCraftedTargetCount += 1
metrics.TotalModuleCount += 1
+ compatLayer.AddNameToLabelEntry(m.Name(), b.HandcraftedLabel())
pathToBuildFile := getBazelPackagePath(b)
// We are using the entire contents of handcrafted build file, so if multiple targets within
// a package have handcrafted targets, we only want to include the contents one time.
@@ -216,6 +269,7 @@
} else if btm, ok := m.(android.BazelTargetModule); ok {
t = generateBazelTarget(bpCtx, m, btm)
metrics.RuleClassCount[t.ruleClass] += 1
+ compatLayer.AddNameToLabelEntry(m.Name(), t.Label())
} else {
metrics.TotalModuleCount += 1
return
@@ -246,7 +300,7 @@
}
}
- return buildFileToTargets, metrics
+ return buildFileToTargets, metrics, compatLayer
}
func getBazelPackagePath(b android.Bazelable) string {
@@ -267,7 +321,8 @@
}
// TODO(b/181575318): once this is more targeted, we need to include name, rule class, etc
return BazelTarget{
- content: c,
+ content: c,
+ handcrafted: true,
}, nil
}
@@ -286,6 +341,7 @@
targetName := targetNameForBp2Build(ctx, m)
return BazelTarget{
name: targetName,
+ packageName: ctx.ModuleDir(m),
ruleClass: ruleClass,
bzlLoadLocation: bzlLoadLocation,
content: fmt.Sprintf(
@@ -294,6 +350,7 @@
targetName,
attributes,
),
+ handcrafted: false,
}
}
@@ -406,7 +463,7 @@
return prettyPrint(propertyValue.Elem(), indent)
case reflect.Slice:
if propertyValue.Len() == 0 {
- return "", nil
+ return "[]", nil
}
if propertyValue.Len() == 1 {
@@ -449,6 +506,9 @@
ret = "{\n"
// Sort and print the struct props by the key.
structProps := extractStructProperties(propertyValue, indent)
+ if len(structProps) == 0 {
+ return "", nil
+ }
for _, k := range android.SortedStringKeys(structProps) {
ret += makeIndent(indent + 1)
ret += fmt.Sprintf("%q: %s,\n", k, structProps[k])
@@ -528,7 +588,14 @@
} else {
return true
}
+ // Always print bools, if you want a bool attribute to be able to take the default value, use a
+ // bool pointer instead
+ case reflect.Bool:
+ return false
default:
+ if !value.IsValid() {
+ return true
+ }
zeroValue := reflect.Zero(value.Type())
result := value.Interface() == zeroValue.Interface()
return result
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 63a6c2e..e5dbda6 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -23,12 +23,14 @@
func TestGenerateSoongModuleTargets(t *testing.T) {
testCases := []struct {
+ description string
bp string
expectedBazelTarget string
}{
{
+ description: "only name",
bp: `custom { name: "foo" }
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -36,14 +38,16 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
)`,
},
{
+ description: "handles bool",
bp: `custom {
- name: "foo",
- ramdisk: true,
+ name: "foo",
+ bool_prop: true,
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -51,15 +55,16 @@
soong_module_variant = "",
soong_module_deps = [
],
- ramdisk = True,
+ bool_prop = True,
)`,
},
{
+ description: "string escaping",
bp: `custom {
- name: "foo",
- owner: "a_string_with\"quotes\"_and_\\backslashes\\\\",
+ name: "foo",
+ owner: "a_string_with\"quotes\"_and_\\backslashes\\\\",
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -67,15 +72,17 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
owner = "a_string_with\"quotes\"_and_\\backslashes\\\\",
)`,
},
{
+ description: "single item string list",
bp: `custom {
- name: "foo",
- required: ["bar"],
+ name: "foo",
+ required: ["bar"],
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -83,15 +90,17 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
required = ["bar"],
)`,
},
{
+ description: "list of strings",
bp: `custom {
- name: "foo",
- target_required: ["qux", "bazqux"],
+ name: "foo",
+ target_required: ["qux", "bazqux"],
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -99,6 +108,7 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
target_required = [
"qux",
"bazqux",
@@ -106,18 +116,19 @@
)`,
},
{
+ description: "dist/dists",
bp: `custom {
- name: "foo",
- dist: {
- targets: ["goal_foo"],
- tag: ".foo",
- },
- dists: [{
- targets: ["goal_bar"],
- tag: ".bar",
- }],
+ name: "foo",
+ dist: {
+ targets: ["goal_foo"],
+ tag: ".foo",
+ },
+ dists: [{
+ targets: ["goal_bar"],
+ tag: ".bar",
+ }],
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -125,6 +136,7 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = False,
dist = {
"tag": ".foo",
"targets": ["goal_foo"],
@@ -136,20 +148,21 @@
)`,
},
{
+ description: "put it together",
bp: `custom {
- name: "foo",
- required: ["bar"],
- target_required: ["qux", "bazqux"],
- ramdisk: true,
- owner: "custom_owner",
- dists: [
- {
- tag: ".tag",
- targets: ["my_goal"],
- },
- ],
+ name: "foo",
+ required: ["bar"],
+ target_required: ["qux", "bazqux"],
+ bool_prop: true,
+ owner: "custom_owner",
+ dists: [
+ {
+ tag: ".tag",
+ targets: ["my_goal"],
+ },
+ ],
}
- `,
+ `,
expectedBazelTarget: `soong_module(
name = "foo",
soong_module_name = "foo",
@@ -157,12 +170,12 @@
soong_module_variant = "",
soong_module_deps = [
],
+ bool_prop = True,
dists = [{
"tag": ".tag",
"targets": ["my_goal"],
}],
owner = "custom_owner",
- ramdisk = True,
required = ["bar"],
target_required = [
"qux",
@@ -174,31 +187,33 @@
dir := "."
for _, testCase := range testCases {
- config := android.TestConfig(buildDir, nil, testCase.bp, nil)
- ctx := android.NewTestContext(config)
+ t.Run(testCase.description, func(t *testing.T) {
+ config := android.TestConfig(buildDir, nil, testCase.bp, nil)
+ ctx := android.NewTestContext(config)
- ctx.RegisterModuleType("custom", customModuleFactory)
- ctx.Register()
+ ctx.RegisterModuleType("custom", customModuleFactory)
+ ctx.Register()
- _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
+ _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
- codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
- if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
- t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
- }
+ codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView)
+ bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
+ t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
+ }
- actualBazelTarget := bazelTargets[0]
- if actualBazelTarget.content != testCase.expectedBazelTarget {
- t.Errorf(
- "Expected generated Bazel target to be '%s', got '%s'",
- testCase.expectedBazelTarget,
- actualBazelTarget.content,
- )
- }
+ actualBazelTarget := bazelTargets[0]
+ if actualBazelTarget.content != testCase.expectedBazelTarget {
+ t.Errorf(
+ "Expected generated Bazel target to be '%s', got '%s'",
+ testCase.expectedBazelTarget,
+ actualBazelTarget.content,
+ )
+ }
+ })
}
}
@@ -324,11 +339,11 @@
ctx.RegisterForBazelConversion()
_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
- if Errored(t, "", errs) {
+ if errored(t, "", errs) {
continue
}
_, errs = ctx.ResolveDependencies(config)
- if Errored(t, "", errs) {
+ if errored(t, "", errs) {
continue
}
@@ -541,7 +556,6 @@
moduleTypeUnderTestFactory android.ModuleFactory
moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
preArchMutators []android.RegisterMutatorFunc
- depsMutators []android.RegisterMutatorFunc
bp string
expectedBazelTargets []string
fs map[string]string
@@ -705,7 +719,6 @@
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
- depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo.tool",
out: ["foo_tool.out"],
@@ -743,7 +756,6 @@
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
- depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo.tools",
out: ["foo_tool.out", "foo_tool2.out"],
@@ -783,7 +795,6 @@
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
- depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo",
out: ["foo.out"],
@@ -807,7 +818,6 @@
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
- depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo",
out: ["foo.out"],
@@ -831,7 +841,6 @@
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
- depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo",
out: ["foo.out"],
@@ -858,7 +867,6 @@
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
- depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo",
out: ["foo.out"],
@@ -885,7 +893,6 @@
moduleTypeUnderTest: "genrule",
moduleTypeUnderTestFactory: genrule.GenRuleFactory,
moduleTypeUnderTestBp2BuildMutator: genrule.GenruleBp2Build,
- depsMutators: []android.RegisterMutatorFunc{genrule.RegisterGenruleBp2BuildDeps},
bp: `genrule {
name: "foo",
out: ["foo.out"],
@@ -918,18 +925,15 @@
config := android.TestConfig(buildDir, nil, testCase.bp, fs)
ctx := android.NewTestContext(config)
ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- for _, m := range testCase.depsMutators {
- ctx.DepsBp2BuildMutators(m)
- }
ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
ctx.RegisterForBazelConversion()
_, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
+ if errored(t, testCase.description, errs) {
continue
}
_, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
+ if errored(t, testCase.description, errs) {
continue
}
@@ -957,17 +961,6 @@
}
}
-func Errored(t *testing.T, desc string, errs []error) bool {
- t.Helper()
- if len(errs) > 0 {
- for _, err := range errs {
- t.Errorf("%s: %s", desc, err)
- }
- return true
- }
- return false
-}
-
type bp2buildMutator = func(android.TopDownMutatorContext)
func TestBp2BuildInlinesDefaults(t *testing.T) {
@@ -1120,8 +1113,8 @@
"out",
],
srcs = [
- "in1",
"srcs-from-3",
+ "in1",
],
)`,
description: "genrule applies properties from genrule_defaults transitively",
@@ -1366,7 +1359,6 @@
moduleTypeUnderTestFactory android.ModuleFactory
moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
preArchMutators []android.RegisterMutatorFunc
- depsMutators []android.RegisterMutatorFunc
bp string
expectedBazelTargets []string
fs map[string]string
@@ -1394,14 +1386,14 @@
moduleTypeUnderTestFactory: android.FileGroupFactory,
moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
bp: `filegroup {
- name: "fg_foo",
- bazel_module: { label: "//other:fg_foo" },
-}
+ name: "fg_foo",
+ bazel_module: { label: "//other:fg_foo" },
+ }
-filegroup {
- name: "foo",
- bazel_module: { label: "//other:foo" },
-}`,
+ filegroup {
+ name: "foo",
+ bazel_module: { label: "//other:foo" },
+ }`,
expectedBazelTargets: []string{
`// BUILD file`,
},
@@ -1410,25 +1402,31 @@
},
},
{
- description: "filegroup bazel_module.label and bp2build",
+ description: "filegroup bazel_module.label and bp2build in subdir",
moduleTypeUnderTest: "filegroup",
moduleTypeUnderTestFactory: android.FileGroupFactory,
moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
- bp: `filegroup {
- name: "fg_foo",
- bazel_module: {
- label: "//other:fg_foo",
- bp2build_available: true,
- },
-}`,
+ dir: "other",
+ bp: ``,
+ fs: map[string]string{
+ "other/Android.bp": `filegroup {
+ name: "fg_foo",
+ bazel_module: {
+ bp2build_available: true,
+ },
+ }
+ filegroup {
+ name: "fg_bar",
+ bazel_module: {
+ label: "//other:fg_bar"
+ },
+ }`,
+ "other/BUILD.bazel": `// definition for fg_bar`,
+ },
expectedBazelTargets: []string{
`filegroup(
name = "fg_foo",
-)`,
- `// BUILD file`,
- },
- fs: map[string]string{
- "other/BUILD.bazel": `// BUILD file`,
+)`, `// definition for fg_bar`,
},
},
{
@@ -1437,18 +1435,18 @@
moduleTypeUnderTestFactory: android.FileGroupFactory,
moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
bp: `filegroup {
- name: "fg_foo",
- bazel_module: {
- label: "//other:fg_foo",
- },
-}
+ name: "fg_foo",
+ bazel_module: {
+ label: "//other:fg_foo",
+ },
+ }
-filegroup {
- name: "fg_bar",
- bazel_module: {
- bp2build_available: true,
- },
-}`,
+ filegroup {
+ name: "fg_bar",
+ bazel_module: {
+ bp2build_available: true,
+ },
+ }`,
expectedBazelTargets: []string{
`filegroup(
name = "fg_bar",
@@ -1463,53 +1461,58 @@
dir := "."
for _, testCase := range testCases {
- fs := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.fs {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
+ t.Run(testCase.description, func(t *testing.T) {
+ fs := make(map[string][]byte)
+ toParse := []string{
+ "Android.bp",
}
- fs[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.bp, fs)
- ctx := android.NewTestContext(config)
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- for _, m := range testCase.depsMutators {
- ctx.DepsBp2BuildMutators(m)
- }
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterForBazelConversion()
+ for f, content := range testCase.fs {
+ if strings.HasSuffix(f, "Android.bp") {
+ toParse = append(toParse, f)
+ }
+ fs[f] = []byte(content)
+ }
+ config := android.TestConfig(buildDir, nil, testCase.bp, fs)
+ ctx := android.NewTestContext(config)
+ ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+ ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
+ ctx.RegisterForBazelConversion()
- _, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
- continue
- }
+ _, errs := ctx.ParseFileList(dir, toParse)
+ if errored(t, testCase.description, errs) {
+ return
+ }
+ _, errs = ctx.ResolveDependencies(config)
+ if errored(t, testCase.description, errs) {
+ return
+ }
- checkDir := dir
- if testCase.dir != "" {
- checkDir = testCase.dir
- }
- bazelTargets := generateBazelTargetsForDir(NewCodegenContext(config, *ctx.Context, Bp2Build), checkDir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d\n%s", testCase.description, expectedCount, actualCount, bazelTargets)
- } else {
+ checkDir := dir
+ if testCase.dir != "" {
+ checkDir = testCase.dir
+ }
+ bazelTargets := generateBazelTargetsForDir(NewCodegenContext(config, *ctx.Context, Bp2Build), checkDir)
+ bazelTargets.sort()
+ actualCount := len(bazelTargets)
+ expectedCount := len(testCase.expectedBazelTargets)
+ if actualCount != expectedCount {
+ t.Errorf("Expected %d bazel target, got %d\n%s", expectedCount, actualCount, bazelTargets)
+ }
+ if !strings.Contains(bazelTargets.String(), "Section: Handcrafted targets. ") {
+ t.Errorf("Expected string representation of bazelTargets to contain handcrafted section header.")
+ }
for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
+ actualContent := target.content
+ expectedContent := testCase.expectedBazelTargets[i]
+ if expectedContent != actualContent {
t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
+ "Expected generated Bazel target to be '%s', got '%s'",
+ expectedContent,
+ actualContent,
)
}
}
- }
+ })
}
}
@@ -1538,10 +1541,10 @@
expectedBazelTargets: []string{`filegroup(
name = "fg_foo",
srcs = [
- "//dir:e.txt",
- "//dir:f.txt",
"a.txt",
"b.txt",
+ "//dir:e.txt",
+ "//dir:f.txt",
],
)`,
},
@@ -1578,9 +1581,9 @@
expectedBazelTargets: []string{`filegroup(
name = "fg_foo",
srcs = [
+ "a.txt",
"//dir/subdir:e.txt",
"//dir/subdir:f.txt",
- "a.txt",
],
)`,
},
@@ -1606,11 +1609,11 @@
ctx.RegisterForBazelConversion()
_, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
+ if errored(t, testCase.description, errs) {
continue
}
_, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
+ if errored(t, testCase.description, errs) {
continue
}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 32b12e4..204c519 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -22,8 +22,6 @@
"testing"
)
-var buildDir string
-
func setUp() {
var err error
buildDir, err = ioutil.TempDir("", "bazel_queryview_test")
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index bf40a6b..8dcba55 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -25,60 +25,115 @@
// See cc/testing.go for more context
soongCcLibraryPreamble = `
cc_defaults {
- name: "linux_bionic_supported",
+ name: "linux_bionic_supported",
}
toolchain_library {
- name: "libclang_rt.builtins-x86_64-android",
- defaults: ["linux_bionic_supported"],
- vendor_available: true,
- vendor_ramdisk_available: true,
- product_available: true,
- recovery_available: true,
- native_bridge_supported: true,
- src: "",
+ name: "libclang_rt.builtins-x86_64-android",
+ defaults: ["linux_bionic_supported"],
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ product_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
+ src: "",
}`
)
-func TestCcLibraryBp2Build(t *testing.T) {
- // b/191166471 disabled in sc-dev
- t.Skip()
- testCases := []struct {
- description string
- moduleTypeUnderTest string
- moduleTypeUnderTestFactory android.ModuleFactory
- moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
- bp string
- expectedBazelTargets []string
- filesystem map[string]string
- dir string
- depsMutators []android.RegisterMutatorFunc
- }{
- {
- description: "cc_library - simple example",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- filesystem: map[string]string{
- "android.cpp": "",
- "darwin.cpp": "",
- // Refer to cc.headerExts for the supported header extensions in Soong.
- "header.h": "",
- "header.hh": "",
- "header.hpp": "",
- "header.hxx": "",
- "header.h++": "",
- "header.inl": "",
- "header.inc": "",
- "header.ipp": "",
- "header.h.generic": "",
- "impl.cpp": "",
- "linux.cpp": "",
- "x86.cpp": "",
- "x86_64.cpp": "",
- "foo-dir/a.h": "",
- },
- bp: soongCcLibraryPreamble + `
+func runCcLibraryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerCcLibraryModuleTypes, tc)
+}
+
+func registerCcLibraryModuleTypes(ctx android.RegistrationContext) {
+ cc.RegisterCCBuildComponents(ctx)
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
+ ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
+ ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
+ ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
+}
+
+func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) {
+ t.Helper()
+ dir := "."
+ filesystem := make(map[string][]byte)
+ toParse := []string{
+ "Android.bp",
+ }
+ for f, content := range tc.filesystem {
+ if strings.HasSuffix(f, "Android.bp") {
+ toParse = append(toParse, f)
+ }
+ filesystem[f] = []byte(content)
+ }
+ config := android.TestConfig(buildDir, nil, tc.blueprint, filesystem)
+ ctx := android.NewTestContext(config)
+
+ registerModuleTypes(ctx)
+ ctx.RegisterModuleType(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestFactory)
+ ctx.RegisterBp2BuildConfig(bp2buildConfig)
+ ctx.RegisterBp2BuildMutator(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestBp2BuildMutator)
+ ctx.RegisterForBazelConversion()
+
+ _, errs := ctx.ParseFileList(dir, toParse)
+ if errored(t, tc.description, errs) {
+ return
+ }
+ _, errs = ctx.ResolveDependencies(config)
+ if errored(t, tc.description, errs) {
+ return
+ }
+
+ checkDir := dir
+ if tc.dir != "" {
+ checkDir = tc.dir
+ }
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+ bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
+ if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount {
+ 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,
+ )
+ }
+ }
+ }
+}
+
+func TestCcLibrarySimple(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library - simple example",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "android.cpp": "",
+ "bionic.cpp": "",
+ "darwin.cpp": "",
+ // Refer to cc.headerExts for the supported header extensions in Soong.
+ "header.h": "",
+ "header.hh": "",
+ "header.hpp": "",
+ "header.hxx": "",
+ "header.h++": "",
+ "header.inl": "",
+ "header.inc": "",
+ "header.ipp": "",
+ "header.h.generic": "",
+ "impl.cpp": "",
+ "linux.cpp": "",
+ "x86.cpp": "",
+ "x86_64.cpp": "",
+ "foo-dir/a.h": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
cc_library_headers { name: "some-headers" }
cc_library {
name: "foo-lib",
@@ -107,16 +162,20 @@
darwin: {
srcs: ["darwin.cpp"],
},
+ bionic: {
+ srcs: ["bionic.cpp"]
+ },
},
}
`,
- expectedBazelTargets: []string{`cc_library(
+ expectedBazelTargets: []string{`cc_library(
name = "foo-lib",
copts = [
"-Wall",
"-I.",
+ "-I$(BINDIR)/.",
],
- deps = [":some-headers"],
+ implementation_deps = [":some-headers"],
includes = ["foo-dir"],
linkopts = ["-Wl,--exclude-libs=bar.a"] + select({
"//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=baz.a"],
@@ -132,22 +191,27 @@
"//build/bazel/platforms/os:darwin": ["darwin.cpp"],
"//build/bazel/platforms/os:linux": ["linux.cpp"],
"//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:bionic": ["bionic.cpp"],
+ "//conditions:default": [],
}),
-)`},
+)`}})
+}
+
+func TestCcLibraryTrimmedLdAndroid(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library - trimmed example of //bionic/linker:ld-android",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "ld-android.cpp": "",
+ "linked_list.h": "",
+ "linker.h": "",
+ "linker_block_allocator.h": "",
+ "linker_cfi.h": "",
},
- {
- description: "cc_library - trimmed example of //bionic/linker:ld-android",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- filesystem: map[string]string{
- "ld-android.cpp": "",
- "linked_list.h": "",
- "linker.h": "",
- "linker_block_allocator.h": "",
- "linker_cfi.h": "",
- },
- bp: soongCcLibraryPreamble + `
+ blueprint: soongCcLibraryPreamble + `
cc_library_headers { name: "libc_headers" }
cc_library {
name: "fake-ld-android",
@@ -177,7 +241,7 @@
},
}
`,
- expectedBazelTargets: []string{`cc_library(
+ expectedBazelTargets: []string{`cc_library(
name = "fake-ld-android",
copts = [
"-Wall",
@@ -185,8 +249,9 @@
"-Wunused",
"-Werror",
"-I.",
+ "-I$(BINDIR)/.",
],
- deps = [":libc_headers"],
+ implementation_deps = [":libc_headers"],
linkopts = [
"-Wl,--exclude-libs=libgcc.a",
"-Wl,--exclude-libs=libgcc_stripped.a",
@@ -201,20 +266,23 @@
}),
srcs = ["ld_android.cpp"],
)`},
- },
- {
- description: "cc_library exclude_srcs - trimmed example of //external/arm-optimized-routines:libarm-optimized-routines-math",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- dir: "external",
- filesystem: map[string]string{
- "external/math/cosf.c": "",
- "external/math/erf.c": "",
- "external/math/erf_data.c": "",
- "external/math/erff.c": "",
- "external/math/erff_data.c": "",
- "external/Android.bp": `
+ })
+}
+
+func TestCcLibraryExcludeSrcs(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library exclude_srcs - trimmed example of //external/arm-optimized-routines:libarm-optimized-routines-math",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "external",
+ filesystem: map[string]string{
+ "external/math/cosf.c": "",
+ "external/math/erf.c": "",
+ "external/math/erf_data.c": "",
+ "external/math/erff.c": "",
+ "external/math/erff_data.c": "",
+ "external/Android.bp": `
cc_library {
name: "fake-libarm-optimized-routines-math",
exclude_srcs: [
@@ -240,29 +308,34 @@
bazel_module: { bp2build_available: true },
}
`,
- },
- bp: soongCcLibraryPreamble,
- expectedBazelTargets: []string{`cc_library(
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
name = "fake-libarm-optimized-routines-math",
- copts = ["-Iexternal"] + select({
+ copts = [
+ "-Iexternal",
+ "-I$(BINDIR)/external",
+ ] + select({
"//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
"//conditions:default": [],
}),
- srcs = ["math/cosf.c"],
+ srcs_c = ["math/cosf.c"],
)`},
- },
- {
- description: "cc_library shared/static props",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/both.cpp": "",
- "foo/bar/sharedonly.cpp": "",
- "foo/bar/staticonly.cpp": "",
- "foo/bar/Android.bp": `
+ })
+}
+
+func TestCcLibrarySharedStaticProps(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library shared/static props",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/both.cpp": "",
+ "foo/bar/sharedonly.cpp": "",
+ "foo/bar/staticonly.cpp": "",
+ "foo/bar/Android.bp": `
cc_library {
name: "a",
srcs: ["both.cpp"],
@@ -305,39 +378,369 @@
cc_library { name: "shared_dep_for_both" }
`,
- },
- bp: soongCcLibraryPreamble,
- expectedBazelTargets: []string{`cc_library(
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
name = "a",
copts = [
"bothflag",
"-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
],
- deps = [":static_dep_for_both"],
dynamic_deps = [":shared_dep_for_both"],
- dynamic_deps_for_shared = [":shared_dep_for_shared"],
- dynamic_deps_for_static = [":shared_dep_for_static"],
- shared_copts = ["sharedflag"],
- shared_srcs = ["sharedonly.cpp"],
+ implementation_deps = [":static_dep_for_both"],
+ shared = {
+ "copts": ["sharedflag"],
+ "dynamic_deps": [":shared_dep_for_shared"],
+ "srcs": ["sharedonly.cpp"],
+ "static_deps": [":static_dep_for_shared"],
+ "whole_archive_deps": [":whole_static_lib_for_shared"],
+ },
srcs = ["both.cpp"],
- static_copts = ["staticflag"],
- static_deps_for_shared = [":static_dep_for_shared"],
- static_deps_for_static = [":static_dep_for_static"],
- static_srcs = ["staticonly.cpp"],
+ static = {
+ "copts": ["staticflag"],
+ "dynamic_deps": [":shared_dep_for_static"],
+ "srcs": ["staticonly.cpp"],
+ "static_deps": [":static_dep_for_static"],
+ "whole_archive_deps": [":whole_static_lib_for_static"],
+ },
whole_archive_deps = [":whole_static_lib_for_both"],
- whole_archive_deps_for_shared = [":whole_static_lib_for_shared"],
- whole_archive_deps_for_static = [":whole_static_lib_for_static"],
)`},
+ })
+}
+
+func TestCcLibraryWholeStaticLibsAlwaysLink(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
+cc_library {
+ name: "a",
+ whole_static_libs: ["whole_static_lib_for_both"],
+ static: {
+ whole_static_libs: ["whole_static_lib_for_static"],
+ },
+ shared: {
+ whole_static_libs: ["whole_static_lib_for_shared"],
+ },
+ bazel_module: { bp2build_available: true },
+}
+
+cc_prebuilt_library_static { name: "whole_static_lib_for_shared" }
+
+cc_prebuilt_library_static { name: "whole_static_lib_for_static" }
+
+cc_prebuilt_library_static { name: "whole_static_lib_for_both" }
+`,
},
- {
- description: "cc_library non-configured version script",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "a",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ shared = {
+ "whole_archive_deps": [":whole_static_lib_for_shared_alwayslink"],
+ },
+ static = {
+ "whole_archive_deps": [":whole_static_lib_for_static_alwayslink"],
+ },
+ whole_archive_deps = [":whole_static_lib_for_both_alwayslink"],
+)`},
+ })
+}
+
+func TestCcLibrarySharedStaticPropsInArch(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library shared/static props in arch",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/arm.cpp": "",
+ "foo/bar/x86.cpp": "",
+ "foo/bar/sharedonly.cpp": "",
+ "foo/bar/staticonly.cpp": "",
+ "foo/bar/Android.bp": `
+cc_library {
+ name: "a",
+ arch: {
+ arm: {
+ shared: {
+ srcs: ["arm_shared.cpp"],
+ cflags: ["-DARM_SHARED"],
+ static_libs: ["arm_static_dep_for_shared"],
+ whole_static_libs: ["arm_whole_static_dep_for_shared"],
+ shared_libs: ["arm_shared_dep_for_shared"],
+ },
+ },
+ x86: {
+ static: {
+ srcs: ["x86_static.cpp"],
+ cflags: ["-DX86_STATIC"],
+ static_libs: ["x86_dep_for_static"],
+ },
+ },
+ },
+ target: {
+ android: {
+ shared: {
+ srcs: ["android_shared.cpp"],
+ cflags: ["-DANDROID_SHARED"],
+ static_libs: ["android_dep_for_shared"],
+ },
+ },
+ android_arm: {
+ shared: {
+ cflags: ["-DANDROID_ARM_SHARED"],
+ },
+ },
+ },
+ srcs: ["both.cpp"],
+ cflags: ["bothflag"],
+ static_libs: ["static_dep_for_both"],
+ static: {
+ srcs: ["staticonly.cpp"],
+ cflags: ["staticflag"],
+ static_libs: ["static_dep_for_static"],
+ },
+ shared: {
+ srcs: ["sharedonly.cpp"],
+ cflags: ["sharedflag"],
+ static_libs: ["static_dep_for_shared"],
+ },
+ bazel_module: { bp2build_available: true },
+}
+
+cc_library_static { name: "static_dep_for_shared" }
+cc_library_static { name: "static_dep_for_static" }
+cc_library_static { name: "static_dep_for_both" }
+
+cc_library_static { name: "arm_static_dep_for_shared" }
+cc_library_static { name: "arm_whole_static_dep_for_shared" }
+cc_library_static { name: "arm_shared_dep_for_shared" }
+
+cc_library_static { name: "x86_dep_for_static" }
+
+cc_library_static { name: "android_dep_for_shared" }
+`,
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "a",
+ copts = [
+ "bothflag",
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ implementation_deps = [":static_dep_for_both"],
+ shared = {
+ "copts": ["sharedflag"] + select({
+ "//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": ["-DANDROID_SHARED"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os_arch:android_arm": ["-DANDROID_ARM_SHARED"],
+ "//conditions:default": [],
+ }),
+ "dynamic_deps": select({
+ "//build/bazel/platforms/arch:arm": [":arm_shared_dep_for_shared"],
+ "//conditions:default": [],
+ }),
+ "srcs": ["sharedonly.cpp"] + select({
+ "//build/bazel/platforms/arch:arm": ["arm_shared.cpp"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": ["android_shared.cpp"],
+ "//conditions:default": [],
+ }),
+ "static_deps": [":static_dep_for_shared"] + select({
+ "//build/bazel/platforms/arch:arm": [":arm_static_dep_for_shared"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": [":android_dep_for_shared"],
+ "//conditions:default": [],
+ }),
+ "whole_archive_deps": select({
+ "//build/bazel/platforms/arch:arm": [":arm_whole_static_dep_for_shared"],
+ "//conditions:default": [],
+ }),
+ },
+ srcs = ["both.cpp"],
+ static = {
+ "copts": ["staticflag"] + select({
+ "//build/bazel/platforms/arch:x86": ["-DX86_STATIC"],
+ "//conditions:default": [],
+ }),
+ "srcs": ["staticonly.cpp"] + select({
+ "//build/bazel/platforms/arch:x86": ["x86_static.cpp"],
+ "//conditions:default": [],
+ }),
+ "static_deps": [":static_dep_for_static"] + select({
+ "//build/bazel/platforms/arch:x86": [":x86_dep_for_static"],
+ "//conditions:default": [],
+ }),
+ },
+)`},
+ })
+}
+
+func TestCcLibrarySharedStaticPropsWithMixedSources(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library shared/static props with c/cpp/s mixed sources",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/both_source.cpp": "",
+ "foo/bar/both_source.cc": "",
+ "foo/bar/both_source.c": "",
+ "foo/bar/both_source.s": "",
+ "foo/bar/both_source.S": "",
+ "foo/bar/shared_source.cpp": "",
+ "foo/bar/shared_source.cc": "",
+ "foo/bar/shared_source.c": "",
+ "foo/bar/shared_source.s": "",
+ "foo/bar/shared_source.S": "",
+ "foo/bar/static_source.cpp": "",
+ "foo/bar/static_source.cc": "",
+ "foo/bar/static_source.c": "",
+ "foo/bar/static_source.s": "",
+ "foo/bar/static_source.S": "",
+ "foo/bar/Android.bp": `
+cc_library {
+ name: "a",
+ srcs: [
+ "both_source.cpp",
+ "both_source.cc",
+ "both_source.c",
+ "both_source.s",
+ "both_source.S",
+ ":both_filegroup",
+ ],
+ static: {
+ srcs: [
+ "static_source.cpp",
+ "static_source.cc",
+ "static_source.c",
+ "static_source.s",
+ "static_source.S",
+ ":static_filegroup",
+ ],
+ },
+ shared: {
+ srcs: [
+ "shared_source.cpp",
+ "shared_source.cc",
+ "shared_source.c",
+ "shared_source.s",
+ "shared_source.S",
+ ":shared_filegroup",
+ ],
+ },
+ bazel_module: { bp2build_available: true },
+}
+
+filegroup {
+ name: "both_filegroup",
+ srcs: [
+ // Not relevant, handled by filegroup macro
+ ],
+}
+
+filegroup {
+ name: "shared_filegroup",
+ srcs: [
+ // Not relevant, handled by filegroup macro
+ ],
+}
+
+filegroup {
+ name: "static_filegroup",
+ srcs: [
+ // Not relevant, handled by filegroup macro
+ ],
+}
+`,
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "a",
+ asflags = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ shared = {
+ "srcs": [
+ ":shared_filegroup_cpp_srcs",
+ "shared_source.cc",
+ "shared_source.cpp",
+ ],
+ "srcs_as": [
+ "shared_source.s",
+ "shared_source.S",
+ ":shared_filegroup_as_srcs",
+ ],
+ "srcs_c": [
+ "shared_source.c",
+ ":shared_filegroup_c_srcs",
+ ],
+ },
+ srcs = [
+ ":both_filegroup_cpp_srcs",
+ "both_source.cc",
+ "both_source.cpp",
+ ],
+ srcs_as = [
+ "both_source.s",
+ "both_source.S",
+ ":both_filegroup_as_srcs",
+ ],
+ srcs_c = [
+ "both_source.c",
+ ":both_filegroup_c_srcs",
+ ],
+ static = {
+ "srcs": [
+ ":static_filegroup_cpp_srcs",
+ "static_source.cc",
+ "static_source.cpp",
+ ],
+ "srcs_as": [
+ "static_source.s",
+ "static_source.S",
+ ":static_filegroup_as_srcs",
+ ],
+ "srcs_c": [
+ "static_source.c",
+ ":static_filegroup_c_srcs",
+ ],
+ },
+)`},
+ })
+}
+
+func TestCcLibraryNonConfiguredVersionScript(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library non-configured version script",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
cc_library {
name: "a",
srcs: ["a.cpp"],
@@ -345,44 +748,52 @@
bazel_module: { bp2build_available: true },
}
`,
- },
- bp: soongCcLibraryPreamble,
- expectedBazelTargets: []string{`cc_library(
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = ["-Ifoo/bar"],
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
srcs = ["a.cpp"],
version_script = "v.map",
)`},
- },
- {
- description: "cc_library configured version script",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
- cc_library {
- name: "a",
- srcs: ["a.cpp"],
- arch: {
- arm: {
- version_script: "arm.map",
- },
- arm64: {
- version_script: "arm64.map",
- },
- },
+ })
+}
- bazel_module: { bp2build_available: true },
- }
- `,
- },
- bp: soongCcLibraryPreamble,
- expectedBazelTargets: []string{`cc_library(
+func TestCcLibraryConfiguredVersionScript(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library configured version script",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
+ cc_library {
+ name: "a",
+ srcs: ["a.cpp"],
+ arch: {
+ arm: {
+ version_script: "arm.map",
+ },
+ arm64: {
+ version_script: "arm64.map",
+ },
+ },
+
+ bazel_module: { bp2build_available: true },
+ }
+ `,
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = ["-Ifoo/bar"],
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
srcs = ["a.cpp"],
version_script = select({
"//build/bazel/platforms/arch:arm": "arm.map",
@@ -390,16 +801,18 @@
"//conditions:default": None,
}),
)`},
- },
- {
- description: "cc_library shared_libs",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ })
+}
+
+func TestCcLibrarySharedLibs(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library shared_libs",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
cc_library {
name: "mylib",
bazel_module: { bp2build_available: true },
@@ -411,26 +824,34 @@
bazel_module: { bp2build_available: true },
}
`,
- },
- bp: soongCcLibraryPreamble,
- expectedBazelTargets: []string{`cc_library(
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = ["-Ifoo/bar"],
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
dynamic_deps = [":mylib"],
)`, `cc_library(
name = "mylib",
- copts = ["-Ifoo/bar"],
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
)`},
- },
- {
- description: "cc_library pack_relocations test",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ })
+}
+
+func TestCcLibraryPackRelocations(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library pack_relocations test",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
cc_library {
name: "a",
srcs: ["a.cpp"],
@@ -443,8 +864,8 @@
srcs: ["b.cpp"],
arch: {
x86_64: {
- pack_relocations: false,
- },
+ pack_relocations: false,
+ },
},
bazel_module: { bp2build_available: true },
}
@@ -454,21 +875,27 @@
srcs: ["c.cpp"],
target: {
darwin: {
- pack_relocations: false,
- },
+ pack_relocations: false,
+ },
},
bazel_module: { bp2build_available: true },
}`,
- },
- bp: soongCcLibraryPreamble,
- expectedBazelTargets: []string{`cc_library(
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = ["-Ifoo/bar"],
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
linkopts = ["-Wl,--pack-dyn-relocs=none"],
srcs = ["a.cpp"],
)`, `cc_library(
name = "b",
- copts = ["-Ifoo/bar"],
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
linkopts = select({
"//build/bazel/platforms/arch:x86_64": ["-Wl,--pack-dyn-relocs=none"],
"//conditions:default": [],
@@ -476,80 +903,91 @@
srcs = ["b.cpp"],
)`, `cc_library(
name = "c",
- copts = ["-Ifoo/bar"],
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
linkopts = select({
"//build/bazel/platforms/os:darwin": ["-Wl,--pack-dyn-relocs=none"],
"//conditions:default": [],
}),
srcs = ["c.cpp"],
)`},
- },
- {
- description: "cc_library spaces in copts",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `
+ })
+}
+
+func TestCcLibrarySpacesInCopts(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library spaces in copts",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
cc_library {
name: "a",
cflags: ["-include header.h",],
bazel_module: { bp2build_available: true },
}
`,
- },
- bp: soongCcLibraryPreamble,
- expectedBazelTargets: []string{`cc_library(
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
name = "a",
copts = [
"-include",
"header.h",
"-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
],
)`},
- },
- {
- description: "cc_library cppflags goes into copts",
- moduleTypeUnderTest: "cc_library",
- moduleTypeUnderTestFactory: cc.LibraryFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- dir: "foo/bar",
- filesystem: map[string]string{
- "foo/bar/Android.bp": `cc_library {
+ })
+}
+
+func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library cppflags usage",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `cc_library {
name: "a",
srcs: ["a.cpp"],
cflags: [
- "-Wall",
- ],
+ "-Wall",
+ ],
cppflags: [
"-fsigned-char",
"-pedantic",
- ],
+ ],
arch: {
arm64: {
cppflags: ["-DARM64=1"],
- },
- },
+ },
+ },
target: {
android: {
cppflags: ["-DANDROID=1"],
- },
- },
+ },
+ },
bazel_module: { bp2build_available: true },
}
`,
- },
- bp: soongCcLibraryPreamble,
- expectedBazelTargets: []string{`cc_library(
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
name = "a",
copts = [
"-Wall",
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ cppflags = [
"-fsigned-char",
"-pedantic",
- "-Ifoo/bar",
] + select({
"//build/bazel/platforms/arch:arm64": ["-DARM64=1"],
"//conditions:default": [],
@@ -559,64 +997,460 @@
}),
srcs = ["a.cpp"],
)`},
+ })
+}
+
+func TestCcLibraryLabelAttributeGetTargetProperties(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library GetTargetProperties on a LabelAttribute",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
+ cc_library {
+ name: "a",
+ srcs: ["a.cpp"],
+ target: {
+ android_arm: {
+ version_script: "android_arm.map",
+ },
+ linux_bionic_arm64: {
+ version_script: "linux_bionic_arm64.map",
+ },
+ },
+
+ bazel_module: { bp2build_available: true },
+ }
+ `,
},
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "a",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ 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",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library {
+ name: "foo_static",
+ srcs: ["common.c"],
+ whole_static_libs: [
+ "arm_whole_static_lib_excludes",
+ "malloc_not_svelte_whole_static_lib_excludes"
+ ],
+ static_libs: [
+ "arm_static_lib_excludes",
+ "malloc_not_svelte_static_lib_excludes"
+ ],
+ shared_libs: [
+ "arm_shared_lib_excludes",
+ ],
+ arch: {
+ arm: {
+ exclude_shared_libs: [
+ "arm_shared_lib_excludes",
+ ],
+ exclude_static_libs: [
+ "arm_static_lib_excludes",
+ "arm_whole_static_lib_excludes",
+ ],
+ },
+ },
+ product_variables: {
+ malloc_not_svelte: {
+ shared_libs: ["malloc_not_svelte_shared_lib"],
+ whole_static_libs: ["malloc_not_svelte_whole_static_lib"],
+ exclude_static_libs: [
+ "malloc_not_svelte_static_lib_excludes",
+ "malloc_not_svelte_whole_static_lib_excludes",
+ ],
+ },
+ },
+}
+
+cc_library {
+ name: "arm_whole_static_lib_excludes",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "malloc_not_svelte_whole_static_lib",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "malloc_not_svelte_whole_static_lib_excludes",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "arm_static_lib_excludes",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "malloc_not_svelte_static_lib_excludes",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "arm_shared_lib_excludes",
+ bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+ name: "malloc_not_svelte_shared_lib",
+ bazel_module: { bp2build_available: false },
+}
+`,
+ expectedBazelTargets: []string{
+ `cc_library(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ dynamic_deps = select({
+ "//build/bazel/platforms/arch:arm": [],
+ "//conditions:default": [":arm_shared_lib_excludes"],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_shared_lib"],
+ "//conditions:default": [],
+ }),
+ implementation_deps = select({
+ "//build/bazel/platforms/arch:arm": [],
+ "//conditions:default": [":arm_static_lib_excludes"],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte": [],
+ "//conditions:default": [":malloc_not_svelte_static_lib_excludes"],
+ }),
+ srcs_c = ["common.c"],
+ whole_archive_deps = select({
+ "//build/bazel/platforms/arch:arm": [],
+ "//conditions:default": [":arm_whole_static_lib_excludes"],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_whole_static_lib"],
+ "//conditions:default": [":malloc_not_svelte_whole_static_lib_excludes"],
+ }),
+)`,
+ },
+ })
+}
+
+func TestCCLibraryNoCrtTrue(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library - simple example",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ no_libcrt: true,
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ srcs = ["impl.cpp"],
+ use_libcrt = False,
+)`}})
+}
+
+func TestCCLibraryNoCrtFalse(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_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ no_libcrt: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ srcs = ["impl.cpp"],
+ use_libcrt = True,
+)`}})
+}
+
+func TestCCLibraryNoCrtArchVariant(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_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ arch: {
+ arm: {
+ no_libcrt: true,
+ },
+ x86: {
+ no_libcrt: true,
+ },
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ srcs = ["impl.cpp"],
+ use_libcrt = select({
+ "//build/bazel/platforms/arch:arm": False,
+ "//build/bazel/platforms/arch:x86": False,
+ "//conditions:default": None,
+ }),
+)`}})
+}
+
+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_headers { name: "some-headers" }
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ no_libcrt: false,
+ arch: {
+ arm: {
+ no_libcrt: true,
+ },
+ x86: {
+ no_libcrt: true,
+ },
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_library(
+ name = "foo-lib",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ 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",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
+cc_library {
+ name: "nothing",
+ bazel_module: { bp2build_available: true },
+}
+cc_library {
+ name: "keep_symbols",
+ bazel_module: { bp2build_available: true },
+ strip: {
+ keep_symbols: true,
}
-
- dir := "."
- for _, testCase := range testCases {
- filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
- filesystem[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
- ctx := android.NewTestContext(config)
-
- cc.RegisterCCBuildComponents(ctx)
- ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
- ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
- ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterBp2BuildConfig(bp2buildConfig) // TODO(jingwen): make this the default for all tests
- for _, m := range testCase.depsMutators {
- ctx.DepsBp2BuildMutators(m)
- }
- ctx.RegisterForBazelConversion()
-
- _, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
- continue
- }
-
- checkDir := dir
- if testCase.dir != "" {
- checkDir = testCase.dir
- }
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
- )
- }
- }
- }
+}
+cc_library {
+ name: "keep_symbols_and_debug_frame",
+ bazel_module: { bp2build_available: true },
+ strip: {
+ keep_symbols_and_debug_frame: true,
}
}
+cc_library {
+ name: "none",
+ bazel_module: { bp2build_available: true },
+ strip: {
+ none: true,
+ }
+}
+cc_library {
+ name: "keep_symbols_list",
+ bazel_module: { bp2build_available: true },
+ strip: {
+ keep_symbols_list: ["symbol"],
+ }
+}
+cc_library {
+ name: "all",
+ bazel_module: { bp2build_available: true },
+ strip: {
+ all: true,
+ }
+}
+`,
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "all",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ strip = {
+ "all": True,
+ },
+)`, `cc_library(
+ name = "keep_symbols",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ strip = {
+ "keep_symbols": True,
+ },
+)`, `cc_library(
+ name = "keep_symbols_and_debug_frame",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ strip = {
+ "keep_symbols_and_debug_frame": True,
+ },
+)`, `cc_library(
+ name = "keep_symbols_list",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ strip = {
+ "keep_symbols_list": ["symbol"],
+ },
+)`, `cc_library(
+ name = "none",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ strip = {
+ "none": True,
+ },
+)`, `cc_library(
+ name = "nothing",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+)`},
+ })
+}
+
+func TestCcLibraryStripWithArch(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library strip args",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/Android.bp": `
+cc_library {
+ name: "multi-arch",
+ bazel_module: { bp2build_available: true },
+ target: {
+ darwin: {
+ strip: {
+ keep_symbols_list: ["foo", "bar"]
+ }
+ },
+ },
+ arch: {
+ arm: {
+ strip: {
+ keep_symbols_and_debug_frame: true,
+ },
+ },
+ arm64: {
+ strip: {
+ keep_symbols: true,
+ },
+ },
+ }
+}
+`,
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "multi-arch",
+ copts = [
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ strip = {
+ "keep_symbols": select({
+ "//build/bazel/platforms/arch:arm64": True,
+ "//conditions:default": None,
+ }),
+ "keep_symbols_and_debug_frame": select({
+ "//build/bazel/platforms/arch:arm": True,
+ "//conditions:default": None,
+ }),
+ "keep_symbols_list": select({
+ "//build/bazel/platforms/os:darwin": [
+ "foo",
+ "bar",
+ ],
+ "//conditions:default": [],
+ }),
+ },
+)`},
+ })
+}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 0905aba..712d0bd 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -15,10 +15,10 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/cc"
- "strings"
- "testing"
)
const (
@@ -40,6 +40,17 @@
}`
)
+type bp2buildTestCase struct {
+ description string
+ moduleTypeUnderTest string
+ moduleTypeUnderTestFactory android.ModuleFactory
+ moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
+ blueprint string
+ expectedBazelTargets []string
+ filesystem map[string]string
+ dir string
+}
+
func TestCcLibraryHeadersLoadStatement(t *testing.T) {
testCases := []struct {
bazelTargets BazelTargets
@@ -64,41 +75,38 @@
t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
}
}
-
}
-func TestCcLibraryHeadersBp2Build(t *testing.T) {
- testCases := []struct {
- description string
- moduleTypeUnderTest string
- moduleTypeUnderTestFactory android.ModuleFactory
- moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
- preArchMutators []android.RegisterMutatorFunc
- depsMutators []android.RegisterMutatorFunc
- bp string
- expectedBazelTargets []string
- filesystem map[string]string
- dir string
- }{
- {
- description: "cc_library_headers test",
- moduleTypeUnderTest: "cc_library_headers",
- moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
- filesystem: map[string]string{
- "lib-1/lib1a.h": "",
- "lib-1/lib1b.h": "",
- "lib-2/lib2a.h": "",
- "lib-2/lib2b.h": "",
- "dir-1/dir1a.h": "",
- "dir-1/dir1b.h": "",
- "dir-2/dir2a.h": "",
- "dir-2/dir2b.h": "",
- "arch_arm64_exported_include_dir/a.h": "",
- "arch_x86_exported_include_dir/b.h": "",
- "arch_x86_64_exported_include_dir/c.h": "",
- },
- bp: soongCcLibraryHeadersPreamble + `
+func registerCcLibraryHeadersModuleTypes(ctx android.RegistrationContext) {
+ cc.RegisterCCBuildComponents(ctx)
+ ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
+}
+
+func runCcLibraryHeadersTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerCcLibraryHeadersModuleTypes, tc)
+}
+
+func TestCcLibraryHeadersSimple(t *testing.T) {
+ runCcLibraryHeadersTestCase(t, bp2buildTestCase{
+ description: "cc_library_headers test",
+ moduleTypeUnderTest: "cc_library_headers",
+ moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
+ filesystem: map[string]string{
+ "lib-1/lib1a.h": "",
+ "lib-1/lib1b.h": "",
+ "lib-2/lib2a.h": "",
+ "lib-2/lib2b.h": "",
+ "dir-1/dir1a.h": "",
+ "dir-1/dir1b.h": "",
+ "dir-2/dir2a.h": "",
+ "dir-2/dir2b.h": "",
+ "arch_arm64_exported_include_dir/a.h": "",
+ "arch_x86_exported_include_dir/b.h": "",
+ "arch_x86_64_exported_include_dir/c.h": "",
+ },
+ blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "lib-1",
export_include_dirs: ["lib-1"],
@@ -129,10 +137,13 @@
// TODO: Also support export_header_lib_headers
}`,
- expectedBazelTargets: []string{`cc_library_headers(
+ expectedBazelTargets: []string{`cc_library_headers(
name = "foo_headers",
- copts = ["-I."],
- deps = [
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ implementation_deps = [
":lib-1",
":lib-2",
],
@@ -147,26 +158,33 @@
}),
)`, `cc_library_headers(
name = "lib-1",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
includes = ["lib-1"],
)`, `cc_library_headers(
name = "lib-2",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
includes = ["lib-2"],
)`},
- },
- {
- description: "cc_library_headers test with os-specific header_libs props",
- moduleTypeUnderTest: "cc_library_headers",
- moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{},
- bp: soongCcLibraryPreamble + `
+ })
+}
+
+func TestCcLibraryHeadersOSSpecificHeader(t *testing.T) {
+ runCcLibraryHeadersTestCase(t, bp2buildTestCase{
+ description: "cc_library_headers test with os-specific header_libs props",
+ moduleTypeUnderTest: "cc_library_headers",
+ moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryPreamble + `
cc_library_headers { name: "android-lib" }
cc_library_headers { name: "base-lib" }
cc_library_headers { name: "darwin-lib" }
-cc_library_headers { name: "fuchsia-lib" }
cc_library_headers { name: "linux-lib" }
cc_library_headers { name: "linux_bionic-lib" }
cc_library_headers { name: "windows-lib" }
@@ -176,56 +194,74 @@
target: {
android: { header_libs: ["android-lib"] },
darwin: { header_libs: ["darwin-lib"] },
- fuchsia: { header_libs: ["fuchsia-lib"] },
linux_bionic: { header_libs: ["linux_bionic-lib"] },
linux_glibc: { header_libs: ["linux-lib"] },
windows: { header_libs: ["windows-lib"] },
},
bazel_module: { bp2build_available: true },
}`,
- expectedBazelTargets: []string{`cc_library_headers(
+ expectedBazelTargets: []string{`cc_library_headers(
name = "android-lib",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
)`, `cc_library_headers(
name = "base-lib",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
)`, `cc_library_headers(
name = "darwin-lib",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
)`, `cc_library_headers(
name = "foo_headers",
- copts = ["-I."],
- deps = [":base-lib"] + select({
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ implementation_deps = [":base-lib"] + select({
"//build/bazel/platforms/os:android": [":android-lib"],
"//build/bazel/platforms/os:darwin": [":darwin-lib"],
- "//build/bazel/platforms/os:fuchsia": [":fuchsia-lib"],
"//build/bazel/platforms/os:linux": [":linux-lib"],
"//build/bazel/platforms/os:linux_bionic": [":linux_bionic-lib"],
"//build/bazel/platforms/os:windows": [":windows-lib"],
"//conditions:default": [],
}),
)`, `cc_library_headers(
- name = "fuchsia-lib",
- copts = ["-I."],
-)`, `cc_library_headers(
name = "linux-lib",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
)`, `cc_library_headers(
name = "linux_bionic-lib",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
)`, `cc_library_headers(
name = "windows-lib",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
)`},
- },
- {
- description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props",
- moduleTypeUnderTest: "cc_library_headers",
- moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{},
- bp: soongCcLibraryPreamble + `
+ })
+}
+
+func TestCcLibraryHeadersOsSpecficHeaderLibsExportHeaderLibHeaders(t *testing.T) {
+ runCcLibraryHeadersTestCase(t, bp2buildTestCase{
+ description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props",
+ moduleTypeUnderTest: "cc_library_headers",
+ moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryPreamble + `
cc_library_headers { name: "android-lib" }
cc_library_headers { name: "exported-lib" }
cc_library_headers {
@@ -234,32 +270,44 @@
android: { header_libs: ["android-lib"], export_header_lib_headers: ["exported-lib"] },
},
}`,
- expectedBazelTargets: []string{`cc_library_headers(
+ expectedBazelTargets: []string{`cc_library_headers(
name = "android-lib",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
)`, `cc_library_headers(
name = "exported-lib",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
)`, `cc_library_headers(
name = "foo_headers",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
deps = select({
- "//build/bazel/platforms/os:android": [
- ":android-lib",
- ":exported-lib",
- ],
+ "//build/bazel/platforms/os:android": [":exported-lib"],
+ "//conditions:default": [],
+ }),
+ implementation_deps = select({
+ "//build/bazel/platforms/os:android": [":android-lib"],
"//conditions:default": [],
}),
)`},
- },
- {
- description: "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props",
- moduleTypeUnderTest: "cc_library_headers",
- moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{},
- bp: soongCcLibraryPreamble + `cc_library_headers {
+ })
+}
+
+func TestCcLibraryHeadersArchAndTargetExportSystemIncludes(t *testing.T) {
+ runCcLibraryHeadersTestCase(t, bp2buildTestCase{
+ description: "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props",
+ moduleTypeUnderTest: "cc_library_headers",
+ moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryPreamble + `cc_library_headers {
name: "foo_headers",
export_system_include_dirs: [
"shared_include_dir",
@@ -294,9 +342,12 @@
},
},
}`,
- expectedBazelTargets: []string{`cc_library_headers(
+ expectedBazelTargets: []string{`cc_library_headers(
name = "foo_headers",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
includes = ["shared_include_dir"] + select({
"//build/bazel/platforms/arch:arm": ["arm_include_dir"],
"//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
@@ -308,65 +359,41 @@
"//conditions:default": [],
}),
)`},
+ })
+}
+
+func TestCcLibraryHeadersNoCrtIgnored(t *testing.T) {
+ runCcLibraryHeadersTestCase(t, bp2buildTestCase{
+ description: "cc_library_headers test",
+ moduleTypeUnderTest: "cc_library_headers",
+ moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
+ filesystem: map[string]string{
+ "lib-1/lib1a.h": "",
+ "lib-1/lib1b.h": "",
+ "lib-2/lib2a.h": "",
+ "lib-2/lib2b.h": "",
+ "dir-1/dir1a.h": "",
+ "dir-1/dir1b.h": "",
+ "dir-2/dir2a.h": "",
+ "dir-2/dir2b.h": "",
+ "arch_arm64_exported_include_dir/a.h": "",
+ "arch_x86_exported_include_dir/b.h": "",
+ "arch_x86_64_exported_include_dir/c.h": "",
},
- }
-
- dir := "."
- for _, testCase := range testCases {
- filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
- filesystem[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
- ctx := android.NewTestContext(config)
-
- // TODO(jingwen): make this default for all bp2build tests
- ctx.RegisterBp2BuildConfig(bp2buildConfig)
-
- cc.RegisterCCBuildComponents(ctx)
- ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
-
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- for _, m := range testCase.depsMutators {
- ctx.DepsBp2BuildMutators(m)
- }
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterForBazelConversion()
-
- _, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
- continue
- }
-
- checkDir := dir
- if testCase.dir != "" {
- checkDir = testCase.dir
- }
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
- )
- }
- }
- }
- }
+ blueprint: soongCcLibraryHeadersPreamble + `
+cc_library_headers {
+ name: "lib-1",
+ export_include_dirs: ["lib-1"],
+ no_libcrt: true,
+}`,
+ expectedBazelTargets: []string{`cc_library_headers(
+ name = "lib-1",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ includes = ["lib-1"],
+)`},
+ })
}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index d082db1..1dc6713 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -17,7 +17,8 @@
import (
"android/soong/android"
"android/soong/cc"
- "strings"
+ "android/soong/genrule"
+
"testing"
)
@@ -67,45 +68,45 @@
}
-func TestCcLibraryStaticBp2Build(t *testing.T) {
- testCases := []struct {
- description string
- moduleTypeUnderTest string
- moduleTypeUnderTestFactory android.ModuleFactory
- moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
- preArchMutators []android.RegisterMutatorFunc
- depsMutators []android.RegisterMutatorFunc
- bp string
- expectedBazelTargets []string
- filesystem map[string]string
- dir string
- }{
- {
- description: "cc_library_static test",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- filesystem: map[string]string{
- // NOTE: include_dir headers *should not* appear in Bazel hdrs later (?)
- "include_dir_1/include_dir_1_a.h": "",
- "include_dir_1/include_dir_1_b.h": "",
- "include_dir_2/include_dir_2_a.h": "",
- "include_dir_2/include_dir_2_b.h": "",
- // NOTE: local_include_dir headers *should not* appear in Bazel hdrs later (?)
- "local_include_dir_1/local_include_dir_1_a.h": "",
- "local_include_dir_1/local_include_dir_1_b.h": "",
- "local_include_dir_2/local_include_dir_2_a.h": "",
- "local_include_dir_2/local_include_dir_2_b.h": "",
- // NOTE: export_include_dir headers *should* appear in Bazel hdrs later
- "export_include_dir_1/export_include_dir_1_a.h": "",
- "export_include_dir_1/export_include_dir_1_b.h": "",
- "export_include_dir_2/export_include_dir_2_a.h": "",
- "export_include_dir_2/export_include_dir_2_b.h": "",
- // NOTE: Soong implicitly includes headers in the current directory
- "implicit_include_1.h": "",
- "implicit_include_2.h": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+func registerCcLibraryStaticModuleTypes(ctx android.RegistrationContext) {
+ cc.RegisterCCBuildComponents(ctx)
+ ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
+ ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
+ ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
+}
+
+func runCcLibraryStaticTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerCcLibraryStaticModuleTypes, tc)
+}
+
+func TestCcLibraryStaticSimple(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static test",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ // NOTE: include_dir headers *should not* appear in Bazel hdrs later (?)
+ "include_dir_1/include_dir_1_a.h": "",
+ "include_dir_1/include_dir_1_b.h": "",
+ "include_dir_2/include_dir_2_a.h": "",
+ "include_dir_2/include_dir_2_b.h": "",
+ // NOTE: local_include_dir headers *should not* appear in Bazel hdrs later (?)
+ "local_include_dir_1/local_include_dir_1_a.h": "",
+ "local_include_dir_1/local_include_dir_1_b.h": "",
+ "local_include_dir_2/local_include_dir_2_a.h": "",
+ "local_include_dir_2/local_include_dir_2_b.h": "",
+ // NOTE: export_include_dir headers *should* appear in Bazel hdrs later
+ "export_include_dir_1/export_include_dir_1_a.h": "",
+ "export_include_dir_1/export_include_dir_1_b.h": "",
+ "export_include_dir_2/export_include_dir_2_a.h": "",
+ "export_include_dir_2/export_include_dir_2_b.h": "",
+ // NOTE: Soong implicitly includes headers in the current directory
+ "implicit_include_1.h": "",
+ "implicit_include_2.h": "",
+ },
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_headers {
name: "header_lib_1",
export_include_dirs: ["header_lib_1"],
@@ -163,8 +164,8 @@
"local_include_dir_2",
],
export_include_dirs: [
- "export_include_dir_1",
- "export_include_dir_2"
+ "export_include_dir_1",
+ "export_include_dir_2"
],
header_libs: [
"header_lib_1",
@@ -173,18 +174,23 @@
// TODO: Also support export_header_lib_headers
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
copts = [
"-Dflag1",
"-Dflag2",
"-Iinclude_dir_1",
+ "-I$(BINDIR)/include_dir_1",
"-Iinclude_dir_2",
+ "-I$(BINDIR)/include_dir_2",
"-Ilocal_include_dir_1",
+ "-I$(BINDIR)/local_include_dir_1",
"-Ilocal_include_dir_2",
+ "-I$(BINDIR)/local_include_dir_2",
"-I.",
+ "-I$(BINDIR)/.",
],
- deps = [
+ implementation_deps = [
":header_lib_1",
":header_lib_2",
":static_lib_1",
@@ -205,46 +211,61 @@
],
)`, `cc_library_static(
name = "static_lib_1",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
srcs = ["static_lib_1.cc"],
)`, `cc_library_static(
name = "static_lib_2",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
srcs = ["static_lib_2.cc"],
)`, `cc_library_static(
name = "whole_static_lib_1",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
srcs = ["whole_static_lib_1.cc"],
)`, `cc_library_static(
name = "whole_static_lib_2",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
srcs = ["whole_static_lib_2.cc"],
)`},
+ })
+}
+
+func TestCcLibraryStaticSubpackage(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static subpackage test",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ // subpackage with subdirectory
+ "subpackage/Android.bp": "",
+ "subpackage/subpackage_header.h": "",
+ "subpackage/subdirectory/subdirectory_header.h": "",
+ // subsubpackage with subdirectory
+ "subpackage/subsubpackage/Android.bp": "",
+ "subpackage/subsubpackage/subsubpackage_header.h": "",
+ "subpackage/subsubpackage/subdirectory/subdirectory_header.h": "",
+ // subsubsubpackage with subdirectory
+ "subpackage/subsubpackage/subsubsubpackage/Android.bp": "",
+ "subpackage/subsubpackage/subsubsubpackage/subsubsubpackage_header.h": "",
+ "subpackage/subsubpackage/subsubsubpackage/subdirectory/subdirectory_header.h": "",
},
- {
- description: "cc_library_static subpackage test",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- filesystem: map[string]string{
- // subpackage with subdirectory
- "subpackage/Android.bp": "",
- "subpackage/subpackage_header.h": "",
- "subpackage/subdirectory/subdirectory_header.h": "",
- // subsubpackage with subdirectory
- "subpackage/subsubpackage/Android.bp": "",
- "subpackage/subsubpackage/subsubpackage_header.h": "",
- "subpackage/subsubpackage/subdirectory/subdirectory_header.h": "",
- // subsubsubpackage with subdirectory
- "subpackage/subsubpackage/subsubsubpackage/Android.bp": "",
- "subpackage/subsubpackage/subsubsubpackage/subsubsubpackage_header.h": "",
- "subpackage/subsubpackage/subsubsubpackage/subdirectory/subdirectory_header.h": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
srcs: [
@@ -253,70 +274,87 @@
"subpackage",
],
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
copts = [
"-Isubpackage",
+ "-I$(BINDIR)/subpackage",
"-I.",
+ "-I$(BINDIR)/.",
],
linkstatic = True,
)`},
+ })
+}
+
+func TestCcLibraryStaticExportIncludeDir(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static export include dir",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ // subpackage with subdirectory
+ "subpackage/Android.bp": "",
+ "subpackage/subpackage_header.h": "",
+ "subpackage/subdirectory/subdirectory_header.h": "",
},
- {
- description: "cc_library_static export include dir",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- filesystem: map[string]string{
- // subpackage with subdirectory
- "subpackage/Android.bp": "",
- "subpackage/subpackage_header.h": "",
- "subpackage/subdirectory/subdirectory_header.h": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
export_include_dirs: ["subpackage"],
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
includes = ["subpackage"],
linkstatic = True,
)`},
+ })
+}
+
+func TestCcLibraryStaticExportSystemIncludeDir(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static export system include dir",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ // subpackage with subdirectory
+ "subpackage/Android.bp": "",
+ "subpackage/subpackage_header.h": "",
+ "subpackage/subdirectory/subdirectory_header.h": "",
},
- {
- description: "cc_library_static export system include dir",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- filesystem: map[string]string{
- // subpackage with subdirectory
- "subpackage/Android.bp": "",
- "subpackage/subpackage_header.h": "",
- "subpackage/subdirectory/subdirectory_header.h": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
export_system_include_dirs: ["subpackage"],
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
includes = ["subpackage"],
linkstatic = True,
)`},
- },
- {
- description: "cc_library_static include_dirs, local_include_dirs, export_include_dirs (b/183742505)",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- dir: "subpackage",
- filesystem: map[string]string{
- // subpackage with subdirectory
- "subpackage/Android.bp": `
+ })
+}
+
+func TestCcLibraryStaticManyIncludeDirs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static include_dirs, local_include_dirs, export_include_dirs (b/183742505)",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ dir: "subpackage",
+ filesystem: map[string]string{
+ // subpackage with subdirectory
+ "subpackage/Android.bp": `
cc_library_static {
name: "foo_static",
// include_dirs are workspace/root relative
@@ -330,101 +368,122 @@
include_build_directory: true,
bazel_module: { bp2build_available: true },
}`,
- "subpackage/subsubpackage/header.h": "",
- "subpackage/subsubpackage2/header.h": "",
- "subpackage/exported_subsubpackage/header.h": "",
- "subpackage2/header.h": "",
- "subpackage3/subsubpackage/header.h": "",
- },
- bp: soongCcLibraryStaticPreamble,
- expectedBazelTargets: []string{`cc_library_static(
+ "subpackage/subsubpackage/header.h": "",
+ "subpackage/subsubpackage2/header.h": "",
+ "subpackage/exported_subsubpackage/header.h": "",
+ "subpackage2/header.h": "",
+ "subpackage3/subsubpackage/header.h": "",
+ },
+ blueprint: soongCcLibraryStaticPreamble,
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
copts = [
"-Isubpackage/subsubpackage",
+ "-I$(BINDIR)/subpackage/subsubpackage",
"-Isubpackage2",
+ "-I$(BINDIR)/subpackage2",
"-Isubpackage3/subsubpackage",
+ "-I$(BINDIR)/subpackage3/subsubpackage",
"-Isubpackage/subsubpackage2",
+ "-I$(BINDIR)/subpackage/subsubpackage2",
"-Isubpackage",
+ "-I$(BINDIR)/subpackage",
],
includes = ["./exported_subsubpackage"],
linkstatic = True,
)`},
+ })
+}
+
+func TestCcLibraryStaticIncludeBuildDirectoryDisabled(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static include_build_directory disabled",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ // subpackage with subdirectory
+ "subpackage/Android.bp": "",
+ "subpackage/subpackage_header.h": "",
+ "subpackage/subdirectory/subdirectory_header.h": "",
},
- {
- description: "cc_library_static include_build_directory disabled",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- filesystem: map[string]string{
- // subpackage with subdirectory
- "subpackage/Android.bp": "",
- "subpackage/subpackage_header.h": "",
- "subpackage/subdirectory/subdirectory_header.h": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
include_dirs: ["subpackage"], // still used, but local_include_dirs is recommended
local_include_dirs: ["subpackage2"],
include_build_directory: false,
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
copts = [
"-Isubpackage",
+ "-I$(BINDIR)/subpackage",
"-Isubpackage2",
+ "-I$(BINDIR)/subpackage2",
],
linkstatic = True,
)`},
+ })
+}
+
+func TestCcLibraryStaticIncludeBuildDirectoryEnabled(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static include_build_directory enabled",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ // subpackage with subdirectory
+ "subpackage/Android.bp": "",
+ "subpackage/subpackage_header.h": "",
+ "subpackage2/Android.bp": "",
+ "subpackage2/subpackage2_header.h": "",
+ "subpackage/subdirectory/subdirectory_header.h": "",
},
- {
- description: "cc_library_static include_build_directory enabled",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- filesystem: map[string]string{
- // subpackage with subdirectory
- "subpackage/Android.bp": "",
- "subpackage/subpackage_header.h": "",
- "subpackage2/Android.bp": "",
- "subpackage2/subpackage2_header.h": "",
- "subpackage/subdirectory/subdirectory_header.h": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
include_dirs: ["subpackage"], // still used, but local_include_dirs is recommended
local_include_dirs: ["subpackage2"],
include_build_directory: true,
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
copts = [
"-Isubpackage",
+ "-I$(BINDIR)/subpackage",
"-Isubpackage2",
+ "-I$(BINDIR)/subpackage2",
"-I.",
+ "-I$(BINDIR)/.",
],
linkstatic = True,
)`},
- },
- {
- description: "cc_library_static arch-specific static_libs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{},
- bp: soongCcLibraryStaticPreamble + `
+ })
+}
+
+func TestCcLibraryStaticArchSpecificStaticLib(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static arch-specific static_libs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static { name: "static_dep" }
cc_library_static { name: "static_dep2" }
cc_library_static {
name: "foo_static",
arch: { arm64: { static_libs: ["static_dep"], whole_static_libs: ["static_dep2"] } },
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
- deps = select({
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ implementation_deps = select({
"//build/bazel/platforms/arch:arm64": [":static_dep"],
"//conditions:default": [],
}),
@@ -435,32 +494,43 @@
}),
)`, `cc_library_static(
name = "static_dep",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`, `cc_library_static(
name = "static_dep2",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`},
- },
- {
- description: "cc_library_static os-specific static_libs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{},
- bp: soongCcLibraryStaticPreamble + `
+ })
+}
+
+func TestCcLibraryStaticOsSpecificStaticLib(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static os-specific static_libs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static { name: "static_dep" }
cc_library_static { name: "static_dep2" }
cc_library_static {
name: "foo_static",
target: { android: { static_libs: ["static_dep"], whole_static_libs: ["static_dep2"] } },
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
- deps = select({
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ implementation_deps = select({
"//build/bazel/platforms/os:android": [":static_dep"],
"//conditions:default": [],
}),
@@ -471,22 +541,30 @@
}),
)`, `cc_library_static(
name = "static_dep",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`, `cc_library_static(
name = "static_dep2",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`},
- },
- {
- description: "cc_library_static base, arch and os-specific static_libs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{},
- bp: soongCcLibraryStaticPreamble + `
+ })
+}
+
+func TestCcLibraryStaticBaseArchOsSpecificStaticLib(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static base, arch and os-specific static_libs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static { name: "static_dep" }
cc_library_static { name: "static_dep2" }
cc_library_static { name: "static_dep3" }
@@ -498,10 +576,13 @@
target: { android: { static_libs: ["static_dep3"] } },
arch: { arm64: { static_libs: ["static_dep4"] } },
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
- deps = [":static_dep"] + select({
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ implementation_deps = [":static_dep"] + select({
"//build/bazel/platforms/arch:arm64": [":static_dep4"],
"//conditions:default": [],
}) + select({
@@ -512,88 +593,112 @@
whole_archive_deps = [":static_dep2"],
)`, `cc_library_static(
name = "static_dep",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`, `cc_library_static(
name = "static_dep2",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`, `cc_library_static(
name = "static_dep3",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`, `cc_library_static(
name = "static_dep4",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`},
+ })
+}
+
+func TestCcLibraryStaticSimpleExcludeSrcs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static simple exclude_srcs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.c": "",
+ "foo-a.c": "",
+ "foo-excluded.c": "",
},
- {
- description: "cc_library_static simple exclude_srcs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{
- "common.c": "",
- "foo-a.c": "",
- "foo-excluded.c": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
srcs: ["common.c", "foo-*.c"],
exclude_srcs: ["foo-excluded.c"],
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
- srcs = [
+ srcs_c = [
"common.c",
"foo-a.c",
],
)`},
+ })
+}
+
+func TestCcLibraryStaticOneArchSrcs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static one arch specific srcs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.c": "",
+ "foo-arm.c": "",
},
- {
- description: "cc_library_static one arch specific srcs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{
- "common.c": "",
- "foo-arm.c": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
srcs: ["common.c"],
arch: { arm: { srcs: ["foo-arm.c"] } }
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["foo-arm.c"],
"//conditions:default": [],
}),
)`},
+ })
+}
+
+func TestCcLibraryStaticOneArchSrcsExcludeSrcs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static one arch specific srcs and exclude_srcs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.c": "",
+ "for-arm.c": "",
+ "not-for-arm.c": "",
+ "not-for-anything.c": "",
},
- {
- description: "cc_library_static one arch specific srcs and exclude_srcs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{
- "common.c": "",
- "for-arm.c": "",
- "not-for-arm.c": "",
- "not-for-anything.c": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
srcs: ["common.c", "not-for-*.c"],
@@ -602,30 +707,35 @@
arm: { srcs: ["for-arm.c"], exclude_srcs: ["not-for-arm.c"] },
},
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["for-arm.c"],
"//conditions:default": ["not-for-arm.c"],
}),
)`},
+ })
+}
+
+func TestCcLibraryStaticTwoArchExcludeSrcs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static arch specific exclude_srcs for 2 architectures",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.c": "",
+ "for-arm.c": "",
+ "for-x86.c": "",
+ "not-for-arm.c": "",
+ "not-for-x86.c": "",
},
- {
- description: "cc_library_static arch specific exclude_srcs for 2 architectures",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{
- "common.c": "",
- "for-arm.c": "",
- "for-x86.c": "",
- "not-for-arm.c": "",
- "not-for-x86.c": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
srcs: ["common.c", "not-for-*.c"],
@@ -635,11 +745,14 @@
x86: { srcs: ["for-x86.c"], exclude_srcs: ["not-for-x86.c"] },
},
} `,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
"for-arm.c",
"not-for-x86.c",
@@ -654,26 +767,27 @@
],
}),
)`},
+ })
+}
+func TestCcLibraryStaticFourArchExcludeSrcs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static arch specific exclude_srcs for 4 architectures",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.c": "",
+ "for-arm.c": "",
+ "for-arm64.c": "",
+ "for-x86.c": "",
+ "for-x86_64.c": "",
+ "not-for-arm.c": "",
+ "not-for-arm64.c": "",
+ "not-for-x86.c": "",
+ "not-for-x86_64.c": "",
+ "not-for-everything.c": "",
},
- {
- description: "cc_library_static arch specific exclude_srcs for 4 architectures",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{
- "common.c": "",
- "for-arm.c": "",
- "for-arm64.c": "",
- "for-x86.c": "",
- "for-x86_64.c": "",
- "not-for-arm.c": "",
- "not-for-arm64.c": "",
- "not-for-x86.c": "",
- "not-for-x86_64.c": "",
- "not-for-everything.c": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
srcs: ["common.c", "not-for-*.c"],
@@ -685,11 +799,14 @@
x86_64: { srcs: ["for-x86_64.c"], exclude_srcs: ["not-for-x86_64.c"] },
},
} `,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
"for-arm.c",
"not-for-arm64.c",
@@ -722,43 +839,129 @@
],
}),
)`},
+ })
+}
+
+func TestCcLibraryStaticOneArchEmpty(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static one arch empty",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.cc": "",
+ "foo-no-arm.cc": "",
+ "foo-excluded.cc": "",
},
- {
- description: "cc_library_static multiple dep same name panic",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{},
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.cc", "foo-*.cc"],
+ exclude_srcs: ["foo-excluded.cc"],
+ arch: {
+ arm: { exclude_srcs: ["foo-no-arm.cc"] },
+ },
+}`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs = ["common.cc"] + select({
+ "//build/bazel/platforms/arch:arm": [],
+ "//conditions:default": ["foo-no-arm.cc"],
+ }),
+)`},
+ })
+}
+
+func TestCcLibraryStaticOneArchEmptyOtherSet(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static one arch empty other set",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.cc": "",
+ "foo-no-arm.cc": "",
+ "x86-only.cc": "",
+ "foo-excluded.cc": "",
+ },
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.cc", "foo-*.cc"],
+ exclude_srcs: ["foo-excluded.cc"],
+ arch: {
+ arm: { exclude_srcs: ["foo-no-arm.cc"] },
+ x86: { srcs: ["x86-only.cc"] },
+ },
+}`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs = ["common.cc"] + select({
+ "//build/bazel/platforms/arch:arm": [],
+ "//build/bazel/platforms/arch:x86": [
+ "foo-no-arm.cc",
+ "x86-only.cc",
+ ],
+ "//conditions:default": ["foo-no-arm.cc"],
+ }),
+)`},
+ })
+}
+
+func TestCcLibraryStaticMultipleDepSameName(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static multiple dep same name panic",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static { name: "static_dep" }
cc_library_static {
name: "foo_static",
static_libs: ["static_dep", "static_dep"],
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
- deps = [":static_dep"],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ implementation_deps = [":static_dep"],
linkstatic = True,
)`, `cc_library_static(
name = "static_dep",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
)`},
+ })
+}
+
+func TestCcLibraryStaticOneMultilibSrcsExcludeSrcs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static 1 multilib srcs and exclude_srcs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.c": "",
+ "for-lib32.c": "",
+ "not-for-lib32.c": "",
},
- {
- description: "cc_library_static 1 multilib srcs and exclude_srcs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{
- "common.c": "",
- "for-lib32.c": "",
- "not-for-lib32.c": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static",
srcs: ["common.c", "not-for-*.c"],
@@ -766,31 +969,36 @@
lib32: { srcs: ["for-lib32.c"], exclude_srcs: ["not-for-lib32.c"] },
},
} `,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["for-lib32.c"],
"//build/bazel/platforms/arch:x86": ["for-lib32.c"],
"//conditions:default": ["not-for-lib32.c"],
}),
)`},
+ })
+}
+
+func TestCcLibraryStaticTwoMultilibSrcsExcludeSrcs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static 2 multilib srcs and exclude_srcs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.c": "",
+ "for-lib32.c": "",
+ "for-lib64.c": "",
+ "not-for-lib32.c": "",
+ "not-for-lib64.c": "",
},
- {
- description: "cc_library_static 2 multilib srcs and exclude_srcs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{
- "common.c": "",
- "for-lib32.c": "",
- "for-lib64.c": "",
- "not-for-lib32.c": "",
- "not-for-lib64.c": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static2",
srcs: ["common.c", "not-for-*.c"],
@@ -799,11 +1007,14 @@
lib64: { srcs: ["for-lib64.c"], exclude_srcs: ["not-for-lib64.c"] },
},
} `,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static2",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
"for-lib32.c",
"not-for-lib64.c",
@@ -826,30 +1037,32 @@
],
}),
)`},
+ })
+}
+
+func TestCcLibrarySTaticArchMultilibSrcsExcludeSrcs(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static arch and multilib srcs and exclude_srcs",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.c": "",
+ "for-arm.c": "",
+ "for-arm64.c": "",
+ "for-x86.c": "",
+ "for-x86_64.c": "",
+ "for-lib32.c": "",
+ "for-lib64.c": "",
+ "not-for-arm.c": "",
+ "not-for-arm64.c": "",
+ "not-for-x86.c": "",
+ "not-for-x86_64.c": "",
+ "not-for-lib32.c": "",
+ "not-for-lib64.c": "",
+ "not-for-everything.c": "",
},
- {
- description: "cc_library_static arch and multilib srcs and exclude_srcs",
- moduleTypeUnderTest: "cc_library_static",
- moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
- depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
- filesystem: map[string]string{
- "common.c": "",
- "for-arm.c": "",
- "for-arm64.c": "",
- "for-x86.c": "",
- "for-x86_64.c": "",
- "for-lib32.c": "",
- "for-lib64.c": "",
- "not-for-arm.c": "",
- "not-for-arm64.c": "",
- "not-for-x86.c": "",
- "not-for-x86_64.c": "",
- "not-for-lib32.c": "",
- "not-for-lib64.c": "",
- "not-for-everything.c": "",
- },
- bp: soongCcLibraryStaticPreamble + `
+ blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "foo_static3",
srcs: ["common.c", "not-for-*.c"],
@@ -865,11 +1078,14 @@
lib64: { srcs: ["for-lib64.c"], exclude_srcs: ["not-for-lib64.c"] },
},
}`,
- expectedBazelTargets: []string{`cc_library_static(
+ expectedBazelTargets: []string{`cc_library_static(
name = "foo_static3",
- copts = ["-I."],
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
"for-arm.c",
"for-lib32.c",
@@ -912,64 +1128,302 @@
],
}),
)`},
+ })
+}
+
+func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static arch srcs/exclude_srcs with generated files",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{
+ "common.cpp": "",
+ "for-x86.cpp": "",
+ "not-for-x86.cpp": "",
+ "not-for-everything.cpp": "",
+ "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",
+}`,
},
- }
+ blueprint: soongCcLibraryStaticPreamble + `
+genrule {
+ name: "generated_src",
+ out: ["generated_src.cpp"],
+ cmd: "nothing to see here",
+}
- dir := "."
- for _, testCase := range testCases {
- filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
- filesystem[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
- ctx := android.NewTestContext(config)
+genrule {
+ name: "generated_src_x86",
+ out: ["generated_src_x86.cpp"],
+ cmd: "nothing to see here",
+}
- cc.RegisterCCBuildComponents(ctx)
- ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
- ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
+genrule {
+ name: "generated_hdr",
+ out: ["generated_hdr.h"],
+ cmd: "nothing to see here",
+}
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- for _, m := range testCase.depsMutators {
- ctx.DepsBp2BuildMutators(m)
- }
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterBp2BuildConfig(bp2buildConfig)
- ctx.RegisterForBazelConversion()
+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"],
+ },
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static3",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs = [
+ "//dep:generated_hdr_other_pkg",
+ "//dep:generated_src_other_pkg",
+ ":generated_hdr",
+ ":generated_src",
+ "common.cpp",
+ ] + select({
+ "//build/bazel/platforms/arch:x86": [
+ "//dep:generated_hdr_other_pkg_x86",
+ ":generated_src_x86",
+ "for-x86.cpp",
+ ],
+ "//conditions:default": ["not-for-x86.cpp"],
+ }),
+)`},
+ })
+}
- _, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
- continue
- }
+func TestCcLibraryStaticGetTargetProperties(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
- checkDir := dir
- if testCase.dir != "" {
- checkDir = testCase.dir
- }
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
- )
+ description: "cc_library_static complex GetTargetProperties",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ target: {
+ android: {
+ srcs: ["android_src.c"],
+ },
+ android_arm: {
+ srcs: ["android_arm_src.c"],
+ },
+ android_arm64: {
+ srcs: ["android_arm64_src.c"],
+ },
+ android_x86: {
+ srcs: ["android_x86_src.c"],
+ },
+ android_x86_64: {
+ srcs: ["android_x86_64_src.c"],
+ },
+ linux_bionic_arm64: {
+ srcs: ["linux_bionic_arm64_src.c"],
+ },
+ linux_bionic_x86_64: {
+ srcs: ["linux_bionic_x86_64_src.c"],
+ },
+ },
+}`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs_c = select({
+ "//build/bazel/platforms/os:android": ["android_src.c"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os_arch:android_arm": ["android_arm_src.c"],
+ "//build/bazel/platforms/os_arch:android_arm64": ["android_arm64_src.c"],
+ "//build/bazel/platforms/os_arch:android_x86": ["android_x86_src.c"],
+ "//build/bazel/platforms/os_arch:android_x86_64": ["android_x86_64_src.c"],
+ "//build/bazel/platforms/os_arch:linux_bionic_arm64": ["linux_bionic_arm64_src.c"],
+ "//build/bazel/platforms/os_arch:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"],
+ "//conditions:default": [],
+ }),
+)`},
+ })
+}
+
+func TestCcLibraryStaticProductVariableSelects(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static product variable selects",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.c"],
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wmalloc_not_svelte"],
+ },
+ malloc_zero_contents: {
+ cflags: ["-Wmalloc_zero_contents"],
+ },
+ binder32bit: {
+ cflags: ["-Wbinder32bit"],
+ },
+ },
+} `,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ] + select({
+ "//build/bazel/product_variables:binder32bit": ["-Wbinder32bit"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_zero_contents": ["-Wmalloc_zero_contents"],
+ "//conditions:default": [],
+ }),
+ linkstatic = True,
+ srcs_c = ["common.c"],
+)`},
+ })
+}
+
+func TestCcLibraryStaticProductVariableArchSpecificSelects(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static arch-specific product variable selects",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.c"],
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wmalloc_not_svelte"],
+ },
+ },
+ arch: {
+ arm64: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Warm64_malloc_not_svelte"],
+ },
+ },
+ },
+ },
+ multilib: {
+ lib32: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wlib32_malloc_not_svelte"],
+ },
+ },
+ },
+ },
+ target: {
+ android: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wandroid_malloc_not_svelte"],
+ },
+ },
}
- }
- }
- }
+ },
+} `,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ] + select({
+ "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte-android": ["-Wandroid_malloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte-arm": ["-Wlib32_malloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte-arm64": ["-Warm64_malloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte-x86": ["-Wlib32_malloc_not_svelte"],
+ "//conditions:default": [],
+ }),
+ linkstatic = True,
+ srcs_c = ["common.c"],
+)`},
+ })
+}
+
+func TestCcLibraryStaticProductVariableStringReplacement(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static product variable string replacement",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.S"],
+ product_variables: {
+ platform_sdk_version: {
+ asflags: ["-DPLATFORM_SDK_VERSION=%d"],
+ },
+ },
+} `,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ asflags = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ] + select({
+ "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
+ "//conditions:default": [],
+ }),
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs_as = ["common.S"],
+)`},
+ })
}
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index 9efdb53..9ac28a5 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -15,37 +15,38 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/cc"
- "fmt"
- "strings"
- "testing"
)
-func TestCcObjectBp2Build(t *testing.T) {
- testCases := []struct {
- description string
- moduleTypeUnderTest string
- moduleTypeUnderTestFactory android.ModuleFactory
- moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
- blueprint string
- expectedBazelTargets []string
- filesystem map[string]string
- }{
- {
- description: "simple cc_object generates cc_object with include header dep",
- moduleTypeUnderTest: "cc_object",
- moduleTypeUnderTestFactory: cc.ObjectFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
- filesystem: map[string]string{
- "a/b/foo.h": "",
- "a/b/bar.h": "",
- "a/b/exclude.c": "",
- "a/b/c.c": "",
- },
- blueprint: `cc_object {
+func registerCcObjectModuleTypes(ctx android.RegistrationContext) {
+ // Always register cc_defaults module factory
+ ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
+}
+
+func runCcObjectTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerCcObjectModuleTypes, tc)
+}
+
+func TestCcObjectSimple(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "simple cc_object generates cc_object with include header dep",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ filesystem: map[string]string{
+ "a/b/foo.h": "",
+ "a/b/bar.h": "",
+ "a/b/exclude.c": "",
+ "a/b/c.c": "",
+ },
+ blueprint: `cc_object {
name: "foo",
local_include_dirs: ["include"],
+ system_shared_libs: [],
cflags: [
"-Wno-gcc-compat",
"-Wall",
@@ -57,7 +58,7 @@
exclude_srcs: ["a/b/exclude.c"],
}
`,
- expectedBazelTargets: []string{`cc_object(
+ expectedBazelTargets: []string{`cc_object(
name = "foo",
copts = [
"-fno-addrsig",
@@ -65,19 +66,25 @@
"-Wall",
"-Werror",
"-Iinclude",
+ "-I$(BINDIR)/include",
"-I.",
+ "-I$(BINDIR)/.",
],
srcs = ["a/b/c.c"],
)`,
- },
},
- {
- description: "simple cc_object with defaults",
- moduleTypeUnderTest: "cc_object",
- moduleTypeUnderTestFactory: cc.ObjectFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
- blueprint: `cc_object {
+ })
+}
+
+func TestCcObjectDefaults(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "simple cc_object with defaults",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
name: "foo",
+ system_shared_libs: [],
local_include_dirs: ["include"],
srcs: [
"a/b/*.h",
@@ -101,7 +108,7 @@
],
}
`,
- expectedBazelTargets: []string{`cc_object(
+ expectedBazelTargets: []string{`cc_object(
name = "foo",
copts = [
"-Wno-gcc-compat",
@@ -109,37 +116,44 @@
"-Werror",
"-fno-addrsig",
"-Iinclude",
+ "-I$(BINDIR)/include",
"-I.",
+ "-I$(BINDIR)/.",
],
srcs = ["a/b/c.c"],
)`,
- },
+ }})
+}
+
+func TestCcObjectCcObjetDepsInObjs(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "cc_object with cc_object deps in objs props",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ filesystem: map[string]string{
+ "a/b/c.c": "",
+ "x/y/z.c": "",
},
- {
- description: "cc_object with cc_object deps in objs props",
- moduleTypeUnderTest: "cc_object",
- moduleTypeUnderTestFactory: cc.ObjectFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
- filesystem: map[string]string{
- "a/b/c.c": "",
- "x/y/z.c": "",
- },
- blueprint: `cc_object {
+ blueprint: `cc_object {
name: "foo",
+ system_shared_libs: [],
srcs: ["a/b/c.c"],
objs: ["bar"],
}
cc_object {
name: "bar",
+ system_shared_libs: [],
srcs: ["x/y/z.c"],
}
`,
- expectedBazelTargets: []string{`cc_object(
+ expectedBazelTargets: []string{`cc_object(
name = "bar",
copts = [
"-fno-addrsig",
"-I.",
+ "-I$(BINDIR)/.",
],
srcs = ["x/y/z.c"],
)`, `cc_object(
@@ -147,161 +161,121 @@
copts = [
"-fno-addrsig",
"-I.",
+ "-I$(BINDIR)/.",
],
deps = [":bar"],
srcs = ["a/b/c.c"],
)`,
- },
},
- {
- description: "cc_object with include_build_dir: false",
- moduleTypeUnderTest: "cc_object",
- moduleTypeUnderTestFactory: cc.ObjectFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
- filesystem: map[string]string{
- "a/b/c.c": "",
- "x/y/z.c": "",
- },
- blueprint: `cc_object {
+ })
+}
+
+func TestCcObjectIncludeBuildDirFalse(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "cc_object with include_build_dir: false",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ filesystem: map[string]string{
+ "a/b/c.c": "",
+ "x/y/z.c": "",
+ },
+ blueprint: `cc_object {
name: "foo",
+ system_shared_libs: [],
srcs: ["a/b/c.c"],
include_build_directory: false,
}
`,
- expectedBazelTargets: []string{`cc_object(
+ expectedBazelTargets: []string{`cc_object(
name = "foo",
copts = ["-fno-addrsig"],
srcs = ["a/b/c.c"],
)`,
- },
},
- {
- description: "cc_object with product variable",
- moduleTypeUnderTest: "cc_object",
- moduleTypeUnderTestFactory: cc.ObjectFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
- blueprint: `cc_object {
+ })
+}
+
+func TestCcObjectProductVariable(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "cc_object with product variable",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
name: "foo",
+ system_shared_libs: [],
include_build_directory: false,
product_variables: {
platform_sdk_version: {
asflags: ["-DPLATFORM_SDK_VERSION=%d"],
},
},
+ srcs: ["src.S"],
}
`,
- expectedBazelTargets: []string{`cc_object(
+ expectedBazelTargets: []string{`cc_object(
name = "foo",
- asflags = ["-DPLATFORM_SDK_VERSION={Platform_sdk_version}"],
+ asflags = select({
+ "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
+ "//conditions:default": [],
+ }),
copts = ["-fno-addrsig"],
+ srcs_as = ["src.S"],
)`,
- },
},
- }
-
- dir := "."
- for _, testCase := range testCases {
- filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
- filesystem[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
- ctx := android.NewTestContext(config)
- // Always register cc_defaults module factory
- ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
-
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterBp2BuildConfig(bp2buildConfig)
- ctx.RegisterForBazelConversion()
-
- _, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
- continue
- }
-
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- fmt.Println(bazelTargets)
- t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
- )
- }
- }
- }
- }
+ })
}
-func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) {
- testCases := []struct {
- description string
- moduleTypeUnderTest string
- moduleTypeUnderTestFactory android.ModuleFactory
- moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
- blueprint string
- expectedBazelTargets []string
- filesystem map[string]string
- }{
- {
- description: "cc_object setting cflags for one arch",
- moduleTypeUnderTest: "cc_object",
- moduleTypeUnderTestFactory: cc.ObjectFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
- blueprint: `cc_object {
+func TestCcObjectCflagsOneArch(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "cc_object setting cflags for one arch",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
name: "foo",
+ system_shared_libs: [],
srcs: ["a.cpp"],
arch: {
x86: {
cflags: ["-fPIC"], // string list
},
arm: {
- srcs: ["arch/arm/file.S"], // label list
+ srcs: ["arch/arm/file.cpp"], // label list
},
},
}
`,
- expectedBazelTargets: []string{
- `cc_object(
+ expectedBazelTargets: []string{
+ `cc_object(
name = "foo",
copts = [
"-fno-addrsig",
"-I.",
+ "-I$(BINDIR)/.",
] + select({
"//build/bazel/platforms/arch:x86": ["-fPIC"],
"//conditions:default": [],
}),
srcs = ["a.cpp"] + select({
- "//build/bazel/platforms/arch:arm": ["arch/arm/file.S"],
+ "//build/bazel/platforms/arch:arm": ["arch/arm/file.cpp"],
"//conditions:default": [],
}),
)`,
- },
},
- {
- description: "cc_object setting cflags for 4 architectures",
- moduleTypeUnderTest: "cc_object",
- moduleTypeUnderTestFactory: cc.ObjectFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
- blueprint: `cc_object {
+ })
+}
+
+func TestCcObjectCflagsFourArch(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "cc_object setting cflags for 4 architectures",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
name: "foo",
+ system_shared_libs: [],
srcs: ["base.cpp"],
arch: {
x86: {
@@ -323,12 +297,13 @@
},
}
`,
- expectedBazelTargets: []string{
- `cc_object(
+ expectedBazelTargets: []string{
+ `cc_object(
name = "foo",
copts = [
"-fno-addrsig",
"-I.",
+ "-I$(BINDIR)/.",
] + select({
"//build/bazel/platforms/arch:arm": ["-Wall"],
"//build/bazel/platforms/arch:arm64": ["-Wall"],
@@ -344,15 +319,19 @@
"//conditions:default": [],
}),
)`,
- },
},
- {
- description: "cc_object setting cflags for multiple OSes",
- moduleTypeUnderTest: "cc_object",
- moduleTypeUnderTestFactory: cc.ObjectFactory,
- moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
- blueprint: `cc_object {
+ })
+}
+
+func TestCcObjectCflagsMultiOs(t *testing.T) {
+ runCcObjectTestCase(t, bp2buildTestCase{
+ description: "cc_object setting cflags for multiple OSes",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
name: "foo",
+ system_shared_libs: [],
srcs: ["base.cpp"],
target: {
android: {
@@ -367,12 +346,13 @@
},
}
`,
- expectedBazelTargets: []string{
- `cc_object(
+ expectedBazelTargets: []string{
+ `cc_object(
name = "foo",
copts = [
"-fno-addrsig",
"-I.",
+ "-I$(BINDIR)/.",
] + select({
"//build/bazel/platforms/os:android": ["-fPIC"],
"//build/bazel/platforms/os:darwin": ["-Wall"],
@@ -381,51 +361,6 @@
}),
srcs = ["base.cpp"],
)`,
- },
},
- }
-
- dir := "."
- for _, testCase := range testCases {
- filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
- ctx := android.NewTestContext(config)
- // Always register cc_defaults module factory
- ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
-
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterBp2BuildConfig(bp2buildConfig)
- ctx.RegisterForBazelConversion()
-
- _, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
- continue
- }
-
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- fmt.Println(bazelTargets)
- t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
- )
- }
- }
- }
- }
+ })
}
diff --git a/bp2build/compatibility.go b/bp2build/compatibility.go
new file mode 100644
index 0000000..5baa524
--- /dev/null
+++ b/bp2build/compatibility.go
@@ -0,0 +1,31 @@
+package bp2build
+
+import (
+ "android/soong/bazel"
+ "fmt"
+)
+
+// Data from the code generation process that is used to improve compatibility
+// between build systems.
+type CodegenCompatLayer struct {
+ // A map from the original module name to the generated/handcrafted Bazel
+ // label for legacy build systems to be able to build a fully-qualified
+ // Bazel target from an unique module name.
+ NameToLabelMap map[string]string
+}
+
+// Log an entry of module name -> Bazel target label.
+func (compatLayer CodegenCompatLayer) AddNameToLabelEntry(name, label string) {
+ // The module name may be prefixed with bazel.BazelTargetModuleNamePrefix if
+ // generated from bp2build.
+ name = bazel.StripNamePrefix(name)
+ if existingLabel, ok := compatLayer.NameToLabelMap[name]; ok {
+ panic(fmt.Errorf(
+ "Module '%s' maps to more than one Bazel target label: %s, %s. "+
+ "This shouldn't happen. It probably indicates a bug with the bp2build internals.",
+ name,
+ existingLabel,
+ label))
+ }
+ compatLayer.NameToLabelMap[name] = label
+}
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index 2b8f6cc..c8105eb 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -11,80 +11,131 @@
type selects map[string]reflect.Value
-func getStringListValues(list bazel.StringListAttribute) (reflect.Value, selects, selects) {
+func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(list.Value)
if !list.HasConfigurableValues() {
- return value, nil, nil
+ return value, []selects{}
}
- archSelects := map[string]reflect.Value{}
- for arch, selectKey := range bazel.PlatformArchMap {
- archSelects[selectKey] = reflect.ValueOf(list.GetValueForArch(arch))
- }
-
- osSelects := map[string]reflect.Value{}
- for os, selectKey := range bazel.PlatformOsMap {
- osSelects[selectKey] = reflect.ValueOf(list.GetValueForOS(os))
- }
-
- return value, archSelects, osSelects
-}
-
-func getLabelValue(label bazel.LabelAttribute) (reflect.Value, selects, selects) {
- var value reflect.Value
- var archSelects selects
-
- if label.HasConfigurableValues() {
- archSelects = map[string]reflect.Value{}
- for arch, selectKey := range bazel.PlatformArchMap {
- archSelects[selectKey] = reflect.ValueOf(label.GetValueForArch(arch))
+ var ret []selects
+ for _, axis := range list.SortedConfigurationAxes() {
+ configToLists := list.ConfigurableValues[axis]
+ archSelects := map[string]reflect.Value{}
+ for config, labels := range configToLists {
+ selectKey := axis.SelectKey(config)
+ archSelects[selectKey] = reflect.ValueOf(labels)
}
- } else {
- value = reflect.ValueOf(label.Value)
+ if len(archSelects) > 0 {
+ ret = append(ret, archSelects)
+ }
}
- return value, archSelects, nil
+ return value, ret
}
-func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, selects, selects) {
+func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
+ value := reflect.ValueOf(label.Value)
+ if !label.HasConfigurableValues() {
+ return value, []selects{}
+ }
+
+ ret := selects{}
+ for _, axis := range label.SortedConfigurationAxes() {
+ configToLabels := label.ConfigurableValues[axis]
+ for config, labels := range configToLabels {
+ selectKey := axis.SelectKey(config)
+ ret[selectKey] = reflect.ValueOf(labels)
+ }
+ }
+
+ return value, []selects{ret}
+}
+
+func getBoolValue(boolAttr bazel.BoolAttribute) (reflect.Value, []selects) {
+ value := reflect.ValueOf(boolAttr.Value)
+ if !boolAttr.HasConfigurableValues() {
+ return value, []selects{}
+ }
+
+ ret := selects{}
+ for _, axis := range boolAttr.SortedConfigurationAxes() {
+ configToBools := boolAttr.ConfigurableValues[axis]
+ for config, bools := range configToBools {
+ selectKey := axis.SelectKey(config)
+ ret[selectKey] = reflect.ValueOf(bools)
+ }
+ }
+ // if there is a select, use the base value as the conditions default value
+ if len(ret) > 0 {
+ ret[bazel.ConditionsDefaultSelectKey] = value
+ value = reflect.Zero(value.Type())
+ }
+
+ return value, []selects{ret}
+}
+func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(list.Value.Includes)
- if !list.HasConfigurableValues() {
- return value, nil, nil
+ var ret []selects
+ for _, axis := range list.SortedConfigurationAxes() {
+ configToLabels := list.ConfigurableValues[axis]
+ if !configToLabels.HasConfigurableValues() {
+ continue
+ }
+ archSelects := map[string]reflect.Value{}
+ for config, labels := range configToLabels {
+ selectKey := axis.SelectKey(config)
+ if use, value := labelListSelectValue(selectKey, labels); use {
+ archSelects[selectKey] = value
+ }
+ }
+ if len(archSelects) > 0 {
+ ret = append(ret, archSelects)
+ }
}
- archSelects := map[string]reflect.Value{}
- for arch, selectKey := range bazel.PlatformArchMap {
- archSelects[selectKey] = reflect.ValueOf(list.GetValueForArch(arch).Includes)
- }
-
- osSelects := map[string]reflect.Value{}
- for os, selectKey := range bazel.PlatformOsMap {
- osSelects[selectKey] = reflect.ValueOf(list.GetValueForOS(os).Includes)
- }
-
- return value, archSelects, osSelects
+ return value, ret
}
+func labelListSelectValue(selectKey string, list bazel.LabelList) (bool, reflect.Value) {
+ if selectKey == bazel.ConditionsDefaultSelectKey || len(list.Includes) > 0 {
+ return true, reflect.ValueOf(list.Includes)
+ } else if len(list.Excludes) > 0 {
+ // if there is still an excludes -- we need to have an empty list for this select & use the
+ // value in conditions default Includes
+ return true, reflect.ValueOf([]string{})
+ }
+ return false, reflect.Zero(reflect.TypeOf([]string{}))
+}
+
+var (
+ emptyBazelList = "[]"
+ bazelNone = "None"
+)
+
// prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain
// select statements.
func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
var value reflect.Value
- var archSelects, osSelects selects
- var defaultSelectValue string
+ var configurableAttrs []selects
+ var defaultSelectValue *string
switch list := v.(type) {
case bazel.StringListAttribute:
- value, archSelects, osSelects = getStringListValues(list)
- defaultSelectValue = "[]"
+ value, configurableAttrs = getStringListValues(list)
+ defaultSelectValue = &emptyBazelList
case bazel.LabelListAttribute:
- value, archSelects, osSelects = getLabelListValues(list)
- defaultSelectValue = "[]"
+ value, configurableAttrs = getLabelListValues(list)
+ defaultSelectValue = &emptyBazelList
case bazel.LabelAttribute:
- value, archSelects, osSelects = getLabelValue(list)
- defaultSelectValue = "None"
+ value, configurableAttrs = getLabelValue(list)
+ defaultSelectValue = &bazelNone
+ case bazel.BoolAttribute:
+ value, configurableAttrs = getBoolValue(list)
+ defaultSelectValue = &bazelNone
default:
return "", fmt.Errorf("Not a supported Bazel attribute type: %s", v)
}
+ var err error
ret := ""
if value.Kind() != reflect.Invalid {
s, err := prettyPrint(value, indent)
@@ -95,7 +146,7 @@
ret += s
}
// Convenience function to append selects components to an attribute value.
- appendSelects := func(selectsData selects, defaultValue, s string) (string, error) {
+ appendSelects := func(selectsData selects, defaultValue *string, s string) (string, error) {
selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent)
if err != nil {
return "", err
@@ -108,28 +159,26 @@
return s, nil
}
- ret, err := appendSelects(archSelects, defaultSelectValue, ret)
- if err != nil {
- return "", err
+ for _, configurableAttr := range configurableAttrs {
+ ret, err = appendSelects(configurableAttr, defaultSelectValue, ret)
+ if err != nil {
+ return "", err
+ }
}
- ret, err = appendSelects(osSelects, defaultSelectValue, ret)
- return ret, err
+ return ret, nil
}
// prettyPrintSelectMap converts a map of select keys to reflected Values as a generic way
// to construct a select map for any kind of attribute type.
-func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue string, indent int) (string, error) {
+func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue *string, indent int) (string, error) {
if selectMap == nil {
return "", nil
}
- // addConditionsDefault := false
- conditionsDefaultKey := bazel.PlatformArchMap[bazel.CONDITIONS_DEFAULT]
-
var selects string
for _, selectKey := range android.SortedStringKeys(selectMap) {
- if selectKey == conditionsDefaultKey {
+ if selectKey == bazel.ConditionsDefaultSelectKey {
// Handle default condition later.
continue
}
@@ -159,18 +208,18 @@
ret += selects
// Handle the default condition
- s, err := prettyPrintSelectEntry(selectMap[conditionsDefaultKey], conditionsDefaultKey, indent)
+ s, err := prettyPrintSelectEntry(selectMap[bazel.ConditionsDefaultSelectKey], bazel.ConditionsDefaultSelectKey, indent)
if err != nil {
return "", err
}
- if s == "" {
- // Print an explicit empty list (the default value) even if the value is
- // empty, to avoid errors about not finding a configuration that matches.
- ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), "//conditions:default", defaultValue)
- } else {
+ if s != "" {
// Print the custom default value.
ret += s
ret += ",\n"
+ } else if defaultValue != nil {
+ // Print an explicit empty list (the default value) even if the value is
+ // empty, to avoid errors about not finding a configuration that matches.
+ ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), bazel.ConditionsDefaultSelectKey, *defaultValue)
}
ret += makeIndent(indent)
diff --git a/bp2build/constants.go b/bp2build/constants.go
index 70f320e..4870dff 100644
--- a/bp2build/constants.go
+++ b/bp2build/constants.go
@@ -19,7 +19,10 @@
// be preferred for use within a Bazel build.
// The file name used for automatically generated files.
- GeneratedBuildFileName = "BUILD"
+ GeneratedBuildFileName = "BUILD.bazel"
+
// The file name used for hand-crafted build targets.
+ // NOTE: It is okay that this matches GeneratedBuildFileName, since we generate BUILD files in a different directory to source files
+ // FIXME: Because there are hundreds of existing BUILD.bazel files in the AOSP tree, we should pick another name here, like BUILD.android
HandcraftedBuildFileName = "BUILD.bazel"
)
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index eb83b38..75bc2b4 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -5,7 +5,6 @@
"android/soong/cc/config"
"fmt"
"reflect"
- "sort"
"strings"
"github.com/google/blueprint/proptools"
@@ -17,15 +16,31 @@
Contents string
}
-func CreateSoongInjectionFiles() []BazelFile {
+func CreateSoongInjectionFiles(compatLayer CodegenCompatLayer) []BazelFile {
var files []BazelFile
- files = append(files, newFile("cc_toolchain", "BUILD", "")) // Creates a //cc_toolchain package.
+ 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("module_name_to_label", GeneratedBuildFileName, nameToLabelAliases(compatLayer.NameToLabelMap)))
+
return files
}
+func nameToLabelAliases(nameToLabelMap map[string]string) string {
+ ret := make([]string, len(nameToLabelMap))
+
+ for k, v := range nameToLabelMap {
+ // v is the fully qualified label rooted at '//'
+ ret = append(ret, fmt.Sprintf(
+ `alias(
+ name = "%s",
+ actual = "@%s",
+)`, k, v))
+ }
+ return strings.Join(ret, "\n\n")
+}
+
func CreateBazelFiles(
ruleShims map[string]RuleShim,
buildToTargets map[string]BazelTargets,
@@ -59,27 +74,33 @@
func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
files := make([]BazelFile, 0, len(buildToTargets))
for _, dir := range android.SortedStringKeys(buildToTargets) {
- if mode == Bp2Build && !android.ShouldWriteBuildFileForDir(dir) {
+ if mode == Bp2Build && android.ShouldKeepExistingBuildFileForDir(dir) {
fmt.Printf("[bp2build] Not writing generated BUILD file for dir: '%s'\n", dir)
continue
}
targets := buildToTargets[dir]
- sort.Slice(targets, func(i, j int) bool {
- // this will cover all bp2build generated targets
- if targets[i].name < targets[j].name {
- return true
- }
- // give a strict ordering to content from hand-crafted targets
- return targets[i].content < targets[j].content
- })
- content := soongModuleLoad
+ targets.sort()
+
+ var content string
if mode == Bp2Build {
- content = `# This file was automatically generated by bp2build for the Bazel migration project.
-# Feel free to edit or test it, but do *not* check it into your version control system.`
- content += "\n\n"
- content += "package(default_visibility = [\"//visibility:public\"])"
- content += "\n\n"
+ content = `# READ THIS FIRST:
+# This file was automatically generated by bp2build for the Bazel migration project.
+# Feel free to edit or test it, but do *not* check it into your version control system.
+`
+ if targets.hasHandcraftedTargets() {
+ // For BUILD files with both handcrafted and generated targets,
+ // don't hardcode actual content, like package() declarations.
+ // Leave that responsibility to the checked-in BUILD file
+ // instead.
+ content += `# This file contains generated targets and handcrafted targets that are manually managed in the source tree.`
+ } else {
+ // For fully-generated BUILD files, hardcode the default visibility.
+ content += "package(default_visibility = [\"//visibility:public\"])"
+ }
+ content += "\n"
content += targets.LoadStatements()
+ } else if mode == QueryView {
+ content = soongModuleLoad
}
if content != "" {
// If there are load statements, add a couple of newlines.
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index a08c03d..56ea589 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -29,7 +29,7 @@
expectedFilePaths := []bazelFilepath{
{
dir: "",
- basename: "BUILD",
+ basename: "BUILD.bazel",
},
{
dir: "",
@@ -37,7 +37,7 @@
},
{
dir: bazelRulesSubDir,
- basename: "BUILD",
+ basename: "BUILD.bazel",
},
{
dir: bazelRulesSubDir,
@@ -69,7 +69,7 @@
if actualFile.Dir != expectedFile.dir || actualFile.Basename != expectedFile.basename {
t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename)
- } else if actualFile.Basename == "BUILD" || actualFile.Basename == "WORKSPACE" {
+ } else if actualFile.Basename == "BUILD.bazel" || actualFile.Basename == "WORKSPACE" {
if actualFile.Contents != "" {
t.Errorf("Expected %s to have no content.", actualFile)
}
@@ -80,17 +80,21 @@
}
func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
- files := CreateSoongInjectionFiles()
+ files := CreateSoongInjectionFiles(CodegenCompatLayer{})
expectedFilePaths := []bazelFilepath{
{
dir: "cc_toolchain",
- basename: "BUILD",
+ basename: GeneratedBuildFileName,
},
{
dir: "cc_toolchain",
basename: "constants.bzl",
},
+ {
+ dir: "module_name_to_label",
+ basename: GeneratedBuildFileName,
+ },
}
if len(files) != len(expectedFilePaths) {
@@ -104,7 +108,7 @@
t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename)
}
- if expectedFile.basename != "BUILD" && actualFile.Contents == "" {
+ if expectedFile.basename != GeneratedBuildFileName && actualFile.Contents == "" {
t.Errorf("Contents of %s unexpected empty.", actualFile)
}
}
diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go
new file mode 100644
index 0000000..4e25d1b
--- /dev/null
+++ b/bp2build/prebuilt_etc_conversion_test.go
@@ -0,0 +1,55 @@
+// 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/etc"
+
+ "testing"
+)
+
+func runPrebuiltEtcTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, registerPrebuiltEtcModuleTypes, tc)
+}
+
+func registerPrebuiltEtcModuleTypes(ctx android.RegistrationContext) {
+}
+
+func TestPrebuiltEtcSimple(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,
+}
+`,
+ expectedBazelTargets: []string{`prebuilt_etc(
+ name = "apex_tz_version",
+ filename = "tz_version",
+ installable = False,
+ src = "version/tz_version",
+ sub_dir = "tz",
+)`}})
+}
diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go
index 2054e06..7bedf71 100644
--- a/bp2build/python_binary_conversion_test.go
+++ b/bp2build/python_binary_conversion_test.go
@@ -1,36 +1,31 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/python"
- "fmt"
- "strings"
- "testing"
)
-func TestPythonBinaryHost(t *testing.T) {
- testCases := []struct {
- description string
- moduleTypeUnderTest string
- moduleTypeUnderTestFactory android.ModuleFactory
- moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
- blueprint string
- expectedBazelTargets []string
- filesystem map[string]string
- }{
- {
- description: "simple python_binary_host converts to a native py_binary",
- moduleTypeUnderTest: "python_binary_host",
- moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
- moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build,
- filesystem: map[string]string{
- "a.py": "",
- "b/c.py": "",
- "b/d.py": "",
- "b/e.py": "",
- "files/data.txt": "",
- },
- blueprint: `python_binary_host {
+func runPythonTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
+}
+
+func TestPythonBinaryHostSimple(t *testing.T) {
+ runPythonTestCase(t, bp2buildTestCase{
+ description: "simple python_binary_host converts to a native py_binary",
+ moduleTypeUnderTest: "python_binary_host",
+ moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
+ moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build,
+ filesystem: map[string]string{
+ "a.py": "",
+ "b/c.py": "",
+ "b/d.py": "",
+ "b/e.py": "",
+ "files/data.txt": "",
+ },
+ blueprint: `python_binary_host {
name: "foo",
main: "a.py",
srcs: ["**/*.py"],
@@ -39,7 +34,7 @@
bazel_module: { bp2build_available: true },
}
`,
- expectedBazelTargets: []string{`py_binary(
+ expectedBazelTargets: []string{`py_binary(
name = "foo",
data = ["files/data.txt"],
main = "a.py",
@@ -49,14 +44,17 @@
"b/d.py",
],
)`,
- },
},
- {
- description: "py2 python_binary_host",
- moduleTypeUnderTest: "python_binary_host",
- moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
- moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build,
- blueprint: `python_binary_host {
+ })
+}
+
+func TestPythonBinaryHostPy2(t *testing.T) {
+ runPythonTestCase(t, bp2buildTestCase{
+ description: "py2 python_binary_host",
+ moduleTypeUnderTest: "python_binary_host",
+ moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
+ moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build,
+ blueprint: `python_binary_host {
name: "foo",
srcs: ["a.py"],
version: {
@@ -71,19 +69,22 @@
bazel_module: { bp2build_available: true },
}
`,
- expectedBazelTargets: []string{`py_binary(
+ expectedBazelTargets: []string{`py_binary(
name = "foo",
python_version = "PY2",
srcs = ["a.py"],
)`,
- },
},
- {
- description: "py3 python_binary_host",
- moduleTypeUnderTest: "python_binary_host",
- moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
- moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build,
- blueprint: `python_binary_host {
+ })
+}
+
+func TestPythonBinaryHostPy3(t *testing.T) {
+ runPythonTestCase(t, bp2buildTestCase{
+ description: "py3 python_binary_host",
+ moduleTypeUnderTest: "python_binary_host",
+ moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
+ moduleTypeUnderTestBp2BuildMutator: python.PythonBinaryBp2Build,
+ blueprint: `python_binary_host {
name: "foo",
srcs: ["a.py"],
version: {
@@ -98,60 +99,12 @@
bazel_module: { bp2build_available: true },
}
`,
- expectedBazelTargets: []string{
- // python_version is PY3 by default.
- `py_binary(
+ expectedBazelTargets: []string{
+ // python_version is PY3 by default.
+ `py_binary(
name = "foo",
srcs = ["a.py"],
)`,
- },
},
- }
-
- dir := "."
- for _, testCase := range testCases {
- filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
- filesystem[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
- ctx := android.NewTestContext(config)
-
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterForBazelConversion()
-
- _, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
- continue
- }
-
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- fmt.Println(bazelTargets)
- t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
- )
- }
- }
- }
- }
+ })
}
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
index 37f542e..82e0a14 100644
--- a/bp2build/sh_conversion_test.go
+++ b/bp2build/sh_conversion_test.go
@@ -15,10 +15,10 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/sh"
- "strings"
- "testing"
)
func TestShBinaryLoadStatement(t *testing.T) {
@@ -46,88 +46,27 @@
t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
}
}
-
}
-func TestShBinaryBp2Build(t *testing.T) {
- testCases := []struct {
- description string
- moduleTypeUnderTest string
- moduleTypeUnderTestFactory android.ModuleFactory
- moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
- preArchMutators []android.RegisterMutatorFunc
- depsMutators []android.RegisterMutatorFunc
- bp string
- expectedBazelTargets []string
- filesystem map[string]string
- dir string
- }{
- {
- description: "sh_binary test",
- moduleTypeUnderTest: "sh_binary",
- moduleTypeUnderTestFactory: sh.ShBinaryFactory,
- moduleTypeUnderTestBp2BuildMutator: sh.ShBinaryBp2Build,
- bp: `sh_binary {
+func runShBinaryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
+}
+
+func TestShBinarySimple(t *testing.T) {
+ runShBinaryTestCase(t, bp2buildTestCase{
+ description: "sh_binary test",
+ moduleTypeUnderTest: "sh_binary",
+ moduleTypeUnderTestFactory: sh.ShBinaryFactory,
+ moduleTypeUnderTestBp2BuildMutator: sh.ShBinaryBp2Build,
+ blueprint: `sh_binary {
name: "foo",
src: "foo.sh",
bazel_module: { bp2build_available: true },
}`,
- expectedBazelTargets: []string{`sh_binary(
+ expectedBazelTargets: []string{`sh_binary(
name = "foo",
srcs = ["foo.sh"],
)`},
- },
- }
-
- dir := "."
- for _, testCase := range testCases {
- filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
- filesystem[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
- ctx := android.NewTestContext(config)
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- for _, m := range testCase.depsMutators {
- ctx.DepsBp2BuildMutators(m)
- }
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterForBazelConversion()
-
- _, errs := ctx.ParseFileList(dir, toParse)
- if Errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if Errored(t, testCase.description, errs) {
- continue
- }
-
- checkDir := dir
- if testCase.dir != "" {
- checkDir = testCase.dir
- }
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
- )
- }
- }
- }
- }
+ })
}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index b925682..f3cd7f0 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -1,6 +1,8 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/bazel"
)
@@ -10,6 +12,8 @@
bp2buildConfig = android.Bp2BuildConfig{
android.BP2BUILD_TOPLEVEL: android.Bp2BuildDefaultTrueRecursively,
}
+
+ buildDir string
)
type nestedProps struct {
@@ -39,6 +43,17 @@
props customProps
}
+func errored(t *testing.T, desc string, errs []error) bool {
+ t.Helper()
+ if len(errs) > 0 {
+ for _, err := range errs {
+ t.Errorf("%s: %s", desc, err)
+ }
+ return true
+ }
+ return false
+}
+
// OutputFiles is needed because some instances of this module use dist with a
// tag property which requires the module implements OutputFileProducer.
func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
@@ -142,9 +157,11 @@
paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.props.Arch_paths))
- for arch, props := range m.GetArchProperties(ctx, &customProps{}) {
- if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
- paths.SetValueForArch(arch.Name, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths))
+ for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
+ for config, props := range configToProps {
+ if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
+ paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths))
+ }
}
}
@@ -196,6 +213,6 @@
// Helper method for tests to easily access the targets in a dir.
func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) BazelTargets {
// TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
- buildFileToTargets, _ := GenerateBazelTargets(codegenCtx, false)
+ buildFileToTargets, _, _ := GenerateBazelTargets(codegenCtx, false)
return buildFileToTargets[dir]
}
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index fae6101..a608630 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -130,7 +130,15 @@
},
{
Name: "removePdkProperty",
- Fix: runPatchListMod(removePdkProperty),
+ Fix: runPatchListMod(removeObsoleteProperty("product_variables.pdk")),
+ },
+ {
+ Name: "removeScudoProperty",
+ Fix: runPatchListMod(removeObsoleteProperty("sanitize.scudo")),
+ },
+ {
+ Name: "formatFlagProperties",
+ Fix: runPatchListMod(formatFlagProperties),
},
}
@@ -319,7 +327,7 @@
var defStr string
switch mod.Type {
case "cts_support_package":
- mod.Type = "android_test"
+ mod.Type = "android_test_helper_app"
defStr = "cts_support_defaults"
case "cts_package":
mod.Type = "android_test"
@@ -392,7 +400,7 @@
continue
}
- if !strings.HasPrefix(mod.Type, "java_") && !strings.HasPrefix(mod.Type, "android_") {
+ if !strings.HasPrefix(mod.Type, "java_") && !strings.HasPrefix(mod.Type, "android_") && mod.Type != "cc_binary" {
continue
}
@@ -420,6 +428,14 @@
mod.Type = "java_test_host"
}
}
+
+ // when a cc_binary module has a nonempty test_suites field, modify the type to cc_test
+ if mod.Type == "cc_binary" {
+ hasTestSuites := hasNonEmptyLiteralListProperty(mod, "test_suites")
+ if hasTestSuites {
+ mod.Type = "cc_test"
+ }
+ }
}
return nil
@@ -622,12 +638,20 @@
func rewriteAndroidTest(f *Fixer) error {
for _, def := range f.tree.Defs {
mod, ok := def.(*parser.Module)
- if !(ok && mod.Type == "android_test") {
+ if !ok {
+ // The definition is not a module.
+ continue
+ }
+ if mod.Type != "android_test" && mod.Type != "android_test_helper_app" {
+ // The module is not an android_test or android_test_helper_app.
continue
}
// The rewriter converts LOCAL_MODULE_PATH attribute into a struct attribute
// 'local_module_path'. For the android_test module, it should be $(TARGET_OUT_DATA_APPS),
// that is, `local_module_path: { var: "TARGET_OUT_DATA_APPS"}`
+ // 1. if the `key: val` pair matches, (key is `local_module_path`,
+ // and val is `{ var: "TARGET_OUT_DATA_APPS"}`), this property is removed;
+ // 2. o/w, an error msg is thrown.
const local_module_path = "local_module_path"
if prop_local_module_path, ok := mod.GetProperty(local_module_path); ok {
removeProperty(mod, local_module_path)
@@ -637,7 +661,7 @@
continue
}
return indicateAttributeError(mod, "filename",
- "Only LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) is allowed for the android_test")
+ "Only LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) is allowed for the %s", mod.Type)
}
}
return nil
@@ -847,7 +871,9 @@
}
}
-func runPatchListMod(modFunc func(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error) func(*Fixer) error {
+type patchListModFunction func(*parser.Module, []byte, *parser.PatchList) error
+
+func runPatchListMod(modFunc patchListModFunction) func(*Fixer) error {
return func(f *Fixer) error {
// Make sure all the offsets are accurate
buf, err := f.reparse()
@@ -1017,23 +1043,63 @@
return patchlist.Add(prop.Pos().Offset, prop.End().Offset+2, replaceStr)
}
-func removePdkProperty(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error {
- prop, ok := mod.GetProperty("product_variables")
- if !ok {
- return nil
+type propertyProvider interface {
+ GetProperty(string) (*parser.Property, bool)
+ RemoveProperty(string) bool
+}
+
+func removeNestedProperty(mod *parser.Module, patchList *parser.PatchList, propName string) error {
+ propNames := strings.Split(propName, ".")
+
+ var propProvider, toRemoveFrom propertyProvider
+ propProvider = mod
+
+ var propToRemove *parser.Property
+ for i, name := range propNames {
+ p, ok := propProvider.GetProperty(name)
+ if !ok {
+ return nil
+ }
+ // if this is the inner most element, it's time to delete
+ if i == len(propNames)-1 {
+ if propToRemove == nil {
+ // if we cannot remove the properties that the current property is nested in,
+ // remove only the current property
+ propToRemove = p
+ toRemoveFrom = propProvider
+ }
+
+ // remove the property from the list, in case we remove other properties in this list
+ toRemoveFrom.RemoveProperty(propToRemove.Name)
+ // only removing the property would leave blank line(s), remove with a patch
+ if err := patchList.Add(propToRemove.Pos().Offset, propToRemove.End().Offset+2, ""); err != nil {
+ return err
+ }
+ } else {
+ propMap, ok := p.Value.(*parser.Map)
+ if !ok {
+ return nil
+ }
+ if len(propMap.Properties) > 1 {
+ // if there are other properties in this struct, we need to keep this struct
+ toRemoveFrom = nil
+ propToRemove = nil
+ } else if propToRemove == nil {
+ // otherwise, we can remove the empty struct entirely
+ toRemoveFrom = propProvider
+ propToRemove = p
+ }
+ propProvider = propMap
+ }
}
- propMap, ok := prop.Value.(*parser.Map)
- if !ok {
- return nil
+
+ return nil
+}
+
+func removeObsoleteProperty(propName string) patchListModFunction {
+ return func(mod *parser.Module, buf []byte, patchList *parser.PatchList) error {
+ return removeNestedProperty(mod, patchList, propName)
}
- pdkProp, ok := propMap.GetProperty("pdk")
- if !ok {
- return nil
- }
- if len(propMap.Properties) > 1 {
- return patchlist.Add(pdkProp.Pos().Offset, pdkProp.End().Offset+2, "")
- }
- return patchlist.Add(prop.Pos().Offset, prop.End().Offset+2, "")
}
func mergeMatchingModuleProperties(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error {
@@ -1281,3 +1347,69 @@
}
return false
}
+
+func formatFlagProperty(mod *parser.Module, field string, buf []byte, patchlist *parser.PatchList) error {
+ // the comment or empty lines in the value of the field are skipped
+ listValue, ok := getLiteralListProperty(mod, field)
+ if !ok {
+ // if do not find
+ return nil
+ }
+ for i := 0; i < len(listValue.Values); i++ {
+ curValue, ok := listValue.Values[i].(*parser.String)
+ if !ok {
+ return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field)
+ }
+ if !strings.HasPrefix(curValue.Value, "-") {
+ return fmt.Errorf("Expecting the string `%s` starting with '-'", curValue.Value)
+ }
+ if i+1 < len(listValue.Values) {
+ nextValue, ok := listValue.Values[i+1].(*parser.String)
+ if !ok {
+ return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field)
+ }
+ if !strings.HasPrefix(nextValue.Value, "-") {
+ // delete the line
+ err := patchlist.Add(curValue.Pos().Offset, curValue.End().Offset+2, "")
+ if err != nil {
+ return err
+ }
+ // replace the line
+ value := "\"" + curValue.Value + " " + nextValue.Value + "\","
+ err = patchlist.Add(nextValue.Pos().Offset, nextValue.End().Offset+1, value)
+ if err != nil {
+ return err
+ }
+ // combined two lines to one
+ i++
+ }
+ }
+ }
+ return nil
+}
+
+func formatFlagProperties(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error {
+ relevantFields := []string{
+ // cc flags
+ "asflags",
+ "cflags",
+ "clang_asflags",
+ "clang_cflags",
+ "conlyflags",
+ "cppflags",
+ "ldflags",
+ "tidy_flags",
+ // java flags
+ "aaptflags",
+ "dxflags",
+ "javacflags",
+ "kotlincflags",
+ }
+ for _, field := range relevantFields {
+ err := formatFlagProperty(mod, field, buf, patchlist)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 61dfe1a..d8772c1 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -636,7 +636,7 @@
}
`,
out: `
- android_test {
+ android_test_helper_app {
name: "foo",
defaults: ["cts_support_defaults"],
}
@@ -999,7 +999,171 @@
}
}
-func TestRemovePdkProperty(t *testing.T) {
+func TestRemoveNestedProperty(t *testing.T) {
+ tests := []struct {
+ name string
+ in string
+ out string
+ propertyName string
+ }{
+ {
+ name: "remove no nesting",
+ in: `
+cc_library {
+ name: "foo",
+ foo: true,
+}`,
+ out: `
+cc_library {
+ name: "foo",
+}
+`,
+ propertyName: "foo",
+ },
+ {
+ name: "remove one nest",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: true,
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+}
+`,
+ propertyName: "foo.bar",
+ },
+ {
+ name: "remove one nest, multiple props",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: true,
+ baz: false,
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+ foo: {
+ baz: false,
+ },
+}
+`,
+ propertyName: "foo.bar",
+ },
+ {
+ name: "remove multiple nest",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ a: true,
+ }
+ },
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+}
+`,
+ propertyName: "foo.bar.baz.a",
+ },
+ {
+ name: "remove multiple nest, outer non-empty",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ a: true,
+ }
+ },
+ other: true,
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+ foo: {
+ other: true,
+ },
+}
+`,
+ propertyName: "foo.bar.baz.a",
+ },
+ {
+ name: "remove multiple nest, inner non-empty",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ a: true,
+ },
+ other: true,
+ },
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ other: true,
+ },
+ },
+}
+`,
+ propertyName: "foo.bar.baz.a",
+ },
+ {
+ name: "remove multiple nest, inner-most non-empty",
+ in: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ a: true,
+ other: true,
+ },
+ },
+ },
+}`,
+ out: `
+cc_library {
+ name: "foo",
+ foo: {
+ bar: {
+ baz: {
+ other: true,
+ },
+ },
+ },
+}
+`,
+ propertyName: "foo.bar.baz.a",
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ runPass(t, test.in, test.out, runPatchListMod(removeObsoleteProperty(test.propertyName)))
+ })
+ }
+}
+
+func TestRemoveObsoleteProperties(t *testing.T) {
tests := []struct {
name string
in string
@@ -1052,7 +1216,7 @@
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- runPass(t, test.in, test.out, runPatchListMod(removePdkProperty))
+ runPass(t, test.in, test.out, runPatchListMod(removeObsoleteProperty("product_variables.pdk")))
})
}
}
@@ -1124,3 +1288,323 @@
})
}
}
+
+func TestRewriteTestModuleTypes(t *testing.T) {
+ tests := []struct {
+ name string
+ in string
+ out string
+ }{
+ {
+ name: "cc_binary with test_suites",
+ in: `
+ cc_binary {
+ name: "foo",
+ srcs: ["srcs"],
+ test_suites: ["test_suite1"],
+ }
+ `,
+ out: `
+ cc_test {
+ name: "foo",
+ srcs: ["srcs"],
+ test_suites: ["test_suite1"],
+ }
+ `,
+ },
+ {
+ name: "cc_binary without test_suites",
+ in: `
+ cc_binary {
+ name: "foo",
+ srcs: ["srcs"],
+ }
+ `,
+ out: `
+ cc_binary {
+ name: "foo",
+ srcs: ["srcs"],
+ }
+ `,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ runPass(t, test.in, test.out, func(fixer *Fixer) error {
+ return rewriteTestModuleTypes(fixer)
+ })
+ })
+ }
+}
+
+func TestFormatFlagProperty(t *testing.T) {
+ tests := []struct {
+ name string
+ in string
+ out string
+ }{
+ {
+ name: "group options and values for apptflags, dxflags, javacflags, and kotlincflags",
+ in: `
+ android_test {
+ name: "foo",
+ aaptflags: [
+ // comment1_1
+ "--flag1",
+ // comment1_2
+ "1",
+ // comment2_1
+ // comment2_2
+ "--flag2",
+ // comment3_1
+ // comment3_2
+ // comment3_3
+ "--flag3",
+ // comment3_4
+ // comment3_5
+ // comment3_6
+ "3",
+ // other comment1_1
+ // other comment1_2
+ ],
+ dxflags: [
+ "--flag1",
+ // comment1_1
+ "1",
+ // comment2_1
+ "--flag2",
+ // comment3_1
+ "--flag3",
+ // comment3_2
+ "3",
+ ],
+ javacflags: [
+ "--flag1",
+
+ "1",
+ "--flag2",
+ "--flag3",
+ "3",
+ ],
+ kotlincflags: [
+
+ "--flag1",
+ "1",
+
+ "--flag2",
+ "--flag3",
+ "3",
+
+ ],
+ }
+ `,
+ out: `
+ android_test {
+ name: "foo",
+ aaptflags: [
+ // comment1_1
+ // comment1_2
+ "--flag1 1",
+ // comment2_1
+ // comment2_2
+ "--flag2",
+ // comment3_1
+ // comment3_2
+ // comment3_3
+ // comment3_4
+ // comment3_5
+ // comment3_6
+ "--flag3 3",
+ // other comment1_1
+ // other comment1_2
+ ],
+ dxflags: [
+ // comment1_1
+ "--flag1 1",
+ // comment2_1
+ "--flag2",
+ // comment3_1
+ // comment3_2
+ "--flag3 3",
+ ],
+ javacflags: [
+
+ "--flag1 1",
+ "--flag2",
+ "--flag3 3",
+ ],
+ kotlincflags: [
+
+ "--flag1 1",
+
+ "--flag2",
+ "--flag3 3",
+
+ ],
+ }
+ `,
+ },
+ {
+ name: "group options and values for asflags, cflags, clang_asflags, clang_cflags, conlyflags, cppflags, ldflags, and tidy_flags",
+ in: `
+ cc_test {
+ name: "foo",
+ asflags: [
+ // comment1_1
+ "--flag1",
+ "1",
+ // comment2_1
+ // comment2_2
+ "--flag2",
+ // comment2_3
+ "2",
+ // comment3_1
+ // comment3_2
+ "--flag3",
+ // comment3_3
+ // comment3_4
+ // comment3_4
+ "3",
+ // comment4_1
+ // comment4_2
+ // comment4_3
+ "--flag4",
+ ],
+ cflags: [
+ "--flag1",
+ "1",
+ "--flag2",
+ "2",
+ "--flag3",
+ "3",
+ "--flag4",
+ ],
+ clang_asflags: [
+ "--flag1",
+ "1",
+ "--flag2",
+ "2",
+ "--flag3",
+ "3",
+ "--flag4",
+ ],
+ clang_cflags: [
+ "--flag1",
+ "1",
+ "--flag2",
+ "2",
+ "--flag3",
+ "3",
+ "--flag4",
+ ],
+ conlyflags: [
+ "--flag1",
+ "1",
+ "--flag2",
+ "2",
+ "--flag3",
+ "3",
+ "--flag4",
+ ],
+ cppflags: [
+ "--flag1",
+ "1",
+ "--flag2",
+ "2",
+ "--flag3",
+ "3",
+ "--flag4",
+ ],
+ ldflags: [
+ "--flag1",
+ "1",
+ "--flag2",
+ "2",
+ "--flag3",
+ "3",
+ "--flag4",
+ ],
+ tidy_flags: [
+ "--flag1",
+ "1",
+ "--flag2",
+ "2",
+ "--flag3",
+ "3",
+ "--flag4",
+ ],
+ }
+ `,
+ out: `
+ cc_test {
+ name: "foo",
+ asflags: [
+ // comment1_1
+ "--flag1 1",
+ // comment2_1
+ // comment2_2
+ // comment2_3
+ "--flag2 2",
+ // comment3_1
+ // comment3_2
+ // comment3_3
+ // comment3_4
+ // comment3_4
+ "--flag3 3",
+ // comment4_1
+ // comment4_2
+ // comment4_3
+ "--flag4",
+ ],
+ cflags: [
+ "--flag1 1",
+ "--flag2 2",
+ "--flag3 3",
+ "--flag4",
+ ],
+ clang_asflags: [
+ "--flag1 1",
+ "--flag2 2",
+ "--flag3 3",
+ "--flag4",
+ ],
+ clang_cflags: [
+ "--flag1 1",
+ "--flag2 2",
+ "--flag3 3",
+ "--flag4",
+ ],
+ conlyflags: [
+ "--flag1 1",
+ "--flag2 2",
+ "--flag3 3",
+ "--flag4",
+ ],
+ cppflags: [
+ "--flag1 1",
+ "--flag2 2",
+ "--flag3 3",
+ "--flag4",
+ ],
+ ldflags: [
+ "--flag1 1",
+ "--flag2 2",
+ "--flag3 3",
+ "--flag4",
+ ],
+ tidy_flags: [
+ "--flag1 1",
+ "--flag2 2",
+ "--flag3 3",
+ "--flag4",
+ ],
+ }
+ `,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ runPass(t, test.in, test.out, runPatchListMod(formatFlagProperties))
+ })
+ }
+}
diff --git a/build_kzip.bash b/build_kzip.bash
index a09335e..5655067 100755
--- a/build_kzip.bash
+++ b/build_kzip.bash
@@ -6,6 +6,8 @@
# The following environment variables affect the result:
# BUILD_NUMBER build number, used to generate unique ID (will use UUID if not set)
# SUPERPROJECT_SHA superproject sha, used to generate unique id (will use BUILD_NUMBER if not set)
+# SUPERPROJECT_REVISION superproject revision, used for unique id if defined as a sha
+# KZIP_NAME name of the output file (will use SUPERPROJECT_REVISION|SUPERPROJECT_SHA|BUILD_NUMBER|UUID if not set)
# DIST_DIR where the resulting all.kzip will be placed
# KYTHE_KZIP_ENCODING proto or json (proto is default)
# KYTHE_JAVA_SOURCE_BATCH_SIZE maximum number of the Java source files in a compilation unit
@@ -14,8 +16,16 @@
# TARGET_PRODUCT target device name, e.g., 'aosp_blueline'
# XREF_CORPUS source code repository URI, e.g., 'android.googlesource.com/platform/superproject'
-: ${BUILD_NUMBER:=$(uuidgen)}
-: ${SUPERPROJECT_SHA:=$BUILD_NUMBER}
+# If the SUPERPROJECT_REVISION is defined as a sha, use this as the default value if no
+# SUPERPROJECT_SHA is specified.
+if [[ ${SUPERPROJECT_REVISION:-} =~ [0-9a-f]{40} ]]; then
+ : ${KZIP_NAME:=${SUPERPROJECT_REVISION:-}}
+fi
+
+: ${KZIP_NAME:=${SUPERPROJECT_SHA:-}}
+: ${KZIP_NAME:=${BUILD_NUMBER:-}}
+: ${KZIP_NAME:=$(uuidgen)}
+
: ${KYTHE_JAVA_SOURCE_BATCH_SIZE:=500}
: ${KYTHE_KZIP_ENCODING:=proto}
: ${XREF_CORPUS:?should be set}
@@ -50,6 +60,6 @@
# Pack
# TODO(asmundak): this should be done by soong.
-declare -r allkzip="$SUPERPROJECT_SHA.kzip"
+declare -r allkzip="$KZIP_NAME.kzip"
"$out/soong/host/linux-x86/bin/merge_zips" "$DIST_DIR/$allkzip" @<(find "$out" -name '*.kzip')
diff --git a/build_test.bash b/build_test.bash
index 3230f2d..b039285 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -49,8 +49,12 @@
esac
echo
+echo "Free disk space:"
+df -h
+
+echo
echo "Running Bazel smoke test..."
-"${TOP}/tools/bazel" --batch --max_idle_secs=1 info
+STANDALONE_BAZEL=true "${TOP}/tools/bazel" --batch --max_idle_secs=1 info
echo
echo "Running Soong test..."
diff --git a/cc/Android.bp b/cc/Android.bp
index 1fc8d9f..164d32b 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -14,6 +14,7 @@
"soong-cc-config",
"soong-etc",
"soong-genrule",
+ "soong-snapshot",
"soong-tradefed",
],
srcs: [
@@ -58,6 +59,7 @@
"binary.go",
"binary_sdk_member.go",
"fuzz.go",
+ "fuzz_common.go",
"library.go",
"library_headers.go",
"library_sdk_member.go",
@@ -65,9 +67,10 @@
"test.go",
"toolchain_library.go",
- "ndk_prebuilt.go",
+ "ndk_abi.go",
"ndk_headers.go",
"ndk_library.go",
+ "ndk_prebuilt.go",
"ndk_sysroot.go",
"llndk_library.go",
diff --git a/cc/androidmk.go b/cc/androidmk.go
index e58d166..bda1006 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -401,24 +401,24 @@
ctx.subAndroidMk(entries, fuzz.binaryDecorator)
var fuzzFiles []string
- for _, d := range fuzz.corpus {
+ for _, d := range fuzz.fuzzPackagedModule.Corpus {
fuzzFiles = append(fuzzFiles,
- filepath.Dir(fuzz.corpusIntermediateDir.String())+":corpus/"+d.Base())
+ filepath.Dir(fuzz.fuzzPackagedModule.CorpusIntermediateDir.String())+":corpus/"+d.Base())
}
- for _, d := range fuzz.data {
+ for _, d := range fuzz.fuzzPackagedModule.Data {
fuzzFiles = append(fuzzFiles,
- filepath.Dir(fuzz.dataIntermediateDir.String())+":data/"+d.Rel())
+ filepath.Dir(fuzz.fuzzPackagedModule.DataIntermediateDir.String())+":data/"+d.Rel())
}
- if fuzz.dictionary != nil {
+ if fuzz.fuzzPackagedModule.Dictionary != nil {
fuzzFiles = append(fuzzFiles,
- filepath.Dir(fuzz.dictionary.String())+":"+fuzz.dictionary.Base())
+ filepath.Dir(fuzz.fuzzPackagedModule.Dictionary.String())+":"+fuzz.fuzzPackagedModule.Dictionary.Base())
}
- if fuzz.config != nil {
+ if fuzz.fuzzPackagedModule.Config != nil {
fuzzFiles = append(fuzzFiles,
- filepath.Dir(fuzz.config.String())+":config.json")
+ filepath.Dir(fuzz.fuzzPackagedModule.Config.String())+":config.json")
}
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
diff --git a/cc/binary.go b/cc/binary.go
index 999b82c..763d2b9 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -146,16 +146,17 @@
// modules common to most binaries, such as bionic libraries.
func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
deps = binary.baseLinker.linkerDeps(ctx, deps)
- if ctx.toolchain().Bionic() {
- if !Bool(binary.baseLinker.Properties.Nocrt) {
- if binary.static() {
- deps.CrtBegin = "crtbegin_static"
- } else {
- deps.CrtBegin = "crtbegin_dynamic"
- }
- deps.CrtEnd = "crtend_android"
+ if !Bool(binary.baseLinker.Properties.Nocrt) {
+ if binary.static() {
+ deps.CrtBegin = ctx.toolchain().CrtBeginStaticBinary()
+ deps.CrtEnd = ctx.toolchain().CrtEndStaticBinary()
+ } else {
+ deps.CrtBegin = ctx.toolchain().CrtBeginSharedBinary()
+ deps.CrtEnd = ctx.toolchain().CrtEndSharedBinary()
}
+ }
+ if ctx.toolchain().Bionic() {
if binary.static() {
if ctx.selectedStl() == "libc++_static" {
deps.StaticLibs = append(deps.StaticLibs, "libm", "libc")
@@ -169,16 +170,8 @@
deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
}
- // Embed the linker into host bionic binaries. This is needed to support host bionic,
- // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be
- // either an absolute path, or relative from CWD. To work around this, we extract
- // the load sections from the runtime linker ELF binary and embed them into each host
- // bionic binary, omitting the PT_INTERP declaration. The kernel will treat it as a static
- // binary, and then we use a special entry point to fix up the arguments passed by
- // the kernel before jumping to the embedded linker.
if ctx.Os() == android.LinuxBionic && !binary.static() {
deps.DynamicLinker = "linker"
- deps.LinkerFlagsFile = "host_bionic_linker_flags"
}
}
@@ -190,11 +183,6 @@
return deps
}
-func (binary *binaryDecorator) isDependencyRoot() bool {
- // Binaries are always the dependency root.
- return true
-}
-
// NewBinary builds and returns a new Module corresponding to a C++ binary.
// Individual module implementations which comprise a C++ binary should call this function,
// set some fields on the result, and then call the Init function.
@@ -227,7 +215,7 @@
if binary.Properties.Static_executable == nil && ctx.Config().HostStaticBinaries() {
binary.Properties.Static_executable = BoolPtr(true)
}
- } else if !ctx.Fuchsia() {
+ } else {
// Static executables are not supported on Darwin or Windows
binary.Properties.Static_executable = nil
}
@@ -345,15 +333,9 @@
var linkerDeps android.Paths
- // Add flags from linker flags file.
- if deps.LinkerFlagsFile.Valid() {
- flags.Local.LdFlags = append(flags.Local.LdFlags, "$$(cat "+deps.LinkerFlagsFile.String()+")")
- linkerDeps = append(linkerDeps, deps.LinkerFlagsFile.Path())
- }
-
if flags.DynamicLinker != "" {
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker)
- } else if ctx.toolchain().Bionic() && !binary.static() {
+ } else if (ctx.toolchain().Bionic() || ctx.toolchain().Musl()) && !binary.static() {
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-dynamic-linker")
}
@@ -401,16 +383,18 @@
}
}
+ var validations android.WritablePaths
+
// Handle host bionic linker symbols.
if ctx.Os() == android.LinuxBionic && !binary.static() {
- injectedOutputFile := outputFile
- outputFile = android.PathForModuleOut(ctx, "prelinker", fileName)
+ verifyFile := android.PathForModuleOut(ctx, "host_bionic_verify.stamp")
if !deps.DynamicLinker.Valid() {
panic("Non-static host bionic modules must have a dynamic linker")
}
- binary.injectHostBionicLinkerSymbols(ctx, outputFile, deps.DynamicLinker.Path(), injectedOutputFile)
+ binary.verifyHostBionicLinker(ctx, outputFile, deps.DynamicLinker.Path(), verifyFile)
+ validations = append(validations, verifyFile)
}
var sharedLibs android.Paths
@@ -430,7 +414,7 @@
// Register link action.
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
- builderFlags, outputFile, nil)
+ builderFlags, outputFile, nil, validations)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
@@ -532,19 +516,19 @@
}
func init() {
- pctx.HostBinToolVariable("hostBionicSymbolsInjectCmd", "host_bionic_inject")
+ pctx.HostBinToolVariable("verifyHostBionicCmd", "host_bionic_verify")
}
-var injectHostBionicSymbols = pctx.AndroidStaticRule("injectHostBionicSymbols",
+var verifyHostBionic = pctx.AndroidStaticRule("verifyHostBionic",
blueprint.RuleParams{
- Command: "$hostBionicSymbolsInjectCmd -i $in -l $linker -o $out",
- CommandDeps: []string{"$hostBionicSymbolsInjectCmd"},
+ Command: "$verifyHostBionicCmd -i $in -l $linker && touch $out",
+ CommandDeps: []string{"$verifyHostBionicCmd"},
}, "linker")
-func (binary *binaryDecorator) injectHostBionicLinkerSymbols(ctx ModuleContext, in, linker android.Path, out android.WritablePath) {
+func (binary *binaryDecorator) verifyHostBionicLinker(ctx ModuleContext, in, linker android.Path, out android.WritablePath) {
ctx.Build(pctx, android.BuildParams{
- Rule: injectHostBionicSymbols,
- Description: "inject host bionic symbols",
+ Rule: verifyHostBionic,
+ Description: "verify host bionic",
Input: in,
Implicit: linker,
Output: out,
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 9f9143b..68afd0d 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -14,170 +14,245 @@
package cc
import (
- "android/soong/android"
- "android/soong/bazel"
+ "fmt"
"path/filepath"
"strings"
+
+ "android/soong/android"
+ "android/soong/bazel"
+
+ "github.com/google/blueprint/proptools"
)
-// bp2build functions and helpers for converting cc_* modules to Bazel.
+// 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
+ Copts bazel.StringListAttribute
-func init() {
- android.DepsBp2BuildMutators(RegisterDepsBp2Build)
+ Static_deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
}
-func RegisterDepsBp2Build(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("cc_bp2build_deps", depsBp2BuildMutator)
-}
-
-// A naive deps mutator to add deps on all modules across all combinations of
-// target props for cc modules. This is needed to make module -> bazel label
-// resolution work in the bp2build mutator later. This is probably
-// the wrong way to do it, but it works.
-//
-// TODO(jingwen): can we create a custom os mutator in depsBp2BuildMutator to do this?
-func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) {
- module, ok := ctx.Module().(*Module)
- if !ok {
- // Not a cc module
- return
+func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) {
+ // Branch srcs into three language-specific groups.
+ // 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.
+ // TODO(b/190006308): Handle language detection of sources in a Bazel rule.
+ isCSrcOrFilegroup := func(s string) bool {
+ return strings.HasSuffix(s, ".c") || strings.HasSuffix(s, "_c_srcs")
}
- if !module.ConvertWithBp2build(ctx) {
- return
+ isAsmSrcOrFilegroup := func(s string) bool {
+ return strings.HasSuffix(s, ".S") || strings.HasSuffix(s, ".s") || strings.HasSuffix(s, "_as_srcs")
}
- var allDeps []string
-
- for _, p := range module.GetTargetProperties(&BaseLinkerProperties{}) {
- // arch specific linker props
- if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
- allDeps = append(allDeps, baseLinkerProps.Header_libs...)
- allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...)
- allDeps = append(allDeps, baseLinkerProps.Static_libs...)
- allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...)
+ // Check that a module is a filegroup type named <label>.
+ isFilegroupNamed := func(m android.Module, fullLabel string) bool {
+ if ctx.OtherModuleType(m) != "filegroup" {
+ return false
+ }
+ labelParts := strings.Split(fullLabel, ":")
+ if len(labelParts) > 2 {
+ // There should not be more than one colon in a label.
+ panic(fmt.Errorf("%s is not a valid Bazel label for a filegroup", fullLabel))
+ } else {
+ return m.Name() == labelParts[len(labelParts)-1]
}
}
- for _, p := range module.GetArchProperties(ctx, &BaseLinkerProperties{}) {
- // arch specific linker props
- if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
- allDeps = append(allDeps, baseLinkerProps.Header_libs...)
- allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...)
- allDeps = append(allDeps, baseLinkerProps.Static_libs...)
- allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...)
+ // Convert the filegroup dependencies into the extension-specific filegroups
+ // filtered in the filegroup.bzl macro.
+ cppFilegroup := func(label string) string {
+ m, exists := ctx.ModuleFromName(label)
+ if exists {
+ aModule, _ := m.(android.Module)
+ if isFilegroupNamed(aModule, label) {
+ label = label + "_cpp_srcs"
+ }
}
+ return label
+ }
+ cFilegroup := func(label string) string {
+ m, exists := ctx.ModuleFromName(label)
+ if exists {
+ aModule, _ := m.(android.Module)
+ if isFilegroupNamed(aModule, label) {
+ label = label + "_c_srcs"
+ }
+ }
+ return label
+ }
+ asFilegroup := func(label string) string {
+ m, exists := ctx.ModuleFromName(label)
+ if exists {
+ aModule, _ := m.(android.Module)
+ if isFilegroupNamed(aModule, label) {
+ label = label + "_as_srcs"
+ }
+ }
+ return label
}
- // Deps in the static: { .. } and shared: { .. } props of a cc_library.
- if lib, ok := module.compiler.(*libraryDecorator); ok {
- allDeps = append(allDeps, lib.SharedProperties.Shared.Static_libs...)
- allDeps = append(allDeps, lib.SharedProperties.Shared.Whole_static_libs...)
- allDeps = append(allDeps, lib.SharedProperties.Shared.Shared_libs...)
- allDeps = append(allDeps, lib.SharedProperties.Shared.System_shared_libs...)
+ cSrcs = bazel.MapLabelListAttribute(srcs, cFilegroup)
+ cSrcs = bazel.FilterLabelListAttribute(cSrcs, isCSrcOrFilegroup)
- allDeps = append(allDeps, lib.StaticProperties.Static.Static_libs...)
- allDeps = append(allDeps, lib.StaticProperties.Static.Whole_static_libs...)
- allDeps = append(allDeps, lib.StaticProperties.Static.Shared_libs...)
- allDeps = append(allDeps, lib.StaticProperties.Static.System_shared_libs...)
- }
+ asSrcs = bazel.MapLabelListAttribute(srcs, asFilegroup)
+ asSrcs = bazel.FilterLabelListAttribute(asSrcs, isAsmSrcOrFilegroup)
- ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
-}
-
-type sharedAttributes struct {
- copts bazel.StringListAttribute
- srcs bazel.LabelListAttribute
- staticDeps bazel.LabelListAttribute
- dynamicDeps bazel.LabelListAttribute
- wholeArchiveDeps bazel.LabelListAttribute
+ cppSrcs = bazel.MapLabelListAttribute(srcs, cppFilegroup)
+ cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, cSrcs)
+ cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, asSrcs)
+ return
}
// bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
-func bp2BuildParseSharedProps(ctx android.TopDownMutatorContext, module *Module) sharedAttributes {
+func bp2BuildParseSharedProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
lib, ok := module.compiler.(*libraryDecorator)
if !ok {
- return sharedAttributes{}
+ return staticOrSharedAttributes{}
}
- copts := bazel.StringListAttribute{Value: lib.SharedProperties.Shared.Cflags}
-
- srcs := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleSrc(ctx, lib.SharedProperties.Shared.Srcs)}
-
- staticDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, lib.SharedProperties.Shared.Static_libs)}
-
- dynamicDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, lib.SharedProperties.Shared.Shared_libs)}
-
- wholeArchiveDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, lib.SharedProperties.Shared.Whole_static_libs)}
-
- return sharedAttributes{
- copts: copts,
- srcs: srcs,
- staticDeps: staticDeps,
- dynamicDeps: dynamicDeps,
- wholeArchiveDeps: wholeArchiveDeps,
- }
-}
-
-type staticAttributes struct {
- copts bazel.StringListAttribute
- srcs bazel.LabelListAttribute
- staticDeps bazel.LabelListAttribute
- dynamicDeps bazel.LabelListAttribute
- wholeArchiveDeps bazel.LabelListAttribute
+ return bp2buildParseStaticOrSharedProps(ctx, module, lib, false)
}
// bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
-func bp2BuildParseStaticProps(ctx android.TopDownMutatorContext, module *Module) staticAttributes {
+func bp2BuildParseStaticProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
lib, ok := module.compiler.(*libraryDecorator)
if !ok {
- return staticAttributes{}
+ return staticOrSharedAttributes{}
}
- copts := bazel.StringListAttribute{Value: lib.StaticProperties.Static.Cflags}
+ return bp2buildParseStaticOrSharedProps(ctx, module, lib, true)
+}
- srcs := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleSrc(ctx, lib.StaticProperties.Static.Srcs)}
+func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
+ var props StaticOrSharedProperties
+ if isStatic {
+ props = lib.StaticProperties.Static
+ } else {
+ props = lib.SharedProperties.Shared
+ }
- staticDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, lib.StaticProperties.Static.Static_libs)}
+ attrs := staticOrSharedAttributes{
+ Copts: bazel.StringListAttribute{Value: props.Cflags},
+ Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)),
+ Static_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)),
+ Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, append(props.Shared_libs, props.System_shared_libs...))),
+ Whole_archive_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)),
+ }
- dynamicDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, lib.StaticProperties.Static.Shared_libs)}
+ setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
+ attrs.Copts.SetSelectValue(axis, config, props.Cflags)
+ attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
+ attrs.Static_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
+ attrs.Dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
+ attrs.Whole_archive_deps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs))
+ }
- wholeArchiveDeps := bazel.LabelListAttribute{
- Value: android.BazelLabelForModuleDeps(ctx, lib.StaticProperties.Static.Whole_static_libs)}
+ if isStatic {
+ for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
+ for config, props := range configToProps {
+ if staticOrSharedProps, ok := props.(*StaticProperties); ok {
+ setAttrs(axis, config, staticOrSharedProps.Static)
+ }
+ }
+ }
+ } else {
+ for axis, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
+ for config, props := range configToProps {
+ if staticOrSharedProps, ok := props.(*SharedProperties); ok {
+ setAttrs(axis, config, staticOrSharedProps.Shared)
+ }
+ }
+ }
+ }
- return staticAttributes{
- copts: copts,
- srcs: srcs,
- staticDeps: staticDeps,
- dynamicDeps: dynamicDeps,
- wholeArchiveDeps: wholeArchiveDeps,
+ cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
+ attrs.Srcs = cppSrcs
+ attrs.Srcs_c = cSrcs
+ attrs.Srcs_as = asSrcs
+
+ return attrs
+}
+
+// Convenience struct to hold all attributes parsed from prebuilt properties.
+type prebuiltAttributes struct {
+ Src bazel.LabelAttribute
+}
+
+func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
+ prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
+ prebuiltLinker := prebuiltLibraryLinker.prebuiltLinker
+
+ var srcLabelAttribute bazel.LabelAttribute
+
+ if len(prebuiltLinker.properties.Srcs) > 1 {
+ ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file\n")
+ }
+
+ if len(prebuiltLinker.properties.Srcs) == 1 {
+ srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]))
+ }
+ for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
+ for config, props := range configToProps {
+ if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
+ if len(prebuiltLinkerProperties.Srcs) > 1 {
+ ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
+ continue
+ } else if len(prebuiltLinkerProperties.Srcs) == 0 {
+ continue
+ }
+ src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])
+ srcLabelAttribute.SetSelectValue(axis, config, src)
+ }
+ }
+ }
+
+ return prebuiltAttributes{
+ Src: srcLabelAttribute,
}
}
// Convenience struct to hold all attributes parsed from compiler properties.
type compilerAttributes struct {
- copts bazel.StringListAttribute
+ // Options for all languages
+ copts bazel.StringListAttribute
+ // Assembly options and sources
+ asFlags bazel.StringListAttribute
+ asSrcs bazel.LabelListAttribute
+ // C options and sources
+ conlyFlags bazel.StringListAttribute
+ cSrcs bazel.LabelListAttribute
+ // C++ options and sources
+ cppFlags bazel.StringListAttribute
srcs bazel.LabelListAttribute
- includes 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
- // Creates the -I flag for a directory, while making the directory relative
+ // Creates the -I flags for a directory, while making the directory relative
// to the exec root for Bazel to work.
- includeFlag := func(dir string) string {
+ includeFlags := func(dir string) []string {
// filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
- return "-I" + filepath.Join(ctx.ModuleDir(), dir)
+ moduleDirRootedPath := filepath.Join(ctx.ModuleDir(), dir)
+ return []string{
+ "-I" + moduleDirRootedPath,
+ // Include the bindir-rooted path (using make variable substitution). This most
+ // closely matches Bazel's native include path handling, which allows for dependency
+ // on generated headers in these directories.
+ // TODO(b/188084383): Handle local include directories in Bazel.
+ "-I$(BINDIR)/" + moduleDirRootedPath,
+ }
}
// Parse the list of module-relative include directories (-I).
@@ -187,48 +262,41 @@
return append(includeDirs, baseCompilerProps.Local_include_dirs...)
}
- // Parse the list of copts.
- parseCopts := func(baseCompilerProps *BaseCompilerProperties) []string {
- var copts []string
- for _, flag := range append(baseCompilerProps.Cflags, baseCompilerProps.Cppflags...) {
+ 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.
- copts = append(copts, strings.Split(flag, " ")...)
+ result = append(result, strings.Split(flag, " ")...)
}
- for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
- copts = append(copts, includeFlag(dir))
- }
- return copts
+ return result
}
- // baseSrcs contain the list of src files that are used for every configuration.
- var baseSrcs []string
- // baseExcludeSrcs contain the list of src files that are excluded for every configuration.
- var baseExcludeSrcs []string
- // baseSrcsLabelList is a clone of the base srcs LabelList, used for computing the
- // arch or os specific srcs later.
- var baseSrcsLabelList bazel.LabelList
-
- // Parse srcs from an arch or OS's props value, taking the base srcs and
- // exclude srcs into account.
+ // Parse srcs from an arch or OS's props value.
parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
- // Combine the base srcs and arch-specific srcs
- allSrcs := append(baseSrcs, baseCompilerProps.Srcs...)
- // Combine the base exclude_srcs and configuration-specific exclude_srcs
- allExcludeSrcs := append(baseExcludeSrcs, baseCompilerProps.Exclude_srcs...)
- return android.BazelLabelForModuleSrcExcludes(ctx, allSrcs, allExcludeSrcs)
+ // 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)
+
+ allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
+ return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
}
for _, props := range module.compiler.compilerProps() {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- srcs.Value = parseSrcs(baseCompilerProps)
- copts.Value = parseCopts(baseCompilerProps)
+ srcs.SetValue(parseSrcs(baseCompilerProps))
+ copts.Value = parseCommandLineFlags(baseCompilerProps.Cflags)
+ asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
+ conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
+ cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
- // Used for arch-specific srcs later.
- baseSrcs = baseCompilerProps.Srcs
- baseExcludeSrcs = baseCompilerProps.Exclude_srcs
- baseSrcsLabelList = parseSrcs(baseCompilerProps)
+ for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
+ copts.Value = append(copts.Value, includeFlags(dir)...)
+ asFlags.Value = append(asFlags.Value, includeFlags(dir)...)
+ }
break
}
}
@@ -237,64 +305,88 @@
// target has access to all headers recursively in the package, and has
// "-I<module-dir>" in its copts.
if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
- copts.Value = append(copts.Value, includeFlag("."))
+ copts.Value = append(copts.Value, includeFlags(".")...)
+ asFlags.Value = append(asFlags.Value, includeFlags(".")...)
} else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
- copts.Value = append(copts.Value, includeFlag("."))
+ copts.Value = append(copts.Value, includeFlags(".")...)
+ asFlags.Value = append(asFlags.Value, includeFlags(".")...)
}
- for arch, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) {
- 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.SetValueForArch(arch.Name, srcsList)
- // The base srcs value should not contain any arch-specific excludes.
- srcs.Value = bazel.SubtractBazelLabelList(srcs.Value, bazel.LabelList{Includes: srcsList.Excludes})
+ 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)
+ }
+
+ archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
+ archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
+ for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
+ archVariantCopts = append(archVariantCopts, includeFlags(dir)...)
+ archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
+ }
+
+ copts.SetSelectValue(axis, config, archVariantCopts)
+ asFlags.SetSelectValue(axis, config, archVariantAsflags)
+ conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
+ cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
}
-
- copts.SetValueForArch(arch.Name, parseCopts(baseCompilerProps))
}
}
- // After going through all archs, delete the duplicate files in the arch
- // values that are already in the base srcs.Value.
- for arch, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) {
- if _, ok := props.(*BaseCompilerProperties); ok {
- srcs.SetValueForArch(arch.Name, bazel.SubtractBazelLabelList(srcs.GetValueForArch(arch.Name), srcs.Value))
+ srcs.ResolveExcludes()
+
+ productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
+ "Cflags": &copts,
+ "Asflags": &asFlags,
+ "CppFlags": &cppFlags,
+ }
+ productVariableProps := android.ProductVariableProperties(ctx)
+ for propName, attr := range productVarPropNameToAttribute {
+ if props, exists := productVariableProps[propName]; exists {
+ for _, prop := range props {
+ flags, ok := prop.Property.([]string)
+ if !ok {
+ ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
+ }
+ newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
+ attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
+ }
}
}
- // Now that the srcs.Value list is finalized, compare it with the original
- // list, and put the difference into the default condition for the arch
- // select.
- defaultsSrcs := bazel.SubtractBazelLabelList(baseSrcsLabelList, srcs.Value)
- // TODO(b/186153868): handle the case with multiple variant types, e.g. when arch and os are both used.
- srcs.SetValueForArch(bazel.CONDITIONS_DEFAULT, defaultsSrcs)
-
- // Handle OS specific props.
- for os, props := range module.GetTargetProperties(&BaseCompilerProperties{}) {
- if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- srcsList := parseSrcs(baseCompilerProps)
- // TODO(b/186153868): add support for os-specific srcs and exclude_srcs
- srcs.SetValueForOS(os.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
- copts.SetValueForOS(os.Name, parseCopts(baseCompilerProps))
- }
- }
+ srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
return compilerAttributes{
- srcs: srcs,
- copts: copts,
+ copts: copts,
+ srcs: srcs,
+ asFlags: asFlags,
+ asSrcs: asSrcs,
+ cSrcs: cSrcs,
+ conlyFlags: conlyFlags,
+ cppFlags: cppFlags,
}
}
// Convenience struct to hold all attributes parsed from linker properties.
type linkerAttributes struct {
- deps bazel.LabelListAttribute
- dynamicDeps bazel.LabelListAttribute
- wholeArchiveDeps bazel.LabelListAttribute
- linkopts bazel.StringListAttribute
- versionScript bazel.LabelAttribute
+ deps bazel.LabelListAttribute
+ dynamicDeps bazel.LabelListAttribute
+ wholeArchiveDeps bazel.LabelListAttribute
+ exportedDeps bazel.LabelListAttribute
+ useLibcrt bazel.BoolAttribute
+ linkopts bazel.StringListAttribute
+ versionScript bazel.LabelAttribute
+ stripKeepSymbols bazel.BoolAttribute
+ stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
+ stripKeepSymbolsList bazel.StringListAttribute
+ stripAll bazel.BoolAttribute
+ stripNone bazel.BoolAttribute
}
// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
@@ -309,78 +401,169 @@
// bp2BuildParseLinkerProps parses the linker properties of a module, including
// configurable attribute values.
func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
- var deps bazel.LabelListAttribute
+ var headerDeps bazel.LabelListAttribute
+ var staticDeps bazel.LabelListAttribute
+ var exportedDeps bazel.LabelListAttribute
var dynamicDeps bazel.LabelListAttribute
var wholeArchiveDeps bazel.LabelListAttribute
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
+
+ if libraryDecorator, ok := module.linker.(*libraryDecorator); ok {
+ stripProperties := libraryDecorator.stripper.StripProperties
+ stripKeepSymbols.Value = stripProperties.Strip.Keep_symbols
+ stripKeepSymbolsList.Value = stripProperties.Strip.Keep_symbols_list
+ stripKeepSymbolsAndDebugFrame.Value = stripProperties.Strip.Keep_symbols_and_debug_frame
+ stripAll.Value = stripProperties.Strip.All
+ stripNone.Value = stripProperties.Strip.None
+ }
+
+ 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)
+ }
+ }
+ }
for _, linkerProps := range module.linker.linkerProps() {
if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
- libs := baseLinkerProps.Header_libs
- libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
- libs = append(libs, baseLinkerProps.Static_libs...)
- wholeArchiveLibs := baseLinkerProps.Whole_static_libs
- libs = android.SortedUniqueStrings(libs)
- deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, libs))
+ // 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.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
+ wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
+ wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
+ // TODO(b/186024507): Handle system_shared_libs as its own attribute, so that the appropriate default
+ // may be supported.
+ sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...))
+ dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
+
+ headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
+ headerDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
+ // TODO(b/188796939): also handle export_static_lib_headers, export_shared_lib_headers,
+ // export_generated_headers
+ exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
+ exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
+
linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
- wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
-
if baseLinkerProps.Version_script != nil {
- versionScript.Value = android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)
+ versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
}
-
- sharedLibs := baseLinkerProps.Shared_libs
- dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, sharedLibs))
+ useLibcrt.Value = baseLinkerProps.libCrt()
break
}
}
- for arch, p := range module.GetArchProperties(ctx, &BaseLinkerProperties{}) {
- if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
- libs := baseLinkerProps.Header_libs
- libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
- libs = append(libs, baseLinkerProps.Static_libs...)
- wholeArchiveLibs := baseLinkerProps.Whole_static_libs
- libs = android.SortedUniqueStrings(libs)
- deps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, libs))
- linkopts.SetValueForArch(arch.Name, getBp2BuildLinkerFlags(baseLinkerProps))
- wholeArchiveDeps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
+ for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
+ for config, props := range configToProps {
+ if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
+ staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
+ staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
+ wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
+ wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
+ sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...))
+ dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
- if baseLinkerProps.Version_script != nil {
- versionScript.SetValueForArch(arch.Name,
- android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
+ headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
+ headerDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, headerLibs))
+ exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
+ exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
+
+ 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())
+ }
+ }
+ }
+
+ type productVarDep struct {
+ // the name of the corresponding excludes field, if one exists
+ excludesField string
+ // reference to the bazel attribute that should be set for the given product variable config
+ attribute *bazel.LabelListAttribute
+
+ depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
+ }
+
+ productVarToDepFields := map[string]productVarDep{
+ // product variables do not support exclude_shared_libs
+ "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: android.BazelLabelForModuleDepsExcludes},
+ "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, android.BazelLabelForModuleDepsExcludes},
+ "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, android.BazelLabelForModuleWholeDepsExcludes},
+ }
+
+ productVariableProps := android.ProductVariableProperties(ctx)
+ for name, dep := range productVarToDepFields {
+ props, exists := productVariableProps[name]
+ excludeProps, excludesExists := productVariableProps[dep.excludesField]
+ // if neither an include or excludes property exists, then skip it
+ if !exists && !excludesExists {
+ continue
+ }
+ // collect all the configurations that an include or exclude property exists for.
+ // we want to iterate all configurations rather than either the include or exclude because for a
+ // particular configuration we may have only and include or only an exclude to handle
+ configs := make(map[string]bool, len(props)+len(excludeProps))
+ for config := range props {
+ configs[config] = true
+ }
+ for config := range excludeProps {
+ configs[config] = true
+ }
+
+ for config := range configs {
+ prop, includesExists := props[config]
+ excludesProp, excludesExists := excludeProps[config]
+ var includes, excludes []string
+ var ok bool
+ // if there was no includes/excludes property, casting fails and that's expected
+ if includes, ok = prop.Property.([]string); includesExists && !ok {
+ ctx.ModuleErrorf("Could not convert product variable %s property", name)
+ }
+ if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
+ ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
}
- sharedLibs := baseLinkerProps.Shared_libs
- dynamicDeps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs))
+ dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
}
}
- for os, p := range module.GetTargetProperties(&BaseLinkerProperties{}) {
- if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
- libs := baseLinkerProps.Header_libs
- libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
- libs = append(libs, baseLinkerProps.Static_libs...)
- wholeArchiveLibs := baseLinkerProps.Whole_static_libs
- libs = android.SortedUniqueStrings(libs)
- wholeArchiveDeps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
- deps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
+ staticDeps.ResolveExcludes()
+ dynamicDeps.ResolveExcludes()
+ wholeArchiveDeps.ResolveExcludes()
- linkopts.SetValueForOS(os.Name, getBp2BuildLinkerFlags(baseLinkerProps))
-
- sharedLibs := baseLinkerProps.Shared_libs
- dynamicDeps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs))
- }
- }
+ headerDeps.Append(staticDeps)
return linkerAttributes{
- deps: deps,
+ deps: headerDeps,
+ exportedDeps: exportedDeps,
dynamicDeps: dynamicDeps,
wholeArchiveDeps: wholeArchiveDeps,
linkopts: linkopts,
+ useLibcrt: useLibcrt,
versionScript: versionScript,
+
+ // Strip properties
+ stripKeepSymbols: stripKeepSymbols,
+ stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
+ stripKeepSymbolsList: stripKeepSymbolsList,
+ stripAll: stripAll,
+ stripNone: stripNone,
}
}
@@ -407,11 +590,20 @@
return relativePaths
}
-// bp2BuildParseExportedIncludes creates a string list attribute contains the
-// exported included directories of a module.
func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
libraryDecorator := module.linker.(*libraryDecorator)
+ return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
+}
+func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
+ prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
+ libraryDecorator := prebuiltLibraryLinker.libraryDecorator
+ return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
+}
+
+// bp2BuildParseExportedIncludes creates a string list attribute contains the
+// exported included directories of a module.
+func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) bazel.StringListAttribute {
// Export_system_include_dirs and export_include_dirs are already module dir
// relative, so they don't need to be relativized like include_dirs, which
// are root-relative.
@@ -419,32 +611,23 @@
includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
- for arch, props := range module.GetArchProperties(ctx, &FlagExporterProperties{}) {
- if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
- archIncludeDirs := flagExporterProperties.Export_system_include_dirs
- archIncludeDirs = append(archIncludeDirs, flagExporterProperties.Export_include_dirs...)
+ getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties) []string {
+ variantIncludeDirs := flagExporterProperties.Export_system_include_dirs
+ variantIncludeDirs = append(variantIncludeDirs, flagExporterProperties.Export_include_dirs...)
- // To avoid duplicate includes when base includes + arch includes are combined
- // FIXME: This doesn't take conflicts between arch and os includes into account
- archIncludeDirs = bazel.SubtractStrings(archIncludeDirs, includeDirs)
-
- if len(archIncludeDirs) > 0 {
- includeDirsAttribute.SetValueForArch(arch.Name, archIncludeDirs)
- }
- }
+ // To avoid duplicate includes when base includes + arch includes are combined
+ // TODO: This doesn't take conflicts between arch and os includes into account
+ variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
+ return variantIncludeDirs
}
- for os, props := range module.GetTargetProperties(&FlagExporterProperties{}) {
- if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
- osIncludeDirs := flagExporterProperties.Export_system_include_dirs
- osIncludeDirs = append(osIncludeDirs, flagExporterProperties.Export_include_dirs...)
-
- // To avoid duplicate includes when base includes + os includes are combined
- // FIXME: This doesn't take conflicts between arch and os includes into account
- osIncludeDirs = bazel.SubtractStrings(osIncludeDirs, includeDirs)
-
- if len(osIncludeDirs) > 0 {
- includeDirsAttribute.SetValueForOS(os.Name, osIncludeDirs)
+ for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
+ for config, props := range configToProps {
+ if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
+ archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties)
+ if len(archVariantIncludeDirs) > 0 {
+ includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
+ }
}
}
}
diff --git a/cc/builder.go b/cc/builder.go
index 51c8a0b..842ce85 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -237,7 +237,7 @@
// -w has been added since header-abi-dumper does not need to produce any sort of diagnostic information.
sAbiDump, sAbiDumpRE = pctx.RemoteStaticRules("sAbiDump",
blueprint.RuleParams{
- Command: "rm -f $out && $reTemplate$sAbiDumper -o ${out} $in $exportDirs -- $cFlags -w -isystem prebuilts/clang-tools/${config.HostPrebuiltTag}/clang-headers",
+ Command: "rm -f $out && $reTemplate$sAbiDumper --root-dir . --root-dir $$OUT_DIR:out -o ${out} $in $exportDirs -- $cFlags -w -isystem prebuilts/clang-tools/${config.HostPrebuiltTag}/clang-headers",
CommandDeps: []string{"$sAbiDumper"},
}, &remoteexec.REParams{
Labels: map[string]string{"type": "abi-dump", "tool": "header-abi-dumper"},
@@ -255,7 +255,7 @@
// sAbi dump file.
sAbiLink, sAbiLinkRE = pctx.RemoteStaticRules("sAbiLink",
blueprint.RuleParams{
- Command: "$reTemplate$sAbiLinker -o ${out} $symbolFilter -arch $arch $exportedHeaderFlags @${out}.rsp ",
+ Command: "$reTemplate$sAbiLinker --root-dir . --root-dir $$OUT_DIR:out -o ${out} $symbolFilter -arch $arch $exportedHeaderFlags @${out}.rsp",
CommandDeps: []string{"$sAbiLinker"},
Rspfile: "${out}.rsp",
RspfileContent: "${in}",
@@ -500,10 +500,10 @@
sAbiDumpFiles = make(android.Paths, 0, len(srcFiles))
}
- cflags += " ${config.NoOverrideClangGlobalCflags}"
- toolingCflags += " ${config.NoOverrideClangGlobalCflags}"
- cppflags += " ${config.NoOverrideClangGlobalCflags}"
- toolingCppflags += " ${config.NoOverrideClangGlobalCflags}"
+ cflags += " ${config.NoOverrideGlobalCflags}"
+ toolingCflags += " ${config.NoOverrideGlobalCflags}"
+ cppflags += " ${config.NoOverrideGlobalCflags}"
+ toolingCppflags += " ${config.NoOverrideGlobalCflags}"
for i, srcFile := range srcFiles {
objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o")
@@ -534,7 +534,7 @@
Implicits: cFlagsDeps,
OrderOnly: pathDeps,
Args: map[string]string{
- "windresCmd": gccCmd(flags.toolchain, "windres"),
+ "windresCmd": mingwCmd(flags.toolchain, "windres"),
"flags": flags.toolchain.WindresFlags(),
},
})
@@ -730,8 +730,9 @@
// Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
// and shared libraries, to a shared library (.so) or dynamic executable
func transformObjToDynamicBinary(ctx android.ModuleContext,
- objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps android.Paths,
- crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath, implicitOutputs android.WritablePaths) {
+ objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps, crtBegin, crtEnd android.Paths,
+ groupLate bool, flags builderFlags, outputFile android.WritablePath,
+ implicitOutputs android.WritablePaths, validations android.WritablePaths) {
ldCmd := "${config.ClangBin}/clang++"
@@ -778,18 +779,17 @@
deps = append(deps, staticLibs...)
deps = append(deps, lateStaticLibs...)
deps = append(deps, wholeStaticLibs...)
- if crtBegin.Valid() {
- deps = append(deps, crtBegin.Path(), crtEnd.Path())
- }
+ deps = append(deps, crtBegin...)
+ deps = append(deps, crtEnd...)
rule := ld
args := map[string]string{
"ldCmd": ldCmd,
- "crtBegin": crtBegin.String(),
+ "crtBegin": strings.Join(crtBegin.Strings(), " "),
"libFlags": strings.Join(libFlagsList, " "),
"extraLibFlags": flags.extraLibFlags,
"ldFlags": flags.globalLdFlags + " " + flags.localLdFlags,
- "crtEnd": crtEnd.String(),
+ "crtEnd": strings.Join(crtEnd.Strings(), " "),
}
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CXX_LINKS") {
rule = ldRE
@@ -805,6 +805,7 @@
Inputs: objFiles,
Implicits: deps,
OrderOnly: sharedLibs,
+ Validations: validations.Paths(),
Args: args,
})
}
@@ -1069,6 +1070,6 @@
})
}
-func gccCmd(toolchain config.Toolchain, cmd string) string {
+func mingwCmd(toolchain config.Toolchain, cmd string) string {
return filepath.Join(toolchain.GccRoot(), "bin", toolchain.GccTriple()+"-"+cmd)
}
diff --git a/cc/cc.go b/cc/cc.go
index c62fd6c..5178d10 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -53,25 +53,9 @@
})
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("asan_deps", sanitizerDepsMutator(Asan))
- ctx.BottomUp("asan", sanitizerMutator(Asan)).Parallel()
-
- ctx.TopDown("hwasan_deps", sanitizerDepsMutator(Hwasan))
- ctx.BottomUp("hwasan", sanitizerMutator(Hwasan)).Parallel()
-
- ctx.TopDown("fuzzer_deps", sanitizerDepsMutator(Fuzzer))
- ctx.BottomUp("fuzzer", sanitizerMutator(Fuzzer)).Parallel()
-
- // cfi mutator shouldn't run before sanitizers that return true for
- // incompatibleWithCfi()
- ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi))
- ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel()
-
- ctx.TopDown("scs_deps", sanitizerDepsMutator(scs))
- ctx.BottomUp("scs", sanitizerMutator(scs)).Parallel()
-
- ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
- ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
+ for _, san := range Sanitizers {
+ san.registerMutators(ctx)
+ }
ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
@@ -126,11 +110,10 @@
ReexportGeneratedHeaders []string
- CrtBegin, CrtEnd string
+ CrtBegin, CrtEnd []string
// Used for host bionic
- LinkerFlagsFile string
- DynamicLinker string
+ DynamicLinker string
// List of libs that need to be excluded for APEX variant
ExcludeLibsForApex []string
@@ -177,10 +160,7 @@
ReexportedDeps android.Paths
// Paths to crt*.o files
- CrtBegin, CrtEnd android.OptionalPath
-
- // Path to the file container flags to use with the linker
- LinkerFlagsFile android.OptionalPath
+ CrtBegin, CrtEnd android.Paths
// Path to the dynamic linker binary
DynamicLinker android.OptionalPath
@@ -290,9 +270,15 @@
// Set by DepsMutator.
AndroidMkSystemSharedLibs []string `blueprint:"mutated"`
+ // The name of the image this module is built for, suffixed with a '.'
ImageVariationPrefix string `blueprint:"mutated"`
- VndkVersion string `blueprint:"mutated"`
- SubName string `blueprint:"mutated"`
+
+ // The VNDK version this module is built against. If empty, the module is not
+ // build against the VNDK.
+ VndkVersion string `blueprint:"mutated"`
+
+ // Suffix for the name of Android.mk entries generated by this module
+ SubName string `blueprint:"mutated"`
// *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
// file
@@ -315,12 +301,15 @@
// Make this module available when building for recovery
Recovery_available *bool
- // Set by imageMutator
- CoreVariantNeeded bool `blueprint:"mutated"`
- RamdiskVariantNeeded bool `blueprint:"mutated"`
- VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
- RecoveryVariantNeeded bool `blueprint:"mutated"`
- ExtraVariants []string `blueprint:"mutated"`
+ // Used by imageMutator, set by ImageMutatorBegin()
+ CoreVariantNeeded bool `blueprint:"mutated"`
+ RamdiskVariantNeeded bool `blueprint:"mutated"`
+ VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
+ RecoveryVariantNeeded bool `blueprint:"mutated"`
+
+ // A list of variations for the "image" mutator of the form
+ //<image name> '.' <version char>, for example, 'vendor.S'
+ ExtraVersionedImageVariations []string `blueprint:"mutated"`
// Allows this module to use non-APEX version of libraries. Useful
// for building binaries that are started before APEXes are activated.
@@ -332,6 +321,7 @@
// Used by vendor snapshot to record dependencies from snapshot modules.
SnapshotSharedLibs []string `blueprint:"mutated"`
+ SnapshotStaticLibs []string `blueprint:"mutated"`
SnapshotRuntimeLibs []string `blueprint:"mutated"`
Installable *bool
@@ -364,6 +354,24 @@
// can depend on libraries that are not exported by the APEXes and use private symbols
// from the exported libraries.
Test_for []string `android:"arch_variant"`
+
+ Target struct {
+ Platform struct {
+ // List of modules required by the core variant.
+ Required []string `android:"arch_variant"`
+
+ // List of modules not required by the core variant.
+ Exclude_required []string `android:"arch_variant"`
+ } `android:"arch_variant"`
+
+ Recovery struct {
+ // List of modules required by the recovery variant.
+ Required []string `android:"arch_variant"`
+
+ // List of modules not required by the recovery variant.
+ Exclude_required []string `android:"arch_variant"`
+ } `android:"arch_variant"`
+ } `android:"arch_variant"`
}
type VendorProperties struct {
@@ -520,8 +528,6 @@
// feature represents additional (optional) steps to building cc-related modules, such as invocation
// of clang-tidy.
type feature interface {
- begin(ctx BaseModuleContext)
- deps(ctx DepsContext, deps Deps) Deps
flags(ctx ModuleContext, flags Flags) Flags
props() []interface{}
}
@@ -580,6 +586,7 @@
hostToolPath() android.OptionalPath
relativeInstallPath() string
makeUninstallable(mod *Module)
+ installInRoot() bool
}
// bazelHandler is the interface for a helper object related to deferring to Bazel for
@@ -717,7 +724,6 @@
genHeaderDepTag = dependencyTag{name: "gen header"}
genHeaderExportDepTag = dependencyTag{name: "gen header export"}
objDepTag = dependencyTag{name: "obj"}
- linkerFlagsDepTag = dependencyTag{name: "linker flags file"}
dynamicLinkerDepTag = installDependencyTag{name: "dynamic linker"}
reuseObjTag = dependencyTag{name: "reuse objects"}
staticVariantTag = dependencyTag{name: "static variant"}
@@ -726,7 +732,6 @@
runtimeDepTag = installDependencyTag{name: "runtime lib"}
testPerSrcDepTag = dependencyTag{name: "test_per_src"}
stubImplDepTag = dependencyTag{name: "stub_impl"}
- llndkStubDepTag = dependencyTag{name: "llndk stub"}
)
func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
@@ -768,14 +773,13 @@
// members of the cc.Module to this decorator. Thus, a cc_binary module has custom linker and
// installer logic.
type Module struct {
- android.ModuleBase
- android.DefaultableModuleBase
- android.ApexModuleBase
+ FuzzModule
+
android.SdkBase
android.BazelModuleBase
- Properties BaseProperties
VendorProperties VendorProperties
+ Properties BaseProperties
// initialize before calling Init
hod android.HostOrDeviceSupported
@@ -827,6 +831,46 @@
hideApexVariantFromMake bool
}
+func (c *Module) AddJSONData(d *map[string]interface{}) {
+ c.AndroidModuleBase().AddJSONData(d)
+ (*d)["Cc"] = map[string]interface{}{
+ "SdkVersion": c.SdkVersion(),
+ "MinSdkVersion": c.MinSdkVersion(),
+ "VndkVersion": c.VndkVersion(),
+ "ProductSpecific": c.ProductSpecific(),
+ "SocSpecific": c.SocSpecific(),
+ "DeviceSpecific": c.DeviceSpecific(),
+ "InProduct": c.InProduct(),
+ "InVendor": c.InVendor(),
+ "InRamdisk": c.InRamdisk(),
+ "InVendorRamdisk": c.InVendorRamdisk(),
+ "InRecovery": c.InRecovery(),
+ "VendorAvailable": c.VendorAvailable(),
+ "ProductAvailable": c.ProductAvailable(),
+ "RamdiskAvailable": c.RamdiskAvailable(),
+ "VendorRamdiskAvailable": c.VendorRamdiskAvailable(),
+ "RecoveryAvailable": c.RecoveryAvailable(),
+ "OdmAvailable": c.OdmAvailable(),
+ "InstallInData": c.InstallInData(),
+ "InstallInRamdisk": c.InstallInRamdisk(),
+ "InstallInSanitizerDir": c.InstallInSanitizerDir(),
+ "InstallInVendorRamdisk": c.InstallInVendorRamdisk(),
+ "InstallInRecovery": c.InstallInRecovery(),
+ "InstallInRoot": c.InstallInRoot(),
+ "IsVndk": c.IsVndk(),
+ "IsVndkExt": c.IsVndkExt(),
+ "IsVndkPrivate": c.IsVndkPrivate(),
+ "IsVndkSp": c.IsVndkSp(),
+ "IsLlndk": c.IsLlndk(),
+ "IsLlndkPublic": c.IsLlndkPublic(),
+ "IsSnapshotLibrary": c.IsSnapshotLibrary(),
+ "IsSnapshotPrebuilt": c.IsSnapshotPrebuilt(),
+ "IsVendorPublicLibrary": c.IsVendorPublicLibrary(),
+ "ApexSdkVersion": c.apexSdkVersion,
+ "TestFor": c.TestFor(),
+ }
+}
+
func (c *Module) SetPreventInstall() {
c.Properties.PreventInstall = true
}
@@ -839,6 +883,18 @@
return c.Properties.HideFromMake
}
+func (c *Module) RequiredModuleNames() []string {
+ required := android.CopyOf(c.ModuleBase.RequiredModuleNames())
+ if c.ImageVariation().Variation == android.CoreVariation {
+ required = append(required, c.Properties.Target.Platform.Required...)
+ required = removeListFromList(required, c.Properties.Target.Platform.Exclude_required)
+ } else if c.InRecovery() {
+ required = append(required, c.Properties.Target.Recovery.Required...)
+ required = removeListFromList(required, c.Properties.Target.Recovery.Exclude_required)
+ }
+ return android.FirstUniqueStrings(required)
+}
+
func (c *Module) Toc() android.OptionalPath {
if c.linker != nil {
if library, ok := c.linker.(libraryInterface); ok {
@@ -1075,17 +1131,6 @@
return c
}
-// Returns true for dependency roots (binaries)
-// TODO(ccross): also handle dlopenable libraries
-func (c *Module) IsDependencyRoot() bool {
- if root, ok := c.linker.(interface {
- isDependencyRoot() bool
- }); ok {
- return root.isDependencyRoot()
- }
- return false
-}
-
func (c *Module) UseVndk() bool {
return c.Properties.VndkVersion != ""
}
@@ -1255,7 +1300,7 @@
return name
}
-func (c *Module) bootstrap() bool {
+func (c *Module) Bootstrap() bool {
return Bool(c.Properties.Bootstrap)
}
@@ -1268,8 +1313,8 @@
}
func (c *Module) IsSnapshotPrebuilt() bool {
- if p, ok := c.linker.(snapshotInterface); ok {
- return p.isSnapshotPrebuilt()
+ if p, ok := c.linker.(SnapshotInterface); ok {
+ return p.IsSnapshotPrebuilt()
}
return false
}
@@ -1306,6 +1351,10 @@
Bool(c.sanitize.Properties.Sanitize.Config.Cfi_assembly_support)
}
+func (c *Module) InstallInRoot() bool {
+ return c.installer != nil && c.installer.installInRoot()
+}
+
type baseModuleContext struct {
android.BaseModuleContext
moduleContextImpl
@@ -1496,7 +1545,7 @@
}
func (ctx *moduleContextImpl) bootstrap() bool {
- return ctx.mod.bootstrap()
+ return ctx.mod.Bootstrap()
}
func (ctx *moduleContextImpl) nativeCoverage() bool {
@@ -1674,10 +1723,6 @@
c.makeLinkType = GetMakeLinkType(actx, c)
- if c.maybeGenerateBazelActions(actx) {
- return
- }
-
ctx := &moduleContext{
ModuleContext: actx,
moduleContextImpl: moduleContextImpl{
@@ -1686,6 +1731,11 @@
}
ctx.ctx = ctx
+ if c.maybeGenerateBazelActions(actx) {
+ c.maybeInstall(ctx, apexInfo)
+ return
+ }
+
deps := c.depsToPaths(ctx)
if ctx.Failed() {
return
@@ -1773,19 +1823,7 @@
}
c.outputFile = android.OptionalPathForPath(outputFile)
- // If a lib is directly included in any of the APEXes or is not available to the
- // platform (which is often the case when the stub is provided as a prebuilt),
- // unhide the stubs variant having the latest version gets visible to make. In
- // addition, the non-stubs variant is renamed to <libname>.bootstrap. This is to
- // force anything in the make world to link against the stubs library. (unless it
- // is explicitly referenced via .bootstrap suffix or the module is marked with
- // 'bootstrap: true').
- if c.HasStubsVariants() && c.NotInPlatform() && !c.InRamdisk() &&
- !c.InRecovery() && !c.UseVndk() && !c.static() && !c.isCoverageVariant() &&
- c.IsStubs() && !c.InVendorRamdisk() {
- c.Properties.HideFromMake = false // unhide
- // Note: this is still non-installable
- }
+ c.maybeUnhideFromMake()
// glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
// RECOVERY_SNAPSHOT_VERSION is current.
@@ -1796,6 +1834,26 @@
}
}
+ c.maybeInstall(ctx, apexInfo)
+}
+
+func (c *Module) maybeUnhideFromMake() {
+ // If a lib is directly included in any of the APEXes or is not available to the
+ // platform (which is often the case when the stub is provided as a prebuilt),
+ // unhide the stubs variant having the latest version gets visible to make. In
+ // addition, the non-stubs variant is renamed to <libname>.bootstrap. This is to
+ // force anything in the make world to link against the stubs library. (unless it
+ // is explicitly referenced via .bootstrap suffix or the module is marked with
+ // 'bootstrap: true').
+ if c.HasStubsVariants() && c.NotInPlatform() && !c.InRamdisk() &&
+ !c.InRecovery() && !c.UseVndk() && !c.static() && !c.isCoverageVariant() &&
+ c.IsStubs() && !c.InVendorRamdisk() {
+ c.Properties.HideFromMake = false // unhide
+ // Note: this is still non-installable
+ }
+}
+
+func (c *Module) maybeInstall(ctx ModuleContext, apexInfo android.ApexInfo) {
if !proptools.BoolDefault(c.Properties.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
@@ -1840,21 +1898,12 @@
if c.coverage != nil {
c.coverage.begin(ctx)
}
- if c.sabi != nil {
- c.sabi.begin(ctx)
- }
- if c.vndkdep != nil {
- c.vndkdep.begin(ctx)
- }
if c.lto != nil {
c.lto.begin(ctx)
}
if c.pgo != nil {
c.pgo.begin(ctx)
}
- for _, feature := range c.features {
- feature.begin(ctx)
- }
if ctx.useSdk() && c.IsSdkVariant() {
version, err := nativeApiLevelFromUser(ctx, ctx.sdkVersion())
if err != nil {
@@ -1878,24 +1927,9 @@
if c.stl != nil {
deps = c.stl.deps(ctx, deps)
}
- if c.sanitize != nil {
- deps = c.sanitize.deps(ctx, deps)
- }
if c.coverage != nil {
deps = c.coverage.deps(ctx, deps)
}
- if c.sabi != nil {
- deps = c.sabi.deps(ctx, deps)
- }
- if c.vndkdep != nil {
- deps = c.vndkdep.deps(ctx, deps)
- }
- if c.lto != nil {
- deps = c.lto.deps(ctx, deps)
- }
- for _, feature := range c.features {
- deps = feature.deps(ctx, deps)
- }
deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs)
deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs)
@@ -1985,15 +2019,19 @@
}
}
-func (c *Module) addSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext,
- variations []blueprint.Variation, depTag libraryDependencyTag, name, version string, far bool) {
+func AddSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext, mod LinkableInterface,
+ variations []blueprint.Variation, depTag blueprint.DependencyTag, name, version string, far bool) {
variations = append([]blueprint.Variation(nil), variations...)
- if version != "" && CanBeOrLinkAgainstVersionVariants(c) {
+ if version != "" && CanBeOrLinkAgainstVersionVariants(mod) {
// Version is explicitly specified. i.e. libFoo#30
variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
- depTag.explicitlyVersioned = true
+ if tag, ok := depTag.(libraryDependencyTag); ok {
+ tag.explicitlyVersioned = true
+ } else {
+ panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
+ }
}
if far {
@@ -2003,6 +2041,74 @@
}
}
+func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo {
+ // Only device modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of
+ // SnapshotInfo, which provides no mappings.
+ if *snapshotInfo == nil && c.Device() {
+ // Only retrieve the snapshot on demand in order to avoid circular dependencies
+ // between the modules in the snapshot and the snapshot itself.
+ var snapshotModule []blueprint.Module
+ if c.InVendor() && c.VndkVersion() == actx.DeviceConfig().VndkVersion() {
+ snapshotModule = actx.AddVariationDependencies(nil, nil, "vendor_snapshot")
+ } else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() {
+ snapshotModule = actx.AddVariationDependencies(nil, nil, "recovery_snapshot")
+ }
+ if len(snapshotModule) > 0 && snapshotModule[0] != nil {
+ snapshot := actx.OtherModuleProvider(snapshotModule[0], SnapshotInfoProvider).(SnapshotInfo)
+ *snapshotInfo = &snapshot
+ // republish the snapshot for use in later mutators on this module
+ actx.SetProvider(SnapshotInfoProvider, snapshot)
+ }
+ }
+ if *snapshotInfo == nil {
+ *snapshotInfo = &SnapshotInfo{}
+ }
+ return **snapshotInfo
+}
+
+func RewriteSnapshotLib(lib string, snapshotMap map[string]string) string {
+ if snapshot, ok := snapshotMap[lib]; ok {
+ return snapshot
+ }
+
+ return lib
+}
+
+// RewriteLibs takes a list of names of shared libraries and scans it for three types
+// of names:
+//
+// 1. Name of an NDK library that refers to a prebuilt module.
+// For each of these, it adds the name of the prebuilt module (which will be in
+// prebuilts/ndk) to the list of nonvariant libs.
+// 2. Name of an NDK library that refers to an ndk_library module.
+// For each of these, it adds the name of the ndk_library module to the list of
+// variant libs.
+// 3. Anything else (so anything that isn't an NDK library).
+// It adds these to the nonvariantLibs list.
+//
+// The caller can then know to add the variantLibs dependencies differently from the
+// nonvariantLibs
+func RewriteLibs(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext, config android.Config, list []string) (nonvariantLibs []string, variantLibs []string) {
+ variantLibs = []string{}
+
+ nonvariantLibs = []string{}
+ for _, entry := range list {
+ // strip #version suffix out
+ name, _ := StubsLibNameAndVersion(entry)
+ if c.InRecovery() {
+ nonvariantLibs = append(nonvariantLibs, RewriteSnapshotLib(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs))
+ } else if c.UseSdk() && inList(name, *getNDKKnownLibs(config)) {
+ variantLibs = append(variantLibs, name+ndkLibrarySuffix)
+ } else if c.UseVndk() {
+ nonvariantLibs = append(nonvariantLibs, RewriteSnapshotLib(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs))
+ } else {
+ // put name#version back
+ nonvariantLibs = append(nonvariantLibs, entry)
+ }
+ }
+ return nonvariantLibs, variantLibs
+}
+
func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
if !c.Enabled() {
return
@@ -2021,83 +2127,16 @@
c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs
var snapshotInfo *SnapshotInfo
- getSnapshot := func() SnapshotInfo {
- // Only modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of
- // SnapshotInfo, which provides no mappings.
- if snapshotInfo == nil {
- // Only retrieve the snapshot on demand in order to avoid circular dependencies
- // between the modules in the snapshot and the snapshot itself.
- var snapshotModule []blueprint.Module
- if c.InVendor() && c.VndkVersion() == actx.DeviceConfig().VndkVersion() {
- snapshotModule = ctx.AddVariationDependencies(nil, nil, "vendor_snapshot")
- } else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() {
- snapshotModule = ctx.AddVariationDependencies(nil, nil, "recovery_snapshot")
- }
- if len(snapshotModule) > 0 {
- snapshot := ctx.OtherModuleProvider(snapshotModule[0], SnapshotInfoProvider).(SnapshotInfo)
- snapshotInfo = &snapshot
- // republish the snapshot for use in later mutators on this module
- ctx.SetProvider(SnapshotInfoProvider, snapshot)
- } else {
- snapshotInfo = &SnapshotInfo{}
- }
- }
-
- return *snapshotInfo
- }
-
- rewriteSnapshotLib := func(lib string, snapshotMap map[string]string) string {
- if snapshot, ok := snapshotMap[lib]; ok {
- return snapshot
- }
-
- return lib
- }
variantNdkLibs := []string{}
variantLateNdkLibs := []string{}
if ctx.Os() == android.Android {
- // rewriteLibs takes a list of names of shared libraries and scans it for three types
- // of names:
- //
- // 1. Name of an NDK library that refers to a prebuilt module.
- // For each of these, it adds the name of the prebuilt module (which will be in
- // prebuilts/ndk) to the list of nonvariant libs.
- // 2. Name of an NDK library that refers to an ndk_library module.
- // For each of these, it adds the name of the ndk_library module to the list of
- // variant libs.
- // 3. Anything else (so anything that isn't an NDK library).
- // It adds these to the nonvariantLibs list.
- //
- // The caller can then know to add the variantLibs dependencies differently from the
- // nonvariantLibs
-
- rewriteLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) {
- variantLibs = []string{}
- nonvariantLibs = []string{}
- for _, entry := range list {
- // strip #version suffix out
- name, _ := StubsLibNameAndVersion(entry)
- if c.InRecovery() {
- nonvariantLibs = append(nonvariantLibs, rewriteSnapshotLib(entry, getSnapshot().SharedLibs))
- } else if ctx.useSdk() && inList(name, *getNDKKnownLibs(ctx.Config())) {
- variantLibs = append(variantLibs, name+ndkLibrarySuffix)
- } else if ctx.useVndk() {
- nonvariantLibs = append(nonvariantLibs, rewriteSnapshotLib(entry, getSnapshot().SharedLibs))
- } else {
- // put name#version back
- nonvariantLibs = append(nonvariantLibs, entry)
- }
- }
- return nonvariantLibs, variantLibs
- }
-
- deps.SharedLibs, variantNdkLibs = rewriteLibs(deps.SharedLibs)
- deps.LateSharedLibs, variantLateNdkLibs = rewriteLibs(deps.LateSharedLibs)
- deps.ReexportSharedLibHeaders, _ = rewriteLibs(deps.ReexportSharedLibHeaders)
+ deps.SharedLibs, variantNdkLibs = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs)
+ deps.LateSharedLibs, variantLateNdkLibs = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.LateSharedLibs)
+ deps.ReexportSharedLibHeaders, _ = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.ReexportSharedLibHeaders)
for idx, lib := range deps.RuntimeLibs {
- deps.RuntimeLibs[idx] = rewriteSnapshotLib(lib, getSnapshot().SharedLibs)
+ deps.RuntimeLibs[idx] = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs)
}
}
@@ -2107,7 +2146,7 @@
depTag.reexportFlags = true
}
- lib = rewriteSnapshotLib(lib, getSnapshot().HeaderLibs)
+ lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs)
if c.IsStubs() {
actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()),
@@ -2117,6 +2156,15 @@
}
}
+ if c.isNDKStubLibrary() {
+ // NDK stubs depend on their implementation because the ABI dumps are
+ // generated from the implementation library.
+ actx.AddFarVariationDependencies(append(ctx.Target().Variations(),
+ c.ImageVariation(),
+ blueprint.Variation{Mutator: "link", Variation: "shared"},
+ ), stubImplementation, c.BaseModuleName())
+ }
+
// sysprop_library has to support both C++ and Java. So sysprop_library internally creates one
// C++ implementation library and one Java implementation library. When a module links against
// sysprop_library, the C++ implementation library has to be linked. syspropImplLibraries is a
@@ -2130,7 +2178,7 @@
lib = impl
}
- lib = rewriteSnapshotLib(lib, getSnapshot().StaticLibs)
+ lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
@@ -2150,7 +2198,7 @@
lib = impl
}
- lib = rewriteSnapshotLib(lib, getSnapshot().StaticLibs)
+ lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
@@ -2164,14 +2212,7 @@
depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true}
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
- }, depTag, rewriteSnapshotLib(staticUnwinder(actx), getSnapshot().StaticLibs))
- }
-
- for _, lib := range deps.LateStaticLibs {
- depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
- actx.AddVariationDependencies([]blueprint.Variation{
- {Mutator: "link", Variation: "static"},
- }, depTag, rewriteSnapshotLib(lib, getSnapshot().StaticLibs))
+ }, depTag, RewriteSnapshotLib(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
}
// shared lib names without the #version suffix
@@ -2196,7 +2237,14 @@
variations := []blueprint.Variation{
{Mutator: "link", Variation: "shared"},
}
- c.addSharedLibDependenciesWithVersions(ctx, variations, depTag, name, version, false)
+ AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
+ }
+
+ for _, lib := range deps.LateStaticLibs {
+ depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
+ actx.AddVariationDependencies([]blueprint.Variation{
+ {Mutator: "link", Variation: "static"},
+ }, depTag, RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
}
for _, lib := range deps.LateSharedLibs {
@@ -2210,7 +2258,7 @@
variations := []blueprint.Variation{
{Mutator: "link", Variation: "shared"},
}
- c.addSharedLibDependenciesWithVersions(ctx, variations, depTag, lib, "", false)
+ AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, lib, "", false)
}
actx.AddVariationDependencies([]blueprint.Variation{
@@ -2233,16 +2281,13 @@
crtVariations := GetCrtVariations(ctx, c)
actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...)
- if deps.CrtBegin != "" {
+ for _, crt := range deps.CrtBegin {
actx.AddVariationDependencies(crtVariations, CrtBeginDepTag,
- rewriteSnapshotLib(deps.CrtBegin, getSnapshot().Objects))
+ RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
}
- if deps.CrtEnd != "" {
+ for _, crt := range deps.CrtEnd {
actx.AddVariationDependencies(crtVariations, CrtEndDepTag,
- rewriteSnapshotLib(deps.CrtEnd, getSnapshot().Objects))
- }
- if deps.LinkerFlagsFile != "" {
- actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)
+ RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
}
if deps.DynamicLinker != "" {
actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker)
@@ -2267,7 +2312,7 @@
actx.AddVariationDependencies([]blueprint.Variation{
c.ImageVariation(),
{Mutator: "link", Variation: "shared"},
- }, vndkExtDepTag, vndkdep.getVndkExtendsModuleName())
+ }, vndkExtDepTag, RewriteSnapshotLib(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs))
}
}
}
@@ -2542,17 +2587,10 @@
} else {
ctx.ModuleErrorf("module %q is not a genrule", depName)
}
- case linkerFlagsDepTag:
- if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
- files := genRule.GeneratedSourceFiles()
- if len(files) == 1 {
- depPaths.LinkerFlagsFile = android.OptionalPathForPath(files[0])
- } else if len(files) > 1 {
- ctx.ModuleErrorf("module %q can only generate a single file if used for a linker flag file", depName)
- }
- } else {
- ctx.ModuleErrorf("module %q is not a genrule", depName)
- }
+ case CrtBeginDepTag:
+ depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, ""))
+ case CrtEndDepTag:
+ depPaths.CrtEnd = append(depPaths.CrtEnd, android.OutputFileForModule(ctx, dep, ""))
}
return
}
@@ -2625,64 +2663,8 @@
return
}
- sharedLibraryInfo := ctx.OtherModuleProvider(dep, SharedLibraryInfoProvider).(SharedLibraryInfo)
- sharedLibraryStubsInfo := ctx.OtherModuleProvider(dep, SharedLibraryStubsProvider).(SharedLibraryStubsInfo)
-
- if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedStubLibraries) > 0 {
- useStubs := false
-
- if lib := moduleLibraryInterface(dep); lib.buildStubs() && c.UseVndk() { // LLNDK
- if !apexInfo.IsForPlatform() {
- // For platform libraries, use current version of LLNDK
- useStubs = true
- }
- } else if apexInfo.IsForPlatform() {
- // If not building for APEX, use stubs only when it is from
- // an APEX (and not from platform)
- // However, for host, ramdisk, vendor_ramdisk, recovery or bootstrap modules,
- // always link to non-stub variant
- useStubs = dep.(android.ApexModule).NotInPlatform() && !c.bootstrap()
- if useStubs {
- // Another exception: if this module is a test for an APEX, then
- // it is linked with the non-stub variant of a module in the APEX
- // as if this is part of the APEX.
- testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
- for _, apexContents := range testFor.ApexContents {
- if apexContents.DirectlyInApex(depName) {
- useStubs = false
- break
- }
- }
- }
- if useStubs {
- // Yet another exception: If this module and the dependency are
- // available to the same APEXes then skip stubs between their
- // platform variants. This complements the test_for case above,
- // which avoids the stubs on a direct APEX library dependency, by
- // avoiding stubs for indirect test dependencies as well.
- //
- // TODO(b/183882457): This doesn't work if the two libraries have
- // only partially overlapping apex_available. For that test_for
- // modules would need to be split into APEX variants and resolved
- // separately for each APEX they have access to.
- if android.AvailableToSameApexes(c, dep.(android.ApexModule)) {
- useStubs = false
- }
- }
- } else {
- // If building for APEX, use stubs when the parent is in any APEX that
- // the child is not in.
- useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
- }
-
- // when to use (unspecified) stubs, use the latest one.
- if useStubs {
- stubs := sharedLibraryStubsInfo.SharedStubLibraries
- toUse := stubs[len(stubs)-1]
- sharedLibraryInfo = toUse.SharedLibraryInfo
- depExporterInfo = toUse.FlagExporterInfo
- }
- }
+ sharedLibraryInfo, returnedDepExporterInfo := ChooseStubOrImpl(ctx, dep)
+ depExporterInfo = returnedDepExporterInfo
// Stubs lib doesn't link to the shared lib dependencies. Don't set
// linkFile, depFile, and ptr.
@@ -2840,8 +2822,8 @@
// they merely serve as Make dependencies and do not affect this lib itself.
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs, makeLibName)
- // Record baseLibName for snapshots.
- c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, baseLibName(depName))
+ // Record BaseLibName for snapshots.
+ c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, BaseLibName(depName))
case libDepTag.static():
if libDepTag.wholeStatic {
c.Properties.AndroidMkWholeStaticLibs = append(
@@ -2850,6 +2832,8 @@
c.Properties.AndroidMkStaticLibs = append(
c.Properties.AndroidMkStaticLibs, makeLibName)
}
+ // Record BaseLibName for snapshots.
+ c.Properties.SnapshotStaticLibs = append(c.Properties.SnapshotStaticLibs, BaseLibName(depName))
}
} else if !c.IsStubs() {
// Stubs lib doesn't link to the runtime lib, object, crt, etc. dependencies.
@@ -2858,14 +2842,14 @@
case runtimeDepTag:
c.Properties.AndroidMkRuntimeLibs = append(
c.Properties.AndroidMkRuntimeLibs, MakeLibName(ctx, c, ccDep, depName)+libDepTag.makeSuffix)
- // Record baseLibName for snapshots.
- c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, baseLibName(depName))
+ // Record BaseLibName for snapshots.
+ c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, BaseLibName(depName))
case objDepTag:
depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
case CrtBeginDepTag:
- depPaths.CrtBegin = linkFile
+ depPaths.CrtBegin = append(depPaths.CrtBegin, linkFile.Path())
case CrtEndDepTag:
- depPaths.CrtEnd = linkFile
+ depPaths.CrtEnd = append(depPaths.CrtEnd, linkFile.Path())
case dynamicLinkerDepTag:
depPaths.DynamicLinker = linkFile
}
@@ -2895,6 +2879,100 @@
return depPaths
}
+// ChooseStubOrImpl determines whether a given dependency should be redirected to the stub variant
+// of the dependency or not, and returns the SharedLibraryInfo and FlagExporterInfo for the right
+// dependency. The stub variant is selected when the dependency crosses a boundary where each side
+// has different level of updatability. For example, if a library foo in an APEX depends on a
+// library bar which provides stable interface and exists in the platform, foo uses the stub variant
+// of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the
+// same APEX as foo, the non-stub variant of bar is used.
+func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) {
+ depName := ctx.OtherModuleName(dep)
+ depTag := ctx.OtherModuleDependencyTag(dep)
+ libDepTag, ok := depTag.(libraryDependencyTag)
+ if !ok || !libDepTag.shared() {
+ panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
+ }
+
+ thisModule, ok := ctx.Module().(android.ApexModule)
+ if !ok {
+ panic(fmt.Errorf("Not an APEX module: %q", ctx.ModuleName()))
+ }
+
+ useVndk := false
+ bootstrap := false
+ if linkable, ok := ctx.Module().(LinkableInterface); !ok {
+ panic(fmt.Errorf("Not a Linkable module: %q", ctx.ModuleName()))
+ } else {
+ useVndk = linkable.UseVndk()
+ bootstrap = linkable.Bootstrap()
+ }
+
+ sharedLibraryInfo := ctx.OtherModuleProvider(dep, SharedLibraryInfoProvider).(SharedLibraryInfo)
+ depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
+ sharedLibraryStubsInfo := ctx.OtherModuleProvider(dep, SharedLibraryStubsProvider).(SharedLibraryStubsInfo)
+ apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+
+ if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedStubLibraries) > 0 {
+ useStubs := false
+
+ if lib := moduleLibraryInterface(dep); lib.buildStubs() && useVndk { // LLNDK
+ if !apexInfo.IsForPlatform() {
+ // For platform libraries, use current version of LLNDK
+ // If this is for use_vendor apex we will apply the same rules
+ // of apex sdk enforcement below to choose right version.
+ useStubs = true
+ }
+ } else if apexInfo.IsForPlatform() || apexInfo.UsePlatformApis {
+ // If not building for APEX or the containing APEX allows the use of
+ // platform APIs, use stubs only when it is from an APEX (and not from
+ // platform) However, for host, ramdisk, vendor_ramdisk, recovery or
+ // bootstrap modules, always link to non-stub variant
+ useStubs = dep.(android.ApexModule).NotInPlatform() && !bootstrap
+ if useStubs {
+ // Another exception: if this module is a test for an APEX, then
+ // it is linked with the non-stub variant of a module in the APEX
+ // as if this is part of the APEX.
+ testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
+ for _, apexContents := range testFor.ApexContents {
+ if apexContents.DirectlyInApex(depName) {
+ useStubs = false
+ break
+ }
+ }
+ }
+ if useStubs {
+ // Yet another exception: If this module and the dependency are
+ // available to the same APEXes then skip stubs between their
+ // platform variants. This complements the test_for case above,
+ // which avoids the stubs on a direct APEX library dependency, by
+ // avoiding stubs for indirect test dependencies as well.
+ //
+ // TODO(b/183882457): This doesn't work if the two libraries have
+ // only partially overlapping apex_available. For that test_for
+ // modules would need to be split into APEX variants and resolved
+ // separately for each APEX they have access to.
+ if android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
+ useStubs = false
+ }
+ }
+ } else {
+ // If building for APEX, use stubs when the parent is in any APEX that
+ // the child is not in.
+ useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
+ }
+
+ // when to use (unspecified) stubs, use the latest one.
+ if useStubs {
+ stubs := sharedLibraryStubsInfo.SharedStubLibraries
+ toUse := stubs[len(stubs)-1]
+ sharedLibraryInfo = toUse.SharedLibraryInfo
+ depExporterInfo = toUse.FlagExporterInfo
+ }
+ }
+ return sharedLibraryInfo, depExporterInfo
+}
+
// orderStaticModuleDeps rearranges the order of the static library dependencies of the module
// to match the topological order of the dependency tree, including any static analogues of
// direct shared libraries. It returns the ordered static dependencies, and an android.DepSet
@@ -2907,8 +2985,8 @@
transitiveStaticLibsBuilder.Transitive(staticDep.TransitiveStaticLibrariesForOrdering)
}
for _, sharedDep := range sharedDeps {
- if sharedDep.StaticAnalogue != nil {
- transitiveStaticLibsBuilder.Transitive(sharedDep.StaticAnalogue.TransitiveStaticLibrariesForOrdering)
+ if sharedDep.TransitiveStaticLibrariesForOrdering != nil {
+ transitiveStaticLibsBuilder.Transitive(sharedDep.TransitiveStaticLibrariesForOrdering)
}
}
transitiveStaticLibs := transitiveStaticLibsBuilder.Build()
@@ -2927,8 +3005,8 @@
return orderedStaticPaths, transitiveStaticLibs
}
-// baseLibName trims known prefixes and suffixes
-func baseLibName(depName string) string {
+// BaseLibName trims known prefixes and suffixes
+func BaseLibName(depName string) string {
libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
libName = android.RemoveOptionalPrebuiltPrefix(libName)
@@ -2936,7 +3014,7 @@
}
func MakeLibName(ctx android.ModuleContext, c LinkableInterface, ccDep LinkableInterface, depName string) string {
- libName := baseLibName(depName)
+ libName := BaseLibName(depName)
ccDepModule, _ := ccDep.(*Module)
isLLndk := ccDepModule != nil && ccDepModule.IsLlndk()
nonSystemVariantsExist := ccDep.HasNonSystemVariants() || isLLndk
@@ -2944,10 +3022,10 @@
if ccDepModule != nil {
// TODO(ivanlozano) Support snapshots for Rust-produced C library variants.
// Use base module name for snapshots when exporting to Makefile.
- if snapshotPrebuilt, ok := ccDepModule.linker.(snapshotInterface); ok {
+ if snapshotPrebuilt, ok := ccDepModule.linker.(SnapshotInterface); ok {
baseName := ccDepModule.BaseModuleName()
- return baseName + snapshotPrebuilt.snapshotAndroidMkSuffix()
+ return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix()
}
}
@@ -3079,6 +3157,13 @@
return false
}
+func (c *Module) StaticExecutable() bool {
+ if b, ok := c.linker.(*binaryDecorator); ok {
+ return b.static()
+ }
+ return false
+}
+
func (c *Module) Object() bool {
if o, ok := c.linker.(interface {
object() bool
@@ -3240,8 +3325,8 @@
return false
}
}
- if depTag == stubImplDepTag || depTag == llndkStubDepTag {
- // We don't track beyond LLNDK or from an implementation library to its stubs.
+ if depTag == stubImplDepTag {
+ // We don't track from an implementation library to its stubs.
return false
}
if depTag == staticVariantTag {
@@ -3366,7 +3451,7 @@
}
func (c *Module) IsSdkVariant() bool {
- return c.Properties.IsSdkVariant || c.AlwaysSdk()
+ return c.Properties.IsSdkVariant
}
func kytheExtractAllFactory() android.Singleton {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 5acafbe..84c3a86 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -152,71 +152,6 @@
).RunTest(t)
}
-func TestFuchsiaDeps(t *testing.T) {
- t.Helper()
-
- bp := `
- cc_library {
- name: "libTest",
- srcs: ["foo.c"],
- target: {
- fuchsia: {
- srcs: ["bar.c"],
- },
- },
- }`
-
- result := android.GroupFixturePreparers(
- prepareForCcTest,
- PrepareForTestOnFuchsia,
- ).RunTestWithBp(t, bp)
-
- rt := false
- fb := false
-
- ld := result.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
- implicits := ld.Implicits
- for _, lib := range implicits {
- if strings.Contains(lib.Rel(), "libcompiler_rt") {
- rt = true
- }
-
- if strings.Contains(lib.Rel(), "libbioniccompat") {
- fb = true
- }
- }
-
- if !rt || !fb {
- t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
- }
-}
-
-func TestFuchsiaTargetDecl(t *testing.T) {
- t.Helper()
-
- bp := `
- cc_library {
- name: "libTest",
- srcs: ["foo.c"],
- target: {
- fuchsia: {
- srcs: ["bar.c"],
- },
- },
- }`
-
- result := android.GroupFixturePreparers(
- prepareForCcTest,
- PrepareForTestOnFuchsia,
- ).RunTestWithBp(t, bp)
- ld := result.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
- var objs []string
- for _, o := range ld.Inputs {
- objs = append(objs, o.Base())
- }
- android.AssertArrayString(t, "libTest inputs", []string{"foo.o", "bar.o"}, objs)
-}
-
func TestVendorSrc(t *testing.T) {
ctx := testCc(t, `
cc_library {
@@ -396,50 +331,6 @@
}
}
-func checkSnapshotIncludeExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string, include bool, fake bool) {
- t.Helper()
- mod := ctx.ModuleForTests(moduleName, variant)
- outputFiles := mod.OutputFiles(t, "")
- if len(outputFiles) != 1 {
- t.Errorf("%q must have single output\n", moduleName)
- return
- }
- snapshotPath := filepath.Join(subDir, snapshotFilename)
-
- if include {
- out := singleton.Output(snapshotPath)
- if fake {
- if out.Rule == nil {
- t.Errorf("Missing rule for module %q output file %q", moduleName, outputFiles[0])
- }
- } else {
- if out.Input.String() != outputFiles[0].String() {
- t.Errorf("The input of snapshot %q must be %q, but %q", moduleName, out.Input.String(), outputFiles[0])
- }
- }
- } else {
- out := singleton.MaybeOutput(snapshotPath)
- if out.Rule != nil {
- t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0])
- }
- }
-}
-
-func checkSnapshot(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
- t.Helper()
- checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, false)
-}
-
-func checkSnapshotExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
- t.Helper()
- checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, false, false)
-}
-
-func checkSnapshotRule(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
- t.Helper()
- checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, true)
-}
-
func checkWriteFileOutput(t *testing.T, params android.TestingBuildParams, expected []string) {
t.Helper()
content := android.ContentFromFileRuleForTests(t, params)
@@ -631,21 +522,21 @@
snapshotSingleton := ctx.SingletonForTests("vndk-snapshot")
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd)
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLibPath, variant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLib2ndPath, variant2nd)
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd)
- checkSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLibPath, variant)
- checkSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLib2ndPath, variant2nd)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLibPath, variant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLib2ndPath, variant2nd)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLibPath, variant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLib2ndPath, variant2nd)
snapshotConfigsPath := filepath.Join(snapshotVariantPath, "configs")
- checkSnapshot(t, ctx, snapshotSingleton, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "")
- checkSnapshot(t, ctx, snapshotSingleton, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "")
- checkSnapshot(t, ctx, snapshotSingleton, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "")
- checkSnapshot(t, ctx, snapshotSingleton, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "")
- checkSnapshot(t, ctx, snapshotSingleton, "vndkproduct.libraries.txt", "vndkproduct.libraries.txt", snapshotConfigsPath, "")
+ CheckSnapshot(t, ctx, snapshotSingleton, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "")
+ CheckSnapshot(t, ctx, snapshotSingleton, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "")
+ CheckSnapshot(t, ctx, snapshotSingleton, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "")
+ CheckSnapshot(t, ctx, snapshotSingleton, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "")
+ CheckSnapshot(t, ctx, snapshotSingleton, "vndkproduct.libraries.txt", "vndkproduct.libraries.txt", snapshotConfigsPath, "")
checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
"LLNDK: libc.so",
@@ -2643,15 +2534,6 @@
return modulesInOrder, allDeps
}
-func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
- for _, moduleName := range moduleNames {
- module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
- output := module.outputFile.Path().RelativeToTop()
- paths = append(paths, output)
- }
- return paths
-}
-
func TestStaticLibDepReordering(t *testing.T) {
ctx := testCc(t, `
cc_library {
@@ -2679,7 +2561,7 @@
moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo).
TransitiveStaticLibrariesForOrdering.ToList().RelativeToTop()
- expected := getOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
+ expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
if !reflect.DeepEqual(actual, expected) {
t.Errorf("staticDeps orderings were not propagated correctly"+
@@ -2714,7 +2596,7 @@
moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo).
TransitiveStaticLibrariesForOrdering.ToList().RelativeToTop()
- expected := getOutputPaths(ctx, variant, []string{"a", "c", "b"})
+ expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
if !reflect.DeepEqual(actual, expected) {
t.Errorf("staticDeps orderings did not account for shared libs"+
@@ -2799,12 +2681,8 @@
}
}
expected := []string{
- "android_vendor.29_arm64_armv8-a_shared_1",
- "android_vendor.29_arm64_armv8-a_shared_2",
"android_vendor.29_arm64_armv8-a_shared_current",
"android_vendor.29_arm64_armv8-a_shared",
- "android_vendor.29_arm_armv7-a-neon_shared_1",
- "android_vendor.29_arm_armv7-a-neon_shared_2",
"android_vendor.29_arm_armv7-a-neon_shared_current",
"android_vendor.29_arm_armv7-a-neon_shared",
}
@@ -2813,9 +2691,6 @@
params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub")
android.AssertSame(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
- params = result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared_1").Description("generate stub")
- android.AssertSame(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
-
checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
t.Helper()
m := result.ModuleForTests(module, variant).Module()
@@ -3364,7 +3239,7 @@
mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
actual := mybin.Implicits[:2]
- expected := getOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
+ expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
if !reflect.DeepEqual(actual, expected) {
t.Errorf("staticDeps orderings were not propagated correctly"+
@@ -3722,305 +3597,6 @@
android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
}
-type MemtagNoteType int
-
-const (
- None MemtagNoteType = iota + 1
- Sync
- Async
-)
-
-func (t MemtagNoteType) str() string {
- switch t {
- case None:
- return "none"
- case Sync:
- return "sync"
- case Async:
- return "async"
- default:
- panic("invalid note type")
- }
-}
-
-func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) {
- note_async := "note_memtag_heap_async"
- note_sync := "note_memtag_heap_sync"
-
- found := None
- implicits := m.Rule("ld").Implicits
- for _, lib := range implicits {
- if strings.Contains(lib.Rel(), note_async) {
- found = Async
- break
- } else if strings.Contains(lib.Rel(), note_sync) {
- found = Sync
- break
- }
- }
-
- if found != expected {
- t.Errorf("Wrong Memtag note in target %q: found %q, expected %q", m.Module().(*Module).Name(), found.str(), expected.str())
- }
-}
-
-var prepareForTestWithMemtagHeap = android.GroupFixturePreparers(
- android.FixtureModifyMockFS(func(fs android.MockFS) {
- templateBp := `
- cc_test {
- name: "%[1]s_test",
- gtest: false,
- }
-
- cc_test {
- name: "%[1]s_test_false",
- gtest: false,
- sanitize: { memtag_heap: false },
- }
-
- cc_test {
- name: "%[1]s_test_true",
- gtest: false,
- sanitize: { memtag_heap: true },
- }
-
- cc_test {
- name: "%[1]s_test_true_nodiag",
- gtest: false,
- sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
- }
-
- cc_test {
- name: "%[1]s_test_true_diag",
- gtest: false,
- sanitize: { memtag_heap: true, diag: { memtag_heap: true } },
- }
-
- cc_binary {
- name: "%[1]s_binary",
- }
-
- cc_binary {
- name: "%[1]s_binary_false",
- sanitize: { memtag_heap: false },
- }
-
- cc_binary {
- name: "%[1]s_binary_true",
- sanitize: { memtag_heap: true },
- }
-
- cc_binary {
- name: "%[1]s_binary_true_nodiag",
- sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
- }
-
- cc_binary {
- name: "%[1]s_binary_true_diag",
- sanitize: { memtag_heap: true, diag: { memtag_heap: true } },
- }
- `
- subdirDefaultBp := fmt.Sprintf(templateBp, "default")
- subdirExcludeBp := fmt.Sprintf(templateBp, "exclude")
- subdirSyncBp := fmt.Sprintf(templateBp, "sync")
- subdirAsyncBp := fmt.Sprintf(templateBp, "async")
-
- fs.Merge(android.MockFS{
- "subdir_default/Android.bp": []byte(subdirDefaultBp),
- "subdir_exclude/Android.bp": []byte(subdirExcludeBp),
- "subdir_sync/Android.bp": []byte(subdirSyncBp),
- "subdir_async/Android.bp": []byte(subdirAsyncBp),
- })
- }),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.MemtagHeapExcludePaths = []string{"subdir_exclude"}
- // "subdir_exclude" is covered by both include and exclude paths. Exclude wins.
- variables.MemtagHeapSyncIncludePaths = []string{"subdir_sync", "subdir_exclude"}
- variables.MemtagHeapAsyncIncludePaths = []string{"subdir_async", "subdir_exclude"}
- }),
-)
-
-func TestSanitizeMemtagHeap(t *testing.T) {
- variant := "android_arm64_armv8-a"
-
- result := android.GroupFixturePreparers(
- prepareForCcTest,
- prepareForTestWithMemtagHeap,
- ).RunTest(t)
- ctx := result.TestContext
-
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
-}
-
-func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
- variant := "android_arm64_armv8-a"
-
- result := android.GroupFixturePreparers(
- prepareForCcTest,
- prepareForTestWithMemtagHeap,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.SanitizeDevice = []string{"memtag_heap"}
- }),
- ).RunTest(t)
- ctx := result.TestContext
-
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
-}
-
-func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
- variant := "android_arm64_armv8-a"
-
- result := android.GroupFixturePreparers(
- prepareForCcTest,
- prepareForTestWithMemtagHeap,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.SanitizeDevice = []string{"memtag_heap"}
- variables.SanitizeDeviceDiag = []string{"memtag_heap"}
- }),
- ).RunTest(t)
- ctx := result.TestContext
-
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
-
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
- checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
-}
-
func TestIncludeDirsExporting(t *testing.T) {
// Trim spaces from the beginning, end and immediately after any newline characters. Leaves
@@ -4291,3 +3867,155 @@
)
})
}
+
+func TestIncludeDirectoryOrdering(t *testing.T) {
+ bp := `
+ cc_library {
+ name: "libfoo",
+ srcs: ["foo.c"],
+ local_include_dirs: ["local_include_dirs"],
+ export_include_dirs: ["export_include_dirs"],
+ export_system_include_dirs: ["export_system_include_dirs"],
+ static_libs: ["libstatic1", "libstatic2"],
+ whole_static_libs: ["libwhole1", "libwhole2"],
+ shared_libs: ["libshared1", "libshared2"],
+ header_libs: ["libheader1", "libheader2"],
+ target: {
+ android: {
+ shared_libs: ["libandroid"],
+ local_include_dirs: ["android_local_include_dirs"],
+ export_include_dirs: ["android_export_include_dirs"],
+ },
+ android_arm: {
+ shared_libs: ["libandroid_arm"],
+ local_include_dirs: ["android_arm_local_include_dirs"],
+ export_include_dirs: ["android_arm_export_include_dirs"],
+ },
+ linux: {
+ shared_libs: ["liblinux"],
+ local_include_dirs: ["linux_local_include_dirs"],
+ export_include_dirs: ["linux_export_include_dirs"],
+ },
+ },
+ multilib: {
+ lib32: {
+ shared_libs: ["lib32"],
+ local_include_dirs: ["lib32_local_include_dirs"],
+ export_include_dirs: ["lib32_export_include_dirs"],
+ },
+ },
+ arch: {
+ arm: {
+ shared_libs: ["libarm"],
+ local_include_dirs: ["arm_local_include_dirs"],
+ export_include_dirs: ["arm_export_include_dirs"],
+ },
+ },
+ stl: "libc++",
+ sdk_version: "20",
+ }
+
+ cc_library_headers {
+ name: "libheader1",
+ export_include_dirs: ["libheader1"],
+ sdk_version: "20",
+ stl: "none",
+ }
+
+ cc_library_headers {
+ name: "libheader2",
+ export_include_dirs: ["libheader2"],
+ sdk_version: "20",
+ stl: "none",
+ }
+ `
+
+ libs := []string{
+ "libstatic1",
+ "libstatic2",
+ "libwhole1",
+ "libwhole2",
+ "libshared1",
+ "libshared2",
+ "libandroid",
+ "libandroid_arm",
+ "liblinux",
+ "lib32",
+ "libarm",
+ }
+
+ for _, lib := range libs {
+ bp += fmt.Sprintf(`
+ cc_library {
+ name: "%s",
+ export_include_dirs: ["%s"],
+ sdk_version: "20",
+ 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 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 78a5a5d..03214c8 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -92,7 +92,7 @@
// list of generated headers to add to the include path. These are the names
// of genrule modules.
- Generated_headers []string `android:"arch_variant"`
+ Generated_headers []string `android:"arch_variant,variant_prepend"`
// pass -frtti instead of -fno-rtti
Rtti *bool
@@ -189,6 +189,11 @@
// variant of the C/C++ module.
Cflags []string
}
+ Platform struct {
+ // List of additional cflags that should be used to build the platform
+ // variant of the C/C++ module.
+ Cflags []string
+ }
}
Proto struct {
@@ -310,6 +315,7 @@
CheckBadCompilerFlags(ctx, "product.cflags", compiler.Properties.Target.Product.Cflags)
CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
CheckBadCompilerFlags(ctx, "vendor_ramdisk.cflags", compiler.Properties.Target.Vendor_ramdisk.Cflags)
+ CheckBadCompilerFlags(ctx, "platform.cflags", compiler.Properties.Target.Platform.Cflags)
esc := proptools.NinjaAndShellEscapeList
@@ -392,7 +398,7 @@
if flags.RequiredInstructionSet != "" {
instructionSet = flags.RequiredInstructionSet
}
- instructionSetFlags, err := tc.ClangInstructionSetFlags(instructionSet)
+ instructionSetFlags, err := tc.InstructionSetFlags(instructionSet)
if err != nil {
ctx.ModuleErrorf("%s", err)
}
@@ -437,15 +443,15 @@
flags.Global.ConlyFlags = append([]string{"${config.CommonGlobalConlyflags}"}, flags.Global.ConlyFlags...)
flags.Global.CppFlags = append([]string{fmt.Sprintf("${config.%sGlobalCppflags}", hod)}, flags.Global.CppFlags...)
- flags.Global.AsFlags = append(flags.Global.AsFlags, tc.ClangAsflags())
- flags.Global.CppFlags = append([]string{"${config.CommonClangGlobalCppflags}"}, flags.Global.CppFlags...)
+ flags.Global.AsFlags = append(flags.Global.AsFlags, tc.Asflags())
+ flags.Global.CppFlags = append([]string{"${config.CommonGlobalCppflags}"}, flags.Global.CppFlags...)
flags.Global.CommonFlags = append(flags.Global.CommonFlags,
- tc.ClangCflags(),
- "${config.CommonClangGlobalCflags}",
- fmt.Sprintf("${config.%sClangGlobalCflags}", hod))
+ tc.Cflags(),
+ "${config.CommonGlobalCflags}",
+ fmt.Sprintf("${config.%sGlobalCflags}", hod))
- if isThirdParty(modulePath) {
- flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ClangExternalCflags}")
+ if android.IsThirdPartyPath(modulePath) {
+ flags.Global.CommonFlags = append(flags.Global.CommonFlags, "${config.ExternalCflags}")
}
if tc.Bionic() {
@@ -458,11 +464,11 @@
flags.Global.AsFlags = append(flags.Global.AsFlags, "-D__ASSEMBLY__")
- flags.Global.CppFlags = append(flags.Global.CppFlags, tc.ClangCppflags())
+ flags.Global.CppFlags = append(flags.Global.CppFlags, tc.Cppflags())
flags.Global.YasmFlags = append(flags.Global.YasmFlags, tc.YasmFlags())
- flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainClangCflags())
+ flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
cStd := config.CStdVersion
if String(compiler.Properties.C_std) == "experimental" {
@@ -502,6 +508,9 @@
if ctx.inVendorRamdisk() {
flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor_ramdisk.Cflags)...)
}
+ if !ctx.useSdk() {
+ flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Platform.Cflags)...)
+ }
// We can enforce some rules more strictly in the code we own. strict
// indicates if this is code that we can be stricter with. If we have
@@ -666,27 +675,6 @@
return transformSourceToObj(ctx, subdir, srcFiles, flags, pathDeps, cFlagsDeps)
}
-var thirdPartyDirPrefixExceptions = []*regexp.Regexp{
- regexp.MustCompile("^vendor/[^/]*google[^/]*/"),
- regexp.MustCompile("^hardware/google/"),
- regexp.MustCompile("^hardware/interfaces/"),
- regexp.MustCompile("^hardware/libhardware[^/]*/"),
- regexp.MustCompile("^hardware/ril/"),
-}
-
-func isThirdParty(path string) bool {
- thirdPartyDirPrefixes := []string{"external/", "vendor/", "hardware/"}
-
- if android.HasAnyPrefix(path, thirdPartyDirPrefixes) {
- for _, prefix := range thirdPartyDirPrefixExceptions {
- if prefix.MatchString(path) {
- return false
- }
- }
- }
- return true
-}
-
// Properties for rust_bindgen related to generating rust bindings.
// This exists here so these properties can be included in a cc_default
// which can be used in both cc and rust modules.
diff --git a/cc/compiler_test.go b/cc/compiler_test.go
index c301388..9ae4d18 100644
--- a/cc/compiler_test.go
+++ b/cc/compiler_test.go
@@ -16,27 +16,30 @@
import (
"testing"
+
+ "android/soong/android"
)
func TestIsThirdParty(t *testing.T) {
- shouldFail := []string{
+ thirdPartyPaths := []string{
"external/foo/",
"vendor/bar/",
"hardware/underwater_jaguar/",
}
- shouldPass := []string{
+ nonThirdPartyPaths := []string{
"vendor/google/cts/",
"hardware/google/pixel",
"hardware/interfaces/camera",
"hardware/ril/supa_ril",
+ "bionic/libc",
}
- for _, path := range shouldFail {
- if !isThirdParty(path) {
+ for _, path := range thirdPartyPaths {
+ if !android.IsThirdPartyPath(path) {
t.Errorf("Expected %s to be considered third party", path)
}
}
- for _, path := range shouldPass {
- if isThirdParty(path) {
+ for _, path := range nonThirdPartyPaths {
+ if android.IsThirdPartyPath(path) {
t.Errorf("Expected %s to *not* be considered third party", path)
}
}
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
index e4a8b62..3e8ee48 100644
--- a/cc/config/Android.bp
+++ b/cc/config/Android.bp
@@ -17,12 +17,12 @@
"toolchain.go",
"vndk.go",
+ "bionic.go",
+
"arm_device.go",
"arm64_device.go",
- "arm64_fuchsia_device.go",
"x86_device.go",
"x86_64_device.go",
- "x86_64_fuchsia_device.go",
"x86_darwin_host.go",
"x86_linux_host.go",
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 864fba1..812a245 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -48,12 +48,12 @@
"-Wl,-z,separate-code",
}
- arm64Lldflags = append(ClangFilterUnknownLldflags(arm64Ldflags),
+ arm64Lldflags = append(arm64Ldflags,
"-Wl,-z,max-page-size=4096")
arm64Cppflags = []string{}
- arm64ClangCpuVariantCflags = map[string][]string{
+ arm64CpuVariantCflags = map[string][]string{
"cortex-a53": []string{
"-mcpu=cortex-a53",
},
@@ -99,61 +99,60 @@
pctx.StaticVariable("Arm64Ldflags", strings.Join(arm64Ldflags, " "))
pctx.StaticVariable("Arm64Lldflags", strings.Join(arm64Lldflags, " "))
- pctx.StaticVariable("Arm64ClangCflags", strings.Join(ClangFilterUnknownCflags(arm64Cflags), " "))
- pctx.StaticVariable("Arm64ClangLdflags", strings.Join(ClangFilterUnknownCflags(arm64Ldflags), " "))
- pctx.StaticVariable("Arm64ClangLldflags", strings.Join(ClangFilterUnknownCflags(arm64Lldflags), " "))
- pctx.StaticVariable("Arm64ClangCppflags", strings.Join(ClangFilterUnknownCflags(arm64Cppflags), " "))
+ pctx.StaticVariable("Arm64Cflags", strings.Join(arm64Cflags, " "))
+ pctx.StaticVariable("Arm64Cppflags", strings.Join(arm64Cppflags, " "))
- pctx.StaticVariable("Arm64ClangArmv8ACflags", strings.Join(arm64ArchVariantCflags["armv8-a"], " "))
- pctx.StaticVariable("Arm64ClangArmv8ABranchProtCflags", strings.Join(arm64ArchVariantCflags["armv8-a-branchprot"], " "))
- pctx.StaticVariable("Arm64ClangArmv82ACflags", strings.Join(arm64ArchVariantCflags["armv8-2a"], " "))
- pctx.StaticVariable("Arm64ClangArmv82ADotprodCflags", strings.Join(arm64ArchVariantCflags["armv8-2a-dotprod"], " "))
+ pctx.StaticVariable("Arm64Armv8ACflags", strings.Join(arm64ArchVariantCflags["armv8-a"], " "))
+ pctx.StaticVariable("Arm64Armv8ABranchProtCflags", strings.Join(arm64ArchVariantCflags["armv8-a-branchprot"], " "))
+ pctx.StaticVariable("Arm64Armv82ACflags", strings.Join(arm64ArchVariantCflags["armv8-2a"], " "))
+ pctx.StaticVariable("Arm64Armv82ADotprodCflags", strings.Join(arm64ArchVariantCflags["armv8-2a-dotprod"], " "))
- pctx.StaticVariable("Arm64ClangCortexA53Cflags",
- strings.Join(arm64ClangCpuVariantCflags["cortex-a53"], " "))
+ pctx.StaticVariable("Arm64CortexA53Cflags",
+ strings.Join(arm64CpuVariantCflags["cortex-a53"], " "))
- pctx.StaticVariable("Arm64ClangCortexA55Cflags",
- strings.Join(arm64ClangCpuVariantCflags["cortex-a55"], " "))
+ pctx.StaticVariable("Arm64CortexA55Cflags",
+ strings.Join(arm64CpuVariantCflags["cortex-a55"], " "))
- pctx.StaticVariable("Arm64ClangKryoCflags",
- strings.Join(arm64ClangCpuVariantCflags["kryo"], " "))
+ pctx.StaticVariable("Arm64KryoCflags",
+ strings.Join(arm64CpuVariantCflags["kryo"], " "))
- pctx.StaticVariable("Arm64ClangExynosM1Cflags",
- strings.Join(arm64ClangCpuVariantCflags["exynos-m1"], " "))
+ pctx.StaticVariable("Arm64ExynosM1Cflags",
+ strings.Join(arm64CpuVariantCflags["exynos-m1"], " "))
- pctx.StaticVariable("Arm64ClangExynosM2Cflags",
- strings.Join(arm64ClangCpuVariantCflags["exynos-m2"], " "))
+ pctx.StaticVariable("Arm64ExynosM2Cflags",
+ strings.Join(arm64CpuVariantCflags["exynos-m2"], " "))
}
var (
- arm64ClangArchVariantCflagsVar = map[string]string{
- "armv8-a": "${config.Arm64ClangArmv8ACflags}",
- "armv8-a-branchprot": "${config.Arm64ClangArmv8ABranchProtCflags}",
- "armv8-2a": "${config.Arm64ClangArmv82ACflags}",
- "armv8-2a-dotprod": "${config.Arm64ClangArmv82ADotprodCflags}",
+ arm64ArchVariantCflagsVar = map[string]string{
+ "armv8-a": "${config.Arm64Armv8ACflags}",
+ "armv8-a-branchprot": "${config.Arm64Armv8ABranchProtCflags}",
+ "armv8-2a": "${config.Arm64Armv82ACflags}",
+ "armv8-2a-dotprod": "${config.Arm64Armv82ADotprodCflags}",
}
- arm64ClangCpuVariantCflagsVar = map[string]string{
+ arm64CpuVariantCflagsVar = map[string]string{
"": "",
- "cortex-a53": "${config.Arm64ClangCortexA53Cflags}",
- "cortex-a55": "${config.Arm64ClangCortexA55Cflags}",
- "cortex-a72": "${config.Arm64ClangCortexA53Cflags}",
- "cortex-a73": "${config.Arm64ClangCortexA53Cflags}",
- "cortex-a75": "${config.Arm64ClangCortexA55Cflags}",
- "cortex-a76": "${config.Arm64ClangCortexA55Cflags}",
- "kryo": "${config.Arm64ClangKryoCflags}",
- "kryo385": "${config.Arm64ClangCortexA53Cflags}",
- "exynos-m1": "${config.Arm64ClangExynosM1Cflags}",
- "exynos-m2": "${config.Arm64ClangExynosM2Cflags}",
+ "cortex-a53": "${config.Arm64CortexA53Cflags}",
+ "cortex-a55": "${config.Arm64CortexA55Cflags}",
+ "cortex-a72": "${config.Arm64CortexA53Cflags}",
+ "cortex-a73": "${config.Arm64CortexA53Cflags}",
+ "cortex-a75": "${config.Arm64CortexA55Cflags}",
+ "cortex-a76": "${config.Arm64CortexA55Cflags}",
+ "kryo": "${config.Arm64KryoCflags}",
+ "kryo385": "${config.Arm64CortexA53Cflags}",
+ "exynos-m1": "${config.Arm64ExynosM1Cflags}",
+ "exynos-m2": "${config.Arm64ExynosM2Cflags}",
}
)
type toolchainArm64 struct {
+ toolchainBionic
toolchain64Bit
- ldflags string
- lldflags string
- toolchainClangCflags string
+ ldflags string
+ lldflags string
+ toolchainCflags string
}
func (t *toolchainArm64) Name() string {
@@ -180,24 +179,24 @@
return t.GccTriple()
}
-func (t *toolchainArm64) ClangCflags() string {
- return "${config.Arm64ClangCflags}"
+func (t *toolchainArm64) Cflags() string {
+ return "${config.Arm64Cflags}"
}
-func (t *toolchainArm64) ClangCppflags() string {
- return "${config.Arm64ClangCppflags}"
+func (t *toolchainArm64) Cppflags() string {
+ return "${config.Arm64Cppflags}"
}
-func (t *toolchainArm64) ClangLdflags() string {
+func (t *toolchainArm64) Ldflags() string {
return t.ldflags
}
-func (t *toolchainArm64) ClangLldflags() string {
+func (t *toolchainArm64) Lldflags() string {
return t.lldflags
}
-func (t *toolchainArm64) ToolchainClangCflags() string {
- return t.toolchainClangCflags
+func (t *toolchainArm64) ToolchainCflags() string {
+ return t.toolchainCflags
}
func (toolchainArm64) LibclangRuntimeLibraryArch() string {
@@ -215,9 +214,9 @@
panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant))
}
- toolchainClangCflags := []string{arm64ClangArchVariantCflagsVar[arch.ArchVariant]}
- toolchainClangCflags = append(toolchainClangCflags,
- variantOrDefault(arm64ClangCpuVariantCflagsVar, arch.CpuVariant))
+ toolchainCflags := []string{arm64ArchVariantCflagsVar[arch.ArchVariant]}
+ toolchainCflags = append(toolchainCflags,
+ variantOrDefault(arm64CpuVariantCflagsVar, arch.CpuVariant))
var extraLdflags string
switch arch.CpuVariant {
@@ -234,7 +233,7 @@
"${config.Arm64Lldflags}",
extraLdflags,
}, " "),
- toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
+ toolchainCflags: strings.Join(toolchainCflags, " "),
}
}
diff --git a/cc/config/arm64_fuchsia_device.go b/cc/config/arm64_fuchsia_device.go
deleted file mode 100644
index 02c0c14..0000000
--- a/cc/config/arm64_fuchsia_device.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2018 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 config
-
-import (
- "android/soong/android"
-)
-
-var fuchsiaArm64SysRoot string = "prebuilts/fuchsia_sdk/arch/arm64/sysroot"
-var fuchsiaArm64PrebuiltLibsRoot string = "fuchsia/prebuilt_libs/"
-
-type toolchainFuchsiaArm64 struct {
- toolchain64Bit
- toolchainFuchsia
-}
-
-func (t *toolchainFuchsiaArm64) Name() string {
- return "arm64"
-}
-
-func (t *toolchainFuchsiaArm64) GccRoot() string {
- return "${config.Arm64GccRoot}"
-}
-
-func (t *toolchainFuchsiaArm64) GccTriple() string {
- return "aarch64-linux-android"
-}
-
-func (t *toolchainFuchsiaArm64) GccVersion() string {
- return arm64GccVersion
-}
-
-func (t *toolchainFuchsiaArm64) Cflags() string {
- return ""
-}
-
-func (t *toolchainFuchsiaArm64) Cppflags() string {
- return ""
-}
-
-func (t *toolchainFuchsiaArm64) Ldflags() string {
- return "-Wl,--fix-cortex-a53-843419"
-}
-
-func (t *toolchainFuchsiaArm64) IncludeFlags() string {
- return ""
-}
-
-func (t *toolchainFuchsiaArm64) ToolchainCflags() string {
- return "-mcpu=cortex-a53"
-}
-
-func (t *toolchainFuchsiaArm64) ClangTriple() string {
- return "arm64-fuchsia-android"
-}
-
-func (t *toolchainFuchsiaArm64) ClangCppflags() string {
- return "-Wno-error=deprecated-declarations"
-}
-
-func (t *toolchainFuchsiaArm64) ClangLdflags() string {
- return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -L" + fuchsiaArm64PrebuiltLibsRoot + "/aarch64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/arm64/dist/"
-}
-
-func (t *toolchainFuchsiaArm64) ClangLldflags() string {
- return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -L" + fuchsiaArm64PrebuiltLibsRoot + "/aarch64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/arm64/dist/"
-}
-
-func (t *toolchainFuchsiaArm64) ClangCflags() string {
- return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -I" + fuchsiaArm64SysRoot + "/include"
-}
-
-func (t *toolchainFuchsiaArm64) Bionic() bool {
- return false
-}
-
-func (t *toolchainFuchsiaArm64) ToolchainClangCflags() string {
- return "-march=armv8-a"
-}
-
-var toolchainArm64FuchsiaSingleton Toolchain = &toolchainFuchsiaArm64{}
-
-func arm64FuchsiaToolchainFactory(arch android.Arch) Toolchain {
- return toolchainArm64FuchsiaSingleton
-}
-
-func init() {
- registerToolchainFactory(android.Fuchsia, android.Arm64, arm64FuchsiaToolchainFactory)
-}
diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go
index 59c52d1..853d818 100644
--- a/cc/config/arm64_linux_host.go
+++ b/cc/config/arm64_linux_host.go
@@ -15,14 +15,15 @@
package config
import (
- "android/soong/android"
"strings"
+
+ "android/soong/android"
)
var (
// This is a host toolchain but flags for device toolchain are required
// as the flags are actually for Bionic-based builds.
- linuxCrossCflags = ClangFilterUnknownCflags(append(deviceGlobalCflags,
+ linuxCrossCflags = append(deviceGlobalCflags,
// clang by default enables PIC when the clang triple is set to *-android.
// See toolchain/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp#920.
// However, for this host target, we don't set "-android" to avoid __ANDROID__ macro
@@ -33,9 +34,9 @@
// This is normally in ClangExtraTargetCflags, but that's for device and we need
// the same for host
"-nostdlibinc",
- ))
+ )
- linuxCrossLdflags = ClangFilterUnknownCflags([]string{
+ linuxCrossLdflags = []string{
"-Wl,-z,noexecstack",
"-Wl,-z,relro",
"-Wl,-z,now",
@@ -44,7 +45,17 @@
"-Wl,--fatal-warnings",
"-Wl,--hash-style=gnu",
"-Wl,--no-undefined-version",
- })
+ }
+
+ // Embed the linker into host bionic binaries. This is needed to support host bionic,
+ // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be
+ // either an absolute path, or relative from CWD. To work around this, we extract
+ // the load sections from the runtime linker ELF binary and embed them into each host
+ // bionic binary, omitting the PT_INTERP declaration. The kernel will treat it as a static
+ // binary, and then we use a special entry point to fix up the arguments passed by
+ // the kernel before jumping to the embedded linker.
+ linuxArm64CrtBeginSharedBinary = append(android.CopyOf(bionicCrtBeginSharedBinary),
+ "host_bionic_linker_script")
)
func init() {
@@ -63,14 +74,18 @@
return "aarch64-linux"
}
-func (toolchainLinuxArm64) ClangCflags() string {
+func (toolchainLinuxArm64) Cflags() string {
// The inherited flags + extra flags
- return "${config.Arm64ClangCflags} ${config.LinuxBionicArm64Cflags}"
+ return "${config.Arm64Cflags} ${config.LinuxBionicArm64Cflags}"
+}
+
+func (toolchainLinuxArm64) CrtBeginSharedBinary() []string {
+ return linuxArm64CrtBeginSharedBinary
}
func linuxArm64ToolchainFactory(arch android.Arch) Toolchain {
archVariant := "armv8-a" // for host, default to armv8-a
- toolchainClangCflags := []string{arm64ClangArchVariantCflagsVar[archVariant]}
+ toolchainCflags := []string{arm64ArchVariantCflagsVar[archVariant]}
// We don't specify CPU architecture for host. Conservatively assume
// the host CPU needs the fix
@@ -89,7 +104,7 @@
"${config.LinuxBionicArm64Ldflags}",
extraLdflags,
}, " ")
- ret.toolchainArm64.toolchainClangCflags = strings.Join(toolchainClangCflags, " ")
+ ret.toolchainArm64.toolchainCflags = strings.Join(toolchainCflags, " ")
return &ret
}
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index a402f8f..b5afe40 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -23,7 +23,6 @@
var (
armToolchainCflags = []string{
- "-mthumb-interwork",
"-msoft-float",
}
@@ -38,7 +37,7 @@
"-Wl,-m,armelf",
}
- armLldflags = ClangFilterUnknownLldflags(armLdflags)
+ armLldflags = armLdflags
armArmCflags = []string{
"-fstrict-aliasing",
@@ -49,7 +48,7 @@
"-Os",
}
- armClangArchVariantCflags = map[string][]string{
+ armArchVariantCflags = map[string][]string{
"armv7-a": []string{
"-march=armv7-a",
"-mfloat-abi=softfp",
@@ -72,7 +71,7 @@
},
}
- armClangCpuVariantCflags = map[string][]string{
+ armCpuVariantCflags = map[string][]string{
"cortex-a7": []string{
"-mcpu=cortex-a7",
"-mfpu=neon-vfpv4",
@@ -163,95 +162,87 @@
)
const (
+ name = "arm"
armGccVersion = "4.9"
+ gccTriple = "arm-linux-androideabi"
+ clangTriple = "armv7a-linux-androideabi"
)
func init() {
pctx.StaticVariable("armGccVersion", armGccVersion)
- pctx.SourcePathVariable("ArmGccRoot",
- "prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}")
+ pctx.SourcePathVariable("ArmGccRoot", "prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}")
- pctx.StaticVariable("ArmLdflags", strings.Join(armLdflags, " "))
- pctx.StaticVariable("ArmLldflags", strings.Join(armLldflags, " "))
+ // Just exported. Not created as a Ninja static variable.
+ exportedStringVars.Set("ArmClangTriple", clangTriple)
+
+ exportStringListStaticVariable("ArmLdflags", armLdflags)
+ exportStringListStaticVariable("ArmLldflags", armLldflags)
// Clang cflags
- pctx.StaticVariable("ArmToolchainClangCflags", strings.Join(ClangFilterUnknownCflags(armToolchainCflags), " "))
- pctx.StaticVariable("ArmClangCflags", strings.Join(ClangFilterUnknownCflags(armCflags), " "))
- pctx.StaticVariable("ArmClangLdflags", strings.Join(ClangFilterUnknownCflags(armLdflags), " "))
- pctx.StaticVariable("ArmClangLldflags", strings.Join(ClangFilterUnknownCflags(armLldflags), " "))
- pctx.StaticVariable("ArmClangCppflags", strings.Join(ClangFilterUnknownCflags(armCppflags), " "))
+ exportStringListStaticVariable("ArmToolchainCflags", armToolchainCflags)
+ exportStringListStaticVariable("ArmCflags", armCflags)
+ exportStringListStaticVariable("ArmCppflags", armCppflags)
// Clang ARM vs. Thumb instruction set cflags
- pctx.StaticVariable("ArmClangArmCflags", strings.Join(ClangFilterUnknownCflags(armArmCflags), " "))
- pctx.StaticVariable("ArmClangThumbCflags", strings.Join(ClangFilterUnknownCflags(armThumbCflags), " "))
+ exportStringListStaticVariable("ArmArmCflags", armArmCflags)
+ exportStringListStaticVariable("ArmThumbCflags", armThumbCflags)
// Clang arch variant cflags
- pctx.StaticVariable("ArmClangArmv7ACflags",
- strings.Join(armClangArchVariantCflags["armv7-a"], " "))
- pctx.StaticVariable("ArmClangArmv7ANeonCflags",
- strings.Join(armClangArchVariantCflags["armv7-a-neon"], " "))
- pctx.StaticVariable("ArmClangArmv8ACflags",
- strings.Join(armClangArchVariantCflags["armv8-a"], " "))
- pctx.StaticVariable("ArmClangArmv82ACflags",
- strings.Join(armClangArchVariantCflags["armv8-2a"], " "))
+ exportStringListStaticVariable("ArmArmv7ACflags", armArchVariantCflags["armv7-a"])
+ exportStringListStaticVariable("ArmArmv7ANeonCflags", armArchVariantCflags["armv7-a-neon"])
+ exportStringListStaticVariable("ArmArmv8ACflags", armArchVariantCflags["armv8-a"])
+ exportStringListStaticVariable("ArmArmv82ACflags", armArchVariantCflags["armv8-2a"])
// Clang cpu variant cflags
- pctx.StaticVariable("ArmClangGenericCflags",
- strings.Join(armClangCpuVariantCflags[""], " "))
- pctx.StaticVariable("ArmClangCortexA7Cflags",
- strings.Join(armClangCpuVariantCflags["cortex-a7"], " "))
- pctx.StaticVariable("ArmClangCortexA8Cflags",
- strings.Join(armClangCpuVariantCflags["cortex-a8"], " "))
- pctx.StaticVariable("ArmClangCortexA15Cflags",
- strings.Join(armClangCpuVariantCflags["cortex-a15"], " "))
- pctx.StaticVariable("ArmClangCortexA53Cflags",
- strings.Join(armClangCpuVariantCflags["cortex-a53"], " "))
- pctx.StaticVariable("ArmClangCortexA55Cflags",
- strings.Join(armClangCpuVariantCflags["cortex-a55"], " "))
- pctx.StaticVariable("ArmClangKraitCflags",
- strings.Join(armClangCpuVariantCflags["krait"], " "))
- pctx.StaticVariable("ArmClangKryoCflags",
- strings.Join(armClangCpuVariantCflags["kryo"], " "))
+ exportStringListStaticVariable("ArmGenericCflags", armCpuVariantCflags[""])
+ exportStringListStaticVariable("ArmCortexA7Cflags", armCpuVariantCflags["cortex-a7"])
+ exportStringListStaticVariable("ArmCortexA8Cflags", armCpuVariantCflags["cortex-a8"])
+ exportStringListStaticVariable("ArmCortexA15Cflags", armCpuVariantCflags["cortex-a15"])
+ exportStringListStaticVariable("ArmCortexA53Cflags", armCpuVariantCflags["cortex-a53"])
+ exportStringListStaticVariable("ArmCortexA55Cflags", armCpuVariantCflags["cortex-a55"])
+ exportStringListStaticVariable("ArmKraitCflags", armCpuVariantCflags["krait"])
+ exportStringListStaticVariable("ArmKryoCflags", armCpuVariantCflags["kryo"])
}
var (
- armClangArchVariantCflagsVar = map[string]string{
- "armv7-a": "${config.ArmClangArmv7ACflags}",
- "armv7-a-neon": "${config.ArmClangArmv7ANeonCflags}",
- "armv8-a": "${config.ArmClangArmv8ACflags}",
- "armv8-2a": "${config.ArmClangArmv82ACflags}",
+ armArchVariantCflagsVar = map[string]string{
+ "armv7-a": "${config.ArmArmv7ACflags}",
+ "armv7-a-neon": "${config.ArmArmv7ANeonCflags}",
+ "armv8-a": "${config.ArmArmv8ACflags}",
+ "armv8-2a": "${config.ArmArmv82ACflags}",
}
- armClangCpuVariantCflagsVar = map[string]string{
- "": "${config.ArmClangGenericCflags}",
- "cortex-a7": "${config.ArmClangCortexA7Cflags}",
- "cortex-a8": "${config.ArmClangCortexA8Cflags}",
- "cortex-a15": "${config.ArmClangCortexA15Cflags}",
- "cortex-a53": "${config.ArmClangCortexA53Cflags}",
- "cortex-a53.a57": "${config.ArmClangCortexA53Cflags}",
- "cortex-a55": "${config.ArmClangCortexA55Cflags}",
- "cortex-a72": "${config.ArmClangCortexA53Cflags}",
- "cortex-a73": "${config.ArmClangCortexA53Cflags}",
- "cortex-a75": "${config.ArmClangCortexA55Cflags}",
- "cortex-a76": "${config.ArmClangCortexA55Cflags}",
- "krait": "${config.ArmClangKraitCflags}",
- "kryo": "${config.ArmClangKryoCflags}",
- "kryo385": "${config.ArmClangCortexA53Cflags}",
- "exynos-m1": "${config.ArmClangCortexA53Cflags}",
- "exynos-m2": "${config.ArmClangCortexA53Cflags}",
+ armCpuVariantCflagsVar = map[string]string{
+ "": "${config.ArmGenericCflags}",
+ "cortex-a7": "${config.ArmCortexA7Cflags}",
+ "cortex-a8": "${config.ArmCortexA8Cflags}",
+ "cortex-a15": "${config.ArmCortexA15Cflags}",
+ "cortex-a53": "${config.ArmCortexA53Cflags}",
+ "cortex-a53.a57": "${config.ArmCortexA53Cflags}",
+ "cortex-a55": "${config.ArmCortexA55Cflags}",
+ "cortex-a72": "${config.ArmCortexA53Cflags}",
+ "cortex-a73": "${config.ArmCortexA53Cflags}",
+ "cortex-a75": "${config.ArmCortexA55Cflags}",
+ "cortex-a76": "${config.ArmCortexA55Cflags}",
+ "krait": "${config.ArmKraitCflags}",
+ "kryo": "${config.ArmKryoCflags}",
+ "kryo385": "${config.ArmCortexA53Cflags}",
+ "exynos-m1": "${config.ArmCortexA53Cflags}",
+ "exynos-m2": "${config.ArmCortexA53Cflags}",
}
)
type toolchainArm struct {
+ toolchainBionic
toolchain32Bit
- ldflags string
- lldflags string
- toolchainClangCflags string
+ ldflags string
+ lldflags string
+ toolchainCflags string
}
func (t *toolchainArm) Name() string {
- return "arm"
+ return name
}
func (t *toolchainArm) GccRoot() string {
@@ -259,7 +250,7 @@
}
func (t *toolchainArm) GccTriple() string {
- return "arm-linux-androideabi"
+ return gccTriple
}
func (t *toolchainArm) GccVersion() string {
@@ -272,7 +263,7 @@
func (t *toolchainArm) ClangTriple() string {
// http://b/72619014 work around llvm LTO bug.
- return "armv7a-linux-androideabi"
+ return clangTriple
}
func (t *toolchainArm) ndkTriple() string {
@@ -280,50 +271,50 @@
return t.GccTriple()
}
-func (t *toolchainArm) ToolchainClangCflags() string {
- return t.toolchainClangCflags
+func (t *toolchainArm) ToolchainCflags() string {
+ return t.toolchainCflags
}
-func (t *toolchainArm) ClangCflags() string {
- return "${config.ArmClangCflags}"
+func (t *toolchainArm) Cflags() string {
+ return "${config.ArmCflags}"
}
-func (t *toolchainArm) ClangCppflags() string {
- return "${config.ArmClangCppflags}"
+func (t *toolchainArm) Cppflags() string {
+ return "${config.ArmCppflags}"
}
-func (t *toolchainArm) ClangLdflags() string {
+func (t *toolchainArm) Ldflags() string {
return t.ldflags
}
-func (t *toolchainArm) ClangLldflags() string {
+func (t *toolchainArm) Lldflags() string {
return t.lldflags // TODO: handle V8 cases
}
-func (t *toolchainArm) ClangInstructionSetFlags(isa string) (string, error) {
+func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) {
switch isa {
case "arm":
- return "${config.ArmClangArmCflags}", nil
+ return "${config.ArmArmCflags}", nil
case "thumb", "":
- return "${config.ArmClangThumbCflags}", nil
+ return "${config.ArmThumbCflags}", nil
default:
- return t.toolchainBase.ClangInstructionSetFlags(isa)
+ return t.toolchainBase.InstructionSetFlags(isa)
}
}
func (toolchainArm) LibclangRuntimeLibraryArch() string {
- return "arm"
+ return name
}
func armToolchainFactory(arch android.Arch) Toolchain {
var fixCortexA8 string
- toolchainClangCflags := make([]string, 2, 3)
+ toolchainCflags := make([]string, 2, 3)
- toolchainClangCflags[0] = "${config.ArmToolchainClangCflags}"
- toolchainClangCflags[1] = armClangArchVariantCflagsVar[arch.ArchVariant]
+ toolchainCflags[0] = "${config.ArmToolchainCflags}"
+ toolchainCflags[1] = armArchVariantCflagsVar[arch.ArchVariant]
- toolchainClangCflags = append(toolchainClangCflags,
- variantOrDefault(armClangCpuVariantCflagsVar, arch.CpuVariant))
+ toolchainCflags = append(toolchainCflags,
+ variantOrDefault(armCpuVariantCflagsVar, arch.CpuVariant))
switch arch.ArchVariant {
case "armv7-a-neon":
@@ -347,8 +338,8 @@
"${config.ArmLdflags}",
fixCortexA8,
}, " "),
- lldflags: "${config.ArmLldflags}",
- toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
+ lldflags: "${config.ArmLldflags}",
+ toolchainCflags: strings.Join(toolchainCflags, " "),
}
}
diff --git a/cc/config/bionic.go b/cc/config/bionic.go
new file mode 100644
index 0000000..e87f571
--- /dev/null
+++ b/cc/config/bionic.go
@@ -0,0 +1,37 @@
+// Copyright 2015 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 config
+
+type toolchainBionic struct {
+}
+
+var (
+ bionicDefaultSharedLibraries = []string{"libc", "libm", "libdl"}
+
+ bionicCrtBeginStaticBinary, bionicCrtEndStaticBinary = []string{"crtbegin_static"}, []string{"crtend_android"}
+ bionicCrtBeginSharedBinary, bionicCrtEndSharedBinary = []string{"crtbegin_dynamic"}, []string{"crtend_android"}
+ bionicCrtBeginSharedLibrary, bionicCrtEndSharedLibrary = []string{"crtbegin_so"}, []string{"crtend_so"}
+)
+
+func (toolchainBionic) Bionic() bool { return true }
+
+func (toolchainBionic) DefaultSharedLibraries() []string { return bionicDefaultSharedLibraries }
+
+func (toolchainBionic) CrtBeginStaticBinary() []string { return bionicCrtBeginStaticBinary }
+func (toolchainBionic) CrtBeginSharedBinary() []string { return bionicCrtBeginSharedBinary }
+func (toolchainBionic) CrtBeginSharedLibrary() []string { return bionicCrtBeginSharedLibrary }
+func (toolchainBionic) CrtEndStaticBinary() []string { return bionicCrtEndStaticBinary }
+func (toolchainBionic) CrtEndSharedBinary() []string { return bionicCrtEndSharedBinary }
+func (toolchainBionic) CrtEndSharedLibrary() []string { return bionicCrtEndSharedLibrary }
diff --git a/cc/config/bp2build.go b/cc/config/bp2build.go
index 16892e6..e7e94a8 100644
--- a/cc/config/bp2build.go
+++ b/cc/config/bp2build.go
@@ -22,29 +22,34 @@
)
// Helpers for exporting cc configuration information to Bazel.
-
var (
// Map containing toolchain variables that are independent of the
// environment variables of the build.
- exportedVars = exportedVariablesMap{}
+ exportedStringListVars = exportedStringListVariables{}
+ exportedStringVars = exportedStringVariables{}
)
-// variableValue is a string slice because the exported variables are all lists
-// of string, and it's simpler to manipulate string lists before joining them
-// into their final string representation.
-type variableValue []string
+type exportedStringVariables map[string]string
+type exportedStringListVariables map[string][]string
-// envDependentVariable is a toolchain variable computed based on an environment variable.
-type exportedVariablesMap map[string]variableValue
-
-func (m exportedVariablesMap) Set(k string, v variableValue) {
+func (m exportedStringVariables) Set(k string, v string) {
m[k] = v
}
// Convenience function to declare a static variable and export it to Bazel's cc_toolchain.
-func staticVariableExportedToBazel(name string, value []string) {
+func exportStringStaticVariable(name string, value string) {
+ pctx.StaticVariable(name, value)
+ exportedStringVars.Set(name, value)
+}
+
+func (m exportedStringListVariables) Set(k string, v []string) {
+ m[k] = v
+}
+
+// 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, " "))
- exportedVars.Set(name, variableValue(value))
+ exportedStringListVars.Set(name, value)
}
// BazelCcToolchainVars generates bzl file content containing variables for
@@ -64,12 +69,12 @@
// For each exported variable, recursively expand elements in the variableValue
// list to ensure that interpolated variables are expanded according to their values
- // in the exportedVars scope.
- for _, k := range android.SortedStringKeys(exportedVars) {
- variableValue := exportedVars[k]
+ // in the variable scope.
+ for _, k := range android.SortedStringKeys(exportedStringListVars) {
+ variableValue := exportedStringListVars[k]
var expandedVars []string
for _, v := range variableValue {
- expandedVars = append(expandedVars, expandVar(v, exportedVars)...)
+ expandedVars = append(expandedVars, expandVar(v, exportedStringVars, exportedStringListVars)...)
}
// Build the list for this variable.
list := "["
@@ -83,9 +88,22 @@
ret += "\n"
}
+ for _, k := range android.SortedStringKeys(exportedStringVars) {
+ variableValue := exportedStringVars[k]
+ expandedVar := expandVar(variableValue, exportedStringVars, exportedStringListVars)
+ if len(expandedVar) > 1 {
+ panic(fmt.Errorf("%s expands to more than one string value: %s", variableValue, expandedVar))
+ }
+ ret += fmt.Sprintf("_%s = \"%s\"\n", k, validateCharacters(expandedVar[0]))
+ ret += "\n"
+ }
+
// Build the exported constants struct.
ret += "constants = struct(\n"
- for _, k := range android.SortedStringKeys(exportedVars) {
+ for _, k := range android.SortedStringKeys(exportedStringVars) {
+ ret += fmt.Sprintf(" %s = _%s,\n", k, k)
+ }
+ for _, k := range android.SortedStringKeys(exportedStringListVars) {
ret += fmt.Sprintf(" %s = _%s,\n", k, k)
}
ret += ")"
@@ -99,8 +117,8 @@
// 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, exportedVars map[string]variableValue) []string {
- // e.g. "${ClangExternalCflags}"
+func expandVar(toExpand string, stringScope exportedStringVariables, stringListScope exportedStringListVariables) []string {
+ // e.g. "${ExternalCflags}"
r := regexp.MustCompile(`\${([a-zA-Z0-9_]+)}`)
// Internal recursive function.
@@ -136,8 +154,11 @@
newSeenVars[k] = true
}
newSeenVars[variable] = true
- unexpandedVars := exportedVars[variable]
- for _, unexpandedVar := range unexpandedVars {
+ if unexpandedVars, ok := stringListScope[variable]; ok {
+ for _, unexpandedVar := range unexpandedVars {
+ ret = append(ret, expandVarInternal(unexpandedVar, newSeenVars)...)
+ }
+ } else if unexpandedVar, ok := stringScope[variable]; ok {
ret = append(ret, expandVarInternal(unexpandedVar, newSeenVars)...)
}
}
diff --git a/cc/config/bp2build_test.go b/cc/config/bp2build_test.go
index 7744b4b..a4745e6 100644
--- a/cc/config/bp2build_test.go
+++ b/cc/config/bp2build_test.go
@@ -20,54 +20,80 @@
func TestExpandVars(t *testing.T) {
testCases := []struct {
- description string
- exportedVars map[string]variableValue
- toExpand string
- expectedValues []string
+ description string
+ stringScope exportedStringVariables
+ stringListScope exportedStringListVariables
+ toExpand string
+ expectedValues []string
}{
{
- description: "single level expansion",
- exportedVars: map[string]variableValue{
- "foo": variableValue([]string{"bar"}),
+ description: "no expansion for non-interpolated value",
+ toExpand: "foo",
+ expectedValues: []string{"foo"},
+ },
+ {
+ description: "single level expansion for string var",
+ stringScope: exportedStringVariables{
+ "foo": "bar",
},
toExpand: "${foo}",
expectedValues: []string{"bar"},
},
{
+ description: "single level expansion string list var",
+ stringListScope: exportedStringListVariables{
+ "foo": []string{"bar"},
+ },
+ toExpand: "${foo}",
+ expectedValues: []string{"bar"},
+ },
+ {
+ description: "mixed level expansion for string list var",
+ stringScope: exportedStringVariables{
+ "foo": "${bar}",
+ "qux": "hello",
+ },
+ stringListScope: exportedStringListVariables{
+ "bar": []string{"baz", "${qux}"},
+ },
+ toExpand: "${foo}",
+ expectedValues: []string{"baz", "hello"},
+ },
+ {
description: "double level expansion",
- exportedVars: map[string]variableValue{
- "foo": variableValue([]string{"${bar}"}),
- "bar": variableValue([]string{"baz"}),
+ stringListScope: exportedStringListVariables{
+ "foo": []string{"${bar}"},
+ "bar": []string{"baz"},
},
toExpand: "${foo}",
expectedValues: []string{"baz"},
},
{
description: "double level expansion with a literal",
- exportedVars: map[string]variableValue{
- "a": variableValue([]string{"${b}", "c"}),
- "b": variableValue([]string{"d"}),
+ stringListScope: exportedStringListVariables{
+ "a": []string{"${b}", "c"},
+ "b": []string{"d"},
},
toExpand: "${a}",
expectedValues: []string{"d", "c"},
},
{
description: "double level expansion, with two variables in a string",
- exportedVars: map[string]variableValue{
- "a": variableValue([]string{"${b} ${c}"}),
- "b": variableValue([]string{"d"}),
- "c": variableValue([]string{"e"}),
+ stringListScope: exportedStringListVariables{
+ "a": []string{"${b} ${c}"},
+ "b": []string{"d"},
+ "c": []string{"e"},
},
toExpand: "${a}",
expectedValues: []string{"d", "e"},
},
{
description: "triple level expansion with two variables in a string",
- exportedVars: map[string]variableValue{
- "a": variableValue([]string{"${b} ${c}"}),
- "b": variableValue([]string{"${c}", "${d}"}),
- "c": variableValue([]string{"${d}"}),
- "d": variableValue([]string{"foo"}),
+ stringListScope: exportedStringListVariables{
+ "a": []string{"${b} ${c}"},
+ "b": []string{"${c}", "${d}"},
+ "c": []string{"${d}"},
+ "d": []string{"foo"},
},
toExpand: "${a}",
expectedValues: []string{"foo", "foo", "foo"},
@@ -76,7 +102,7 @@
for _, testCase := range testCases {
t.Run(testCase.description, func(t *testing.T) {
- output := expandVar(testCase.toExpand, testCase.exportedVars)
+ output := expandVar(testCase.toExpand, testCase.stringScope, testCase.stringListScope)
if len(output) != len(testCase.expectedValues) {
t.Errorf("Expected %d values, got %d", len(testCase.expectedValues), len(output))
}
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 4fbb9c3..53a7306 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -15,9 +15,10 @@
package config
import (
- "android/soong/android"
"sort"
"strings"
+
+ "android/soong/android"
)
// Cflags that should be filtered out when compiling with clang
@@ -80,12 +81,6 @@
"--enable-stdcall-fixup",
})
-// Ldflags that should be filtered out when linking with clang lld
-var ClangUnknownLldflags = sorted([]string{
- "-Wl,--fix-cortex-a8",
- "-Wl,--no-fix-cortex-a8",
-})
-
var ClangLibToolingUnknownCflags = sorted([]string{})
// List of tidy checks that should be disabled globally. When the compiler is
@@ -97,138 +92,6 @@
"readability-function-cognitive-complexity", // http://b/175055536
}
-func init() {
- staticVariableExportedToBazel("ClangExtraCflags", []string{
- "-D__compiler_offsetof=__builtin_offsetof",
-
- // Emit address-significance table which allows linker to perform safe ICF. Clang does
- // not emit the table by default on Android since NDK still uses GNU binutils.
- "-faddrsig",
-
- // Turn on -fcommon explicitly, since Clang now defaults to -fno-common. The cleanup bug
- // tracking this is http://b/151457797.
- "-fcommon",
-
- // Help catch common 32/64-bit errors.
- "-Werror=int-conversion",
-
- // Enable the new pass manager.
- "-fexperimental-new-pass-manager",
-
- // Disable overly aggressive warning for macros defined with a leading underscore
- // This happens in AndroidConfig.h, which is included nearly everywhere.
- // 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",
-
- // Warnings from clang-7.0
- "-Wno-sign-compare",
-
- // Warnings from clang-8.0
- "-Wno-defaulted-function-deleted",
-
- // Disable -Winconsistent-missing-override until we can clean up the existing
- // codebase for it.
- "-Wno-inconsistent-missing-override",
-
- // Warnings from clang-10
- // Nested and array designated initialization is nice to have.
- "-Wno-c99-designator",
-
- // Warnings from clang-12
- "-Wno-gnu-folding-constant",
-
- // Calls to the APIs that are newer than the min sdk version of the caller should be
- // guarded with __builtin_available.
- "-Wunguarded-availability",
- // This macro allows the bionic versioning.h to indirectly determine whether the
- // option -Wunguarded-availability is on or not.
- "-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__",
- })
-
- staticVariableExportedToBazel("ClangExtraCppflags", []string{
- // -Wimplicit-fallthrough is not enabled by -Wall.
- "-Wimplicit-fallthrough",
-
- // Enable clang's thread-safety annotations in libcxx.
- "-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS",
-
- // libc++'s math.h has an #include_next outside of system_headers.
- "-Wno-gnu-include-next",
- })
-
- staticVariableExportedToBazel("ClangExtraTargetCflags", []string{"-nostdlibinc"})
-
- staticVariableExportedToBazel("ClangExtraNoOverrideCflags", []string{
- "-Werror=address-of-temporary",
- // Bug: http://b/29823425 Disable -Wnull-dereference until the
- // new cases detected by this warning in Clang r271374 are
- // fixed.
- //"-Werror=null-dereference",
- "-Werror=return-type",
-
- // http://b/72331526 Disable -Wtautological-* until the instances detected by these
- // new warnings are fixed.
- "-Wno-tautological-constant-compare",
- "-Wno-tautological-type-limit-compare",
- // http://b/145210666
- "-Wno-reorder-init-list",
- // http://b/145211066
- "-Wno-implicit-int-float-conversion",
- // New warnings to be fixed after clang-r377782.
- "-Wno-int-in-bool-context", // http://b/148287349
- "-Wno-sizeof-array-div", // http://b/148815709
- "-Wno-tautological-overlap-compare", // http://b/148815696
- // New warnings to be fixed after clang-r383902.
- "-Wno-deprecated-copy", // http://b/153746672
- "-Wno-range-loop-construct", // http://b/153747076
- "-Wno-misleading-indentation", // http://b/153746954
- "-Wno-zero-as-null-pointer-constant", // http://b/68236239
- "-Wno-deprecated-anon-enum-enum-conversion", // http://b/153746485
- "-Wno-deprecated-enum-enum-conversion", // http://b/153746563
- "-Wno-string-compare", // http://b/153764102
- "-Wno-enum-enum-conversion", // http://b/154138986
- "-Wno-enum-float-conversion", // http://b/154255917
- "-Wno-pessimizing-move", // http://b/154270751
- // New warnings to be fixed after clang-r399163
- "-Wno-non-c-typedef-for-linkage", // http://b/161304145
- // New warnings to be fixed after clang-r407598
- "-Wno-string-concatenation", // http://b/175068488
- })
-
- // Extra cflags for external third-party projects to disable warnings that
- // are infeasible to fix in all the external projects and their upstream repos.
- staticVariableExportedToBazel("ClangExtraExternalCflags", []string{
- "-Wno-enum-compare",
- "-Wno-enum-compare-switch",
-
- // http://b/72331524 Allow null pointer arithmetic until the instances detected by
- // this new warning are fixed.
- "-Wno-null-pointer-arithmetic",
-
- // Bug: http://b/29823425 Disable -Wnull-dereference until the
- // new instances detected by this warning are fixed.
- "-Wno-null-dereference",
-
- // http://b/145211477
- "-Wno-pointer-compare",
- // http://b/145211022
- "-Wno-xor-used-as-pow",
- // http://b/145211022
- "-Wno-final-dtor-non-final-class",
-
- // http://b/165945989
- "-Wno-psabi",
- })
-}
-
func ClangFilterUnknownCflags(cflags []string) []string {
result, _ := android.FilterList(cflags, ClangUnknownCflags)
return result
@@ -255,26 +118,10 @@
return result
}
-func ClangFilterUnknownLldflags(lldflags []string) []string {
- result, _ := android.FilterList(lldflags, ClangUnknownLldflags)
- return result
-}
-
func ClangLibToolingFilterUnknownCflags(libToolingFlags []string) []string {
return android.RemoveListFromList(libToolingFlags, ClangLibToolingUnknownCflags)
}
-func inListSorted(s string, list []string) bool {
- for _, l := range list {
- if s == l {
- return true
- } else if s < l {
- return false
- }
- }
- return false
-}
-
func sorted(list []string) []string {
sort.Strings(list)
return list
diff --git a/cc/config/global.go b/cc/config/global.go
index ae731b2..3daee38 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -15,6 +15,7 @@
package config
import (
+ "runtime"
"strings"
"android/soong/android"
@@ -36,7 +37,6 @@
// Make paths in deps files relative
"-no-canonical-prefixes",
- "-fno-canonical-system-headers",
"-DNDEBUG",
"-UDEBUG",
@@ -55,13 +55,64 @@
"-Werror=pragma-pack-suspicious-include",
"-Werror=string-plus-int",
"-Werror=unreachable-code-loop-increment",
+
+ "-D__compiler_offsetof=__builtin_offsetof",
+
+ // Emit address-significance table which allows linker to perform safe ICF. Clang does
+ // not emit the table by default on Android since NDK still uses GNU binutils.
+ "-faddrsig",
+
+ // Turn on -fcommon explicitly, since Clang now defaults to -fno-common. The cleanup bug
+ // tracking this is http://b/151457797.
+ "-fcommon",
+
+ // Help catch common 32/64-bit errors.
+ "-Werror=int-conversion",
+
+ // Enable the new pass manager.
+ "-fexperimental-new-pass-manager",
+
+ // Disable overly aggressive warning for macros defined with a leading underscore
+ // This happens in AndroidConfig.h, which is included nearly everywhere.
+ // 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",
+
+ // Warnings from clang-7.0
+ "-Wno-sign-compare",
+
+ // Warnings from clang-8.0
+ "-Wno-defaulted-function-deleted",
+
+ // Disable -Winconsistent-missing-override until we can clean up the existing
+ // codebase for it.
+ "-Wno-inconsistent-missing-override",
+
+ // Warnings from clang-10
+ // Nested and array designated initialization is nice to have.
+ "-Wno-c99-designator",
+
+ // Warnings from clang-12
+ "-Wno-gnu-folding-constant",
+
+ // Calls to the APIs that are newer than the min sdk version of the caller should be
+ // guarded with __builtin_available.
+ "-Wunguarded-availability",
+ // This macro allows the bionic versioning.h to indirectly determine whether the
+ // option -Wunguarded-availability is on or not.
+ "-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__",
}
commonGlobalConlyflags = []string{}
deviceGlobalCflags = []string{
- "-fdiagnostics-color",
-
"-ffunction-sections",
"-fdata-sections",
"-fno-short-enums",
@@ -77,6 +128,7 @@
"-Werror=address",
"-Werror=sequence-point",
"-Werror=format-security",
+ "-nostdlibinc",
}
deviceGlobalCppflags = []string{
@@ -100,7 +152,7 @@
"-Wl,--icf=safe",
}
- deviceGlobalLldflags = append(ClangFilterUnknownLldflags(deviceGlobalLdflags),
+ deviceGlobalLldflags = append(deviceGlobalLdflags,
[]string{
"-fuse-ld=lld",
}...)
@@ -115,6 +167,15 @@
commonGlobalCppflags = []string{
"-Wsign-promo",
+
+ // -Wimplicit-fallthrough is not enabled by -Wall.
+ "-Wimplicit-fallthrough",
+
+ // Enable clang's thread-safety annotations in libcxx.
+ "-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS",
+
+ // libc++'s math.h has an #include_next outside of system_headers.
+ "-Wno-gnu-include-next",
}
noOverrideGlobalCflags = []string{
@@ -132,6 +193,66 @@
// http://b/161386391 for -Wno-pointer-to-int-cast
"-Wno-pointer-to-int-cast",
"-Werror=fortify-source",
+
+ "-Werror=address-of-temporary",
+ // Bug: http://b/29823425 Disable -Wnull-dereference until the
+ // new cases detected by this warning in Clang r271374 are
+ // fixed.
+ //"-Werror=null-dereference",
+ "-Werror=return-type",
+
+ // http://b/72331526 Disable -Wtautological-* until the instances detected by these
+ // new warnings are fixed.
+ "-Wno-tautological-constant-compare",
+ "-Wno-tautological-type-limit-compare",
+ // http://b/145210666
+ "-Wno-reorder-init-list",
+ // http://b/145211066
+ "-Wno-implicit-int-float-conversion",
+ // New warnings to be fixed after clang-r377782.
+ "-Wno-int-in-bool-context", // http://b/148287349
+ "-Wno-sizeof-array-div", // http://b/148815709
+ "-Wno-tautological-overlap-compare", // http://b/148815696
+ // New warnings to be fixed after clang-r383902.
+ "-Wno-deprecated-copy", // http://b/153746672
+ "-Wno-range-loop-construct", // http://b/153747076
+ "-Wno-misleading-indentation", // http://b/153746954
+ "-Wno-zero-as-null-pointer-constant", // http://b/68236239
+ "-Wno-deprecated-anon-enum-enum-conversion", // http://b/153746485
+ "-Wno-deprecated-enum-enum-conversion", // http://b/153746563
+ "-Wno-string-compare", // http://b/153764102
+ "-Wno-enum-enum-conversion", // http://b/154138986
+ "-Wno-enum-float-conversion", // http://b/154255917
+ "-Wno-pessimizing-move", // http://b/154270751
+ // New warnings to be fixed after clang-r399163
+ "-Wno-non-c-typedef-for-linkage", // http://b/161304145
+ // New warnings to be fixed after clang-r407598
+ "-Wno-string-concatenation", // http://b/175068488
+ }
+
+ // Extra cflags for external third-party projects to disable warnings that
+ // are infeasible to fix in all the external projects and their upstream repos.
+ extraExternalCflags = []string{
+ "-Wno-enum-compare",
+ "-Wno-enum-compare-switch",
+
+ // http://b/72331524 Allow null pointer arithmetic until the instances detected by
+ // this new warning are fixed.
+ "-Wno-null-pointer-arithmetic",
+
+ // Bug: http://b/29823425 Disable -Wnull-dereference until the
+ // new instances detected by this warning are fixed.
+ "-Wno-null-dereference",
+
+ // http://b/145211477
+ "-Wno-pointer-compare",
+ // http://b/145211022
+ "-Wno-xor-used-as-pow",
+ // http://b/145211022
+ "-Wno-final-dtor-non-final-class",
+
+ // http://b/165945989
+ "-Wno-psabi",
}
IllegalFlags = []string{
@@ -161,33 +282,31 @@
var pctx = android.NewPackageContext("android/soong/cc/config")
func init() {
- if android.BuildOs == android.Linux {
+ if runtime.GOOS == "linux" {
commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
}
- staticVariableExportedToBazel("CommonGlobalConlyflags", commonGlobalConlyflags)
- staticVariableExportedToBazel("DeviceGlobalCppflags", deviceGlobalCppflags)
- staticVariableExportedToBazel("DeviceGlobalLdflags", deviceGlobalLdflags)
- staticVariableExportedToBazel("DeviceGlobalLldflags", deviceGlobalLldflags)
- staticVariableExportedToBazel("HostGlobalCppflags", hostGlobalCppflags)
- staticVariableExportedToBazel("HostGlobalLdflags", hostGlobalLdflags)
- staticVariableExportedToBazel("HostGlobalLldflags", hostGlobalLldflags)
+ exportStringListStaticVariable("CommonGlobalConlyflags", commonGlobalConlyflags)
+ exportStringListStaticVariable("DeviceGlobalCppflags", deviceGlobalCppflags)
+ exportStringListStaticVariable("DeviceGlobalLdflags", deviceGlobalLdflags)
+ exportStringListStaticVariable("DeviceGlobalLldflags", deviceGlobalLldflags)
+ exportStringListStaticVariable("HostGlobalCppflags", hostGlobalCppflags)
+ exportStringListStaticVariable("HostGlobalLdflags", hostGlobalLdflags)
+ exportStringListStaticVariable("HostGlobalLldflags", hostGlobalLldflags)
- // Export the static default CommonClangGlobalCflags to Bazel.
+ // Export the static default CommonGlobalCflags to Bazel.
// TODO(187086342): handle cflags that are set in VariableFuncs.
- commonClangGlobalCFlags := append(
- ClangFilterUnknownCflags(commonGlobalCflags),
+ bazelCommonGlobalCflags := append(
+ commonGlobalCflags,
[]string{
- "${ClangExtraCflags}",
// Default to zero initialization.
"-ftrivial-auto-var-init=zero",
"-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang",
}...)
- exportedVars.Set("CommonClangGlobalCflags", variableValue(commonClangGlobalCFlags))
+ exportedStringListVars.Set("CommonGlobalCflags", bazelCommonGlobalCflags)
- pctx.VariableFunc("CommonClangGlobalCflags", func(ctx android.PackageVarContext) string {
- flags := ClangFilterUnknownCflags(commonGlobalCflags)
- flags = append(flags, "${ClangExtraCflags}")
+ pctx.VariableFunc("CommonGlobalCflags", func(ctx android.PackageVarContext) string {
+ flags := commonGlobalCflags
// http://b/131390872
// Automatically initialize any uninitialized stack variables.
@@ -205,38 +324,34 @@
return strings.Join(flags, " ")
})
- // Export the static default DeviceClangGlobalCflags to Bazel.
+ // Export the static default DeviceGlobalCflags to Bazel.
// TODO(187086342): handle cflags that are set in VariableFuncs.
- deviceClangGlobalCflags := append(ClangFilterUnknownCflags(deviceGlobalCflags), "${ClangExtraTargetCflags}")
- exportedVars.Set("DeviceClangGlobalCflags", variableValue(deviceClangGlobalCflags))
+ exportedStringListVars.Set("DeviceGlobalCflags", deviceGlobalCflags)
- pctx.VariableFunc("DeviceClangGlobalCflags", func(ctx android.PackageVarContext) string {
- if ctx.Config().Fuchsia() {
- return strings.Join(ClangFilterUnknownCflags(deviceGlobalCflags), " ")
- } else {
- return strings.Join(deviceClangGlobalCflags, " ")
- }
+ pctx.VariableFunc("DeviceGlobalCflags", func(ctx android.PackageVarContext) string {
+ return strings.Join(deviceGlobalCflags, " ")
})
- staticVariableExportedToBazel("HostClangGlobalCflags", ClangFilterUnknownCflags(hostGlobalCflags))
- staticVariableExportedToBazel("NoOverrideClangGlobalCflags", append(ClangFilterUnknownCflags(noOverrideGlobalCflags), "${ClangExtraNoOverrideCflags}"))
- staticVariableExportedToBazel("CommonClangGlobalCppflags", append(ClangFilterUnknownCflags(commonGlobalCppflags), "${ClangExtraCppflags}"))
- staticVariableExportedToBazel("ClangExternalCflags", []string{"${ClangExtraExternalCflags}"})
+ exportStringListStaticVariable("HostGlobalCflags", hostGlobalCflags)
+ exportStringListStaticVariable("NoOverrideGlobalCflags", noOverrideGlobalCflags)
+ exportStringListStaticVariable("CommonGlobalCppflags", commonGlobalCppflags)
+ exportStringListStaticVariable("ExternalCflags", extraExternalCflags)
// Everything in these lists is a crime against abstraction and dependency tracking.
// Do not add anything to this list.
- pctx.PrefixedExistentPathsForSourcesVariable("CommonGlobalIncludes", "-I",
- []string{
- "system/core/include",
- "system/logging/liblog/include",
- "system/media/audio/include",
- "hardware/libhardware/include",
- "hardware/libhardware_legacy/include",
- "hardware/ril/include",
- "frameworks/native/include",
- "frameworks/native/opengl/include",
- "frameworks/av/include",
- })
+ commonGlobalIncludes := []string{
+ "system/core/include",
+ "system/logging/liblog/include",
+ "system/media/audio/include",
+ "hardware/libhardware/include",
+ "hardware/libhardware_legacy/include",
+ "hardware/ril/include",
+ "frameworks/native/include",
+ "frameworks/native/opengl/include",
+ "frameworks/av/include",
+ }
+ exportedStringListVars.Set("CommonGlobalIncludes", commonGlobalIncludes)
+ pctx.PrefixedExistentPathsForSourcesVariable("CommonGlobalIncludes", "-I", commonGlobalIncludes)
pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase)
pctx.VariableFunc("ClangBase", func(ctx android.PackageVarContext) string {
@@ -293,12 +408,3 @@
}
var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
-
-func envOverrideFunc(envVar, defaultVal string) func(ctx android.PackageVarContext) string {
- return func(ctx android.PackageVarContext) string {
- if override := ctx.Config().Getenv(envVar); override != "" {
- return override
- }
- return defaultVal
- }
-}
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index fce28c1..20384a8 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -82,14 +82,14 @@
IncludeFlags() string
ClangTriple() string
- ToolchainClangCflags() string
- ToolchainClangLdflags() string
- ClangAsflags() string
- ClangCflags() string
- ClangCppflags() string
- ClangLdflags() string
- ClangLldflags() string
- ClangInstructionSetFlags(string) (string, error)
+ ToolchainCflags() string
+ ToolchainLdflags() string
+ Asflags() string
+ Cflags() string
+ Cppflags() string
+ Ldflags() string
+ Lldflags() string
+ InstructionSetFlags(string) (string, error)
ndkTriple() string
@@ -106,7 +106,20 @@
AvailableLibraries() []string
+ CrtBeginStaticBinary() []string
+ CrtBeginSharedBinary() []string
+ CrtBeginSharedLibrary() []string
+ CrtEndStaticBinary() []string
+ CrtEndSharedBinary() []string
+ CrtEndSharedLibrary() []string
+
+ // DefaultSharedLibraries returns the list of shared libraries that will be added to all
+ // targets unless they explicitly specify system_shared_libs.
+ DefaultSharedLibraries() []string
+
Bionic() bool
+ Glibc() bool
+ Musl() bool
}
type toolchainBase struct {
@@ -125,18 +138,18 @@
return triple
}
-func (toolchainBase) ClangInstructionSetFlags(s string) (string, error) {
+func (toolchainBase) InstructionSetFlags(s string) (string, error) {
if s != "" {
return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s)
}
return "", nil
}
-func (toolchainBase) ToolchainClangCflags() string {
+func (toolchainBase) ToolchainCflags() string {
return ""
}
-func (toolchainBase) ToolchainClangLdflags() string {
+func (toolchainBase) ToolchainLdflags() string {
return ""
}
@@ -148,7 +161,7 @@
return ""
}
-func (toolchainBase) ClangAsflags() string {
+func (toolchainBase) Asflags() string {
return ""
}
@@ -165,11 +178,30 @@
}
func (toolchainBase) AvailableLibraries() []string {
- return []string{}
+ return nil
+}
+
+func (toolchainBase) CrtBeginStaticBinary() []string { return nil }
+func (toolchainBase) CrtBeginSharedBinary() []string { return nil }
+func (toolchainBase) CrtBeginSharedLibrary() []string { return nil }
+func (toolchainBase) CrtEndStaticBinary() []string { return nil }
+func (toolchainBase) CrtEndSharedBinary() []string { return nil }
+func (toolchainBase) CrtEndSharedLibrary() []string { return nil }
+
+func (toolchainBase) DefaultSharedLibraries() []string {
+ return nil
}
func (toolchainBase) Bionic() bool {
- return true
+ return false
+}
+
+func (toolchainBase) Glibc() bool {
+ return false
+}
+
+func (toolchainBase) Musl() bool {
+ return false
}
func (t toolchainBase) ToolPath() string {
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 2894f89..1dfdc2d 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -19,55 +19,74 @@
// has VndkUseCoreVariant set.
// TODO(b/150578172): clean up unstable and non-versioned aidl module
var VndkMustUseVendorVariantList = []string{
- "android.hardware.authsecret-unstable-ndk_platform",
- "android.hardware.authsecret-ndk_platform",
+ "android.hardware.authsecret-V1-ndk",
"android.hardware.authsecret-V1-ndk_platform",
- "android.hardware.automotive.occupant_awareness-ndk_platform",
+ "android.hardware.authsecret-ndk_platform",
+ "android.hardware.authsecret-unstable-ndk_platform",
+ "android.hardware.automotive.occupant_awareness-V1-ndk",
"android.hardware.automotive.occupant_awareness-V1-ndk_platform",
- "android.hardware.gnss-unstable-ndk_platform",
- "android.hardware.gnss-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.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.light-V1-ndk_platform",
- "android.hardware.light-ndk_platform",
"android.hardware.identity-V2-ndk_platform",
+ "android.hardware.identity-V3-ndk",
"android.hardware.identity-V3-ndk_platform",
"android.hardware.identity-ndk_platform",
- "android.hardware.nfc@1.2",
+ "android.hardware.light-V1-ndk",
+ "android.hardware.light-V1-ndk_platform",
+ "android.hardware.light-ndk_platform",
+ "android.hardware.memtrack-V1-ndk",
"android.hardware.memtrack-V1-ndk_platform",
"android.hardware.memtrack-ndk_platform",
"android.hardware.memtrack-unstable-ndk_platform",
+ "android.hardware.nfc@1.2",
+ "android.hardware.oemlock-V1-ndk",
"android.hardware.oemlock-V1-ndk_platform",
"android.hardware.oemlock-ndk_platform",
"android.hardware.oemlock-unstable-ndk_platform",
"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",
"android.hardware.power.stats-ndk_platform",
"android.hardware.power.stats-unstable-ndk_platform",
+ "android.hardware.rebootescrow-V1-ndk",
"android.hardware.rebootescrow-V1-ndk_platform",
"android.hardware.rebootescrow-ndk_platform",
+ "android.hardware.security.keymint-V1-ndk",
"android.hardware.security.keymint-V1-ndk_platform",
"android.hardware.security.keymint-ndk_platform",
"android.hardware.security.keymint-unstable-ndk_platform",
+ "android.hardware.security.secureclock-V1-ndk",
"android.hardware.security.secureclock-V1-ndk_platform",
- "android.hardware.security.secureclock-unstable-ndk_platform",
"android.hardware.security.secureclock-ndk_platform",
+ "android.hardware.security.secureclock-unstable-ndk_platform",
+ "android.hardware.security.sharedsecret-V1-ndk",
"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_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.system.keystore2-V1-ndk_platform",
"android.system.keystore2-ndk_platform",
"android.system.keystore2-unstable-ndk_platform",
+ "android.system.suspend-V1-ndk_platform",
"libbinder",
"libcrypto",
"libexpat",
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index 1e25a3b..c4f47a7 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -32,8 +32,6 @@
"-Wl,--hash-style=gnu",
}
- x86_64Lldflags = ClangFilterUnknownLldflags(x86_64Ldflags)
-
x86_64ArchVariantCflags = map[string][]string{
"": []string{
"-march=x86-64",
@@ -102,13 +100,11 @@
pctx.StaticVariable("X86_64ToolchainLdflags", "-m64")
pctx.StaticVariable("X86_64Ldflags", strings.Join(x86_64Ldflags, " "))
- pctx.StaticVariable("X86_64Lldflags", strings.Join(x86_64Lldflags, " "))
+ pctx.StaticVariable("X86_64Lldflags", strings.Join(x86_64Ldflags, " "))
// Clang cflags
- pctx.StaticVariable("X86_64ClangCflags", strings.Join(ClangFilterUnknownCflags(x86_64Cflags), " "))
- pctx.StaticVariable("X86_64ClangLdflags", strings.Join(ClangFilterUnknownCflags(x86_64Ldflags), " "))
- pctx.StaticVariable("X86_64ClangLldflags", strings.Join(ClangFilterUnknownCflags(x86_64Lldflags), " "))
- pctx.StaticVariable("X86_64ClangCppflags", strings.Join(ClangFilterUnknownCflags(x86_64Cppflags), " "))
+ pctx.StaticVariable("X86_64Cflags", strings.Join(x86_64Cflags, " "))
+ pctx.StaticVariable("X86_64Cppflags", strings.Join(x86_64Cppflags, " "))
// Yasm flags
pctx.StaticVariable("X86_64YasmFlags", "-f elf64 -m amd64")
@@ -117,14 +113,15 @@
// Architecture variant cflags
for variant, cflags := range x86_64ArchVariantCflags {
- pctx.StaticVariable("X86_64"+variant+"VariantClangCflags",
- strings.Join(ClangFilterUnknownCflags(cflags), " "))
+ pctx.StaticVariable("X86_64"+variant+"VariantCflags",
+ strings.Join(cflags, " "))
}
}
type toolchainX86_64 struct {
+ toolchainBionic
toolchain64Bit
- toolchainClangCflags string
+ toolchainCflags string
}
func (t *toolchainX86_64) Name() string {
@@ -151,27 +148,27 @@
return t.GccTriple()
}
-func (t *toolchainX86_64) ToolchainClangLdflags() string {
+func (t *toolchainX86_64) ToolchainLdflags() string {
return "${config.X86_64ToolchainLdflags}"
}
-func (t *toolchainX86_64) ToolchainClangCflags() string {
- return t.toolchainClangCflags
+func (t *toolchainX86_64) ToolchainCflags() string {
+ return t.toolchainCflags
}
-func (t *toolchainX86_64) ClangCflags() string {
- return "${config.X86_64ClangCflags}"
+func (t *toolchainX86_64) Cflags() string {
+ return "${config.X86_64Cflags}"
}
-func (t *toolchainX86_64) ClangCppflags() string {
- return "${config.X86_64ClangCppflags}"
+func (t *toolchainX86_64) Cppflags() string {
+ return "${config.X86_64Cppflags}"
}
-func (t *toolchainX86_64) ClangLdflags() string {
+func (t *toolchainX86_64) Ldflags() string {
return "${config.X86_64Ldflags}"
}
-func (t *toolchainX86_64) ClangLldflags() string {
+func (t *toolchainX86_64) Lldflags() string {
return "${config.X86_64Lldflags}"
}
@@ -184,17 +181,17 @@
}
func x86_64ToolchainFactory(arch android.Arch) Toolchain {
- toolchainClangCflags := []string{
+ toolchainCflags := []string{
"${config.X86_64ToolchainCflags}",
- "${config.X86_64" + arch.ArchVariant + "VariantClangCflags}",
+ "${config.X86_64" + arch.ArchVariant + "VariantCflags}",
}
for _, feature := range arch.ArchFeatures {
- toolchainClangCflags = append(toolchainClangCflags, x86_64ArchFeatureCflags[feature]...)
+ toolchainCflags = append(toolchainCflags, x86_64ArchFeatureCflags[feature]...)
}
return &toolchainX86_64{
- toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
+ toolchainCflags: strings.Join(toolchainCflags, " "),
}
}
diff --git a/cc/config/x86_64_fuchsia_device.go b/cc/config/x86_64_fuchsia_device.go
deleted file mode 100644
index 0f2013b..0000000
--- a/cc/config/x86_64_fuchsia_device.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2018 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 config
-
-import (
- "android/soong/android"
-)
-
-var fuchsiaSysRoot string = "prebuilts/fuchsia_sdk/arch/x64/sysroot"
-var fuchsiaPrebuiltLibsRoot string = "fuchsia/prebuilt_libs"
-
-type toolchainFuchsia struct {
- cFlags, ldFlags string
-}
-
-type toolchainFuchsiaX8664 struct {
- toolchain64Bit
- toolchainFuchsia
-}
-
-func (t *toolchainFuchsiaX8664) Name() string {
- return "x86_64"
-}
-
-func (t *toolchainFuchsiaX8664) GccRoot() string {
- return "${config.X86_64GccRoot}"
-}
-
-func (t *toolchainFuchsiaX8664) GccTriple() string {
- return "x86_64-linux-android"
-}
-
-func (t *toolchainFuchsiaX8664) GccVersion() string {
- return x86_64GccVersion
-}
-
-func (t *toolchainFuchsiaX8664) Cflags() string {
- return ""
-}
-
-func (t *toolchainFuchsiaX8664) Cppflags() string {
- return ""
-}
-
-func (t *toolchainFuchsiaX8664) Ldflags() string {
- return ""
-}
-
-func (t *toolchainFuchsiaX8664) IncludeFlags() string {
- return ""
-}
-
-func (t *toolchainFuchsiaX8664) ClangTriple() string {
- return "x86_64-fuchsia-android"
-}
-
-func (t *toolchainFuchsiaX8664) ClangCppflags() string {
- return "-Wno-error=deprecated-declarations"
-}
-
-func (t *toolchainFuchsiaX8664) ClangLdflags() string {
- return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -L" + fuchsiaPrebuiltLibsRoot + "/x86_64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/x64/dist/"
-
-}
-
-func (t *toolchainFuchsiaX8664) ClangLldflags() string {
- return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -L" + fuchsiaPrebuiltLibsRoot + "/x86_64-fuchsia/lib " + "-Lprebuilts/fuchsia_sdk/arch/x64/dist/"
-}
-
-func (t *toolchainFuchsiaX8664) ClangCflags() string {
- return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -I" + fuchsiaSysRoot + "/include"
-}
-
-func (t *toolchainFuchsiaX8664) Bionic() bool {
- return false
-}
-
-func (t *toolchainFuchsiaX8664) YasmFlags() string {
- return "-f elf64 -m amd64"
-}
-
-func (t *toolchainFuchsiaX8664) ToolchainClangCflags() string {
- return "-mssse3"
-}
-
-var toolchainFuchsiaSingleton Toolchain = &toolchainFuchsiaX8664{}
-
-func fuchsiaToolchainFactory(arch android.Arch) Toolchain {
- return toolchainFuchsiaSingleton
-}
-
-func init() {
- registerToolchainFactory(android.Fuchsia, android.X86_64, fuchsiaToolchainFactory)
-}
diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go
index b0344af..0bb1a81 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -26,8 +26,6 @@
var (
darwinCflags = []string{
- "-fdiagnostics-color",
-
"-fPIC",
"-funwind-tables",
@@ -41,6 +39,9 @@
"-DMACOSX_DEPLOYMENT_TARGET=${macMinVersion}",
"-m64",
+
+ "-integrated-as",
+ "-fstack-protector-strong",
}
darwinLdflags = []string{
@@ -48,26 +49,16 @@
"-Wl,-syslibroot,${macSdkRoot}",
"-mmacosx-version-min=${macMinVersion}",
"-m64",
+ "-mlinker-version=305",
}
- darwinClangCflags = append(ClangFilterUnknownCflags(darwinCflags), []string{
- "-integrated-as",
- "-fstack-protector-strong",
- }...)
-
- darwinClangLdflags = ClangFilterUnknownCflags(darwinLdflags)
-
- darwinClangLldflags = ClangFilterUnknownLldflags(darwinClangLdflags)
-
darwinSupportedSdkVersions = []string{
- "10.10",
- "10.11",
- "10.12",
"10.13",
"10.14",
"10.15",
"11.0",
"11.1",
+ "11.3",
}
darwinAvailableLibraries = append(
@@ -96,7 +87,7 @@
pctx.VariableFunc("macSdkRoot", func(ctx android.PackageVarContext) string {
return getMacTools(ctx).sdkRoot
})
- pctx.StaticVariable("macMinVersion", "10.10")
+ pctx.StaticVariable("macMinVersion", "10.13")
pctx.VariableFunc("MacArPath", func(ctx android.PackageVarContext) string {
return getMacTools(ctx).arPath
})
@@ -115,9 +106,9 @@
pctx.StaticVariable("DarwinGccTriple", "i686-apple-darwin11")
- pctx.StaticVariable("DarwinClangCflags", strings.Join(darwinClangCflags, " "))
- pctx.StaticVariable("DarwinClangLdflags", strings.Join(darwinClangLdflags, " "))
- pctx.StaticVariable("DarwinClangLldflags", strings.Join(darwinClangLldflags, " "))
+ pctx.StaticVariable("DarwinCflags", strings.Join(darwinCflags, " "))
+ pctx.StaticVariable("DarwinLdflags", strings.Join(darwinLdflags, " "))
+ pctx.StaticVariable("DarwinLldflags", strings.Join(darwinLdflags, " "))
pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64")
}
@@ -213,20 +204,20 @@
return "x86_64-apple-darwin"
}
-func (t *toolchainDarwin) ClangCflags() string {
- return "${config.DarwinClangCflags}"
+func (t *toolchainDarwin) Cflags() string {
+ return "${config.DarwinCflags}"
}
-func (t *toolchainDarwin) ClangCppflags() string {
+func (t *toolchainDarwin) Cppflags() string {
return ""
}
-func (t *toolchainDarwin) ClangLdflags() string {
- return "${config.DarwinClangLdflags}"
+func (t *toolchainDarwin) Ldflags() string {
+ return "${config.DarwinLdflags}"
}
-func (t *toolchainDarwin) ClangLldflags() string {
- return "${config.DarwinClangLldflags}"
+func (t *toolchainDarwin) Lldflags() string {
+ return "${config.DarwinLldflags}"
}
func (t *toolchainDarwin) YasmFlags() string {
@@ -241,10 +232,6 @@
return darwinAvailableLibraries
}
-func (t *toolchainDarwin) Bionic() bool {
- return false
-}
-
func (t *toolchainDarwin) ToolPath() string {
return "${config.MacToolPath}"
}
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index fe83098..5e510a4 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -21,16 +21,14 @@
)
var (
- x86Cflags = []string{}
-
- x86ClangCflags = append(x86Cflags, []string{
+ x86Cflags = []string{
"-msse3",
// -mstackrealign is needed to realign stack in native code
// that could be called from JNI, so that movaps instruction
// will work on assumed stack aligned local variables.
"-mstackrealign",
- }...)
+ }
x86Cppflags = []string{}
@@ -38,8 +36,6 @@
"-Wl,--hash-style=gnu",
}
- x86Lldflags = ClangFilterUnknownLldflags(x86Ldflags)
-
x86ArchVariantCflags = map[string][]string{
"": []string{
"-march=prescott",
@@ -49,35 +45,27 @@
},
"atom": []string{
"-march=atom",
- "-mfpmath=sse",
},
"broadwell": []string{
"-march=broadwell",
- "-mfpmath=sse",
},
"haswell": []string{
"-march=core-avx2",
- "-mfpmath=sse",
},
"ivybridge": []string{
"-march=core-avx-i",
- "-mfpmath=sse",
},
"sandybridge": []string{
"-march=corei7",
- "-mfpmath=sse",
},
"silvermont": []string{
"-march=slm",
- "-mfpmath=sse",
},
"skylake": []string{
"-march=skylake",
- "-mfpmath=sse",
},
"stoneyridge": []string{
"-march=bdver4",
- "-mfpmath=sse",
},
}
@@ -113,13 +101,11 @@
pctx.StaticVariable("X86ToolchainLdflags", "-m32")
pctx.StaticVariable("X86Ldflags", strings.Join(x86Ldflags, " "))
- pctx.StaticVariable("X86Lldflags", strings.Join(x86Lldflags, " "))
+ pctx.StaticVariable("X86Lldflags", strings.Join(x86Ldflags, " "))
// Clang cflags
- pctx.StaticVariable("X86ClangCflags", strings.Join(ClangFilterUnknownCflags(x86ClangCflags), " "))
- pctx.StaticVariable("X86ClangLdflags", strings.Join(ClangFilterUnknownCflags(x86Ldflags), " "))
- pctx.StaticVariable("X86ClangLldflags", strings.Join(ClangFilterUnknownCflags(x86Lldflags), " "))
- pctx.StaticVariable("X86ClangCppflags", strings.Join(ClangFilterUnknownCflags(x86Cppflags), " "))
+ pctx.StaticVariable("X86Cflags", strings.Join(x86Cflags, " "))
+ pctx.StaticVariable("X86Cppflags", strings.Join(x86Cppflags, " "))
// Yasm flags
pctx.StaticVariable("X86YasmFlags", "-f elf32 -m x86")
@@ -128,14 +114,15 @@
// Architecture variant cflags
for variant, cflags := range x86ArchVariantCflags {
- pctx.StaticVariable("X86"+variant+"VariantClangCflags",
- strings.Join(ClangFilterUnknownCflags(cflags), " "))
+ pctx.StaticVariable("X86"+variant+"VariantCflags",
+ strings.Join(cflags, " "))
}
}
type toolchainX86 struct {
+ toolchainBionic
toolchain32Bit
- toolchainClangCflags string
+ toolchainCflags string
}
func (t *toolchainX86) Name() string {
@@ -162,27 +149,27 @@
return "i686-linux-android"
}
-func (t *toolchainX86) ToolchainClangLdflags() string {
+func (t *toolchainX86) ToolchainLdflags() string {
return "${config.X86ToolchainLdflags}"
}
-func (t *toolchainX86) ToolchainClangCflags() string {
- return t.toolchainClangCflags
+func (t *toolchainX86) ToolchainCflags() string {
+ return t.toolchainCflags
}
-func (t *toolchainX86) ClangCflags() string {
- return "${config.X86ClangCflags}"
+func (t *toolchainX86) Cflags() string {
+ return "${config.X86Cflags}"
}
-func (t *toolchainX86) ClangCppflags() string {
- return "${config.X86ClangCppflags}"
+func (t *toolchainX86) Cppflags() string {
+ return "${config.X86Cppflags}"
}
-func (t *toolchainX86) ClangLdflags() string {
+func (t *toolchainX86) Ldflags() string {
return "${config.X86Ldflags}"
}
-func (t *toolchainX86) ClangLldflags() string {
+func (t *toolchainX86) Lldflags() string {
return "${config.X86Lldflags}"
}
@@ -195,17 +182,17 @@
}
func x86ToolchainFactory(arch android.Arch) Toolchain {
- toolchainClangCflags := []string{
+ toolchainCflags := []string{
"${config.X86ToolchainCflags}",
- "${config.X86" + arch.ArchVariant + "VariantClangCflags}",
+ "${config.X86" + arch.ArchVariant + "VariantCflags}",
}
for _, feature := range arch.ArchFeatures {
- toolchainClangCflags = append(toolchainClangCflags, x86ArchFeatureCflags[feature]...)
+ toolchainCflags = append(toolchainCflags, x86ArchFeatureCflags[feature]...)
}
return &toolchainX86{
- toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
+ toolchainCflags: strings.Join(toolchainCflags, " "),
}
}
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index fa625e3..4b7ba6a 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -21,9 +21,7 @@
)
var (
- linuxBionicCflags = ClangFilterUnknownCflags([]string{
- "-fdiagnostics-color",
-
+ linuxBionicCflags = []string{
"-Wa,--noexecstack",
"-fPIC",
@@ -34,21 +32,17 @@
// From x86_64_device
"-ffunction-sections",
- "-finline-functions",
- "-finline-limit=300",
"-fno-short-enums",
- "-funswitch-loops",
"-funwind-tables",
- "-fno-canonical-system-headers",
// Tell clang where the gcc toolchain is
"--gcc-toolchain=${LinuxBionicGccRoot}",
// This is normally in ClangExtraTargetCflags, but this is considered host
"-nostdlibinc",
- })
+ }
- linuxBionicLdflags = ClangFilterUnknownCflags([]string{
+ linuxBionicLdflags = []string{
"-Wl,-z,noexecstack",
"-Wl,-z,relro",
"-Wl,-z,now",
@@ -60,15 +54,23 @@
// Use the device gcc toolchain
"--gcc-toolchain=${LinuxBionicGccRoot}",
- })
+ }
- linuxBionicLldflags = ClangFilterUnknownLldflags(linuxBionicLdflags)
+ // Embed the linker into host bionic binaries. This is needed to support host bionic,
+ // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be
+ // either an absolute path, or relative from CWD. To work around this, we extract
+ // the load sections from the runtime linker ELF binary and embed them into each host
+ // bionic binary, omitting the PT_INTERP declaration. The kernel will treat it as a static
+ // binary, and then we use a special entry point to fix up the arguments passed by
+ // the kernel before jumping to the embedded linker.
+ linuxBionicCrtBeginSharedBinary = append(android.CopyOf(bionicCrtBeginSharedBinary),
+ "host_bionic_linker_script")
)
func init() {
pctx.StaticVariable("LinuxBionicCflags", strings.Join(linuxBionicCflags, " "))
pctx.StaticVariable("LinuxBionicLdflags", strings.Join(linuxBionicLdflags, " "))
- pctx.StaticVariable("LinuxBionicLldflags", strings.Join(linuxBionicLldflags, " "))
+ pctx.StaticVariable("LinuxBionicLldflags", strings.Join(linuxBionicLdflags, " "))
// Use the device gcc toolchain for now
pctx.StaticVariable("LinuxBionicGccRoot", "${X86_64GccRoot}")
@@ -76,6 +78,7 @@
type toolchainLinuxBionic struct {
toolchain64Bit
+ toolchainBionic
}
func (t *toolchainLinuxBionic) Name() string {
@@ -103,29 +106,29 @@
return "x86_64-linux-android"
}
-func (t *toolchainLinuxBionic) ClangCflags() string {
+func (t *toolchainLinuxBionic) Cflags() string {
return "${config.LinuxBionicCflags}"
}
-func (t *toolchainLinuxBionic) ClangCppflags() string {
+func (t *toolchainLinuxBionic) Cppflags() string {
return ""
}
-func (t *toolchainLinuxBionic) ClangLdflags() string {
+func (t *toolchainLinuxBionic) Ldflags() string {
return "${config.LinuxBionicLdflags}"
}
-func (t *toolchainLinuxBionic) ClangLldflags() string {
+func (t *toolchainLinuxBionic) Lldflags() string {
return "${config.LinuxBionicLldflags}"
}
-func (t *toolchainLinuxBionic) ToolchainClangCflags() string {
+func (t *toolchainLinuxBionic) ToolchainCflags() string {
return "-m64 -march=x86-64" +
// TODO: We're not really android, but we don't have a triple yet b/31393676
" -U__ANDROID__"
}
-func (t *toolchainLinuxBionic) ToolchainClangLdflags() string {
+func (t *toolchainLinuxBionic) ToolchainLdflags() string {
return "-m64"
}
@@ -133,14 +136,14 @@
return nil
}
-func (t *toolchainLinuxBionic) Bionic() bool {
- return true
-}
-
func (toolchainLinuxBionic) LibclangRuntimeLibraryArch() string {
return "x86_64"
}
+func (toolchainLinuxBionic) CrtBeginSharedBinary() []string {
+ return linuxBionicCrtBeginSharedBinary
+}
+
var toolchainLinuxBionicSingleton Toolchain = &toolchainLinuxBionic{}
func linuxBionicToolchainFactory(arch android.Arch) Toolchain {
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index 13b5511..1d66cb7 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -22,8 +22,6 @@
var (
linuxCflags = []string{
- "-fdiagnostics-color",
-
"-Wa,--noexecstack",
"-fPIC",
@@ -36,6 +34,18 @@
//See bug 12708004.
"-D__STDC_FORMAT_MACROS",
"-D__STDC_CONSTANT_MACROS",
+
+ "--gcc-toolchain=${LinuxGccRoot}",
+ "-fstack-protector-strong",
+ }
+
+ linuxGlibcCflags = []string{
+ "--sysroot ${LinuxGccRoot}/sysroot",
+ }
+
+ linuxMuslCflags = []string{
+ "-D_LIBCPP_HAS_MUSL_LIBC",
+ "-nostdlibinc",
}
linuxLdflags = []string{
@@ -43,12 +53,22 @@
"-Wl,-z,relro",
"-Wl,-z,now",
"-Wl,--no-undefined-version",
+
+ "--gcc-toolchain=${LinuxGccRoot}",
+ }
+
+ linuxGlibcLdflags = []string{
+ "--sysroot ${LinuxGccRoot}/sysroot",
+ }
+
+ linuxMuslLdflags = []string{
+ "-nostdlib",
+ "-lgcc", "-lgcc_eh",
}
// Extended cflags
linuxX86Cflags = []string{
"-msse3",
- "-mfpmath=sse",
"-m32",
"-march=prescott",
"-D_FILE_OFFSET_BITS=64",
@@ -61,40 +81,17 @@
linuxX86Ldflags = []string{
"-m32",
+ "-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
+ "-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
+ "-L${LinuxGccRoot}/${LinuxGccTriple}/lib32",
}
linuxX8664Ldflags = []string{
"-m64",
- }
-
- linuxClangCflags = append(ClangFilterUnknownCflags(linuxCflags), []string{
- "--gcc-toolchain=${LinuxGccRoot}",
- "--sysroot ${LinuxGccRoot}/sysroot",
- "-fstack-protector-strong",
- }...)
-
- linuxClangLdflags = append(ClangFilterUnknownCflags(linuxLdflags), []string{
- "--gcc-toolchain=${LinuxGccRoot}",
- "--sysroot ${LinuxGccRoot}/sysroot",
- }...)
-
- linuxClangLldflags = ClangFilterUnknownLldflags(linuxClangLdflags)
-
- linuxX86ClangLdflags = append(ClangFilterUnknownCflags(linuxX86Ldflags), []string{
- "-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
- "-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
- "-L${LinuxGccRoot}/${LinuxGccTriple}/lib32",
- }...)
-
- linuxX86ClangLldflags = ClangFilterUnknownLldflags(linuxX86ClangLdflags)
-
- linuxX8664ClangLdflags = append(ClangFilterUnknownCflags(linuxX8664Ldflags), []string{
"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
"-L${LinuxGccRoot}/${LinuxGccTriple}/lib64",
- }...)
-
- linuxX8664ClangLldflags = ClangFilterUnknownLldflags(linuxX8664ClangLdflags)
+ }
linuxAvailableLibraries = addPrefix([]string{
"c",
@@ -108,6 +105,12 @@
"rt",
"util",
}, "-l")
+
+ muslCrtBeginStaticBinary, muslCrtEndStaticBinary = []string{"libc_musl_crtbegin_static"}, []string{"crtend_android"}
+ muslCrtBeginSharedBinary, muslCrtEndSharedBinary = []string{"libc_musl_crtbegin_dynamic", "musl_linker_script"}, []string{"libc_musl_crtend"}
+ muslCrtBeginSharedLibrary, muslCrtEndSharedLibrary = []string{"libc_musl_crtbegin_so"}, []string{"libc_musl_crtend_so"}
+
+ muslDefaultSharedLibraries = []string{"libjemalloc5", "libc_musl"}
)
const (
@@ -130,21 +133,26 @@
pctx.StaticVariable("LinuxGccTriple", "x86_64-linux")
- pctx.StaticVariable("LinuxClangCflags", strings.Join(linuxClangCflags, " "))
- pctx.StaticVariable("LinuxClangLdflags", strings.Join(linuxClangLdflags, " "))
- pctx.StaticVariable("LinuxClangLldflags", strings.Join(linuxClangLldflags, " "))
+ pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " "))
+ pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " "))
+ pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLdflags, " "))
- pctx.StaticVariable("LinuxX86ClangCflags",
- strings.Join(ClangFilterUnknownCflags(linuxX86Cflags), " "))
- pctx.StaticVariable("LinuxX8664ClangCflags",
- strings.Join(ClangFilterUnknownCflags(linuxX8664Cflags), " "))
- pctx.StaticVariable("LinuxX86ClangLdflags", strings.Join(linuxX86ClangLdflags, " "))
- pctx.StaticVariable("LinuxX86ClangLldflags", strings.Join(linuxX86ClangLldflags, " "))
- pctx.StaticVariable("LinuxX8664ClangLdflags", strings.Join(linuxX8664ClangLdflags, " "))
- pctx.StaticVariable("LinuxX8664ClangLldflags", strings.Join(linuxX8664ClangLldflags, " "))
+ 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, " "))
// 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, " "))
}
type toolchainLinux struct {
@@ -189,11 +197,11 @@
return "i686-linux-gnu"
}
-func (t *toolchainLinuxX86) ClangCflags() string {
- return "${config.LinuxClangCflags} ${config.LinuxX86ClangCflags}"
+func (t *toolchainLinuxX86) Cflags() string {
+ return "${config.LinuxCflags} ${config.LinuxX86Cflags}"
}
-func (t *toolchainLinuxX86) ClangCppflags() string {
+func (t *toolchainLinuxX86) Cppflags() string {
return ""
}
@@ -201,28 +209,28 @@
return "x86_64-linux-gnu"
}
-func (t *toolchainLinuxX8664) ClangCflags() string {
- return "${config.LinuxClangCflags} ${config.LinuxX8664ClangCflags}"
+func (t *toolchainLinuxX8664) Cflags() string {
+ return "${config.LinuxCflags} ${config.LinuxX8664Cflags}"
}
-func (t *toolchainLinuxX8664) ClangCppflags() string {
+func (t *toolchainLinuxX8664) Cppflags() string {
return ""
}
-func (t *toolchainLinuxX86) ClangLdflags() string {
- return "${config.LinuxClangLdflags} ${config.LinuxX86ClangLdflags}"
+func (t *toolchainLinuxX86) Ldflags() string {
+ return "${config.LinuxLdflags} ${config.LinuxX86Ldflags}"
}
-func (t *toolchainLinuxX86) ClangLldflags() string {
- return "${config.LinuxClangLldflags} ${config.LinuxX86ClangLldflags}"
+func (t *toolchainLinuxX86) Lldflags() string {
+ return "${config.LinuxLldflags} ${config.LinuxX86Lldflags}"
}
-func (t *toolchainLinuxX8664) ClangLdflags() string {
- return "${config.LinuxClangLdflags} ${config.LinuxX8664ClangLdflags}"
+func (t *toolchainLinuxX8664) Ldflags() string {
+ return "${config.LinuxLdflags} ${config.LinuxX8664Ldflags}"
}
-func (t *toolchainLinuxX8664) ClangLldflags() string {
- return "${config.LinuxClangLldflags} ${config.LinuxX8664ClangLldflags}"
+func (t *toolchainLinuxX8664) Lldflags() string {
+ return "${config.LinuxLldflags} ${config.LinuxX8664Lldflags}"
}
func (t *toolchainLinuxX86) YasmFlags() string {
@@ -245,22 +253,146 @@
return linuxAvailableLibraries
}
-func (t *toolchainLinux) Bionic() bool {
- return false
+// glibc specialization of the linux toolchain
+
+type toolchainGlibc struct {
}
-var toolchainLinuxX86Singleton Toolchain = &toolchainLinuxX86{}
-var toolchainLinuxX8664Singleton Toolchain = &toolchainLinuxX8664{}
+func (toolchainGlibc) Glibc() bool { return true }
-func linuxX86ToolchainFactory(arch android.Arch) Toolchain {
- return toolchainLinuxX86Singleton
+func (toolchainGlibc) Cflags() string {
+ return "${config.LinuxGlibcCflags}"
}
-func linuxX8664ToolchainFactory(arch android.Arch) Toolchain {
- return toolchainLinuxX8664Singleton
+func (toolchainGlibc) Ldflags() string {
+ return "${config.LinuxGlibcLdflags}"
+}
+
+func (toolchainGlibc) Lldflags() string {
+ return "${config.LinuxGlibcLldflags}"
+}
+
+type toolchainLinuxGlibcX86 struct {
+ toolchainLinuxX86
+ toolchainGlibc
+}
+
+type toolchainLinuxGlibcX8664 struct {
+ toolchainLinuxX8664
+ toolchainGlibc
+}
+
+func (t *toolchainLinuxGlibcX86) Cflags() string {
+ return t.toolchainLinuxX86.Cflags() + " " + t.toolchainGlibc.Cflags()
+}
+
+func (t *toolchainLinuxGlibcX86) Ldflags() string {
+ return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainGlibc.Ldflags()
+}
+
+func (t *toolchainLinuxGlibcX86) Lldflags() string {
+ return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainGlibc.Lldflags()
+}
+
+func (t *toolchainLinuxGlibcX8664) Cflags() string {
+ return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainGlibc.Cflags()
+}
+
+func (t *toolchainLinuxGlibcX8664) Ldflags() string {
+ return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainGlibc.Ldflags()
+}
+
+func (t *toolchainLinuxGlibcX8664) Lldflags() string {
+ return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainGlibc.Lldflags()
+}
+
+var toolchainLinuxGlibcX86Singleton Toolchain = &toolchainLinuxGlibcX86{}
+var toolchainLinuxGlibcX8664Singleton Toolchain = &toolchainLinuxGlibcX8664{}
+
+func linuxGlibcX86ToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainLinuxGlibcX86Singleton
+}
+
+func linuxGlibcX8664ToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainLinuxGlibcX8664Singleton
+}
+
+// musl specialization of the linux toolchain
+
+type toolchainMusl struct {
+}
+
+func (toolchainMusl) Musl() bool { return true }
+
+func (toolchainMusl) CrtBeginStaticBinary() []string { return muslCrtBeginStaticBinary }
+func (toolchainMusl) CrtBeginSharedBinary() []string { return muslCrtBeginSharedBinary }
+func (toolchainMusl) CrtBeginSharedLibrary() []string { return muslCrtBeginSharedLibrary }
+func (toolchainMusl) CrtEndStaticBinary() []string { return muslCrtEndStaticBinary }
+func (toolchainMusl) CrtEndSharedBinary() []string { return muslCrtEndSharedBinary }
+func (toolchainMusl) CrtEndSharedLibrary() []string { return muslCrtEndSharedLibrary }
+
+func (toolchainMusl) DefaultSharedLibraries() []string { return muslDefaultSharedLibraries }
+
+func (toolchainMusl) Cflags() string {
+ return "${config.LinuxMuslCflags}"
+}
+
+func (toolchainMusl) Ldflags() string {
+ return "${config.LinuxMuslLdflags}"
+}
+
+func (toolchainMusl) Lldflags() string {
+ return "${config.LinuxMuslLldflags}"
+}
+
+type toolchainLinuxMuslX86 struct {
+ toolchainLinuxX86
+ toolchainMusl
+}
+
+type toolchainLinuxMuslX8664 struct {
+ toolchainLinuxX8664
+ toolchainMusl
+}
+
+func (t *toolchainLinuxMuslX86) Cflags() string {
+ return t.toolchainLinuxX86.Cflags() + " " + t.toolchainMusl.Cflags()
+}
+
+func (t *toolchainLinuxMuslX86) Ldflags() string {
+ return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainMusl.Ldflags()
+}
+
+func (t *toolchainLinuxMuslX86) Lldflags() string {
+ return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainMusl.Lldflags()
+}
+
+func (t *toolchainLinuxMuslX8664) Cflags() string {
+ return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainMusl.Cflags()
+}
+
+func (t *toolchainLinuxMuslX8664) Ldflags() string {
+ return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainMusl.Ldflags()
+}
+
+func (t *toolchainLinuxMuslX8664) Lldflags() string {
+ return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainMusl.Lldflags()
+}
+
+var toolchainLinuxMuslX86Singleton Toolchain = &toolchainLinuxMuslX86{}
+var toolchainLinuxMuslX8664Singleton Toolchain = &toolchainLinuxMuslX8664{}
+
+func linuxMuslX86ToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainLinuxMuslX86Singleton
+}
+
+func linuxMuslX8664ToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainLinuxMuslX8664Singleton
}
func init() {
- registerToolchainFactory(android.Linux, android.X86, linuxX86ToolchainFactory)
- registerToolchainFactory(android.Linux, android.X86_64, linuxX8664ToolchainFactory)
+ registerToolchainFactory(android.Linux, android.X86, linuxGlibcX86ToolchainFactory)
+ registerToolchainFactory(android.Linux, android.X86_64, linuxGlibcX8664ToolchainFactory)
+ registerToolchainFactory(android.LinuxMusl, android.X86, linuxMuslX86ToolchainFactory)
+ registerToolchainFactory(android.LinuxMusl, android.X86_64, linuxMuslX8664ToolchainFactory)
}
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index b77df79..d9a7537 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -44,32 +44,28 @@
"--sysroot ${WindowsGccRoot}/${WindowsGccTriple}",
}
- windowsClangCflags = append(ClangFilterUnknownCflags(windowsCflags), []string{}...)
windowsIncludeFlags = []string{
"-isystem ${WindowsGccRoot}/${WindowsGccTriple}/include",
}
- windowsClangCppflags = []string{}
+ windowsCppflags = []string{}
- windowsX86ClangCppflags = []string{
+ windowsX86Cppflags = []string{
// Use SjLj exceptions for 32-bit. libgcc_eh implements SjLj
// exception model for 32-bit.
"-fsjlj-exceptions",
}
- windowsX8664ClangCppflags = []string{}
+ windowsX8664Cppflags = []string{}
windowsLdflags = []string{
- "--enable-stdcall-fixup",
"-Wl,--dynamicbase",
"-Wl,--nxcompat",
}
- windowsLldflags = []string{
+ windowsLldflags = append(windowsLdflags, []string{
"-Wl,--Xlink=-Brepro", // Enable deterministic build
- }
- windowsClangLdflags = append(ClangFilterUnknownCflags(windowsLdflags), []string{}...)
- windowsClangLldflags = append(ClangFilterUnknownLldflags(windowsClangLdflags), windowsLldflags...)
+ }...)
windowsX86Cflags = []string{
"-m32",
@@ -84,28 +80,24 @@
"-Wl,--large-address-aware",
"-L${WindowsGccRoot}/${WindowsGccTriple}/lib32",
"-static-libgcc",
- }
- windowsX86ClangLdflags = append(ClangFilterUnknownCflags(windowsX86Ldflags), []string{
+
"-B${WindowsGccRoot}/${WindowsGccTriple}/bin",
"-B${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3/32",
"-L${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3/32",
"-B${WindowsGccRoot}/${WindowsGccTriple}/lib32",
- }...)
- windowsX86ClangLldflags = ClangFilterUnknownLldflags(windowsX86ClangLdflags)
+ }
windowsX8664Ldflags = []string{
"-m64",
"-L${WindowsGccRoot}/${WindowsGccTriple}/lib64",
"-Wl,--high-entropy-va",
"-static-libgcc",
- }
- windowsX8664ClangLdflags = append(ClangFilterUnknownCflags(windowsX8664Ldflags), []string{
+
"-B${WindowsGccRoot}/${WindowsGccTriple}/bin",
"-B${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3",
"-L${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3",
"-B${WindowsGccRoot}/${WindowsGccTriple}/lib64",
- }...)
- windowsX8664ClangLldflags = ClangFilterUnknownLldflags(windowsX8664ClangLdflags)
+ }
windowsAvailableLibraries = addPrefix([]string{
"gdi32",
@@ -138,21 +130,19 @@
pctx.StaticVariable("WindowsGccTriple", "x86_64-w64-mingw32")
- pctx.StaticVariable("WindowsClangCflags", strings.Join(windowsClangCflags, " "))
- pctx.StaticVariable("WindowsClangLdflags", strings.Join(windowsClangLdflags, " "))
- pctx.StaticVariable("WindowsClangLldflags", strings.Join(windowsClangLldflags, " "))
- pctx.StaticVariable("WindowsClangCppflags", strings.Join(windowsClangCppflags, " "))
+ pctx.StaticVariable("WindowsCflags", strings.Join(windowsCflags, " "))
+ pctx.StaticVariable("WindowsLdflags", strings.Join(windowsLdflags, " "))
+ pctx.StaticVariable("WindowsLldflags", strings.Join(windowsLldflags, " "))
+ pctx.StaticVariable("WindowsCppflags", strings.Join(windowsCppflags, " "))
- pctx.StaticVariable("WindowsX86ClangCflags",
- strings.Join(ClangFilterUnknownCflags(windowsX86Cflags), " "))
- pctx.StaticVariable("WindowsX8664ClangCflags",
- strings.Join(ClangFilterUnknownCflags(windowsX8664Cflags), " "))
- pctx.StaticVariable("WindowsX86ClangLdflags", strings.Join(windowsX86ClangLdflags, " "))
- pctx.StaticVariable("WindowsX86ClangLldflags", strings.Join(windowsX86ClangLldflags, " "))
- pctx.StaticVariable("WindowsX8664ClangLdflags", strings.Join(windowsX8664ClangLdflags, " "))
- pctx.StaticVariable("WindowsX8664ClangLldflags", strings.Join(windowsX8664ClangLldflags, " "))
- pctx.StaticVariable("WindowsX86ClangCppflags", strings.Join(windowsX86ClangCppflags, " "))
- pctx.StaticVariable("WindowsX8664ClangCppflags", strings.Join(windowsX8664ClangCppflags, " "))
+ pctx.StaticVariable("WindowsX86Cflags", strings.Join(windowsX86Cflags, " "))
+ pctx.StaticVariable("WindowsX8664Cflags", strings.Join(windowsX8664Cflags, " "))
+ pctx.StaticVariable("WindowsX86Ldflags", strings.Join(windowsX86Ldflags, " "))
+ pctx.StaticVariable("WindowsX86Lldflags", strings.Join(windowsX86Ldflags, " "))
+ pctx.StaticVariable("WindowsX8664Ldflags", strings.Join(windowsX8664Ldflags, " "))
+ pctx.StaticVariable("WindowsX8664Lldflags", strings.Join(windowsX8664Ldflags, " "))
+ pctx.StaticVariable("WindowsX86Cppflags", strings.Join(windowsX86Cppflags, " "))
+ pctx.StaticVariable("WindowsX8664Cppflags", strings.Join(windowsX8664Cppflags, " "))
pctx.StaticVariable("WindowsIncludeFlags", strings.Join(windowsIncludeFlags, " "))
// Yasm flags
@@ -214,36 +204,36 @@
return "x86_64-pc-windows-gnu"
}
-func (t *toolchainWindowsX86) ClangCflags() string {
- return "${config.WindowsClangCflags} ${config.WindowsX86ClangCflags}"
+func (t *toolchainWindowsX86) Cflags() string {
+ return "${config.WindowsCflags} ${config.WindowsX86Cflags}"
}
-func (t *toolchainWindowsX8664) ClangCflags() string {
- return "${config.WindowsClangCflags} ${config.WindowsX8664ClangCflags}"
+func (t *toolchainWindowsX8664) Cflags() string {
+ return "${config.WindowsCflags} ${config.WindowsX8664Cflags}"
}
-func (t *toolchainWindowsX86) ClangCppflags() string {
- return "${config.WindowsClangCppflags} ${config.WindowsX86ClangCppflags}"
+func (t *toolchainWindowsX86) Cppflags() string {
+ return "${config.WindowsCppflags} ${config.WindowsX86Cppflags}"
}
-func (t *toolchainWindowsX8664) ClangCppflags() string {
- return "${config.WindowsClangCppflags} ${config.WindowsX8664ClangCppflags}"
+func (t *toolchainWindowsX8664) Cppflags() string {
+ return "${config.WindowsCppflags} ${config.WindowsX8664Cppflags}"
}
-func (t *toolchainWindowsX86) ClangLdflags() string {
- return "${config.WindowsClangLdflags} ${config.WindowsX86ClangLdflags}"
+func (t *toolchainWindowsX86) Ldflags() string {
+ return "${config.WindowsLdflags} ${config.WindowsX86Ldflags}"
}
-func (t *toolchainWindowsX86) ClangLldflags() string {
- return "${config.WindowsClangLldflags} ${config.WindowsX86ClangLldflags}"
+func (t *toolchainWindowsX86) Lldflags() string {
+ return "${config.WindowsLldflags} ${config.WindowsX86Lldflags}"
}
-func (t *toolchainWindowsX8664) ClangLdflags() string {
- return "${config.WindowsClangLdflags} ${config.WindowsX8664ClangLdflags}"
+func (t *toolchainWindowsX8664) Ldflags() string {
+ return "${config.WindowsLdflags} ${config.WindowsX8664Ldflags}"
}
-func (t *toolchainWindowsX8664) ClangLldflags() string {
- return "${config.WindowsClangLldflags} ${config.WindowsX8664ClangLldflags}"
+func (t *toolchainWindowsX8664) Lldflags() string {
+ return "${config.WindowsLldflags} ${config.WindowsX8664Lldflags}"
}
func (t *toolchainWindowsX86) YasmFlags() string {
diff --git a/cc/fuzz.go b/cc/fuzz.go
index c780b6f..8b0f93e 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -94,19 +94,14 @@
*binaryDecorator
*baseCompiler
- Properties FuzzProperties
- dictionary android.Path
- corpus android.Paths
- corpusIntermediateDir android.Path
- config android.Path
- data android.Paths
- dataIntermediateDir android.Path
- installedSharedDeps []string
+ fuzzPackagedModule FuzzPackagedModule
+
+ installedSharedDeps []string
}
func (fuzz *fuzzBinary) linkerProps() []interface{} {
props := fuzz.binaryDecorator.linkerProps()
- props = append(props, &fuzz.Properties)
+ props = append(props, &fuzz.fuzzPackagedModule.FuzzProperties)
return props
}
@@ -257,41 +252,41 @@
"fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
fuzz.binaryDecorator.baseInstaller.install(ctx, file)
- fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus)
+ fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus)
builder := android.NewRuleBuilder(pctx, ctx)
intermediateDir := android.PathForModuleOut(ctx, "corpus")
- for _, entry := range fuzz.corpus {
+ for _, entry := range fuzz.fuzzPackagedModule.Corpus {
builder.Command().Text("cp").
Input(entry).
Output(intermediateDir.Join(ctx, entry.Base()))
}
builder.Build("copy_corpus", "copy corpus")
- fuzz.corpusIntermediateDir = intermediateDir
+ fuzz.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir
- fuzz.data = android.PathsForModuleSrc(ctx, fuzz.Properties.Data)
+ fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data)
builder = android.NewRuleBuilder(pctx, ctx)
intermediateDir = android.PathForModuleOut(ctx, "data")
- for _, entry := range fuzz.data {
+ for _, entry := range fuzz.fuzzPackagedModule.Data {
builder.Command().Text("cp").
Input(entry).
Output(intermediateDir.Join(ctx, entry.Rel()))
}
builder.Build("copy_data", "copy data")
- fuzz.dataIntermediateDir = intermediateDir
+ fuzz.fuzzPackagedModule.DataIntermediateDir = intermediateDir
- if fuzz.Properties.Dictionary != nil {
- fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary)
- if fuzz.dictionary.Ext() != ".dict" {
+ if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
+ fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary)
+ if fuzz.fuzzPackagedModule.Dictionary.Ext() != ".dict" {
ctx.PropertyErrorf("dictionary",
"Fuzzer dictionary %q does not have '.dict' extension",
- fuzz.dictionary.String())
+ fuzz.fuzzPackagedModule.Dictionary.String())
}
}
- if fuzz.Properties.Fuzz_config != nil {
+ if fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
- android.WriteFileRule(ctx, configPath, fuzz.Properties.Fuzz_config.String())
- fuzz.config = configPath
+ android.WriteFileRule(ctx, configPath, fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
+ fuzz.fuzzPackagedModule.Config = configPath
}
// Grab the list of required shared libraries.
@@ -359,32 +354,20 @@
// Responsible for generating GNU Make rules that package fuzz targets into
// their architecture & target/host specific zip file.
-type fuzzPackager struct {
- packages android.Paths
+type ccFuzzPackager struct {
+ FuzzPackager
sharedLibInstallStrings []string
- fuzzTargets map[string]bool
}
func fuzzPackagingFactory() android.Singleton {
- return &fuzzPackager{}
+ return &ccFuzzPackager{}
}
-type fileToZip struct {
- SourceFilePath android.Path
- DestinationPathPrefix string
-}
-
-type archOs struct {
- hostOrTarget string
- arch string
- dir string
-}
-
-func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
+func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
// Map between each architecture + host/device combination, and the files that
// need to be packaged (in the tuple of {source file, destination folder in
// archive}).
- archDirs := make(map[archOs][]fileToZip)
+ archDirs := make(map[ArchOs][]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.
@@ -392,12 +375,16 @@
// 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)
+ s.FuzzTargets = make(map[string]bool)
ctx.VisitAllModules(func(module android.Module) {
- // Discard non-fuzz targets.
ccModule, ok := module.(*Module)
- if !ok {
+ if !ok || ccModule.Properties.PreventInstall {
+ return
+ }
+
+ // Discard non-fuzz targets.
+ if ok := IsValid(ccModule.FuzzModule); !ok {
return
}
@@ -406,18 +393,6 @@
return
}
- // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
- // fuzz targets we're going to package anyway.
- if !ccModule.Enabled() || ccModule.Properties.PreventInstall ||
- ccModule.InRamdisk() || ccModule.InVendorRamdisk() || ccModule.InRecovery() {
- return
- }
-
- // Discard modules that are in an unavailable namespace.
- if !ccModule.ExportedToMake() {
- return
- }
-
hostOrTargetString := "target"
if ccModule.Host() {
hostOrTargetString = "host"
@@ -425,42 +400,21 @@
archString := ccModule.Arch().ArchType.String()
archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
- archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()}
+ archOs := ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
// Grab the list of required shared libraries.
sharedLibraries := collectAllSharedDependencies(ctx, module)
- var files []fileToZip
+ var files []FileToZip
builder := android.NewRuleBuilder(pctx, ctx)
- // Package the corpora into a zipfile.
- if fuzzModule.corpus != nil {
- corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip")
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", corpusZip)
- rspFile := corpusZip.ReplaceExtension(ctx, "rsp")
- command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.corpus)
- files = append(files, fileToZip{corpusZip, ""})
- }
-
- // Package the data into a zipfile.
- if fuzzModule.data != nil {
- dataZip := archDir.Join(ctx, module.Name()+"_data.zip")
- command := builder.Command().BuiltTool("soong_zip").
- FlagWithOutput("-o ", dataZip)
- for _, f := range fuzzModule.data {
- intermediateDir := strings.TrimSuffix(f.String(), f.Rel())
- command.FlagWithArg("-C ", intermediateDir)
- command.FlagWithInput("-f ", f)
- }
- files = append(files, fileToZip{dataZip, ""})
- }
+ // 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, fileToZip{library, "lib"})
+ files = append(files, FileToZip{library, "lib"})
// For each architecture-specific shared library dependency, we need to
// install it to the output directory. Setup the install destination here,
@@ -492,83 +446,20 @@
}
// The executable.
- files = append(files, fileToZip{ccModule.UnstrippedOutputFile(), ""})
+ files = append(files, FileToZip{ccModule.UnstrippedOutputFile(), ""})
- // The dictionary.
- if fuzzModule.dictionary != nil {
- files = append(files, fileToZip{fuzzModule.dictionary, ""})
+ archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
+ if !ok {
+ return
}
-
- // Additional fuzz config.
- if fuzzModule.config != nil {
- files = append(files, fileToZip{fuzzModule.config, ""})
- }
-
- fuzzZip := archDir.Join(ctx, module.Name()+".zip")
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", fuzzZip)
- for _, file := range files {
- if file.DestinationPathPrefix != "" {
- command.FlagWithArg("-P ", file.DestinationPathPrefix)
- } else {
- command.Flag("-P ''")
- }
- command.FlagWithInput("-f ", file.SourceFilePath)
- }
-
- builder.Build("create-"+fuzzZip.String(),
- "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
-
- // Don't add modules to 'make haiku' that are set to not be exported to the
- // fuzzing infrastructure.
- if config := fuzzModule.Properties.Fuzz_config; config != nil {
- if ccModule.Host() && !BoolDefault(config.Fuzz_on_haiku_host, true) {
- return
- } else if !BoolDefault(config.Fuzz_on_haiku_device, true) {
- return
- }
- }
-
- s.fuzzTargets[module.Name()] = true
- archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""})
})
- var archOsList []archOs
- for archOs := range archDirs {
- archOsList = append(archOsList, archOs)
- }
- sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].dir < archOsList[j].dir })
+ s.CreateFuzzPackage(ctx, archDirs, Cc)
- for _, archOs := range archOsList {
- filesToZip := archDirs[archOs]
- arch := archOs.arch
- hostOrTarget := archOs.hostOrTarget
- builder := android.NewRuleBuilder(pctx, ctx)
- outputFile := android.PathForOutput(ctx, "fuzz-"+hostOrTarget+"-"+arch+".zip")
- s.packages = append(s.packages, outputFile)
-
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", outputFile).
- Flag("-L 0") // No need to try and re-compress the zipfiles.
-
- for _, fileToZip := range filesToZip {
- if fileToZip.DestinationPathPrefix != "" {
- command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
- } else {
- command.Flag("-P ''")
- }
- command.FlagWithInput("-f ", fileToZip.SourceFilePath)
- }
-
- builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget,
- "Create fuzz target packages for "+arch+"-"+hostOrTarget)
- }
}
-func (s *fuzzPackager) MakeVars(ctx android.MakeVarsContext) {
- packages := s.packages.Strings()
+func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
+ packages := s.Packages.Strings()
sort.Strings(packages)
sort.Strings(s.sharedLibInstallStrings)
// TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's
@@ -580,10 +471,5 @@
strings.Join(s.sharedLibInstallStrings, " "))
// Preallocate the slice of fuzz targets to minimise memory allocations.
- fuzzTargets := make([]string, 0, len(s.fuzzTargets))
- for target, _ := range s.fuzzTargets {
- fuzzTargets = append(fuzzTargets, target)
- }
- sort.Strings(fuzzTargets)
- ctx.Strict("ALL_FUZZ_TARGETS", strings.Join(fuzzTargets, " "))
+ s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS")
}
diff --git a/cc/fuzz_common.go b/cc/fuzz_common.go
new file mode 100644
index 0000000..98ed7f4
--- /dev/null
+++ b/cc/fuzz_common.go
@@ -0,0 +1,201 @@
+// 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 cc
+
+// This file contains the common code for compiling C/C++ and Rust fuzzers for Android.
+
+import (
+ "sort"
+ "strings"
+
+ "android/soong/android"
+)
+
+type Lang string
+
+const (
+ Cc Lang = ""
+ Rust Lang = "rust"
+)
+
+type FuzzModule struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+ android.ApexModuleBase
+}
+
+type FuzzPackager struct {
+ Packages android.Paths
+ FuzzTargets map[string]bool
+}
+
+type FileToZip struct {
+ SourceFilePath android.Path
+ DestinationPathPrefix string
+}
+
+type ArchOs struct {
+ HostOrTarget string
+ Arch string
+ Dir string
+}
+
+type FuzzPackagedModule struct {
+ FuzzProperties FuzzProperties
+ Dictionary android.Path
+ Corpus android.Paths
+ CorpusIntermediateDir android.Path
+ Config android.Path
+ Data android.Paths
+ DataIntermediateDir android.Path
+}
+
+func IsValid(fuzzModule FuzzModule) bool {
+ // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
+ // fuzz targets we're going to package anyway.
+ if !fuzzModule.Enabled() || fuzzModule.InRamdisk() || fuzzModule.InVendorRamdisk() || fuzzModule.InRecovery() {
+ return false
+ }
+
+ // Discard modules that are in an unavailable namespace.
+ if !fuzzModule.ExportedToMake() {
+ return false
+ }
+
+ return true
+}
+
+func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip {
+ // Package the corpora into a zipfile.
+ var files []FileToZip
+ if fuzzModule.Corpus != nil {
+ corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip")
+ command := builder.Command().BuiltTool("soong_zip").
+ Flag("-j").
+ FlagWithOutput("-o ", corpusZip)
+ rspFile := corpusZip.ReplaceExtension(ctx, "rsp")
+ command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.Corpus)
+ files = append(files, FileToZip{corpusZip, ""})
+ }
+
+ // Package the data into a zipfile.
+ if fuzzModule.Data != nil {
+ dataZip := archDir.Join(ctx, module.Name()+"_data.zip")
+ command := builder.Command().BuiltTool("soong_zip").
+ FlagWithOutput("-o ", dataZip)
+ for _, f := range fuzzModule.Data {
+ intermediateDir := strings.TrimSuffix(f.String(), f.Rel())
+ command.FlagWithArg("-C ", intermediateDir)
+ command.FlagWithInput("-f ", f)
+ }
+ files = append(files, FileToZip{dataZip, ""})
+ }
+
+ // The dictionary.
+ if fuzzModule.Dictionary != nil {
+ files = append(files, FileToZip{fuzzModule.Dictionary, ""})
+ }
+
+ // Additional fuzz config.
+ if fuzzModule.Config != nil {
+ files = append(files, FileToZip{fuzzModule.Config, ""})
+ }
+
+ return files
+}
+
+func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) {
+ fuzzZip := archDir.Join(ctx, module.Name()+".zip")
+
+ command := builder.Command().BuiltTool("soong_zip").
+ Flag("-j").
+ FlagWithOutput("-o ", fuzzZip)
+
+ for _, file := range files {
+ if file.DestinationPathPrefix != "" {
+ command.FlagWithArg("-P ", file.DestinationPathPrefix)
+ } else {
+ command.Flag("-P ''")
+ }
+ command.FlagWithInput("-f ", file.SourceFilePath)
+ }
+
+ builder.Build("create-"+fuzzZip.String(),
+ "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
+
+ // Don't add modules to 'make haiku-rust' that are set to not be
+ // exported to the fuzzing infrastructure.
+ if config := fuzzModule.FuzzProperties.Fuzz_config; config != nil {
+ if strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_host, true) {
+ return archDirs[archOs], false
+ } else if !BoolDefault(config.Fuzz_on_haiku_device, true) {
+ return archDirs[archOs], false
+ }
+ }
+
+ s.FuzzTargets[module.Name()] = true
+ archDirs[archOs] = append(archDirs[archOs], FileToZip{fuzzZip, ""})
+
+ return archDirs[archOs], true
+}
+
+func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, lang Lang) {
+ var archOsList []ArchOs
+ for archOs := range archDirs {
+ archOsList = append(archOsList, archOs)
+ }
+ sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].Dir < archOsList[j].Dir })
+
+ for _, archOs := range archOsList {
+ filesToZip := archDirs[archOs]
+ arch := archOs.Arch
+ hostOrTarget := archOs.HostOrTarget
+ builder := android.NewRuleBuilder(pctx, ctx)
+ zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip"
+ if lang == Rust {
+ zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip"
+ }
+ outputFile := android.PathForOutput(ctx, zipFileName)
+
+ s.Packages = append(s.Packages, outputFile)
+
+ command := builder.Command().BuiltTool("soong_zip").
+ Flag("-j").
+ FlagWithOutput("-o ", outputFile).
+ Flag("-L 0") // No need to try and re-compress the zipfiles.
+
+ for _, fileToZip := range filesToZip {
+
+ if fileToZip.DestinationPathPrefix != "" {
+ command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
+ } else {
+ command.Flag("-P ''")
+ }
+ command.FlagWithInput("-f ", fileToZip.SourceFilePath)
+
+ }
+ builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget,
+ "Create fuzz target packages for "+arch+"-"+hostOrTarget)
+ }
+}
+
+func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets string) {
+ fuzzTargets := make([]string, 0, len(s.FuzzTargets))
+ for target, _ := range s.FuzzTargets {
+ fuzzTargets = append(fuzzTargets, target)
+ }
+ sort.Strings(fuzzTargets)
+ ctx.Strict(targets, strings.Join(fuzzTargets, " "))
+}
diff --git a/cc/gen.go b/cc/gen.go
index b152e02..3a1a0e2 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -204,7 +204,7 @@
headerFile := android.GenPathWithExt(ctx, "windmc", srcFile, "h")
rcFile := android.GenPathWithExt(ctx, "windmc", srcFile, "rc")
- windmcCmd := gccCmd(flags.toolchain, "windmc")
+ windmcCmd := mingwCmd(flags.toolchain, "windmc")
ctx.Build(pctx, android.BuildParams{
Rule: windmc,
diff --git a/cc/genrule.go b/cc/genrule.go
index 82d7205..0ca901e 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -17,6 +17,7 @@
import (
"android/soong/android"
"android/soong/genrule"
+ "android/soong/snapshot"
)
func init() {
@@ -84,7 +85,7 @@
// is not needed.
recoverySnapshotVersion := ctx.DeviceConfig().RecoverySnapshotVersion()
if recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" &&
- !isRecoveryProprietaryModule(ctx) {
+ !snapshot.IsRecoveryProprietaryModule(ctx) {
return false
} else {
return Bool(g.Recovery_available)
@@ -103,7 +104,7 @@
// If not, we assume modules under proprietary paths are compatible for
// BOARD_VNDK_VERSION. The other modules are regarded as AOSP, that is
// PLATFORM_VNDK_VERSION.
- if vndkVersion == "current" || !isVendorProprietaryModule(ctx) {
+ if vndkVersion == "current" || !snapshot.IsVendorProprietaryModule(ctx) {
variants = append(variants, VendorVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
} else {
variants = append(variants, VendorVariationPrefix+vndkVersion)
diff --git a/cc/image.go b/cc/image.go
index 47a424b..3a0857b 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -22,6 +22,7 @@
"strings"
"android/soong/android"
+ "android/soong/snapshot"
)
var _ android.ImageInterface = (*Module)(nil)
@@ -341,11 +342,11 @@
}
func (m *Module) ExtraVariants() []string {
- return m.Properties.ExtraVariants
+ return m.Properties.ExtraVersionedImageVariations
}
func (m *Module) AppendExtraVariant(extraVariant string) {
- m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, extraVariant)
+ m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant)
}
func (m *Module) SetRamdiskVariantNeeded(b bool) {
@@ -365,8 +366,8 @@
}
func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
- if snapshot, ok := m.linker.(snapshotInterface); ok {
- return snapshot.version()
+ if snapshot, ok := m.linker.(SnapshotInterface); ok {
+ return snapshot.Version()
} else {
mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
// Should we be panicking here instead?
@@ -496,7 +497,7 @@
// BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
// PLATFORM_VNDK_VERSION.
if m.HasVendorVariant() {
- if isVendorProprietaryModule(mctx) {
+ if snapshot.IsVendorProprietaryModule(mctx) {
vendorVariants = append(vendorVariants, boardVndkVersion)
} else {
vendorVariants = append(vendorVariants, platformVndkVersion)
@@ -525,7 +526,7 @@
platformVndkVersion,
boardVndkVersion,
)
- } else if isVendorProprietaryModule(mctx) {
+ } else if snapshot.IsVendorProprietaryModule(mctx) {
vendorVariants = append(vendorVariants, boardVndkVersion)
} else {
vendorVariants = append(vendorVariants, platformVndkVersion)
@@ -579,10 +580,10 @@
// If using a snapshot, the recovery variant under AOSP directories is not needed,
// except for kernel headers, which needs all variants.
- if m.KernelHeadersDecorator() &&
+ if !m.KernelHeadersDecorator() &&
!m.IsSnapshotPrebuilt() &&
usingRecoverySnapshot &&
- !isRecoveryProprietaryModule(mctx) {
+ !snapshot.IsRecoveryProprietaryModule(mctx) {
recoveryVariantNeeded = false
}
@@ -629,7 +630,7 @@
}
func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
- return c.Properties.ExtraVariants
+ return c.Properties.ExtraVersionedImageVariations
}
func squashVendorSrcs(m *Module) {
diff --git a/cc/installer.go b/cc/installer.go
index e551c63..f95b493 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -25,6 +25,10 @@
type InstallerProperties struct {
// install to a subdirectory of the default install path for the module
Relative_install_path *string `android:"arch_variant"`
+
+ // 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"`
}
type installLocation int
@@ -66,6 +70,11 @@
if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
dir = installer.dir64
}
+
+ if installer.installInRoot() {
+ dir = ""
+ }
+
if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
} else if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
@@ -110,3 +119,7 @@
func (installer *baseInstaller) makeUninstallable(mod *Module) {
mod.ModuleBase.MakeUninstallable()
}
+
+func (installer *baseInstaller) installInRoot() bool {
+ return Bool(installer.Properties.Install_in_root)
+}
diff --git a/cc/library.go b/cc/library.go
index 1ba3597..8f302fc 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -28,6 +28,7 @@
"android/soong/android"
"android/soong/bazel"
+ "android/soong/bazel/cquery"
"android/soong/cc/config"
)
@@ -111,9 +112,6 @@
Check_all_apis *bool
}
- // Order symbols in .bss section by their sizes. Only useful for shared libraries.
- Sort_bss_symbols_by_size *bool
-
// Inject boringssl hash into the shared library. This is only intended for use by external/boringssl.
Inject_bssl_hash *bool `android:"arch_variant"`
@@ -186,11 +184,11 @@
// be added to the include path (using -I) for this module and any module that links
// against this module. Directories listed in export_include_dirs do not need to be
// listed in local_include_dirs.
- Export_include_dirs []string `android:"arch_variant"`
+ Export_include_dirs []string `android:"arch_variant,variant_prepend"`
// list of directories that will be added to the system include path
// using -isystem for this module and any module that links against this module.
- Export_system_include_dirs []string `android:"arch_variant"`
+ Export_system_include_dirs []string `android:"arch_variant,variant_prepend"`
Target struct {
Vendor, Product struct {
@@ -221,28 +219,40 @@
// For bp2build conversion.
type bazelCcLibraryAttributes struct {
// Attributes pertaining to both static and shared variants.
- Srcs bazel.LabelListAttribute
- Hdrs bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
- Dynamic_deps bazel.LabelListAttribute
- Whole_archive_deps bazel.LabelListAttribute
- Copts bazel.StringListAttribute
- Includes bazel.StringListAttribute
- Linkopts bazel.StringListAttribute
- // Attributes pertaining to shared variant.
- Shared_copts bazel.StringListAttribute
- Shared_srcs bazel.LabelListAttribute
- Static_deps_for_shared bazel.LabelListAttribute
- Dynamic_deps_for_shared bazel.LabelListAttribute
- Whole_archive_deps_for_shared bazel.LabelListAttribute
- User_link_flags bazel.StringListAttribute
- Version_script bazel.LabelAttribute
- // Attributes pertaining to static variant.
- Static_copts bazel.StringListAttribute
- Static_srcs bazel.LabelListAttribute
- Static_deps_for_static bazel.LabelListAttribute
- Dynamic_deps_for_static bazel.LabelListAttribute
- Whole_archive_deps_for_static bazel.LabelListAttribute
+ Srcs bazel.LabelListAttribute
+ Srcs_c bazel.LabelListAttribute
+ Srcs_as bazel.LabelListAttribute
+
+ Copts bazel.StringListAttribute
+ Cppflags bazel.StringListAttribute
+ Conlyflags bazel.StringListAttribute
+ Asflags bazel.StringListAttribute
+
+ Hdrs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ Includes bazel.StringListAttribute
+ Linkopts bazel.StringListAttribute
+ Use_libcrt bazel.BoolAttribute
+
+ // This is shared only.
+ Version_script bazel.LabelAttribute
+
+ // Common properties shared between both shared and static variants.
+ Shared staticOrSharedAttributes
+ Static staticOrSharedAttributes
+
+ Strip stripAttributes
+}
+
+type stripAttributes struct {
+ Keep_symbols bazel.BoolAttribute
+ Keep_symbols_and_debug_frame bazel.BoolAttribute
+ Keep_symbols_list bazel.StringListAttribute
+ All bazel.BoolAttribute
+ None bazel.BoolAttribute
}
type bazelCcLibrary struct {
@@ -287,28 +297,45 @@
linkerAttrs := bp2BuildParseLinkerProps(ctx, m)
exportedIncludes := bp2BuildParseExportedIncludes(ctx, m)
- var srcs bazel.LabelListAttribute
- srcs.Append(compilerAttrs.srcs)
+ srcs := compilerAttrs.srcs
+
+ asFlags := compilerAttrs.asFlags
+ if compilerAttrs.asSrcs.IsEmpty() && sharedAttrs.Srcs_as.IsEmpty() && staticAttrs.Srcs_as.IsEmpty() {
+ // Skip asflags for BUILD file simplicity if there are no assembly sources.
+ asFlags = bazel.MakeStringListAttribute(nil)
+ }
attrs := &bazelCcLibraryAttributes{
- Srcs: srcs,
- Deps: linkerAttrs.deps,
- Dynamic_deps: linkerAttrs.dynamicDeps,
- Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
- Copts: compilerAttrs.copts,
- Includes: exportedIncludes,
- Linkopts: linkerAttrs.linkopts,
- Shared_copts: sharedAttrs.copts,
- Shared_srcs: sharedAttrs.srcs,
- Static_deps_for_shared: sharedAttrs.staticDeps,
- Whole_archive_deps_for_shared: sharedAttrs.wholeArchiveDeps,
- Dynamic_deps_for_shared: sharedAttrs.dynamicDeps,
- Version_script: linkerAttrs.versionScript,
- Static_copts: staticAttrs.copts,
- Static_srcs: staticAttrs.srcs,
- Static_deps_for_static: staticAttrs.staticDeps,
- Whole_archive_deps_for_static: staticAttrs.wholeArchiveDeps,
- Dynamic_deps_for_static: staticAttrs.dynamicDeps,
+ Srcs: srcs,
+ Srcs_c: compilerAttrs.cSrcs,
+ Srcs_as: compilerAttrs.asSrcs,
+
+ Copts: compilerAttrs.copts,
+ Cppflags: compilerAttrs.cppFlags,
+ Conlyflags: compilerAttrs.conlyFlags,
+ Asflags: asFlags,
+
+ Implementation_deps: linkerAttrs.deps,
+ Deps: linkerAttrs.exportedDeps,
+ Dynamic_deps: linkerAttrs.dynamicDeps,
+ Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
+ Includes: exportedIncludes,
+ Linkopts: linkerAttrs.linkopts,
+ Use_libcrt: linkerAttrs.useLibcrt,
+
+ Version_script: linkerAttrs.versionScript,
+
+ Strip: stripAttributes{
+ Keep_symbols: linkerAttrs.stripKeepSymbols,
+ Keep_symbols_and_debug_frame: linkerAttrs.stripKeepSymbolsAndDebugFrame,
+ Keep_symbols_list: linkerAttrs.stripKeepSymbolsList,
+ All: linkerAttrs.stripAll,
+ None: linkerAttrs.stripNone,
+ },
+
+ Shared: sharedAttrs,
+
+ Static: staticAttrs,
}
props := bazel.BazelTargetModuleProperties{
@@ -331,6 +358,7 @@
staticLibrarySdkMemberType,
staticAndSharedLibrarySdkMemberType,
}
+ module.bazelHandler = &ccLibraryBazelHandler{module: module}
return module.Init()
}
@@ -339,7 +367,7 @@
module, library := NewLibrary(android.HostAndDeviceSupported)
library.BuildOnlyStatic()
module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
- module.bazelHandler = &staticLibraryBazelHandler{module: module}
+ module.bazelHandler = &ccLibraryBazelHandler{module: module}
return module.Init()
}
@@ -524,36 +552,24 @@
collectedSnapshotHeaders android.Paths
}
-type staticLibraryBazelHandler struct {
+type ccLibraryBazelHandler struct {
bazelHandler
module *Module
}
-func (handler *staticLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
- bazelCtx := ctx.Config().BazelContext
- ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
- if err != nil {
- ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
+// generateStaticBazelBuildActions constructs the StaticLibraryInfo Soong
+// provider from a Bazel shared library's CcInfo provider.
+func (handler *ccLibraryBazelHandler) generateStaticBazelBuildActions(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool {
+ rootStaticArchives := ccInfo.RootStaticArchives
+ if len(rootStaticArchives) != 1 {
+ ctx.ModuleErrorf("expected exactly one root archive file for '%s', but got %s", label, rootStaticArchives)
return false
}
- if !ok {
- return ok
- }
- outputPaths := ccInfo.OutputFiles
- objPaths := ccInfo.CcObjectFiles
- if len(outputPaths) > 1 {
- // TODO(cparsons): This is actually expected behavior for static libraries with no srcs.
- // We should support this.
- ctx.ModuleErrorf("expected at most one output file for '%s', but got %s", label, objPaths)
- return false
- } else if len(outputPaths) == 0 {
- handler.module.outputFile = android.OptionalPath{}
- return true
- }
- outputFilePath := android.PathForBazelOut(ctx, outputPaths[0])
+ outputFilePath := android.PathForBazelOut(ctx, rootStaticArchives[0])
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
+ objPaths := ccInfo.CcObjectFiles
objFiles := make(android.Paths, len(objPaths))
for i, objPath := range objPaths {
objFiles[i] = android.PathForBazelOut(ctx, objPath)
@@ -567,40 +583,117 @@
ReuseObjects: objects,
Objects: objects,
- // TODO(cparsons): Include transitive static libraries in this provider to support
+ // TODO(b/190524881): Include transitive static libraries in this provider to support
// static libraries with deps.
TransitiveStaticLibrariesForOrdering: android.NewDepSetBuilder(android.TOPOLOGICAL).
Direct(outputFilePath).
Build(),
})
- ctx.SetProvider(FlagExporterInfoProvider, flagExporterInfoFromCcInfo(ctx, ccInfo))
+ return true
+}
+
+// generateSharedBazelBuildActions constructs the SharedLibraryInfo Soong
+// provider from a Bazel shared library's CcInfo provider.
+func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool {
+ rootDynamicLibraries := ccInfo.RootDynamicLibraries
+
+ if len(rootDynamicLibraries) != 1 {
+ ctx.ModuleErrorf("expected exactly one root dynamic library file for '%s', but got %s", label, rootDynamicLibraries)
+ return false
+ }
+ outputFilePath := android.PathForBazelOut(ctx, rootDynamicLibraries[0])
+ handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
+
+ handler.module.linker.(*libraryDecorator).unstrippedOutputFile = outputFilePath
+
+ tocFile := getTocFile(ctx, label, ccInfo.OutputFiles)
+ handler.module.linker.(*libraryDecorator).tocFile = tocFile
+
+ ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
+ TableOfContents: tocFile,
+ SharedLibrary: outputFilePath,
+ Target: ctx.Target(),
+ // TODO(b/190524881): Include transitive static libraries in this provider to support
+ // static libraries with deps. The provider key for this is TransitiveStaticLibrariesForOrdering.
+ })
+ return true
+}
+
+// getTocFile looks for the .so.toc file in the target's output files, if any. The .so.toc file
+// contains the table of contents of all symbols of a shared object.
+func getTocFile(ctx android.ModuleContext, label string, outputFiles []string) android.OptionalPath {
+ var tocFile string
+ for _, file := range outputFiles {
+ if strings.HasSuffix(file, ".so.toc") {
+ if tocFile != "" {
+ ctx.ModuleErrorf("The %s target cannot produce more than 1 .toc file.", label)
+ }
+ tocFile = file
+ // Don't break to validate that there are no multiple .toc files per .so.
+ }
+ }
+ if tocFile == "" {
+ return android.OptionalPath{}
+ }
+ return android.OptionalPathForPath(android.PathForBazelOut(ctx, tocFile))
+}
+
+func (handler *ccLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
+ bazelCtx := ctx.Config().BazelContext
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ if err != nil {
+ ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
+ return false
+ }
+ if !ok {
+ return ok
+ }
+
+ if handler.module.static() {
+ if ok := handler.generateStaticBazelBuildActions(ctx, label, ccInfo); !ok {
+ return false
+ }
+ } else if handler.module.Shared() {
+ if ok := handler.generateSharedBazelBuildActions(ctx, label, ccInfo); !ok {
+ return false
+ }
+ } else {
+ return false
+ }
+
+ handler.module.linker.(*libraryDecorator).setFlagExporterInfoFromCcInfo(ctx, ccInfo)
+ handler.module.maybeUnhideFromMake()
+
if i, ok := handler.module.linker.(snapshotLibraryInterface); ok {
// Dependencies on this library will expect collectedSnapshotHeaders to
// be set, otherwise validation will fail. For now, set this to an empty
// list.
- // TODO(cparsons): More closely mirror the collectHeadersForSnapshot
+ // TODO(b/190533363): More closely mirror the collectHeadersForSnapshot
// implementation.
i.(*libraryDecorator).collectedSnapshotHeaders = android.Paths{}
}
-
return ok
}
-// collectHeadersForSnapshot collects all exported headers from library.
-// It globs header files in the source tree for exported include directories,
-// and tracks generated header files separately.
-//
-// This is to be called from GenerateAndroidBuildActions, and then collected
-// header files can be retrieved by snapshotHeaders().
-func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext) {
+func (library *libraryDecorator) setFlagExporterInfoFromCcInfo(ctx android.ModuleContext, ccInfo cquery.CcInfo) {
+ flagExporterInfo := flagExporterInfoFromCcInfo(ctx, ccInfo)
+ // flag exporters consolidates properties like includes, flags, dependencies that should be
+ // exported from this module to other modules
+ ctx.SetProvider(FlagExporterInfoProvider, flagExporterInfo)
+ // Store flag info to be passed along to androidmk
+ // TODO(b/184387147): Androidmk should be done in Bazel, not Soong.
+ library.flagExporterInfo = &flagExporterInfo
+}
+
+func GlobHeadersForSnapshot(ctx android.ModuleContext, paths android.Paths) android.Paths {
ret := android.Paths{}
// Headers in the source tree should be globbed. On the contrast, generated headers
// can't be globbed, and they should be manually collected.
// So, we first filter out intermediate directories (which contains generated headers)
// from exported directories, and then glob headers under remaining directories.
- for _, path := range append(android.CopyOfPaths(l.flagExporter.dirs), l.flagExporter.systemDirs...) {
+ for _, path := range paths {
dir := path.String()
// Skip if dir is for generated headers
if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
@@ -616,7 +709,7 @@
glob, err := ctx.GlobWithDeps("external/eigen/"+subdir+"/**/*", nil)
if err != nil {
ctx.ModuleErrorf("glob failed: %#v", err)
- return
+ return nil
}
for _, header := range glob {
if strings.HasSuffix(header, "/") {
@@ -634,7 +727,7 @@
glob, err := ctx.GlobWithDeps(dir+"/**/*", nil)
if err != nil {
ctx.ModuleErrorf("glob failed: %#v", err)
- return
+ return nil
}
isLibcxx := strings.HasPrefix(dir, "external/libcxx/include")
for _, header := range glob {
@@ -647,7 +740,7 @@
} else {
// Filter out only the files with extensions that are headers.
found := false
- for _, ext := range headerExts {
+ for _, ext := range HeaderExts {
if strings.HasSuffix(header, ext) {
found = true
break
@@ -660,15 +753,38 @@
ret = append(ret, android.PathForSource(ctx, header))
}
}
+ return ret
+}
- // Collect generated headers
- for _, header := range append(android.CopyOfPaths(l.flagExporter.headers), l.flagExporter.deps...) {
+func GlobGeneratedHeadersForSnapshot(ctx android.ModuleContext, paths android.Paths) android.Paths {
+ ret := android.Paths{}
+ for _, header := range paths {
// TODO(b/148123511): remove exportedDeps after cleaning up genrule
if strings.HasSuffix(header.Base(), "-phony") {
continue
}
ret = append(ret, header)
}
+ return ret
+}
+
+// collectHeadersForSnapshot collects all exported headers from library.
+// It globs header files in the source tree for exported include directories,
+// and tracks generated header files separately.
+//
+// This is to be called from GenerateAndroidBuildActions, and then collected
+// header files can be retrieved by snapshotHeaders().
+func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext) {
+ ret := android.Paths{}
+
+ // Headers in the source tree should be globbed. On the contrast, generated headers
+ // can't be globbed, and they should be manually collected.
+ // So, we first filter out intermediate directories (which contains generated headers)
+ // from exported directories, and then glob headers under remaining directories.
+ ret = append(ret, GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(l.flagExporter.dirs), l.flagExporter.systemDirs...))...)
+
+ // Collect generated headers
+ ret = append(ret, GlobGeneratedHeadersForSnapshot(ctx, append(android.CopyOfPaths(l.flagExporter.headers), l.flagExporter.deps...))...)
l.collectedSnapshotHeaders = ret
}
@@ -817,16 +933,23 @@
if library.stubsVersion() != "" {
vndkVer = library.stubsVersion()
}
- objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Llndk.Symbol_file), vndkVer, "--llndk")
+ nativeAbiResult := parseNativeAbiDefinition(ctx,
+ String(library.Properties.Llndk.Symbol_file),
+ android.ApiLevelOrPanic(ctx, vndkVer), "--llndk")
+ objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
if !Bool(library.Properties.Llndk.Unversioned) {
- library.versionScriptPath = android.OptionalPathForPath(versionScript)
+ library.versionScriptPath = android.OptionalPathForPath(
+ nativeAbiResult.versionScript)
}
return objs
}
if ctx.IsVendorPublicLibrary() {
- objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Vendor_public_library.Symbol_file), "current", "")
+ nativeAbiResult := parseNativeAbiDefinition(ctx,
+ String(library.Properties.Vendor_public_library.Symbol_file),
+ android.FutureApiLevel, "")
+ objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
if !Bool(library.Properties.Vendor_public_library.Unversioned) {
- library.versionScriptPath = android.OptionalPathForPath(versionScript)
+ library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.versionScript)
}
return objs
}
@@ -836,8 +959,12 @@
ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
return Objects{}
}
- objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "--apex")
- library.versionScriptPath = android.OptionalPathForPath(versionScript)
+ nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
+ android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion),
+ "--apex")
+ objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+ library.versionScriptPath = android.OptionalPathForPath(
+ nativeAbiResult.versionScript)
return objs
}
@@ -1053,9 +1180,9 @@
deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...)
deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...)
} else if library.shared() {
- if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) {
- deps.CrtBegin = "crtbegin_so"
- deps.CrtEnd = "crtend_so"
+ if !Bool(library.baseLinker.Properties.Nocrt) {
+ deps.CrtBegin = append(deps.CrtBegin, ctx.toolchain().CrtBeginSharedLibrary()...)
+ deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtEndSharedLibrary()...)
}
deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs...)
deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs...)
@@ -1283,22 +1410,9 @@
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
linkerDeps = append(linkerDeps, objs.tidyFiles...)
-
- if Bool(library.Properties.Sort_bss_symbols_by_size) && !library.buildStubs() {
- unsortedOutputFile := android.PathForModuleOut(ctx, "unsorted", fileName)
- transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
- deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
- linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, unsortedOutputFile, implicitOutputs)
-
- symbolOrderingFile := android.PathForModuleOut(ctx, "unsorted", fileName+".symbol_order")
- symbolOrderingFlag := library.baseLinker.sortBssSymbolsBySize(ctx, unsortedOutputFile, symbolOrderingFile, builderFlags)
- builderFlags.localLdFlags += " " + symbolOrderingFlag
- linkerDeps = append(linkerDeps, symbolOrderingFile)
- }
-
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
- linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs)
+ linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, nil)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
@@ -1309,19 +1423,17 @@
library.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, library.getLibName(ctx))
library.linkSAbiDumpFiles(ctx, objs, fileName, unstrippedOutputFile)
- var staticAnalogue *StaticLibraryInfo
+ var transitiveStaticLibrariesForOrdering *android.DepSet
if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 {
s := ctx.OtherModuleProvider(static[0], StaticLibraryInfoProvider).(StaticLibraryInfo)
- staticAnalogue = &s
+ transitiveStaticLibrariesForOrdering = s.TransitiveStaticLibrariesForOrdering
}
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
- TableOfContents: android.OptionalPathForPath(tocFile),
- SharedLibrary: unstrippedOutputFile,
- UnstrippedSharedLibrary: library.unstrippedOutputFile,
- CoverageSharedLibrary: library.coverageOutputFile,
- StaticAnalogue: staticAnalogue,
- Target: ctx.Target(),
+ TableOfContents: android.OptionalPathForPath(tocFile),
+ SharedLibrary: unstrippedOutputFile,
+ TransitiveStaticLibrariesForOrdering: transitiveStaticLibrariesForOrdering,
+ Target: ctx.Target(),
})
stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
@@ -1794,6 +1906,11 @@
return nil
}
+ if library.hasLLNDKStubs() && ctx.Module().(*Module).UseVndk() {
+ // LLNDK libraries only need a single stubs variant.
+ return []string{android.FutureApiLevel.String()}
+ }
+
// Future API level is implicitly added if there isn't
vers := library.Properties.Stubs.Versions
if inList(android.FutureApiLevel.String(), vers) {
@@ -2135,8 +2252,7 @@
return nil
}
-// versionSelector normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions,
-// and propagates the value from implementation libraries to llndk libraries with the same name.
+// versionSelector normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions.
func versionSelectorMutator(mctx android.BottomUpMutatorContext) {
if library := moduleLibraryInterface(mctx.Module()); library != nil && CanBeVersionVariant(mctx.Module().(*Module)) {
if library.buildShared() {
@@ -2150,15 +2266,6 @@
// depend on the implementation library and haven't been mutated yet.
library.setAllStubsVersions(versions)
}
-
- if mctx.Module().(*Module).UseVndk() && library.hasLLNDKStubs() {
- // Propagate the version to the llndk stubs module.
- mctx.VisitDirectDepsWithTag(llndkStubDepTag, func(stubs android.Module) {
- if stubsLib := moduleLibraryInterface(stubs); stubsLib != nil {
- stubsLib.setAllStubsVersions(library.allStubsVersions())
- }
- })
- }
}
}
}
@@ -2217,14 +2324,22 @@
}
type bazelCcLibraryStaticAttributes struct {
- Copts bazel.StringListAttribute
- Srcs bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
- Whole_archive_deps bazel.LabelListAttribute
- Linkopts bazel.StringListAttribute
- Linkstatic bool
- Includes bazel.StringListAttribute
- Hdrs bazel.LabelListAttribute
+ Copts bazel.StringListAttribute
+ Srcs bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ Linkopts bazel.StringListAttribute
+ Linkstatic bool
+ Use_libcrt bazel.BoolAttribute
+ Includes bazel.StringListAttribute
+ Hdrs bazel.LabelListAttribute
+
+ Cppflags bazel.StringListAttribute
+ Srcs_c bazel.LabelListAttribute
+ Conlyflags bazel.StringListAttribute
+ Srcs_as bazel.LabelListAttribute
+ Asflags bazel.StringListAttribute
}
type bazelCcLibraryStatic struct {
@@ -2244,15 +2359,29 @@
linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
+ asFlags := compilerAttrs.asFlags
+ if compilerAttrs.asSrcs.IsEmpty() {
+ // Skip asflags for BUILD file simplicity if there are no assembly sources.
+ asFlags = bazel.MakeStringListAttribute(nil)
+ }
+
attrs := &bazelCcLibraryStaticAttributes{
- Copts: compilerAttrs.copts,
- Srcs: compilerAttrs.srcs,
- Deps: linkerAttrs.deps,
- Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
+ Copts: compilerAttrs.copts,
+ Srcs: compilerAttrs.srcs,
+ Implementation_deps: linkerAttrs.deps,
+ Deps: linkerAttrs.exportedDeps,
+ Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
Linkopts: linkerAttrs.linkopts,
Linkstatic: true,
+ Use_libcrt: linkerAttrs.useLibcrt,
Includes: exportedIncludes,
+
+ Cppflags: compilerAttrs.cppFlags,
+ Srcs_c: compilerAttrs.cSrcs,
+ Conlyflags: compilerAttrs.conlyFlags,
+ Srcs_as: compilerAttrs.asSrcs,
+ Asflags: asFlags,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 0aba8de..d6b4529 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -73,13 +73,7 @@
// HeaderLibraryInfo is an empty struct to indicate to dependencies that this is a header library
ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{})
- flagExporterInfo := flagExporterInfoFromCcInfo(ctx, ccInfo)
- // Store flag info to be passed along to androimk
- // TODO(b/184387147): Androidmk should be done in Bazel, not Soong.
- h.library.flagExporterInfo = &flagExporterInfo
- // flag exporters consolidates properties like includes, flags, dependencies that should be
- // exported from this module to other modules
- ctx.SetProvider(FlagExporterInfoProvider, flagExporterInfo)
+ h.library.setFlagExporterInfoFromCcInfo(ctx, ccInfo)
// Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
// validation will fail. For now, set this to an empty list.
@@ -109,10 +103,11 @@
}
type bazelCcLibraryHeadersAttributes struct {
- Copts bazel.StringListAttribute
- Hdrs bazel.LabelListAttribute
- Includes bazel.StringListAttribute
- Deps bazel.LabelListAttribute
+ Copts bazel.StringListAttribute
+ Hdrs bazel.LabelListAttribute
+ Includes bazel.StringListAttribute
+ Deps bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
}
type bazelCcLibraryHeaders struct {
@@ -147,9 +142,10 @@
linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
attrs := &bazelCcLibraryHeadersAttributes{
- Copts: compilerAttrs.copts,
- Includes: exportedIncludes,
- Deps: linkerAttrs.deps,
+ Copts: compilerAttrs.copts,
+ Includes: exportedIncludes,
+ Implementation_deps: linkerAttrs.deps,
+ Deps: linkerAttrs.exportedDeps,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/library_test.go b/cc/library_test.go
index 7975275..6b349b6 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -19,6 +19,7 @@
"testing"
"android/soong/android"
+ "android/soong/bazel/cquery"
)
func TestLibraryReuse(t *testing.T) {
@@ -240,3 +241,82 @@
testCcError(t, `"libfoo" .*: versions: "X" could not be parsed as an integer and is not a recognized codename`, bp)
}
+
+func TestCcLibraryWithBazel(t *testing.T) {
+ bp := `
+cc_library {
+ name: "foo",
+ srcs: ["foo.cc"],
+ bazel_module: { label: "//foo/bar:bar" },
+}`
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
+ config.BazelContext = android.MockBazelContext{
+ OutputBaseDir: "outputbase",
+ LabelToCcInfo: map[string]cquery.CcInfo{
+ "//foo/bar:bar": cquery.CcInfo{
+ CcObjectFiles: []string{"foo.o"},
+ Includes: []string{"include"},
+ SystemIncludes: []string{"system_include"},
+ RootStaticArchives: []string{"foo.a"},
+ RootDynamicLibraries: []string{"foo.so"},
+ },
+ },
+ }
+ ctx := testCcWithConfig(t, config)
+
+ staticFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
+ outputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
+ if err != nil {
+ t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
+ }
+
+ expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.a"}
+ android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
+
+ sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
+ outputFiles, err = sharedFoo.(android.OutputFileProducer).OutputFiles("")
+ if err != nil {
+ t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
+ }
+ expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"}
+ android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
+
+ entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0]
+ expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
+ gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
+ android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
+}
+
+func TestLibraryVersionScript(t *testing.T) {
+ result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
+ cc_library {
+ name: "libfoo",
+ srcs: ["foo.c"],
+ version_script: "foo.map.txt",
+ }`)
+
+ libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
+
+ android.AssertStringListContains(t, "missing dependency on version_script",
+ libfoo.Implicits.Strings(), "foo.map.txt")
+ android.AssertStringDoesContain(t, "missing flag for version_script",
+ libfoo.Args["ldFlags"], "-Wl,--version-script,foo.map.txt")
+
+}
+
+func TestLibraryDynamicList(t *testing.T) {
+ result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
+ cc_library {
+ name: "libfoo",
+ srcs: ["foo.c"],
+ dynamic_list: "foo.dynamic.txt",
+ }`)
+
+ libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
+
+ android.AssertStringListContains(t, "missing dependency on dynamic_list",
+ libfoo.Implicits.Strings(), "foo.dynamic.txt")
+ android.AssertStringDoesContain(t, "missing flag for dynamic_list",
+ libfoo.Args["ldFlags"], "-Wl,--dynamic-list,foo.dynamic.txt")
+
+}
diff --git a/cc/linkable.go b/cc/linkable.go
index b583b69..b510508 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -3,6 +3,7 @@
import (
"android/soong/android"
"android/soong/bazel/cquery"
+ "android/soong/snapshot"
"github.com/google/blueprint"
)
@@ -14,11 +15,6 @@
// SanitizePropDefined returns whether the Sanitizer properties struct for this module is defined.
SanitizePropDefined() bool
- // IsDependencyRoot returns whether a module is of a type which cannot be a linkage dependency
- // of another module. For example, cc_binary and rust_binary represent dependency roots as other
- // modules cannot have linkage dependencies against these types.
- IsDependencyRoot() bool
-
// IsSanitizerEnabled returns whether a sanitizer is enabled.
IsSanitizerEnabled(t SanitizerType) bool
@@ -76,24 +72,27 @@
// Snapshottable defines those functions necessary for handling module snapshots.
type Snapshottable interface {
+ snapshot.VendorSnapshotModuleInterface
+ snapshot.RecoverySnapshotModuleInterface
+
// SnapshotHeaders returns a list of header paths provided by this module.
SnapshotHeaders() android.Paths
- // ExcludeFromVendorSnapshot returns true if this module should be otherwise excluded from the vendor snapshot.
- ExcludeFromVendorSnapshot() bool
-
- // ExcludeFromRecoverySnapshot returns true if this module should be otherwise excluded from the recovery snapshot.
- ExcludeFromRecoverySnapshot() bool
-
// SnapshotLibrary returns true if this module is a snapshot library.
IsSnapshotLibrary() bool
+ // EffectiveLicenseFiles returns the list of License files for this module.
+ EffectiveLicenseFiles() android.Paths
+
// SnapshotRuntimeLibs returns a list of libraries needed by this module at runtime but which aren't build dependencies.
SnapshotRuntimeLibs() []string
// SnapshotSharedLibs returns the list of shared library dependencies for this module.
SnapshotSharedLibs() []string
+ // SnapshotStaticLibs returns the list of static library dependencies for this module.
+ SnapshotStaticLibs() []string
+
// IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
IsSnapshotPrebuilt() bool
}
@@ -124,6 +123,7 @@
IsPrebuilt() bool
Toc() android.OptionalPath
+ Device() bool
Host() bool
InRamdisk() bool
@@ -165,6 +165,9 @@
// "product_specific: true" modules are included here.
UseVndk() bool
+ // Bootstrap tests if this module is allowed to use non-APEX version of libraries.
+ Bootstrap() bool
+
// IsVndkSp returns true if this is a VNDK-SP module.
IsVndkSp() bool
@@ -223,6 +226,9 @@
// Header returns true if this is a library headers module.
Header() bool
+ // StaticExecutable returns true if this is a binary module with "static_executable: true".
+ StaticExecutable() bool
+
// EverInstallable returns true if the module is ever installable
EverInstallable() bool
@@ -305,14 +311,13 @@
// SharedLibraryInfo is a provider to propagate information about a shared C++ library.
type SharedLibraryInfo struct {
- SharedLibrary android.Path
- UnstrippedSharedLibrary android.Path
- Target android.Target
+ SharedLibrary android.Path
+ Target android.Target
- TableOfContents android.OptionalPath
- CoverageSharedLibrary android.OptionalPath
+ TableOfContents android.OptionalPath
- StaticAnalogue *StaticLibraryInfo
+ // should be obtained from static analogue
+ TransitiveStaticLibrariesForOrdering *android.DepSet
}
var SharedLibraryInfoProvider = blueprint.NewProvider(SharedLibraryInfo{})
diff --git a/cc/linker.go b/cc/linker.go
index 449b9ad..7c710d7 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -15,9 +15,10 @@
package cc
import (
+ "fmt"
+
"android/soong/android"
"android/soong/cc/config"
- "fmt"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -104,6 +105,10 @@
// product variant of the C/C++ module.
Static_libs []string
+ // list of ehader libs that only should be used to build vendor or product
+ // variant of the C/C++ module.
+ Header_libs []string
+
// list of shared libs that should not be used to build vendor or
// product variant of the C/C++ module.
Exclude_shared_libs []string
@@ -172,6 +177,14 @@
// in most cases the same libraries are available for the SDK and platform
// variants.
Shared_libs []string
+
+ // list of ehader libs that only should be used to build platform variant of
+ // the C/C++ module.
+ Header_libs []string
+
+ // list of shared libs that should not be used to build the platform variant
+ // of the C/C++ module.
+ Exclude_shared_libs []string
}
Apex struct {
// list of shared libs that should not be used to build the apex variant of
@@ -193,6 +206,9 @@
// local file name to pass to the linker as --version_script
Version_script *string `android:"path,arch_variant"`
+ // local file name to pass to the linker as --dynamic-list
+ Dynamic_list *string `android:"path,arch_variant"`
+
// list of static libs that should not be used to build this module
Exclude_static_libs []string `android:"arch_variant"`
@@ -200,6 +216,18 @@
Exclude_shared_libs []string `android:"arch_variant"`
}
+func invertBoolPtr(value *bool) *bool {
+ if value == nil {
+ return nil
+ }
+ ret := !(*value)
+ return &ret
+}
+
+func (blp *BaseLinkerProperties) libCrt() *bool {
+ return invertBoolPtr(blp.No_libcrt)
+}
+
func NewBaseLinker(sanitize *sanitize) *baseLinker {
return &baseLinker{sanitize: sanitize}
}
@@ -268,6 +296,7 @@
deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Vendor.Exclude_shared_libs)
deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Vendor.Static_libs...)
deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
+ deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Target.Vendor.Header_libs...)
deps.HeaderLibs = removeListFromList(deps.HeaderLibs, linker.Properties.Target.Vendor.Exclude_header_libs)
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor.Exclude_static_libs)
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
@@ -317,6 +346,18 @@
if !ctx.useSdk() {
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Platform.Shared_libs...)
+ deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Platform.Exclude_shared_libs)
+ deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Target.Platform.Header_libs...)
+ }
+
+ deps.SystemSharedLibs = linker.Properties.System_shared_libs
+ // In Bazel conversion mode, variations have not been specified, so SystemSharedLibs may
+ // inaccuarately appear unset, which can cause issues with circular dependencies.
+ if deps.SystemSharedLibs == nil && !ctx.BazelConversionMode() {
+ // Provide a default system_shared_libs if it is unspecified. Note: If an
+ // empty list [] is specified, it implies that the module declines the
+ // default system_shared_libs.
+ deps.SystemSharedLibs = append(deps.SystemSharedLibs, ctx.toolchain().DefaultSharedLibraries()...)
}
if ctx.toolchain().Bionic() {
@@ -325,16 +366,6 @@
deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
}
- deps.SystemSharedLibs = linker.Properties.System_shared_libs
- // In Bazel conversion mode, variations have not been specified, so SystemSharedLibs may
- // inaccuarately appear unset, which can cause issues with circular dependencies.
- if deps.SystemSharedLibs == nil && !ctx.BazelConversionMode() {
- // Provide a default system_shared_libs if it is unspecified. Note: If an
- // empty list [] is specified, it implies that the module declines the
- // default system_shared_libs.
- deps.SystemSharedLibs = []string{"libc", "libm", "libdl"}
- }
-
if inList("libdl", deps.SharedLibs) {
// If system_shared_libs has libc but not libdl, make sure shared_libs does not
// have libdl to avoid loading libdl before libc.
@@ -353,21 +384,13 @@
indexList("libdl", deps.SystemSharedLibs) < indexList("libc", deps.SystemSharedLibs) {
ctx.PropertyErrorf("system_shared_libs", "libdl must be after libc")
}
-
- deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...)
+ } else if ctx.toolchain().Musl() {
+ if !Bool(linker.Properties.No_libcrt) && !ctx.header() {
+ deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
+ }
}
- if ctx.Fuchsia() {
- if ctx.ModuleName() != "libbioniccompat" &&
- ctx.ModuleName() != "libcompiler_rt-extras" &&
- ctx.ModuleName() != "libcompiler_rt" {
- deps.StaticLibs = append(deps.StaticLibs, "libbioniccompat")
- }
- if ctx.ModuleName() != "libcompiler_rt" && ctx.ModuleName() != "libcompiler_rt-extras" {
- deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt")
- }
-
- }
+ deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...)
if ctx.Windows() {
deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread")
@@ -447,12 +470,12 @@
}
if linker.useClangLld(ctx) {
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLldflags())
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags())
} else {
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLdflags())
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags())
}
- if !ctx.toolchain().Bionic() && !ctx.Fuchsia() {
+ if !ctx.toolchain().Bionic() && ctx.Os() != android.LinuxMusl {
CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs)
flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...)
@@ -471,10 +494,6 @@
}
}
- if ctx.Fuchsia() {
- flags.Global.LdFlags = append(flags.Global.LdFlags, "-lfdio", "-lzircon")
- }
-
if ctx.toolchain().LibclangRuntimeLibraryArch() != "" {
flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--exclude-libs="+config.BuiltinsRuntimeLibrary(ctx.toolchain())+".a")
}
@@ -503,7 +522,7 @@
flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--hash-style=both")
}
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainClangLdflags())
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainLdflags())
if Bool(linker.Properties.Group_static_libs) {
flags.GroupStaticLibs = true
@@ -541,6 +560,17 @@
}
}
}
+
+ dynamicList := android.OptionalPathForModuleSrc(ctx, linker.Properties.Dynamic_list)
+ if dynamicList.Valid() {
+ if ctx.Darwin() {
+ ctx.PropertyErrorf("dynamic_list", "Not supported on Darwin")
+ } else {
+ flags.Local.LdFlags = append(flags.Local.LdFlags,
+ "-Wl,--dynamic-list,"+dynamicList.String())
+ flags.LdFlagsDeps = append(flags.LdFlagsDeps, dynamicList.Path())
+ }
+ }
}
return flags
@@ -594,28 +624,3 @@
},
})
}
-
-// Rule to generate .bss symbol ordering file.
-
-var (
- _ = pctx.SourcePathVariable("genSortedBssSymbolsPath", "build/soong/scripts/gen_sorted_bss_symbols.sh")
- genSortedBssSymbols = pctx.AndroidStaticRule("gen_sorted_bss_symbols",
- blueprint.RuleParams{
- Command: "CLANG_BIN=${clangBin} $genSortedBssSymbolsPath ${in} ${out}",
- CommandDeps: []string{"$genSortedBssSymbolsPath", "${clangBin}/llvm-nm"},
- },
- "clangBin")
-)
-
-func (linker *baseLinker) sortBssSymbolsBySize(ctx ModuleContext, in android.Path, symbolOrderingFile android.ModuleOutPath, flags builderFlags) string {
- ctx.Build(pctx, android.BuildParams{
- Rule: genSortedBssSymbols,
- Description: "generate bss symbol order " + symbolOrderingFile.Base(),
- Output: symbolOrderingFile,
- Input: in,
- Args: map[string]string{
- "clangBin": "${config.ClangBin}",
- },
- })
- return "-Wl,--symbol-ordering-file," + symbolOrderingFile.String()
-}
diff --git a/cc/lto.go b/cc/lto.go
index a3b28d9..d9a0118 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -15,6 +15,8 @@
package cc
import (
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
)
@@ -67,23 +69,19 @@
func (lto *lto) begin(ctx BaseModuleContext) {
if ctx.Config().IsEnvTrue("DISABLE_LTO") {
- lto.Properties.Lto.Never = boolPtr(true)
+ 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 = boolPtr(true)
+ lto.Properties.Lto.Thin = proptools.BoolPtr(true)
}
}
}
}
-func (lto *lto) deps(ctx BaseModuleContext, deps Deps) Deps {
- return deps
-}
-
func (lto *lto) useClangLld(ctx BaseModuleContext) bool {
if lto.Properties.Use_clang_lld != nil {
return Bool(lto.Properties.Use_clang_lld)
@@ -233,12 +231,12 @@
// LTO properties for dependencies
if name == "lto-full" {
- variation.lto.Properties.Lto.Full = boolPtr(true)
- variation.lto.Properties.Lto.Thin = boolPtr(false)
+ 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 = boolPtr(false)
- variation.lto.Properties.Lto.Thin = boolPtr(true)
+ variation.lto.Properties.Lto.Full = proptools.BoolPtr(false)
+ variation.lto.Properties.Lto.Thin = proptools.BoolPtr(true)
}
variation.Properties.PreventInstall = true
variation.Properties.HideFromMake = true
diff --git a/cc/makevars.go b/cc/makevars.go
index da5f1fd..8d7a163 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -92,8 +92,8 @@
ctx.Strict("RS_LLVM_AS", "${config.RSLLVMPrebuiltsPath}/llvm-as")
ctx.Strict("RS_LLVM_LINK", "${config.RSLLVMPrebuiltsPath}/llvm-link")
- ctx.Strict("CLANG_EXTERNAL_CFLAGS", "${config.ClangExternalCflags}")
- ctx.Strict("GLOBAL_CLANG_CFLAGS_NO_OVERRIDE", "${config.NoOverrideClangGlobalCflags}")
+ ctx.Strict("CLANG_EXTERNAL_CFLAGS", "${config.ExternalCflags}")
+ ctx.Strict("GLOBAL_CLANG_CFLAGS_NO_OVERRIDE", "${config.NoOverrideGlobalCflags}")
ctx.Strict("GLOBAL_CLANG_CPPFLAGS_NO_OVERRIDE", "")
ctx.Strict("BOARD_VNDK_VERSION", ctx.DeviceConfig().VndkVersion())
@@ -165,7 +165,7 @@
sort.Strings(ndkKnownLibs)
ctx.Strict("NDK_KNOWN_LIBS", strings.Join(ndkKnownLibs, " "))
- hostTargets := ctx.Config().Targets[android.BuildOs]
+ hostTargets := ctx.Config().Targets[ctx.Config().BuildOS]
makeVarsToolchain(ctx, "", hostTargets[0])
if len(hostTargets) > 1 {
makeVarsToolchain(ctx, "2ND_", hostTargets[1])
@@ -212,13 +212,13 @@
ctx.StrictRaw(makePrefix+"C_SYSTEM_INCLUDES", strings.Join(systemIncludes, " "))
if target.Arch.ArchType == android.Arm {
- flags, err := toolchain.ClangInstructionSetFlags("arm")
+ flags, err := toolchain.InstructionSetFlags("arm")
if err != nil {
panic(err)
}
ctx.Strict(makePrefix+"arm_CFLAGS", flags)
- flags, err = toolchain.ClangInstructionSetFlags("thumb")
+ flags, err = toolchain.InstructionSetFlags("thumb")
if err != nil {
panic(err)
}
@@ -230,29 +230,29 @@
ctx.Strict(clangPrefix+"TRIPLE", toolchain.ClangTriple())
ctx.Strict(clangPrefix+"GLOBAL_CFLAGS", strings.Join([]string{
- toolchain.ClangCflags(),
- "${config.CommonClangGlobalCflags}",
- fmt.Sprintf("${config.%sClangGlobalCflags}", hod),
- toolchain.ToolchainClangCflags(),
+ toolchain.Cflags(),
+ "${config.CommonGlobalCflags}",
+ fmt.Sprintf("${config.%sGlobalCflags}", hod),
+ toolchain.ToolchainCflags(),
clangExtras,
productExtraCflags,
}, " "))
ctx.Strict(clangPrefix+"GLOBAL_CPPFLAGS", strings.Join([]string{
- "${config.CommonClangGlobalCppflags}",
+ "${config.CommonGlobalCppflags}",
fmt.Sprintf("${config.%sGlobalCppflags}", hod),
- toolchain.ClangCppflags(),
+ toolchain.Cppflags(),
}, " "))
ctx.Strict(clangPrefix+"GLOBAL_LDFLAGS", strings.Join([]string{
fmt.Sprintf("${config.%sGlobalLdflags}", hod),
- toolchain.ClangLdflags(),
- toolchain.ToolchainClangLdflags(),
+ toolchain.Ldflags(),
+ toolchain.ToolchainLdflags(),
productExtraLdflags,
clangExtras,
}, " "))
ctx.Strict(clangPrefix+"GLOBAL_LLDFLAGS", strings.Join([]string{
fmt.Sprintf("${config.%sGlobalLldflags}", hod),
- toolchain.ClangLldflags(),
- toolchain.ToolchainClangLdflags(),
+ toolchain.Lldflags(),
+ toolchain.ToolchainLdflags(),
productExtraLdflags,
clangExtras,
}, " "))
@@ -288,9 +288,7 @@
ctx.Strict(makePrefix+"OBJCOPY", "${config.ClangBin}/llvm-objcopy")
ctx.Strict(makePrefix+"LD", "${config.ClangBin}/lld")
ctx.Strict(makePrefix+"NDK_TRIPLE", config.NDKTriple(toolchain))
- // TODO: work out whether to make this "${config.ClangBin}/llvm-", which
- // should mostly work, or remove it.
- ctx.Strict(makePrefix+"TOOLS_PREFIX", gccCmd(toolchain, ""))
+ ctx.Strict(makePrefix+"TOOLS_PREFIX", "${config.ClangBin}/llvm-")
// TODO: GCC version is obsolete now that GCC has been removed.
ctx.Strict(makePrefix+"GCC_VERSION", toolchain.GccVersion())
}
diff --git a/cc/ndk_abi.go b/cc/ndk_abi.go
new file mode 100644
index 0000000..927fa2e
--- /dev/null
+++ b/cc/ndk_abi.go
@@ -0,0 +1,102 @@
+// 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 cc
+
+import (
+ "android/soong/android"
+)
+
+func init() {
+ android.RegisterSingletonType("ndk_abi_dump", NdkAbiDumpSingleton)
+ android.RegisterSingletonType("ndk_abi_diff", NdkAbiDiffSingleton)
+}
+
+func getNdkAbiDumpInstallBase(ctx android.PathContext) android.OutputPath {
+ return android.PathForOutput(ctx).Join(ctx, "abi-dumps/ndk")
+}
+
+func getNdkAbiDumpTimestampFile(ctx android.PathContext) android.OutputPath {
+ return android.PathForOutput(ctx, "ndk_abi_dump.timestamp")
+}
+
+func NdkAbiDumpSingleton() android.Singleton {
+ return &ndkAbiDumpSingleton{}
+}
+
+type ndkAbiDumpSingleton struct{}
+
+func (n *ndkAbiDumpSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ var depPaths android.Paths
+ ctx.VisitAllModules(func(module android.Module) {
+ if !module.Enabled() {
+ return
+ }
+
+ if m, ok := module.(*Module); ok {
+ if installer, ok := m.installer.(*stubDecorator); ok {
+ if canDumpAbi() {
+ depPaths = append(depPaths, installer.abiDumpPath)
+ }
+ }
+ }
+ })
+
+ // `m dump-ndk-abi` will dump the NDK ABI.
+ // `development/tools/ndk/update_ndk_abi.sh` will dump the NDK ABI and
+ // update the golden copies in prebuilts/abi-dumps/ndk.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: getNdkAbiDumpTimestampFile(ctx),
+ Implicits: depPaths,
+ })
+
+ ctx.Phony("dump-ndk-abi", getNdkAbiDumpTimestampFile(ctx))
+}
+
+func getNdkAbiDiffTimestampFile(ctx android.PathContext) android.WritablePath {
+ return android.PathForOutput(ctx, "ndk_abi_diff.timestamp")
+}
+
+func NdkAbiDiffSingleton() android.Singleton {
+ return &ndkAbiDiffSingleton{}
+}
+
+type ndkAbiDiffSingleton struct{}
+
+func (n *ndkAbiDiffSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ var depPaths android.Paths
+ ctx.VisitAllModules(func(module android.Module) {
+ if m, ok := module.(android.Module); ok && !m.Enabled() {
+ return
+ }
+
+ if m, ok := module.(*Module); ok {
+ if installer, ok := m.installer.(*stubDecorator); ok {
+ depPaths = append(depPaths, installer.abiDiffPaths...)
+ }
+ }
+ })
+
+ depPaths = append(depPaths, getNdkAbiDumpTimestampFile(ctx))
+
+ // `m diff-ndk-abi` will diff the NDK ABI.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: getNdkAbiDiffTimestampFile(ctx),
+ Implicits: depPaths,
+ })
+
+ ctx.Phony("diff-ndk-abi", getNdkAbiDiffTimestampFile(ctx))
+}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 95d8477..63e8261 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -16,6 +16,8 @@
import (
"fmt"
+ "path/filepath"
+ "runtime"
"strings"
"sync"
@@ -28,6 +30,9 @@
func init() {
pctx.HostBinToolVariable("ndkStubGenerator", "ndkstubgen")
pctx.HostBinToolVariable("ndk_api_coverage_parser", "ndk_api_coverage_parser")
+ pctx.HostBinToolVariable("abidiff", "abidiff")
+ pctx.HostBinToolVariable("abitidy", "abitidy")
+ pctx.HostBinToolVariable("abidw", "abidw")
}
var (
@@ -44,11 +49,31 @@
CommandDeps: []string{"$ndk_api_coverage_parser"},
}, "apiMap")
+ abidw = pctx.AndroidStaticRule("abidw",
+ blueprint.RuleParams{
+ Command: "$abidw --type-id-style hash --no-corpus-path " +
+ "--no-show-locs --no-comp-dir-path -w $symbolList $in | " +
+ "$abitidy --all -o $out",
+ CommandDeps: []string{"$abitidy", "$abidw"},
+ }, "symbolList")
+
+ abidiff = pctx.AndroidStaticRule("abidiff",
+ blueprint.RuleParams{
+ // Need to create *some* output for ninja. We don't want to use tee
+ // because we don't want to spam the build output with "nothing
+ // changed" messages, so redirect output message to $out, and if
+ // changes were detected print the output and fail.
+ Command: "$abidiff $args $in > $out || (cat $out && false)",
+ CommandDeps: []string{"$abidiff"},
+ }, "args")
+
ndkLibrarySuffix = ".ndk"
ndkKnownLibsKey = android.NewOnceKey("ndkKnownLibsKey")
// protects ndkKnownLibs writes during parallel BeginMutator.
ndkKnownLibsLock sync.Mutex
+
+ stubImplementation = dependencyTag{name: "stubImplementation"}
)
// The First_version and Unversioned_until properties of this struct should not
@@ -89,6 +114,8 @@
versionScriptPath android.ModuleGenPath
parsedCoverageXmlPath android.ModuleOutPath
installPath android.Path
+ abiDumpPath android.OutputPath
+ abiDiffPaths android.Paths
apiLevel android.ApiLevel
firstVersion android.ApiLevel
@@ -123,6 +150,10 @@
if !ctx.Module().Enabled() {
return nil
}
+ if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
+ ctx.Module().Disable()
+ return nil
+ }
firstVersion, err := nativeApiLevelFromUser(ctx,
String(this.properties.First_version))
if err != nil {
@@ -204,30 +235,45 @@
return addStubLibraryCompilerFlags(flags)
}
-func compileStubLibrary(ctx ModuleContext, flags Flags, symbolFile, apiLevel, genstubFlags string) (Objects, android.ModuleGenPath) {
- arch := ctx.Arch().ArchType.String()
+type ndkApiOutputs struct {
+ stubSrc android.ModuleGenPath
+ versionScript android.ModuleGenPath
+ symbolList android.ModuleGenPath
+}
+
+func parseNativeAbiDefinition(ctx ModuleContext, symbolFile string,
+ apiLevel android.ApiLevel, genstubFlags string) ndkApiOutputs {
stubSrcPath := android.PathForModuleGen(ctx, "stub.c")
versionScriptPath := android.PathForModuleGen(ctx, "stub.map")
symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
+ symbolListPath := android.PathForModuleGen(ctx, "abi_symbol_list.txt")
apiLevelsJson := android.GetApiLevelsJson(ctx)
ctx.Build(pctx, android.BuildParams{
Rule: genStubSrc,
Description: "generate stubs " + symbolFilePath.Rel(),
- Outputs: []android.WritablePath{stubSrcPath, versionScriptPath},
- Input: symbolFilePath,
- Implicits: []android.Path{apiLevelsJson},
+ Outputs: []android.WritablePath{stubSrcPath, versionScriptPath,
+ symbolListPath},
+ Input: symbolFilePath,
+ Implicits: []android.Path{apiLevelsJson},
Args: map[string]string{
- "arch": arch,
- "apiLevel": apiLevel,
+ "arch": ctx.Arch().ArchType.String(),
+ "apiLevel": apiLevel.String(),
"apiMap": apiLevelsJson.String(),
"flags": genstubFlags,
},
})
- subdir := ""
- srcs := []android.Path{stubSrcPath}
- return compileObjs(ctx, flagsToBuilderFlags(flags), subdir, srcs, nil, nil), versionScriptPath
+ return ndkApiOutputs{
+ stubSrc: stubSrcPath,
+ versionScript: versionScriptPath,
+ symbolList: symbolListPath,
+ }
+}
+
+func compileStubLibrary(ctx ModuleContext, flags Flags, src android.Path) Objects {
+ return compileObjs(ctx, flagsToBuilderFlags(flags), "",
+ android.Paths{src}, nil, nil)
}
func parseSymbolFileForCoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath {
@@ -248,6 +294,140 @@
return parsedApiCoveragePath
}
+func (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path {
+ dep := ctx.GetDirectDepWithTag(strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix),
+ stubImplementation)
+ if dep == nil {
+ ctx.ModuleErrorf("Could not find implementation for stub")
+ return nil
+ }
+ impl, ok := dep.(*Module)
+ if !ok {
+ ctx.ModuleErrorf("Implementation for stub is not correct module type")
+ }
+ output := impl.UnstrippedOutputFile()
+ if output == nil {
+ ctx.ModuleErrorf("implementation module (%s) has no output", impl)
+ return nil
+ }
+
+ return output
+}
+
+func (this *stubDecorator) libraryName(ctx ModuleContext) string {
+ return strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix)
+}
+
+func (this *stubDecorator) findPrebuiltAbiDump(ctx ModuleContext,
+ apiLevel android.ApiLevel) android.OptionalPath {
+
+ subpath := filepath.Join("prebuilts/abi-dumps/ndk", apiLevel.String(),
+ ctx.Arch().ArchType.String(), this.libraryName(ctx), "abi.xml")
+ return android.ExistentPathForSource(ctx, subpath)
+}
+
+// Feature flag.
+func canDumpAbi() bool {
+ return runtime.GOOS != "darwin"
+}
+
+// Feature flag to disable diffing against prebuilts.
+func canDiffAbi() bool {
+ return false
+}
+
+func (this *stubDecorator) dumpAbi(ctx ModuleContext, symbolList android.Path) {
+ implementationLibrary := this.findImplementationLibrary(ctx)
+ this.abiDumpPath = getNdkAbiDumpInstallBase(ctx).Join(ctx,
+ this.apiLevel.String(), ctx.Arch().ArchType.String(),
+ this.libraryName(ctx), "abi.xml")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: abidw,
+ Description: fmt.Sprintf("abidw %s", implementationLibrary),
+ Output: this.abiDumpPath,
+ Input: implementationLibrary,
+ Implicit: symbolList,
+ Args: map[string]string{
+ "symbolList": symbolList.String(),
+ },
+ })
+}
+
+func findNextApiLevel(ctx ModuleContext, apiLevel android.ApiLevel) *android.ApiLevel {
+ apiLevels := append(ctx.Config().AllSupportedApiLevels(),
+ android.FutureApiLevel)
+ for _, api := range apiLevels {
+ if api.GreaterThan(apiLevel) {
+ return &api
+ }
+ }
+ return nil
+}
+
+func (this *stubDecorator) diffAbi(ctx ModuleContext) {
+ missingPrebuiltError := fmt.Sprintf(
+ "Did not find prebuilt ABI dump for %q. Generate with "+
+ "//development/tools/ndk/update_ndk_abi.sh.", this.libraryName(ctx))
+
+ // Catch any ABI changes compared to the checked-in definition of this API
+ // level.
+ abiDiffPath := android.PathForModuleOut(ctx, "abidiff.timestamp")
+ prebuiltAbiDump := this.findPrebuiltAbiDump(ctx, this.apiLevel)
+ if !prebuiltAbiDump.Valid() {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.ErrorRule,
+ Output: abiDiffPath,
+ Args: map[string]string{
+ "error": missingPrebuiltError,
+ },
+ })
+ } else {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: abidiff,
+ Description: fmt.Sprintf("abidiff %s %s", prebuiltAbiDump,
+ this.abiDumpPath),
+ Output: abiDiffPath,
+ Inputs: android.Paths{prebuiltAbiDump.Path(), this.abiDumpPath},
+ })
+ }
+ this.abiDiffPaths = append(this.abiDiffPaths, abiDiffPath)
+
+ // Also ensure that the ABI of the next API level (if there is one) matches
+ // this API level. *New* ABI is allowed, but any changes to APIs that exist
+ // in this API level are disallowed.
+ if !this.apiLevel.IsCurrent() {
+ nextApiLevel := findNextApiLevel(ctx, this.apiLevel)
+ if nextApiLevel == nil {
+ panic(fmt.Errorf("could not determine which API level follows "+
+ "non-current API level %s", this.apiLevel))
+ }
+ nextAbiDiffPath := android.PathForModuleOut(ctx,
+ "abidiff_next.timestamp")
+ nextAbiDump := this.findPrebuiltAbiDump(ctx, *nextApiLevel)
+ if !nextAbiDump.Valid() {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.ErrorRule,
+ Output: nextAbiDiffPath,
+ Args: map[string]string{
+ "error": missingPrebuiltError,
+ },
+ })
+ } else {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: abidiff,
+ Description: fmt.Sprintf("abidiff %s %s", this.abiDumpPath,
+ nextAbiDump),
+ Output: nextAbiDiffPath,
+ Inputs: android.Paths{this.abiDumpPath, nextAbiDump.Path()},
+ Args: map[string]string{
+ "args": "--no-added-syms",
+ },
+ })
+ }
+ this.abiDiffPaths = append(this.abiDiffPaths, nextAbiDiffPath)
+ }
+}
+
func (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
if !strings.HasSuffix(String(c.properties.Symbol_file), ".map.txt") {
ctx.PropertyErrorf("symbol_file", "must end with .map.txt")
@@ -264,9 +444,15 @@
}
symbolFile := String(c.properties.Symbol_file)
- objs, versionScript := compileStubLibrary(ctx, flags, symbolFile,
- c.apiLevel.String(), "")
- c.versionScriptPath = versionScript
+ nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "")
+ objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+ c.versionScriptPath = nativeAbiResult.versionScript
+ if canDumpAbi() {
+ c.dumpAbi(ctx, nativeAbiResult.symbolList)
+ if canDiffAbi() {
+ c.diffAbi(ctx)
+ }
+ }
if c.apiLevel.IsCurrent() && ctx.PrimaryArch() {
c.parsedCoverageXmlPath = parseSymbolFileForCoverage(ctx, symbolFile)
}
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index b91c737..51ec6b8 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -186,9 +186,8 @@
})
} else {
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
- SharedLibrary: lib,
- UnstrippedSharedLibrary: lib,
- Target: ctx.Target(),
+ SharedLibrary: lib,
+ Target: ctx.Target(),
})
}
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index d8c500e..2726b1a 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -146,16 +146,20 @@
baseDepPaths := append(installPaths, combinedLicense)
- // There's a dummy "ndk" rule defined in ndk/Android.mk that depends on
- // this. `m ndk` will build the sysroots.
ctx.Build(pctx, android.BuildParams{
- Rule: android.Touch,
- Output: getNdkBaseTimestampFile(ctx),
- Implicits: baseDepPaths,
+ Rule: android.Touch,
+ Output: getNdkBaseTimestampFile(ctx),
+ Implicits: baseDepPaths,
+ Validation: getNdkAbiDiffTimestampFile(ctx),
})
fullDepPaths := append(staticLibInstallPaths, getNdkBaseTimestampFile(ctx))
+ // There's a phony "ndk" rule defined in core/main.mk that depends on this.
+ // `m ndk` will build the sysroots for the architectures in the current
+ // lunch target. `build/soong/scripts/build-ndk-prebuilts.sh` will build the
+ // sysroots for all the NDK architectures and package them so they can be
+ // imported into the NDK's build.
ctx.Build(pctx, android.BuildParams{
Rule: android.Touch,
Output: getNdkFullTimestampFile(ctx),
diff --git a/cc/ndkstubgen/__init__.py b/cc/ndkstubgen/__init__.py
index 86bf6ff..5e6b8f5 100755
--- a/cc/ndkstubgen/__init__.py
+++ b/cc/ndkstubgen/__init__.py
@@ -18,7 +18,7 @@
import argparse
import json
import logging
-import os
+from pathlib import Path
import sys
from typing import Iterable, TextIO
@@ -28,10 +28,12 @@
class Generator:
"""Output generator that writes stub source files and version scripts."""
- def __init__(self, src_file: TextIO, version_script: TextIO, arch: Arch,
- api: int, llndk: bool, apex: bool) -> None:
+ def __init__(self, src_file: TextIO, version_script: TextIO,
+ symbol_list: TextIO, arch: Arch, api: int, llndk: bool,
+ apex: bool) -> None:
self.src_file = src_file
self.version_script = version_script
+ self.symbol_list = symbol_list
self.arch = arch
self.api = api
self.llndk = llndk
@@ -39,6 +41,7 @@
def write(self, versions: Iterable[Version]) -> None:
"""Writes all symbol data to the output files."""
+ self.symbol_list.write('[abi_symbol_list]\n')
for version in versions:
self.write_version(version)
@@ -76,11 +79,11 @@
weak = '__attribute__((weak)) '
if 'var' in symbol.tags:
- self.src_file.write('{}int {} = 0;\n'.format(
- weak, symbol.name))
+ self.src_file.write(f'{weak}int {symbol.name} = 0;\n')
else:
- self.src_file.write('{}void {}() {{}}\n'.format(
- weak, symbol.name))
+ self.src_file.write(f'{weak}void {symbol.name}() {{}}\n')
+
+ self.symbol_list.write(f'{symbol.name}\n')
if not version_empty and section_versioned:
base = '' if version.base is None else ' ' + version.base
@@ -91,6 +94,10 @@
"""Parses and returns command line arguments."""
parser = argparse.ArgumentParser()
+ def resolved_path(raw: str) -> Path:
+ """Returns a resolved Path for the given string."""
+ return Path(raw).resolve()
+
parser.add_argument('-v', '--verbose', action='count', default=0)
parser.add_argument(
@@ -101,28 +108,32 @@
parser.add_argument(
'--llndk', action='store_true', help='Use the LLNDK variant.')
parser.add_argument(
- '--apex', action='store_true', help='Use the APEX variant.')
+ '--apex',
+ action='store_true',
+ help='Use the APEX variant. Note: equivalent to --system-api.')
+ parser.add_argument(
+ '--system-api',
+ action='store_true',
+ dest='apex',
+ help='Use the SystemAPI variant. Note: equivalent to --apex.')
- # https://github.com/python/mypy/issues/1317
- # mypy has issues with using os.path.realpath as an argument here.
- parser.add_argument(
- '--api-map',
- type=os.path.realpath, # type: ignore
- required=True,
- help='Path to the API level map JSON file.')
+ parser.add_argument('--api-map',
+ type=resolved_path,
+ required=True,
+ help='Path to the API level map JSON file.')
- parser.add_argument(
- 'symbol_file',
- type=os.path.realpath, # type: ignore
- help='Path to symbol file.')
- parser.add_argument(
- 'stub_src',
- type=os.path.realpath, # type: ignore
- help='Path to output stub source file.')
- parser.add_argument(
- 'version_script',
- type=os.path.realpath, # type: ignore
- help='Path to output version script.')
+ parser.add_argument('symbol_file',
+ type=resolved_path,
+ help='Path to symbol file.')
+ parser.add_argument('stub_src',
+ type=resolved_path,
+ help='Path to output stub source file.')
+ parser.add_argument('version_script',
+ type=resolved_path,
+ help='Path to output version script.')
+ parser.add_argument('symbol_list',
+ type=resolved_path,
+ help='Path to output abigail symbol list.')
return parser.parse_args()
@@ -131,7 +142,7 @@
"""Program entry point."""
args = parse_args()
- with open(args.api_map) as map_file:
+ with args.api_map.open() as map_file:
api_map = json.load(map_file)
api = symbolfile.decode_api_level(args.api, api_map)
@@ -141,19 +152,20 @@
verbosity = 2
logging.basicConfig(level=verbose_map[verbosity])
- with open(args.symbol_file) as symbol_file:
+ with args.symbol_file.open() as symbol_file:
try:
versions = symbolfile.SymbolFileParser(symbol_file, api_map,
args.arch, api, args.llndk,
args.apex).parse()
except symbolfile.MultiplyDefinedSymbolError as ex:
- sys.exit('{}: error: {}'.format(args.symbol_file, ex))
+ sys.exit(f'{args.symbol_file}: error: {ex}')
- with open(args.stub_src, 'w') as src_file:
- with open(args.version_script, 'w') as version_file:
- generator = Generator(src_file, version_file, args.arch, api,
- args.llndk, args.apex)
- generator.write(versions)
+ with args.stub_src.open('w') as src_file:
+ with args.version_script.open('w') as version_script:
+ with args.symbol_list.open('w') as symbol_list:
+ generator = Generator(src_file, version_script, symbol_list,
+ args.arch, api, args.llndk, args.apex)
+ generator.write(versions)
if __name__ == '__main__':
diff --git a/cc/ndkstubgen/test_ndkstubgen.py b/cc/ndkstubgen/test_ndkstubgen.py
index 6d2c9d6..c8cd056 100755
--- a/cc/ndkstubgen/test_ndkstubgen.py
+++ b/cc/ndkstubgen/test_ndkstubgen.py
@@ -19,9 +19,10 @@
import textwrap
import unittest
-import ndkstubgen
import symbolfile
-from symbolfile import Arch, Tag
+from symbolfile import Arch, Tags
+
+import ndkstubgen
# pylint: disable=missing-docstring
@@ -33,26 +34,30 @@
# OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
src_file = io.StringIO()
version_file = io.StringIO()
- generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
- 9, False, False)
+ symbol_list_file = io.StringIO()
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file,
+ Arch('arm'), 9, False, False)
- version = symbolfile.Version('VERSION_PRIVATE', None, [], [
- symbolfile.Symbol('foo', []),
+ version = symbolfile.Version('VERSION_PRIVATE', None, Tags(), [
+ symbolfile.Symbol('foo', Tags()),
])
generator.write_version(version)
self.assertEqual('', src_file.getvalue())
self.assertEqual('', version_file.getvalue())
- version = symbolfile.Version('VERSION', None, [Tag('x86')], [
- symbolfile.Symbol('foo', []),
- ])
+ version = symbolfile.Version('VERSION', None, Tags.from_strs(['x86']),
+ [
+ symbolfile.Symbol('foo', Tags()),
+ ])
generator.write_version(version)
self.assertEqual('', src_file.getvalue())
self.assertEqual('', version_file.getvalue())
- version = symbolfile.Version('VERSION', None, [Tag('introduced=14')], [
- symbolfile.Symbol('foo', []),
- ])
+ version = symbolfile.Version('VERSION', None,
+ Tags.from_strs(['introduced=14']), [
+ symbolfile.Symbol('foo', Tags()),
+ ])
generator.write_version(version)
self.assertEqual('', src_file.getvalue())
self.assertEqual('', version_file.getvalue())
@@ -62,32 +67,34 @@
# SymbolPresenceTest.
src_file = io.StringIO()
version_file = io.StringIO()
- generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
- 9, False, False)
+ symbol_list_file = io.StringIO()
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file,
+ Arch('arm'), 9, False, False)
- version = symbolfile.Version('VERSION_1', None, [], [
- symbolfile.Symbol('foo', [Tag('x86')]),
+ version = symbolfile.Version('VERSION_1', None, Tags(), [
+ symbolfile.Symbol('foo', Tags.from_strs(['x86'])),
])
generator.write_version(version)
self.assertEqual('', src_file.getvalue())
self.assertEqual('', version_file.getvalue())
- version = symbolfile.Version('VERSION_1', None, [], [
- symbolfile.Symbol('foo', [Tag('introduced=14')]),
+ version = symbolfile.Version('VERSION_1', None, Tags(), [
+ symbolfile.Symbol('foo', Tags.from_strs(['introduced=14'])),
])
generator.write_version(version)
self.assertEqual('', src_file.getvalue())
self.assertEqual('', version_file.getvalue())
- version = symbolfile.Version('VERSION_1', None, [], [
- symbolfile.Symbol('foo', [Tag('llndk')]),
+ version = symbolfile.Version('VERSION_1', None, Tags(), [
+ symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
])
generator.write_version(version)
self.assertEqual('', src_file.getvalue())
self.assertEqual('', version_file.getvalue())
- version = symbolfile.Version('VERSION_1', None, [], [
- symbolfile.Symbol('foo', [Tag('apex')]),
+ version = symbolfile.Version('VERSION_1', None, Tags(), [
+ symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
])
generator.write_version(version)
self.assertEqual('', src_file.getvalue())
@@ -96,22 +103,23 @@
def test_write(self) -> None:
src_file = io.StringIO()
version_file = io.StringIO()
- generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
- 9, False, False)
+ symbol_list_file = io.StringIO()
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file,
+ Arch('arm'), 9, False, False)
versions = [
- symbolfile.Version('VERSION_1', None, [], [
- symbolfile.Symbol('foo', []),
- symbolfile.Symbol('bar', [Tag('var')]),
- symbolfile.Symbol('woodly', [Tag('weak')]),
- symbolfile.Symbol('doodly',
- [Tag('weak'), Tag('var')]),
+ symbolfile.Version('VERSION_1', None, Tags(), [
+ symbolfile.Symbol('foo', Tags()),
+ symbolfile.Symbol('bar', Tags.from_strs(['var'])),
+ symbolfile.Symbol('woodly', Tags.from_strs(['weak'])),
+ symbolfile.Symbol('doodly', Tags.from_strs(['weak', 'var'])),
]),
- symbolfile.Version('VERSION_2', 'VERSION_1', [], [
- symbolfile.Symbol('baz', []),
+ symbolfile.Version('VERSION_2', 'VERSION_1', Tags(), [
+ symbolfile.Symbol('baz', Tags()),
]),
- symbolfile.Version('VERSION_3', 'VERSION_1', [], [
- symbolfile.Symbol('qux', [Tag('versioned=14')]),
+ symbolfile.Version('VERSION_3', 'VERSION_1', Tags(), [
+ symbolfile.Symbol('qux', Tags.from_strs(['versioned=14'])),
]),
]
@@ -141,6 +149,17 @@
""")
self.assertEqual(expected_version, version_file.getvalue())
+ expected_allowlist = textwrap.dedent("""\
+ [abi_symbol_list]
+ foo
+ bar
+ woodly
+ doodly
+ baz
+ qux
+ """)
+ self.assertEqual(expected_allowlist, symbol_list_file.getvalue())
+
class IntegrationTest(unittest.TestCase):
def test_integration(self) -> None:
@@ -186,8 +205,10 @@
src_file = io.StringIO()
version_file = io.StringIO()
- generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
- 9, False, False)
+ symbol_list_file = io.StringIO()
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file,
+ Arch('arm'), 9, False, False)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -215,6 +236,16 @@
""")
self.assertEqual(expected_version, version_file.getvalue())
+ expected_allowlist = textwrap.dedent("""\
+ [abi_symbol_list]
+ foo
+ baz
+ qux
+ wibble
+ wobble
+ """)
+ self.assertEqual(expected_allowlist, symbol_list_file.getvalue())
+
def test_integration_future_api(self) -> None:
api_map = {
'O': 9000,
@@ -238,8 +269,10 @@
src_file = io.StringIO()
version_file = io.StringIO()
- generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
- 9001, False, False)
+ symbol_list_file = io.StringIO()
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file,
+ Arch('arm'), 9001, False, False)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -257,6 +290,13 @@
""")
self.assertEqual(expected_version, version_file.getvalue())
+ expected_allowlist = textwrap.dedent("""\
+ [abi_symbol_list]
+ foo
+ bar
+ """)
+ self.assertEqual(expected_allowlist, symbol_list_file.getvalue())
+
def test_multiple_definition(self) -> None:
input_file = io.StringIO(textwrap.dedent("""\
VERSION_1 {
@@ -336,8 +376,10 @@
src_file = io.StringIO()
version_file = io.StringIO()
- generator = ndkstubgen.Generator(src_file, version_file, Arch('arm'),
- 9, False, True)
+ symbol_list_file = io.StringIO()
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file,
+ Arch('arm'), 9, False, True)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -371,6 +413,40 @@
""")
self.assertEqual(expected_version, version_file.getvalue())
+ def test_empty_stub(self) -> None:
+ """Tests that empty stubs can be generated.
+
+ This is not a common case, but libraries whose only behavior is to
+ interpose symbols to alter existing behavior do not need to expose
+ their interposing symbols as API, so it's possible for the stub to be
+ empty while still needing a stub to link against. libsigchain is an
+ example of this.
+ """
+ input_file = io.StringIO(textwrap.dedent("""\
+ VERSION_1 {
+ local:
+ *;
+ };
+ """))
+ parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
+ 9, llndk=False, apex=True)
+ versions = parser.parse()
+
+ src_file = io.StringIO()
+ version_file = io.StringIO()
+ symbol_list_file = io.StringIO()
+ generator = ndkstubgen.Generator(src_file,
+ version_file,
+ symbol_list_file,
+ Arch('arm'),
+ 9,
+ llndk=False,
+ apex=True)
+ generator.write(versions)
+
+ self.assertEqual('', src_file.getvalue())
+ self.assertEqual('', version_file.getvalue())
+
def main() -> None:
suite = unittest.TestLoader().loadTestsFromName(__name__)
diff --git a/cc/object.go b/cc/object.go
index d8f1aba..bd9f228 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -67,9 +67,19 @@
}
type ObjectLinkerProperties struct {
+ // list of static library modules that should only provide headers for this module.
+ Static_libs []string `android:"arch_variant,variant_prepend"`
+
+ // list of shared library modules should only provide headers for this module.
+ Shared_libs []string `android:"arch_variant"`
+
// list of modules that should only provide headers for this module.
Header_libs []string `android:"arch_variant,variant_prepend"`
+ // list of default libraries that will provide headers for this module. If unset, generally
+ // defaults to libc, libm, and libdl. Set to [] to prevent using headers from the defaults.
+ System_shared_libs []string `android:"arch_variant"`
+
// names of other cc_object modules to link into this module using partial linking
Objs []string `android:"arch_variant"`
@@ -84,8 +94,8 @@
Crt *bool
}
-func newObject() *Module {
- module := newBaseModule(android.HostAndDeviceSupported, android.MultilibBoth)
+func newObject(hod android.HostOrDeviceSupported) *Module {
+ module := newBaseModule(hod, android.MultilibBoth)
module.sanitize = &sanitize{}
module.stl = &stl{}
return module
@@ -95,7 +105,7 @@
// necessary, but sometimes used to generate .s files from .c files to use as
// input to a cc_genrule module.
func ObjectFactory() android.Module {
- module := newObject()
+ module := newObject(android.HostAndDeviceSupported)
module.linker = &objectLinker{
baseLinker: NewBaseLinker(module.sanitize),
}
@@ -113,10 +123,11 @@
// For bp2build conversion.
type bazelObjectAttributes struct {
Srcs bazel.LabelListAttribute
+ Srcs_as bazel.LabelListAttribute
Hdrs bazel.LabelListAttribute
Deps bazel.LabelListAttribute
Copts bazel.StringListAttribute
- Asflags []string
+ Asflags bazel.StringListAttribute
}
type bazelObject struct {
@@ -157,8 +168,6 @@
// Set arch-specific configurable attributes
compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
- var asFlags []string
-
var deps bazel.LabelListAttribute
for _, props := range m.linker.linkerProps() {
if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
@@ -167,25 +176,20 @@
}
}
- productVariableProps := android.ProductVariableProperties(ctx)
- if props, exists := productVariableProps["Asflags"]; exists {
- // TODO(b/183595873): consider deduplicating handling of product variable properties
- for _, prop := range props {
- flags, ok := prop.Property.([]string)
- if !ok {
- ctx.ModuleErrorf("Could not convert product variable asflag property")
- return
- }
- // TODO(b/183595873) handle other product variable usages -- as selects?
- if newFlags, subbed := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable); subbed {
- asFlags = append(asFlags, newFlags...)
- }
- }
+ // Don't split cc_object srcs across languages. Doing so would add complexity,
+ // and this isn't typically done for cc_object.
+ srcs := compilerAttrs.srcs
+ srcs.Append(compilerAttrs.cSrcs)
+
+ asFlags := compilerAttrs.asFlags
+ if compilerAttrs.asSrcs.IsEmpty() {
+ // Skip asflags for BUILD file simplicity if there are no assembly sources.
+ asFlags = bazel.MakeStringListAttribute(nil)
}
- // TODO(b/183595872) warn/error if we're not handling product variables
attrs := &bazelObjectAttributes{
- Srcs: compilerAttrs.srcs,
+ Srcs: srcs,
+ Srcs_as: compilerAttrs.asSrcs,
Deps: deps,
Copts: compilerAttrs.copts,
Asflags: asFlags,
@@ -211,12 +215,23 @@
func (object *objectLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
deps.HeaderLibs = append(deps.HeaderLibs, object.Properties.Header_libs...)
+ deps.SharedLibs = append(deps.SharedLibs, object.Properties.Shared_libs...)
+ deps.StaticLibs = append(deps.StaticLibs, object.Properties.Static_libs...)
deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
+
+ deps.SystemSharedLibs = object.Properties.System_shared_libs
+ if deps.SystemSharedLibs == nil {
+ // Provide a default set of shared libraries if system_shared_libs is unspecified.
+ // Note: If an empty list [] is specified, it implies that the module declines the
+ // default shared libraries.
+ deps.SystemSharedLibs = append(deps.SystemSharedLibs, ctx.toolchain().DefaultSharedLibraries()...)
+ }
+ deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...)
return deps
}
func (object *objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- flags.Global.LdFlags = append(flags.Global.LdFlags, ctx.toolchain().ToolchainClangLdflags())
+ flags.Global.LdFlags = append(flags.Global.LdFlags, ctx.toolchain().ToolchainLdflags())
if lds := android.OptionalPathForModuleSrc(ctx, object.Properties.Linker_script); lds.Valid() {
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-T,"+lds.String())
@@ -260,6 +275,20 @@
return outputFile
}
+func (object *objectLinker) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps {
+ specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, object.Properties.Shared_libs...)
+
+ // Must distinguish nil and [] in system_shared_libs - ensure that [] in
+ // either input list doesn't come out as nil.
+ if specifiedDeps.systemSharedLibs == nil {
+ specifiedDeps.systemSharedLibs = object.Properties.System_shared_libs
+ } else {
+ specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, object.Properties.System_shared_libs...)
+ }
+
+ return specifiedDeps
+}
+
func (object *objectLinker) unstrippedOutputFilePath() android.Path {
return nil
}
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index bea1782..f7154ec 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -183,9 +183,8 @@
})
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
- SharedLibrary: outputFile,
- UnstrippedSharedLibrary: p.unstrippedOutputFile,
- Target: ctx.Target(),
+ SharedLibrary: outputFile,
+ Target: ctx.Target(),
TableOfContents: p.tocFile,
})
@@ -389,8 +388,8 @@
return true
}
-func newPrebuiltObject() *Module {
- module := newObject()
+func NewPrebuiltObject(hod android.HostOrDeviceSupported) *Module {
+ module := newObject(hod)
prebuilt := &prebuiltObjectLinker{
objectLinker: objectLinker{
baseLinker: NewBaseLinker(nil),
@@ -404,7 +403,7 @@
}
func prebuiltObjectFactory() android.Module {
- module := newPrebuiltObject()
+ module := NewPrebuiltObject(android.HostAndDeviceSupported)
return module.Init()
}
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index fa6dd87..c8f8103 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -15,6 +15,7 @@
package cc
import (
+ "runtime"
"testing"
"android/soong/android"
@@ -271,8 +272,8 @@
}
func TestPrebuiltSymlinkedHostBinary(t *testing.T) {
- if android.BuildOs != android.Linux {
- t.Skipf("Skipping host prebuilt testing that is only supported on %s not %s", android.Linux, android.BuildOs)
+ if runtime.GOOS != "linux" {
+ t.Skipf("Skipping host prebuilt testing that is only supported on linux not %s", runtime.GOOS)
}
ctx := testPrebuilt(t, `
diff --git a/cc/proto_test.go b/cc/proto_test.go
index b9c89c7..abcb273 100644
--- a/cc/proto_test.go
+++ b/cc/proto_test.go
@@ -51,7 +51,7 @@
},
}`)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
proto := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Output("proto/a.pb.cc")
foobar := ctx.ModuleForTests("protoc-gen-foobar", buildOS+"_x86_64")
diff --git a/cc/rs.go b/cc/rs.go
index ba69f23..fbc86e2 100644
--- a/cc/rs.go
+++ b/cc/rs.go
@@ -36,7 +36,8 @@
var rsCppCmdLine = strings.Replace(`
${rsCmd} -o ${outDir} -d ${outDir} -a ${out} -MD -reflect-c++ ${rsFlags} $in &&
-(echo '${out}: \' && cat ${depFiles} | awk 'start { sub(/( \\)?$$/, " \\"); print } /:/ { start=1 }') > ${out}.d &&
+echo '${out}: \' > ${out}.d &&
+for f in ${depFiles}; do cat $${f} | awk 'start { sub(/( \\)?$$/, " \\"); print } /:/ { start=1 }' >> ${out}.d; done &&
touch $out
`, "\n", "", -1)
diff --git a/cc/sabi.go b/cc/sabi.go
index 1f331cb..e62ca66 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -45,12 +45,6 @@
return []interface{}{&sabi.Properties}
}
-func (sabi *sabi) begin(ctx BaseModuleContext) {}
-
-func (sabi *sabi) deps(ctx BaseModuleContext, deps Deps) Deps {
- return deps
-}
-
func (sabi *sabi) flags(ctx ModuleContext, flags Flags) Flags {
// Filter out flags which libTooling don't understand.
// This is here for legacy reasons and future-proof, in case the version of libTooling and clang
@@ -107,10 +101,6 @@
// Called from sabiDepsMutator to check whether ABI dumps should be created for this module.
// ctx should be wrapping a native library type module.
func shouldCreateSourceAbiDumpForLibrary(ctx android.BaseModuleContext) bool {
- if ctx.Fuchsia() {
- return false
- }
-
// Only generate ABI dump for device modules.
if !ctx.Device() {
return false
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 941a955..b244394 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -21,9 +21,11 @@
"sync"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/cc/config"
+ "android/soong/snapshot"
)
var (
@@ -73,25 +75,28 @@
type SanitizerType int
-func boolPtr(v bool) *bool {
- if v {
- return &v
- } else {
- return nil
- }
-}
-
const (
Asan SanitizerType = iota + 1
Hwasan
tsan
intOverflow
- cfi
scs
Fuzzer
memtag_heap
+ cfi // cfi is last to prevent it running before incompatible mutators
)
+var Sanitizers = []SanitizerType{
+ Asan,
+ Hwasan,
+ tsan,
+ intOverflow,
+ scs,
+ Fuzzer,
+ memtag_heap,
+ cfi, // cfi is last to prevent it running before incompatible mutators
+}
+
// Name of the sanitizer variation for this sanitizer type
func (t SanitizerType) variationName() string {
switch t {
@@ -140,6 +145,18 @@
}
}
+func (t SanitizerType) registerMutators(ctx android.RegisterMutatorsContext) {
+ switch t {
+ case Asan, Hwasan, Fuzzer, scs, tsan, cfi:
+ ctx.TopDown(t.variationName()+"_deps", sanitizerDepsMutator(t))
+ ctx.BottomUp(t.variationName(), sanitizerMutator(t))
+ case memtag_heap, intOverflow:
+ // do nothing
+ default:
+ panic(fmt.Errorf("unknown SanitizerType %d", t))
+ }
+}
+
func (*Module) SanitizerSupported(t SanitizerType) bool {
switch t {
case Asan:
@@ -167,24 +184,46 @@
}
type SanitizeUserProps struct {
+ // Prevent use of any sanitizers on this module
Never *bool `android:"arch_variant"`
- // main sanitizers
- Address *bool `android:"arch_variant"`
- Thread *bool `android:"arch_variant"`
+ // ASan (Address sanitizer), incompatible with static binaries.
+ // Always runs in a diagnostic mode.
+ // Use of address sanitizer disables cfi sanitizer.
+ // Hwaddress sanitizer takes precedence over this sanitizer.
+ Address *bool `android:"arch_variant"`
+ // TSan (Thread sanitizer), incompatible with static binaries and 32 bit architectures.
+ // Always runs in a diagnostic mode.
+ // Use of thread sanitizer disables cfi and scudo sanitizers.
+ // Hwaddress sanitizer takes precedence over this sanitizer.
+ Thread *bool `android:"arch_variant"`
+ // HWASan (Hardware Address sanitizer).
+ // Use of hwasan sanitizer disables cfi, address, thread, and scudo sanitizers.
Hwaddress *bool `android:"arch_variant"`
- // local sanitizers
- Undefined *bool `android:"arch_variant"`
- All_undefined *bool `android:"arch_variant"`
- Misc_undefined []string `android:"arch_variant"`
- Fuzzer *bool `android:"arch_variant"`
- Safestack *bool `android:"arch_variant"`
- Cfi *bool `android:"arch_variant"`
- Integer_overflow *bool `android:"arch_variant"`
- Scudo *bool `android:"arch_variant"`
- Scs *bool `android:"arch_variant"`
- Memtag_heap *bool `android:"arch_variant"`
+ // Undefined behavior sanitizer
+ All_undefined *bool `android:"arch_variant"`
+ // Subset of undefined behavior sanitizer
+ Undefined *bool `android:"arch_variant"`
+ // List of specific undefined behavior sanitizers to enable
+ Misc_undefined []string `android:"arch_variant"`
+ // Fuzzer, incompatible with static binaries.
+ Fuzzer *bool `android:"arch_variant"`
+ // safe-stack sanitizer, incompatible with 32-bit architectures.
+ Safestack *bool `android:"arch_variant"`
+ // cfi sanitizer, incompatible with asan, hwasan, fuzzer, or Darwin
+ Cfi *bool `android:"arch_variant"`
+ // signed/unsigned integer overflow sanitizer, incompatible with Darwin.
+ Integer_overflow *bool `android:"arch_variant"`
+ // scudo sanitizer, incompatible with asan, hwasan, tsan
+ // This should not be used in Android 11+ : https://source.android.com/devices/tech/debug/scudo
+ // deprecated
+ Scudo *bool `android:"arch_variant"`
+ // shadow-call-stack sanitizer, only available on arm64
+ Scs *bool `android:"arch_variant"`
+ // Memory-tagging, only available on arm64
+ // if diag.memtag unset or false, enables async memory tagging
+ Memtag_heap *bool `android:"arch_variant"`
// A modifier for ASAN and HWASAN for write only instrumentation
Writeonly *bool `android:"arch_variant"`
@@ -193,12 +232,22 @@
// Replaces abort() on error with a human-readable error message.
// Address and Thread sanitizers always run in diagnostic mode.
Diag struct {
- Undefined *bool `android:"arch_variant"`
- Cfi *bool `android:"arch_variant"`
- Integer_overflow *bool `android:"arch_variant"`
- Memtag_heap *bool `android:"arch_variant"`
- Misc_undefined []string `android:"arch_variant"`
- No_recover []string `android:"arch_variant"`
+ // Undefined behavior sanitizer, diagnostic mode
+ Undefined *bool `android:"arch_variant"`
+ // cfi sanitizer, diagnostic mode, incompatible with asan, hwasan, fuzzer, or Darwin
+ Cfi *bool `android:"arch_variant"`
+ // signed/unsigned integer overflow sanitizer, diagnostic mode, incompatible with Darwin.
+ Integer_overflow *bool `android:"arch_variant"`
+ // Memory-tagging, only available on arm64
+ // requires sanitizer.memtag: true
+ // if set, enables sync memory tagging
+ Memtag_heap *bool `android:"arch_variant"`
+ // List of specific undefined behavior sanitizers to enable in diagnostic mode
+ Misc_undefined []string `android:"arch_variant"`
+ // List of sanitizers to pass to -fno-sanitize-recover
+ // results in only the first detected error for these sanitizers being reported and program then
+ // exits with a non-zero exit code.
+ No_recover []string `android:"arch_variant"`
} `android:"arch_variant"`
// Sanitizers to run with flag configuration specified
@@ -207,7 +256,9 @@
Cfi_assembly_support *bool `android:"arch_variant"`
} `android:"arch_variant"`
- // value to pass to -fsanitize-recover=
+ // List of sanitizers to pass to -fsanitize-recover
+ // allows execution to continue for these sanitizers to detect multiple errors rather than only
+ // the first one
Recover []string
// value to pass to -fsanitize-blacklist
@@ -215,9 +266,6 @@
}
type SanitizeProperties struct {
- // Enable AddressSanitizer, ThreadSanitizer, UndefinedBehaviorSanitizer, and
- // others. Please see SanitizerUserProps in build/soong/cc/sanitize.go for
- // details.
Sanitize SanitizeUserProps `android:"arch_variant"`
SanitizerEnabled bool `blueprint:"mutated"`
SanitizeDep bool `blueprint:"mutated"`
@@ -257,20 +305,19 @@
s.Never = BoolPtr(true)
}
- // Sanitizers do not work on Fuchsia yet.
- if ctx.Fuchsia() {
- s.Never = BoolPtr(true)
- }
-
// Never always wins.
if Bool(s.Never) {
return
}
// cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}).
- if ctx.testBinary() && s.Memtag_heap == nil {
- s.Memtag_heap = boolPtr(true)
- s.Diag.Memtag_heap = boolPtr(true)
+ if ctx.testBinary() {
+ if s.Memtag_heap == nil {
+ s.Memtag_heap = proptools.BoolPtr(true)
+ }
+ if s.Diag.Memtag_heap == nil {
+ s.Diag.Memtag_heap = proptools.BoolPtr(true)
+ }
}
var globalSanitizers []string
@@ -291,48 +338,48 @@
if len(globalSanitizers) > 0 {
var found bool
if found, globalSanitizers = removeFromList("undefined", globalSanitizers); found && s.All_undefined == nil {
- s.All_undefined = boolPtr(true)
+ s.All_undefined = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("default-ub", globalSanitizers); found && s.Undefined == nil {
- s.Undefined = boolPtr(true)
+ s.Undefined = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("address", globalSanitizers); found && s.Address == nil {
- s.Address = boolPtr(true)
+ s.Address = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("thread", globalSanitizers); found && s.Thread == nil {
- s.Thread = boolPtr(true)
+ s.Thread = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil {
- s.Fuzzer = boolPtr(true)
+ s.Fuzzer = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("safe-stack", globalSanitizers); found && s.Safestack == nil {
- s.Safestack = boolPtr(true)
+ s.Safestack = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("cfi", globalSanitizers); found && s.Cfi == nil {
if !ctx.Config().CFIDisabledForPath(ctx.ModuleDir()) {
- s.Cfi = boolPtr(true)
+ s.Cfi = proptools.BoolPtr(true)
}
}
// Global integer_overflow builds do not support static libraries.
if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
if !ctx.Config().IntegerOverflowDisabledForPath(ctx.ModuleDir()) && !ctx.static() {
- s.Integer_overflow = boolPtr(true)
+ s.Integer_overflow = proptools.BoolPtr(true)
}
}
if found, globalSanitizers = removeFromList("scudo", globalSanitizers); found && s.Scudo == nil {
- s.Scudo = boolPtr(true)
+ s.Scudo = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil {
- s.Hwaddress = boolPtr(true)
+ s.Hwaddress = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("writeonly", globalSanitizers); found && s.Writeonly == nil {
@@ -341,11 +388,11 @@
if s.Address == nil && s.Hwaddress == nil {
ctx.ModuleErrorf("writeonly modifier cannot be used without 'address' or 'hwaddress'")
}
- s.Writeonly = boolPtr(true)
+ s.Writeonly = proptools.BoolPtr(true)
}
if found, globalSanitizers = removeFromList("memtag_heap", globalSanitizers); found && s.Memtag_heap == nil {
if !ctx.Config().MemtagHeapDisabledForPath(ctx.ModuleDir()) {
- s.Memtag_heap = boolPtr(true)
+ s.Memtag_heap = proptools.BoolPtr(true)
}
}
@@ -356,17 +403,17 @@
// Global integer_overflow builds do not support static library diagnostics.
if found, globalSanitizersDiag = removeFromList("integer_overflow", globalSanitizersDiag); found &&
s.Diag.Integer_overflow == nil && Bool(s.Integer_overflow) && !ctx.static() {
- s.Diag.Integer_overflow = boolPtr(true)
+ s.Diag.Integer_overflow = proptools.BoolPtr(true)
}
if found, globalSanitizersDiag = removeFromList("cfi", globalSanitizersDiag); found &&
s.Diag.Cfi == nil && Bool(s.Cfi) {
- s.Diag.Cfi = boolPtr(true)
+ s.Diag.Cfi = proptools.BoolPtr(true)
}
if found, globalSanitizersDiag = removeFromList("memtag_heap", globalSanitizersDiag); found &&
s.Diag.Memtag_heap == nil && Bool(s.Memtag_heap) {
- s.Diag.Memtag_heap = boolPtr(true)
+ s.Diag.Memtag_heap = proptools.BoolPtr(true)
}
if len(globalSanitizersDiag) > 0 {
@@ -378,30 +425,30 @@
if ctx.Arch().ArchType == android.Arm64 {
if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
if s.Memtag_heap == nil {
- s.Memtag_heap = boolPtr(true)
+ s.Memtag_heap = proptools.BoolPtr(true)
}
if s.Diag.Memtag_heap == nil {
- s.Diag.Memtag_heap = boolPtr(true)
+ s.Diag.Memtag_heap = proptools.BoolPtr(true)
}
} else if ctx.Config().MemtagHeapAsyncEnabledForPath(ctx.ModuleDir()) {
if s.Memtag_heap == nil {
- s.Memtag_heap = boolPtr(true)
+ s.Memtag_heap = proptools.BoolPtr(true)
}
}
}
// Enable CFI for all components in the include paths (for Aarch64 only)
if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 {
- s.Cfi = boolPtr(true)
+ s.Cfi = proptools.BoolPtr(true)
if inList("cfi", ctx.Config().SanitizeDeviceDiag()) {
- s.Diag.Cfi = boolPtr(true)
+ s.Diag.Cfi = proptools.BoolPtr(true)
}
}
// Is CFI actually enabled?
if !ctx.Config().EnableCFI() {
- s.Cfi = boolPtr(false)
- s.Diag.Cfi = boolPtr(false)
+ s.Cfi = nil
+ s.Diag.Cfi = nil
}
// HWASan requires AArch64 hardware feature (top-byte-ignore).
@@ -421,14 +468,14 @@
// Also disable CFI if ASAN is enabled.
if Bool(s.Address) || Bool(s.Hwaddress) {
- s.Cfi = boolPtr(false)
- s.Diag.Cfi = boolPtr(false)
+ s.Cfi = nil
+ s.Diag.Cfi = nil
}
- // Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
- if !ctx.Os().Linux() {
- s.Cfi = boolPtr(false)
- s.Diag.Cfi = boolPtr(false)
+ // Disable sanitizers that depend on the UBSan runtime for windows/darwin/musl builds.
+ if !ctx.Os().Linux() || ctx.Os() == android.LinuxMusl {
+ s.Cfi = nil
+ s.Diag.Cfi = nil
s.Misc_undefined = nil
s.Undefined = nil
s.All_undefined = nil
@@ -443,8 +490,8 @@
s.Cfi = nil
s.Diag.Cfi = nil
} else {
- s.Cfi = boolPtr(false)
- s.Diag.Cfi = boolPtr(false)
+ s.Cfi = nil
+ s.Diag.Cfi = nil
}
}
@@ -495,18 +542,10 @@
// TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
// mutually incompatible.
if Bool(s.Fuzzer) {
- s.Cfi = boolPtr(false)
+ s.Cfi = nil
}
}
-func (sanitize *sanitize) deps(ctx BaseModuleContext, deps Deps) Deps {
- if !sanitize.Properties.SanitizerEnabled { // || c.static() {
- return deps
- }
-
- return deps
-}
-
func toDisableImplicitIntegerChange(flags []string) bool {
// Returns true if any flag is fsanitize*integer, and there is
// no explicit flag about sanitize=implicit-integer-sign-change.
@@ -789,23 +828,27 @@
}
func (sanitize *sanitize) SetSanitizer(t SanitizerType, b bool) {
+ bPtr := proptools.BoolPtr(b)
+ if !b {
+ bPtr = nil
+ }
switch t {
case Asan:
- sanitize.Properties.Sanitize.Address = boolPtr(b)
+ sanitize.Properties.Sanitize.Address = bPtr
case Hwasan:
- sanitize.Properties.Sanitize.Hwaddress = boolPtr(b)
+ sanitize.Properties.Sanitize.Hwaddress = bPtr
case tsan:
- sanitize.Properties.Sanitize.Thread = boolPtr(b)
+ sanitize.Properties.Sanitize.Thread = bPtr
case intOverflow:
- sanitize.Properties.Sanitize.Integer_overflow = boolPtr(b)
+ sanitize.Properties.Sanitize.Integer_overflow = bPtr
case cfi:
- sanitize.Properties.Sanitize.Cfi = boolPtr(b)
+ sanitize.Properties.Sanitize.Cfi = bPtr
case scs:
- sanitize.Properties.Sanitize.Scs = boolPtr(b)
+ sanitize.Properties.Sanitize.Scs = bPtr
case memtag_heap:
- sanitize.Properties.Sanitize.Memtag_heap = boolPtr(b)
+ sanitize.Properties.Sanitize.Memtag_heap = bPtr
case Fuzzer:
- sanitize.Properties.Sanitize.Fuzzer = boolPtr(b)
+ sanitize.Properties.Sanitize.Fuzzer = bPtr
default:
panic(fmt.Errorf("unknown SanitizerType %d", t))
}
@@ -859,7 +902,7 @@
// as vendor snapshot. Such modules must create both cfi and non-cfi variants,
// except for ones which explicitly disable cfi.
func needsCfiForVendorSnapshot(mctx android.TopDownMutatorContext) bool {
- if isVendorProprietaryModule(mctx) {
+ if snapshot.IsVendorProprietaryModule(mctx) {
return false
}
@@ -1197,7 +1240,7 @@
if c.Device() {
variations = append(variations, c.ImageVariation())
}
- c.addSharedLibDependenciesWithVersions(mctx, variations, depTag, runtimeLibrary, "", true)
+ AddSharedLibDependenciesWithVersions(mctx, c, variations, depTag, runtimeLibrary, "", true)
}
// static lib does not have dependency to the runtime library. The
// dependency will be added to the executables or shared libs using
@@ -1261,7 +1304,7 @@
func sanitizerMutator(t SanitizerType) func(android.BottomUpMutatorContext) {
return func(mctx android.BottomUpMutatorContext) {
if c, ok := mctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
- if c.IsDependencyRoot() && c.IsSanitizerEnabled(t) {
+ if c.Binary() && c.IsSanitizerEnabled(t) {
modules := mctx.CreateVariations(t.variationName())
modules[0].(PlatformSanitizeable).SetSanitizer(t, true)
} else if c.IsSanitizerEnabled(t) || c.SanitizeDep() {
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index f126346..0070e40 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -15,6 +15,8 @@
package cc
import (
+ "fmt"
+ "strings"
"testing"
"android/soong/android"
@@ -202,3 +204,354 @@
t.Run("host", func(t *testing.T) { check(t, result, result.Config.BuildOSTarget.String()) })
t.Run("device", func(t *testing.T) { check(t, result, "android_arm64_armv8-a") })
}
+
+type MemtagNoteType int
+
+const (
+ None MemtagNoteType = iota + 1
+ Sync
+ Async
+)
+
+func (t MemtagNoteType) str() string {
+ switch t {
+ case None:
+ return "none"
+ case Sync:
+ return "sync"
+ case Async:
+ return "async"
+ default:
+ panic("type_note_invalid")
+ }
+}
+
+func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) {
+ t.Helper()
+ note_async := "note_memtag_heap_async"
+ note_sync := "note_memtag_heap_sync"
+
+ found := None
+ implicits := m.Rule("ld").Implicits
+ for _, lib := range implicits {
+ if strings.Contains(lib.Rel(), note_async) {
+ found = Async
+ break
+ } else if strings.Contains(lib.Rel(), note_sync) {
+ found = Sync
+ break
+ }
+ }
+
+ if found != expected {
+ t.Errorf("Wrong Memtag note in target %q: found %q, expected %q", m.Module().(*Module).Name(), found.str(), expected.str())
+ }
+}
+
+var prepareForTestWithMemtagHeap = android.GroupFixturePreparers(
+ android.FixtureModifyMockFS(func(fs android.MockFS) {
+ templateBp := `
+ cc_test {
+ name: "unset_test_%[1]s",
+ gtest: false,
+ }
+
+ cc_test {
+ name: "no_memtag_test_%[1]s",
+ gtest: false,
+ sanitize: { memtag_heap: false },
+ }
+
+ cc_test {
+ name: "set_memtag_test_%[1]s",
+ gtest: false,
+ sanitize: { memtag_heap: true },
+ }
+
+ cc_test {
+ name: "set_memtag_set_async_test_%[1]s",
+ gtest: false,
+ sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
+ }
+
+ cc_test {
+ name: "set_memtag_set_sync_test_%[1]s",
+ gtest: false,
+ sanitize: { memtag_heap: true, diag: { memtag_heap: true } },
+ }
+
+ cc_test {
+ name: "unset_memtag_set_sync_test_%[1]s",
+ gtest: false,
+ sanitize: { diag: { memtag_heap: true } },
+ }
+
+ cc_binary {
+ name: "unset_binary_%[1]s",
+ }
+
+ cc_binary {
+ name: "no_memtag_binary_%[1]s",
+ sanitize: { memtag_heap: false },
+ }
+
+ cc_binary {
+ name: "set_memtag_binary_%[1]s",
+ sanitize: { memtag_heap: true },
+ }
+
+ cc_binary {
+ name: "set_memtag_set_async_binary_%[1]s",
+ sanitize: { memtag_heap: true, diag: { memtag_heap: false } },
+ }
+
+ cc_binary {
+ name: "set_memtag_set_sync_binary_%[1]s",
+ sanitize: { memtag_heap: true, diag: { memtag_heap: true } },
+ }
+
+ cc_binary {
+ name: "unset_memtag_set_sync_binary_%[1]s",
+ sanitize: { diag: { memtag_heap: true } },
+ }
+ `
+ subdirNoOverrideBp := fmt.Sprintf(templateBp, "no_override")
+ subdirOverrideDefaultDisableBp := fmt.Sprintf(templateBp, "override_default_disable")
+ subdirSyncBp := fmt.Sprintf(templateBp, "override_default_sync")
+ subdirAsyncBp := fmt.Sprintf(templateBp, "override_default_async")
+
+ fs.Merge(android.MockFS{
+ "subdir_no_override/Android.bp": []byte(subdirNoOverrideBp),
+ "subdir_override_default_disable/Android.bp": []byte(subdirOverrideDefaultDisableBp),
+ "subdir_sync/Android.bp": []byte(subdirSyncBp),
+ "subdir_async/Android.bp": []byte(subdirAsyncBp),
+ })
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.MemtagHeapExcludePaths = []string{"subdir_override_default_disable"}
+ // "subdir_override_default_disable" is covered by both include and override_default_disable paths. override_default_disable wins.
+ variables.MemtagHeapSyncIncludePaths = []string{"subdir_sync", "subdir_override_default_disable"}
+ variables.MemtagHeapAsyncIncludePaths = []string{"subdir_async", "subdir_override_default_disable"}
+ }),
+)
+
+func TestSanitizeMemtagHeap(t *testing.T) {
+ variant := "android_arm64_armv8-a"
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ prepareForTestWithMemtagHeap,
+ ).RunTest(t)
+ ctx := result.TestContext
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ // should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ // should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+}
+
+func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
+ variant := "android_arm64_armv8-a"
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ prepareForTestWithMemtagHeap,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.SanitizeDevice = []string{"memtag_heap"}
+ }),
+ ).RunTest(t)
+ ctx := result.TestContext
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ // should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+}
+
+func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
+ variant := "android_arm64_armv8-a"
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ prepareForTestWithMemtagHeap,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.SanitizeDevice = []string{"memtag_heap"}
+ variables.SanitizeDeviceDiag = []string{"memtag_heap"}
+ }),
+ ).RunTest(t)
+ ctx := result.TestContext
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_binary_override_default_sync", variant), None)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_no_override", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_async", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("no_memtag_test_override_default_sync", variant), None)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_binary_override_default_sync", variant), Async)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_no_override", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_async", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_disable", variant), Async)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_async_test_override_default_sync", variant), Async)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("set_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_async", variant), Sync)
+ // should sanitize: { diag: { memtag: true } } result in Sync instead of None here?
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_memtag_set_sync_test_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_disable", variant), None)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_binary_override_default_sync", variant), Sync)
+
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_no_override", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_async", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_disable", variant), Sync)
+ checkHasMemtagNote(t, ctx.ModuleForTests("unset_test_override_default_sync", variant), Sync)
+}
diff --git a/cc/sdk.go b/cc/sdk.go
index aec950b..a83e5ad 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -35,7 +35,8 @@
if !m.UseSdk() && !m.SplitPerApiLevel() {
ctx.ModuleErrorf("UseSdk() must return true when AlwaysSdk is set, did the factory forget to set Sdk_version?")
}
- ctx.CreateVariations("sdk")
+ modules := ctx.CreateVariations("sdk")
+ modules[0].(*Module).Properties.IsSdkVariant = true
} else if m.UseSdk() || m.SplitPerApiLevel() {
modules := ctx.CreateVariations("", "sdk")
@@ -75,7 +76,7 @@
}
ctx.AliasVariation("")
}
- case *snapshot:
+ case *snapshotModule:
ctx.CreateVariations("")
}
}
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index a7351a9..9672c0f 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -18,57 +18,17 @@
// snapshot mutators and snapshot information maps which are also defined in this file.
import (
- "path/filepath"
"strings"
"android/soong/android"
+ "android/soong/snapshot"
"github.com/google/blueprint"
)
-// Defines the specifics of different images to which the snapshot process is applicable, e.g.,
-// vendor, recovery, ramdisk.
-type snapshotImage interface {
- // Returns true if a snapshot should be generated for this image.
- shouldGenerateSnapshot(ctx android.SingletonContext) bool
-
- // Function that returns true if the module is included in this image.
- // Using a function return instead of a value to prevent early
- // evalution of a function that may be not be defined.
- inImage(m LinkableInterface) func() bool
-
- // Returns true if the module is private and must not be included in the
- // snapshot. For example VNDK-private modules must return true for the
- // vendor snapshots. But false for the recovery snapshots.
- private(m LinkableInterface) bool
-
- // Returns true if a dir under source tree is an SoC-owned proprietary
- // directory, such as device/, vendor/, etc.
- //
- // For a given snapshot (e.g., vendor, recovery, etc.) if
- // isProprietaryPath(dir, deviceConfig) returns true, then the module in dir
- // will be built from sources.
- isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool
-
- // Whether to include VNDK in the snapshot for this image.
- includeVndk() bool
-
- // Whether a given module has been explicitly excluded from the
- // snapshot, e.g., using the exclude_from_vendor_snapshot or
- // exclude_from_recovery_snapshot properties.
- excludeFromSnapshot(m LinkableInterface) bool
-
- // Returns true if the build is using a snapshot for this image.
- isUsingSnapshot(cfg android.DeviceConfig) bool
-
- // Returns a version of which the snapshot should be used in this target.
- // This will only be meaningful when isUsingSnapshot is true.
- targetSnapshotVersion(cfg android.DeviceConfig) string
-
- // Whether to exclude a given module from the directed snapshot or not.
- // If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on,
- // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured.
- excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool
+// This interface overrides snapshot.SnapshotImage to implement cc module specific functions
+type SnapshotImage interface {
+ snapshot.SnapshotImage
// The image variant name for this snapshot image.
// For example, recovery snapshot image will return "recovery", and vendor snapshot image will
@@ -80,106 +40,12 @@
moduleNameSuffix() string
}
-type vendorSnapshotImage struct{}
-type recoverySnapshotImage struct{}
-
-type directoryMap map[string]bool
-
-var (
- // Modules under following directories are ignored. They are OEM's and vendor's
- // proprietary modules(device/, kernel/, vendor/, and hardware/).
- defaultDirectoryExcludedMap = directoryMap{
- "device": true,
- "hardware": true,
- "kernel": true,
- "vendor": true,
- }
-
- // Modules under following directories are included as they are in AOSP,
- // although hardware/ and kernel/ are normally for vendor's own.
- defaultDirectoryIncludedMap = directoryMap{
- "kernel/configs": true,
- "kernel/prebuilts": true,
- "kernel/tests": true,
- "hardware/interfaces": true,
- "hardware/libhardware": true,
- "hardware/libhardware_legacy": true,
- "hardware/ril": true,
- }
-)
-
-func (vendorSnapshotImage) init(ctx android.RegistrationContext) {
- ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
- ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory)
- ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory)
- ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
- ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
- ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
- ctx.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory)
-
- ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
+type vendorSnapshotImage struct {
+ *snapshot.VendorSnapshotImage
}
-func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
- // BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot.
- return ctx.DeviceConfig().VndkVersion() == "current"
-}
-
-func (vendorSnapshotImage) inImage(m LinkableInterface) func() bool {
- return m.InVendor
-}
-
-func (vendorSnapshotImage) private(m LinkableInterface) bool {
- return m.IsVndkPrivate()
-}
-
-func isDirectoryExcluded(dir string, excludedMap directoryMap, includedMap directoryMap) bool {
- if dir == "." || dir == "/" {
- return false
- }
- if includedMap[dir] {
- return false
- } else if excludedMap[dir] {
- return true
- } else if defaultDirectoryIncludedMap[dir] {
- return false
- } else if defaultDirectoryExcludedMap[dir] {
- return true
- } else {
- return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap)
- }
-}
-
-func (vendorSnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
- return isDirectoryExcluded(dir, deviceConfig.VendorSnapshotDirsExcludedMap(), deviceConfig.VendorSnapshotDirsIncludedMap())
-}
-
-// vendor snapshot includes static/header libraries with vndk: {enabled: true}.
-func (vendorSnapshotImage) includeVndk() bool {
- return true
-}
-
-func (vendorSnapshotImage) excludeFromSnapshot(m LinkableInterface) bool {
- return m.ExcludeFromVendorSnapshot()
-}
-
-func (vendorSnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool {
- vndkVersion := cfg.VndkVersion()
- return vndkVersion != "current" && vndkVersion != ""
-}
-
-func (vendorSnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string {
- return cfg.VndkVersion()
-}
-
-// returns true iff a given module SHOULD BE EXCLUDED, false if included
-func (vendorSnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
- // If we're using full snapshot, not directed snapshot, capture every module
- if !cfg.DirectedVendorSnapshot() {
- return false
- }
- // Else, checks if name is in VENDOR_SNAPSHOT_MODULES.
- return !cfg.VendorSnapshotModules()[name]
+type recoverySnapshotImage struct {
+ *snapshot.RecoverySnapshotImage
}
func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
@@ -190,62 +56,6 @@
return VendorSuffix
}
-func (recoverySnapshotImage) init(ctx android.RegistrationContext) {
- ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton)
- ctx.RegisterModuleType("recovery_snapshot", recoverySnapshotFactory)
- ctx.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory)
- ctx.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory)
- ctx.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory)
- ctx.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory)
- ctx.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory)
-}
-
-func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
- // RECOVERY_SNAPSHOT_VERSION must be set to 'current' in order to generate a
- // snapshot.
- return ctx.DeviceConfig().RecoverySnapshotVersion() == "current"
-}
-
-func (recoverySnapshotImage) inImage(m LinkableInterface) func() bool {
- return m.InRecovery
-}
-
-// recovery snapshot does not have private libraries.
-func (recoverySnapshotImage) private(m LinkableInterface) bool {
- return false
-}
-
-func (recoverySnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
- return isDirectoryExcluded(dir, deviceConfig.RecoverySnapshotDirsExcludedMap(), deviceConfig.RecoverySnapshotDirsIncludedMap())
-}
-
-// recovery snapshot does NOT treat vndk specially.
-func (recoverySnapshotImage) includeVndk() bool {
- return false
-}
-
-func (recoverySnapshotImage) excludeFromSnapshot(m LinkableInterface) bool {
- return m.ExcludeFromRecoverySnapshot()
-}
-
-func (recoverySnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool {
- recoverySnapshotVersion := cfg.RecoverySnapshotVersion()
- return recoverySnapshotVersion != "current" && recoverySnapshotVersion != ""
-}
-
-func (recoverySnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string {
- return cfg.RecoverySnapshotVersion()
-}
-
-func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
- // If we're using full snapshot, not directed snapshot, capture every module
- if !cfg.DirectedRecoverySnapshot() {
- return false
- }
- // Else, checks if name is in RECOVERY_SNAPSHOT_MODULES.
- return !cfg.RecoverySnapshotModules()[name]
-}
-
func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
return android.RecoveryVariation
}
@@ -254,76 +64,97 @@
return recoverySuffix
}
-var vendorSnapshotImageSingleton vendorSnapshotImage
-var recoverySnapshotImageSingleton recoverySnapshotImage
+// Override existing vendor and recovery snapshot for cc module specific extra functions
+var VendorSnapshotImageSingleton vendorSnapshotImage = vendorSnapshotImage{&snapshot.VendorSnapshotImageSingleton}
+var recoverySnapshotImageSingleton recoverySnapshotImage = recoverySnapshotImage{&snapshot.RecoverySnapshotImageSingleton}
+
+func RegisterVendorSnapshotModules(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory)
+ ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory)
+ ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
+ ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
+ ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
+ ctx.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory)
+}
+
+func RegisterRecoverySnapshotModules(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("recovery_snapshot", recoverySnapshotFactory)
+ ctx.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory)
+ ctx.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory)
+ ctx.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory)
+ ctx.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory)
+ ctx.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory)
+}
func init() {
- vendorSnapshotImageSingleton.init(android.InitRegistrationContext)
- recoverySnapshotImageSingleton.init(android.InitRegistrationContext)
+ RegisterVendorSnapshotModules(android.InitRegistrationContext)
+ RegisterRecoverySnapshotModules(android.InitRegistrationContext)
+ android.RegisterMakeVarsProvider(pctx, snapshotMakeVarsProvider)
}
const (
snapshotHeaderSuffix = "_header."
- snapshotSharedSuffix = "_shared."
- snapshotStaticSuffix = "_static."
+ SnapshotSharedSuffix = "_shared."
+ SnapshotStaticSuffix = "_static."
snapshotBinarySuffix = "_binary."
snapshotObjectSuffix = "_object."
+ SnapshotRlibSuffix = "_rlib."
)
type SnapshotProperties struct {
Header_libs []string `android:"arch_variant"`
Static_libs []string `android:"arch_variant"`
Shared_libs []string `android:"arch_variant"`
+ Rlibs []string `android:"arch_variant"`
Vndk_libs []string `android:"arch_variant"`
Binaries []string `android:"arch_variant"`
Objects []string `android:"arch_variant"`
}
-
-type snapshot struct {
+type snapshotModule struct {
android.ModuleBase
properties SnapshotProperties
- baseSnapshot baseSnapshotDecorator
+ baseSnapshot BaseSnapshotDecorator
- image snapshotImage
+ image SnapshotImage
}
-func (s *snapshot) ImageMutatorBegin(ctx android.BaseModuleContext) {
+func (s *snapshotModule) ImageMutatorBegin(ctx android.BaseModuleContext) {
cfg := ctx.DeviceConfig()
- if !s.image.isUsingSnapshot(cfg) || s.image.targetSnapshotVersion(cfg) != s.baseSnapshot.version() {
+ if !s.image.IsUsingSnapshot(cfg) || s.image.TargetSnapshotVersion(cfg) != s.baseSnapshot.Version() {
s.Disable()
}
}
-func (s *snapshot) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *snapshotModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
-func (s *snapshot) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *snapshotModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
-func (s *snapshot) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *snapshotModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
-func (s *snapshot) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *snapshotModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
-func (s *snapshot) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *snapshotModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
return false
}
-func (s *snapshot) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (s *snapshotModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
return []string{s.image.imageVariantName(ctx.DeviceConfig())}
}
-func (s *snapshot) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
+func (s *snapshotModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
}
-func (s *snapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (s *snapshotModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Nothing, the snapshot module is only used to forward dependency information in DepsMutator.
}
@@ -335,13 +166,13 @@
return moduleSuffix + versionSuffix
}
-func (s *snapshot) DepsMutator(ctx android.BottomUpMutatorContext) {
+func (s *snapshotModule) DepsMutator(ctx android.BottomUpMutatorContext) {
collectSnapshotMap := func(names []string, snapshotSuffix, moduleSuffix string) map[string]string {
snapshotMap := make(map[string]string)
for _, name := range names {
snapshotMap[name] = name +
getSnapshotNameSuffix(snapshotSuffix+moduleSuffix,
- s.baseSnapshot.version(),
+ s.baseSnapshot.Version(),
ctx.DeviceConfig().Arches()[0].ArchType.String())
}
return snapshotMap
@@ -351,8 +182,9 @@
headers := collectSnapshotMap(s.properties.Header_libs, snapshotSuffix, snapshotHeaderSuffix)
binaries := collectSnapshotMap(s.properties.Binaries, snapshotSuffix, snapshotBinarySuffix)
objects := collectSnapshotMap(s.properties.Objects, snapshotSuffix, snapshotObjectSuffix)
- staticLibs := collectSnapshotMap(s.properties.Static_libs, snapshotSuffix, snapshotStaticSuffix)
- sharedLibs := collectSnapshotMap(s.properties.Shared_libs, snapshotSuffix, snapshotSharedSuffix)
+ staticLibs := collectSnapshotMap(s.properties.Static_libs, snapshotSuffix, SnapshotStaticSuffix)
+ sharedLibs := collectSnapshotMap(s.properties.Shared_libs, snapshotSuffix, SnapshotSharedSuffix)
+ rlibs := collectSnapshotMap(s.properties.Rlibs, snapshotSuffix, SnapshotRlibSuffix)
vndkLibs := collectSnapshotMap(s.properties.Vndk_libs, "", vndkSuffix)
for k, v := range vndkLibs {
sharedLibs[k] = v
@@ -364,36 +196,55 @@
Objects: objects,
StaticLibs: staticLibs,
SharedLibs: sharedLibs,
+ Rlibs: rlibs,
})
}
type SnapshotInfo struct {
- HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs map[string]string
+ HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs, Rlibs map[string]string
}
var SnapshotInfoProvider = blueprint.NewMutatorProvider(SnapshotInfo{}, "deps")
-var _ android.ImageInterface = (*snapshot)(nil)
+var _ android.ImageInterface = (*snapshotModule)(nil)
+
+func snapshotMakeVarsProvider(ctx android.MakeVarsContext) {
+ snapshotSet := map[string]struct{}{}
+ ctx.VisitAllModules(func(m android.Module) {
+ if s, ok := m.(*snapshotModule); ok {
+ if _, ok := snapshotSet[s.Name()]; ok {
+ // arch variant generates duplicated modules
+ // skip this as we only need to know the path of the module.
+ return
+ }
+ snapshotSet[s.Name()] = struct{}{}
+ imageNameVersion := strings.Split(s.image.imageVariantName(ctx.DeviceConfig()), ".")
+ ctx.Strict(
+ strings.Join([]string{strings.ToUpper(imageNameVersion[0]), s.baseSnapshot.Version(), "SNAPSHOT_DIR"}, "_"),
+ ctx.ModuleDir(s))
+ }
+ })
+}
func vendorSnapshotFactory() android.Module {
- return snapshotFactory(vendorSnapshotImageSingleton)
+ return snapshotFactory(VendorSnapshotImageSingleton)
}
func recoverySnapshotFactory() android.Module {
return snapshotFactory(recoverySnapshotImageSingleton)
}
-func snapshotFactory(image snapshotImage) android.Module {
- snapshot := &snapshot{}
- snapshot.image = image
- snapshot.AddProperties(
- &snapshot.properties,
- &snapshot.baseSnapshot.baseProperties)
- android.InitAndroidArchModule(snapshot, android.DeviceSupported, android.MultilibBoth)
- return snapshot
+func snapshotFactory(image SnapshotImage) android.Module {
+ snapshotModule := &snapshotModule{}
+ snapshotModule.image = image
+ snapshotModule.AddProperties(
+ &snapshotModule.properties,
+ &snapshotModule.baseSnapshot.baseProperties)
+ android.InitAndroidArchModule(snapshotModule, android.DeviceSupported, android.MultilibBoth)
+ return snapshotModule
}
-type baseSnapshotDecoratorProperties struct {
+type BaseSnapshotDecoratorProperties struct {
// snapshot version.
Version string
@@ -408,7 +259,7 @@
ModuleSuffix string `blueprint:"mutated"`
}
-// baseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
+// BaseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
// version, snapshot arch, etc. It also adds a special suffix to Soong module name, so it doesn't
// collide with source modules. e.g. the following example module,
//
@@ -420,70 +271,89 @@
// }
//
// will be seen as "libbase.vendor_static.30.arm64" by Soong.
-type baseSnapshotDecorator struct {
- baseProperties baseSnapshotDecoratorProperties
- image snapshotImage
+type BaseSnapshotDecorator struct {
+ baseProperties BaseSnapshotDecoratorProperties
+ Image SnapshotImage
}
-func (p *baseSnapshotDecorator) Name(name string) string {
+func (p *BaseSnapshotDecorator) Name(name string) string {
return name + p.NameSuffix()
}
-func (p *baseSnapshotDecorator) NameSuffix() string {
- return getSnapshotNameSuffix(p.moduleSuffix(), p.version(), p.arch())
+func (p *BaseSnapshotDecorator) NameSuffix() string {
+ return getSnapshotNameSuffix(p.moduleSuffix(), p.Version(), p.Arch())
}
-func (p *baseSnapshotDecorator) version() string {
+func (p *BaseSnapshotDecorator) Version() string {
return p.baseProperties.Version
}
-func (p *baseSnapshotDecorator) arch() string {
+func (p *BaseSnapshotDecorator) Arch() string {
return p.baseProperties.Target_arch
}
-func (p *baseSnapshotDecorator) moduleSuffix() string {
+func (p *BaseSnapshotDecorator) moduleSuffix() string {
return p.baseProperties.ModuleSuffix
}
-func (p *baseSnapshotDecorator) isSnapshotPrebuilt() bool {
+func (p *BaseSnapshotDecorator) IsSnapshotPrebuilt() bool {
return true
}
-func (p *baseSnapshotDecorator) snapshotAndroidMkSuffix() string {
+func (p *BaseSnapshotDecorator) SnapshotAndroidMkSuffix() string {
return p.baseProperties.Androidmk_suffix
}
-func (p *baseSnapshotDecorator) setSnapshotAndroidMkSuffix(ctx android.ModuleContext) {
- coreVariations := append(ctx.Target().Variations(), blueprint.Variation{
+func (p *BaseSnapshotDecorator) SetSnapshotAndroidMkSuffix(ctx android.ModuleContext, variant string) {
+ // If there are any 2 or more variations among {core, product, vendor, recovery}
+ // we have to add the androidmk suffix to avoid duplicate modules with the same
+ // name.
+ variations := append(ctx.Target().Variations(), blueprint.Variation{
Mutator: "image",
Variation: android.CoreVariation})
- if ctx.OtherModuleFarDependencyVariantExists(coreVariations, ctx.Module().(*Module).BaseModuleName()) {
- p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix()
+ if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
+ p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
return
}
- // If there is no matching core variation, there could still be a
- // product variation, for example if a module is product specific and
- // vendor available. In that case, we also want to add the androidmk
- // suffix.
-
- productVariations := append(ctx.Target().Variations(), blueprint.Variation{
+ variations = append(ctx.Target().Variations(), blueprint.Variation{
Mutator: "image",
Variation: ProductVariationPrefix + ctx.DeviceConfig().PlatformVndkVersion()})
- if ctx.OtherModuleFarDependencyVariantExists(productVariations, ctx.Module().(*Module).BaseModuleName()) {
- p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix()
+ if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
+ p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
return
}
+ images := []SnapshotImage{VendorSnapshotImageSingleton, recoverySnapshotImageSingleton}
+
+ for _, image := range images {
+ if p.Image == image {
+ continue
+ }
+ variations = append(ctx.Target().Variations(), blueprint.Variation{
+ Mutator: "image",
+ Variation: image.imageVariantName(ctx.DeviceConfig())})
+
+ if ctx.OtherModuleFarDependencyVariantExists(variations,
+ ctx.Module().(LinkableInterface).BaseModuleName()+
+ getSnapshotNameSuffix(
+ image.moduleNameSuffix()+variant,
+ p.Version(),
+ ctx.DeviceConfig().Arches()[0].ArchType.String())) {
+ p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
+ return
+ }
+ }
+
p.baseProperties.Androidmk_suffix = ""
}
// Call this with a module suffix after creating a snapshot module, such as
// vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc.
-func (p *baseSnapshotDecorator) init(m *Module, image snapshotImage, moduleSuffix string) {
- p.image = image
+func (p *BaseSnapshotDecorator) Init(m LinkableInterface, image SnapshotImage, moduleSuffix string) {
+ p.Image = image
p.baseProperties.ModuleSuffix = image.moduleNameSuffix() + moduleSuffix
m.AddProperties(&p.baseProperties)
android.AddLoadHook(m, func(ctx android.LoadHookContext) {
@@ -493,8 +363,8 @@
// vendorSnapshotLoadHook disables snapshots if it's not BOARD_VNDK_VERSION.
// As vendor snapshot is only for vendor, such modules won't be used at all.
-func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *baseSnapshotDecorator) {
- if p.version() != ctx.DeviceConfig().VndkVersion() {
+func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *BaseSnapshotDecorator) {
+ if p.Version() != ctx.DeviceConfig().VndkVersion() {
ctx.Module().Disable()
return
}
@@ -509,7 +379,7 @@
// include directories, c flags, sanitize dependency information, etc.
//
// These modules are auto-generated by development/vendor_snapshot/update.py.
-type snapshotLibraryProperties struct {
+type SnapshotLibraryProperties struct {
// Prebuilt file for each arch.
Src *string `android:"arch_variant"`
@@ -535,14 +405,14 @@
}
type snapshotLibraryDecorator struct {
- baseSnapshotDecorator
+ BaseSnapshotDecorator
*libraryDecorator
- properties snapshotLibraryProperties
+ properties SnapshotLibraryProperties
sanitizerProperties struct {
CfiEnabled bool `blueprint:"mutated"`
// Library flags for cfi variant.
- Cfi snapshotLibraryProperties `android:"arch_variant"`
+ Cfi SnapshotLibraryProperties `android:"arch_variant"`
}
}
@@ -551,9 +421,9 @@
return p.libraryDecorator.linkerFlags(ctx, flags)
}
-func (p *snapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
+func (p *snapshotLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
arches := config.Arches()
- if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
+ if len(arches) == 0 || arches[0].ArchType.String() != p.Arch() {
return false
}
if !p.header() && p.properties.Src == nil {
@@ -566,7 +436,16 @@
// As snapshots are prebuilts, this just returns the prebuilt binary after doing things which are
// done by normal library decorator, e.g. exporting flags.
func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
- p.setSnapshotAndroidMkSuffix(ctx)
+ var variant string
+ if p.shared() {
+ variant = SnapshotSharedSuffix
+ } else if p.static() {
+ variant = SnapshotStaticSuffix
+ } else {
+ variant = snapshotHeaderSuffix
+ }
+
+ p.SetSnapshotAndroidMkSuffix(ctx, variant)
if p.header() {
return p.libraryDecorator.link(ctx, flags, deps, objs)
@@ -576,7 +455,7 @@
p.properties = p.sanitizerProperties.Cfi
}
- if !p.matchesWithDevice(ctx.DeviceConfig()) {
+ if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
@@ -606,9 +485,8 @@
transformSharedObjectToToc(ctx, in, tocFile, builderFlags)
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
- SharedLibrary: in,
- UnstrippedSharedLibrary: p.unstrippedOutputFile,
- Target: ctx.Target(),
+ SharedLibrary: in,
+ Target: ctx.Target(),
TableOfContents: p.tocFile,
})
@@ -629,7 +507,7 @@
}
func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
- if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
+ if p.MatchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
p.baseInstaller.install(ctx, file)
}
}
@@ -659,7 +537,7 @@
}
}
-func snapshotLibraryFactory(image snapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
+func snapshotLibraryFactory(image SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
module, library := NewLibrary(android.DeviceSupported)
module.stl = nil
@@ -682,7 +560,7 @@
module.linker = prebuilt
module.installer = prebuilt
- prebuilt.init(module, image, moduleSuffix)
+ prebuilt.Init(module, image, moduleSuffix)
module.AddProperties(
&prebuilt.properties,
&prebuilt.sanitizerProperties,
@@ -696,7 +574,7 @@
// overrides the vendor variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
// is set.
func VendorSnapshotSharedFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotSharedSuffix)
+ module, prebuilt := snapshotLibraryFactory(VendorSnapshotImageSingleton, SnapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared()
return module.Init()
}
@@ -706,7 +584,7 @@
// overrides the recovery variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
// is set.
func RecoverySnapshotSharedFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, snapshotSharedSuffix)
+ module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, SnapshotSharedSuffix)
prebuilt.libraryDecorator.BuildOnlyShared()
return module.Init()
}
@@ -716,7 +594,7 @@
// overrides the vendor variant of the cc static library with the same name, if BOARD_VNDK_VERSION
// is set.
func VendorSnapshotStaticFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotStaticSuffix)
+ module, prebuilt := snapshotLibraryFactory(VendorSnapshotImageSingleton, SnapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic()
return module.Init()
}
@@ -726,7 +604,7 @@
// overrides the recovery variant of the cc static library with the same name, if BOARD_VNDK_VERSION
// is set.
func RecoverySnapshotStaticFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, snapshotStaticSuffix)
+ module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, SnapshotStaticSuffix)
prebuilt.libraryDecorator.BuildOnlyStatic()
return module.Init()
}
@@ -736,7 +614,7 @@
// overrides the vendor variant of the cc header library with the same name, if BOARD_VNDK_VERSION
// is set.
func VendorSnapshotHeaderFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotHeaderSuffix)
+ module, prebuilt := snapshotLibraryFactory(VendorSnapshotImageSingleton, snapshotHeaderSuffix)
prebuilt.libraryDecorator.HeaderOnly()
return module.Init()
}
@@ -766,13 +644,13 @@
}
type snapshotBinaryDecorator struct {
- baseSnapshotDecorator
+ BaseSnapshotDecorator
*binaryDecorator
properties snapshotBinaryProperties
}
-func (p *snapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
- if config.DeviceArch() != p.arch() {
+func (p *snapshotBinaryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
+ if config.DeviceArch() != p.Arch() {
return false
}
if p.properties.Src == nil {
@@ -784,9 +662,9 @@
// cc modules' link functions are to link compiled objects into final binaries.
// As snapshots are prebuilts, this just returns the prebuilt binary
func (p *snapshotBinaryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
- p.setSnapshotAndroidMkSuffix(ctx)
+ p.SetSnapshotAndroidMkSuffix(ctx, snapshotBinarySuffix)
- if !p.matchesWithDevice(ctx.DeviceConfig()) {
+ if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
@@ -814,7 +692,7 @@
// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_binary
// overrides the vendor variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
func VendorSnapshotBinaryFactory() android.Module {
- return snapshotBinaryFactory(vendorSnapshotImageSingleton, snapshotBinarySuffix)
+ return snapshotBinaryFactory(VendorSnapshotImageSingleton, snapshotBinarySuffix)
}
// recovery_snapshot_binary is a special prebuilt executable binary which is auto-generated by
@@ -824,7 +702,7 @@
return snapshotBinaryFactory(recoverySnapshotImageSingleton, snapshotBinarySuffix)
}
-func snapshotBinaryFactory(image snapshotImage, moduleSuffix string) android.Module {
+func snapshotBinaryFactory(image SnapshotImage, moduleSuffix string) android.Module {
module, binary := NewBinary(android.DeviceSupported)
binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
binary.baseLinker.Properties.Nocrt = BoolPtr(true)
@@ -843,7 +721,7 @@
module.stl = nil
module.linker = prebuilt
- prebuilt.init(module, image, moduleSuffix)
+ prebuilt.Init(module, image, moduleSuffix)
module.AddProperties(&prebuilt.properties)
return module.Init()
}
@@ -861,13 +739,13 @@
}
type snapshotObjectLinker struct {
- baseSnapshotDecorator
+ BaseSnapshotDecorator
objectLinker
properties vendorSnapshotObjectProperties
}
-func (p *snapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool {
- if config.DeviceArch() != p.arch() {
+func (p *snapshotObjectLinker) MatchesWithDevice(config android.DeviceConfig) bool {
+ if config.DeviceArch() != p.Arch() {
return false
}
if p.properties.Src == nil {
@@ -879,9 +757,9 @@
// cc modules' link functions are to link compiled objects into final binaries.
// As snapshots are prebuilts, this just returns the prebuilt binary
func (p *snapshotObjectLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
- p.setSnapshotAndroidMkSuffix(ctx)
+ p.SetSnapshotAndroidMkSuffix(ctx, snapshotObjectSuffix)
- if !p.matchesWithDevice(ctx.DeviceConfig()) {
+ if !p.MatchesWithDevice(ctx.DeviceConfig()) {
return nil
}
@@ -896,7 +774,7 @@
// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_object
// overrides the vendor variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
func VendorSnapshotObjectFactory() android.Module {
- module := newObject()
+ module := newObject(android.DeviceSupported)
prebuilt := &snapshotObjectLinker{
objectLinker: objectLinker{
@@ -905,7 +783,7 @@
}
module.linker = prebuilt
- prebuilt.init(module, vendorSnapshotImageSingleton, snapshotObjectSuffix)
+ prebuilt.Init(module, VendorSnapshotImageSingleton, snapshotObjectSuffix)
module.AddProperties(&prebuilt.properties)
return module.Init()
}
@@ -914,7 +792,7 @@
// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_object
// overrides the recovery variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
func RecoverySnapshotObjectFactory() android.Module {
- module := newObject()
+ module := newObject(android.DeviceSupported)
prebuilt := &snapshotObjectLinker{
objectLinker: objectLinker{
@@ -923,19 +801,19 @@
}
module.linker = prebuilt
- prebuilt.init(module, recoverySnapshotImageSingleton, snapshotObjectSuffix)
+ prebuilt.Init(module, recoverySnapshotImageSingleton, snapshotObjectSuffix)
module.AddProperties(&prebuilt.properties)
return module.Init()
}
-type snapshotInterface interface {
- matchesWithDevice(config android.DeviceConfig) bool
- isSnapshotPrebuilt() bool
- version() string
- snapshotAndroidMkSuffix() string
+type SnapshotInterface interface {
+ MatchesWithDevice(config android.DeviceConfig) bool
+ IsSnapshotPrebuilt() bool
+ Version() string
+ SnapshotAndroidMkSuffix() string
}
-var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
-var _ snapshotInterface = (*snapshotLibraryDecorator)(nil)
-var _ snapshotInterface = (*snapshotBinaryDecorator)(nil)
-var _ snapshotInterface = (*snapshotObjectLinker)(nil)
+var _ SnapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
+var _ SnapshotInterface = (*snapshotLibraryDecorator)(nil)
+var _ SnapshotInterface = (*snapshotBinaryDecorator)(nil)
+var _ SnapshotInterface = (*snapshotObjectLinker)(nil)
diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go
index 8eb6164..24abcce 100644
--- a/cc/snapshot_utils.go
+++ b/cc/snapshot_utils.go
@@ -20,7 +20,7 @@
)
var (
- headerExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
+ HeaderExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
)
func (m *Module) IsSnapshotLibrary() bool {
@@ -53,6 +53,10 @@
return m.Properties.SnapshotSharedLibs
}
+func (m *Module) SnapshotStaticLibs() []string {
+ return m.Properties.SnapshotStaticLibs
+}
+
// snapshotLibraryInterface is an interface for libraries captured to VNDK / vendor snapshots.
type snapshotLibraryInterface interface {
libraryInterface
@@ -109,8 +113,8 @@
return ctx.Config().VndkSnapshotBuildArtifacts()
}
- for _, image := range []snapshotImage{vendorSnapshotImageSingleton, recoverySnapshotImageSingleton} {
- if isSnapshotAware(ctx.DeviceConfig(), m, image.isProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()), apexInfo, image) {
+ for _, image := range []SnapshotImage{VendorSnapshotImageSingleton, recoverySnapshotImageSingleton} {
+ if isSnapshotAware(ctx.DeviceConfig(), m, image.IsProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()), apexInfo, image) {
return true
}
}
diff --git a/cc/stl.go b/cc/stl.go
index 75921c6..0f2a878 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -15,8 +15,9 @@
package cc
import (
- "android/soong/android"
"fmt"
+
+ "android/soong/android"
)
func getNdkStlFamily(m LinkableInterface) string {
@@ -92,26 +93,6 @@
ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
return ""
}
- } else if ctx.Fuchsia() {
- switch s {
- case "c++_static":
- return "libc++_static"
- case "c++_shared":
- return "libc++"
- case "libc++", "libc++_static":
- return s
- case "none":
- return ""
- case "":
- if ctx.static() {
- return "libc++_static"
- } else {
- return "libc++"
- }
- default:
- ctx.ModuleErrorf("stl: %q is not a supported STL on Fuchsia", s)
- return ""
- }
} else {
switch s {
case "libc++", "libc++_static":
@@ -199,7 +180,9 @@
deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
}
if needsLibAndroidSupport(ctx) {
- deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
+ // Use LateStaticLibs for ndk_libandroid_support so that its include directories
+ // come after ndk_libc++_static or ndk_libc++_shared.
+ deps.LateStaticLibs = append(deps.LateStaticLibs, "ndk_libandroid_support")
}
deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
default:
diff --git a/cc/strip.go b/cc/strip.go
index b1f34bb..c60e135 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -59,6 +59,7 @@
return !forceDisable && (forceEnable || defaultEnable)
}
+// Keep this consistent with //build/bazel/rules/stripped_shared_library.bzl.
func (stripper *Stripper) strip(actx android.ModuleContext, in android.Path, out android.ModuleOutPath,
flags StripFlags, isStaticLib bool) {
if actx.Darwin() {
diff --git a/cc/symbolfile/__init__.py b/cc/symbolfile/__init__.py
index 5678e7d..31c4443 100644
--- a/cc/symbolfile/__init__.py
+++ b/cc/symbolfile/__init__.py
@@ -14,18 +14,22 @@
# limitations under the License.
#
"""Parser for Android's version script information."""
-from dataclasses import dataclass
+from __future__ import annotations
+
+from dataclasses import dataclass, field
import logging
import re
from typing import (
Dict,
Iterable,
+ Iterator,
List,
Mapping,
NewType,
Optional,
TextIO,
Tuple,
+ Union,
)
@@ -52,11 +56,52 @@
@dataclass
+class Tags:
+ """Container class for the tags attached to a symbol or version."""
+
+ tags: tuple[Tag, ...] = field(default_factory=tuple)
+
+ @classmethod
+ def from_strs(cls, strs: Iterable[str]) -> Tags:
+ """Constructs tags from a collection of strings.
+
+ Does not decode API levels.
+ """
+ return Tags(tuple(Tag(s) for s in strs))
+
+ def __contains__(self, tag: Union[Tag, str]) -> bool:
+ return tag in self.tags
+
+ def __iter__(self) -> Iterator[Tag]:
+ yield from self.tags
+
+ @property
+ def has_mode_tags(self) -> bool:
+ """Returns True if any mode tags (apex, llndk, etc) are set."""
+ return self.has_apex_tags or self.has_llndk_tags
+
+ @property
+ def has_apex_tags(self) -> bool:
+ """Returns True if any APEX tags are set."""
+ return 'apex' in self.tags or 'systemapi' in self.tags
+
+ @property
+ def has_llndk_tags(self) -> bool:
+ """Returns True if any LL-NDK tags are set."""
+ return 'llndk' in self.tags
+
+ @property
+ def has_platform_only_tags(self) -> bool:
+ """Returns True if any platform-only tags are set."""
+ return 'platform-only' in self.tags
+
+
+@dataclass
class Symbol:
"""A symbol definition from a symbol file."""
name: str
- tags: List[Tag]
+ tags: Tags
@dataclass
@@ -65,14 +110,22 @@
name: str
base: Optional[str]
- tags: List[Tag]
+ tags: Tags
symbols: List[Symbol]
+ @property
+ def is_private(self) -> bool:
+ """Returns True if this version block is private (platform only)."""
+ return self.name.endswith('_PRIVATE') or self.name.endswith('_PLATFORM')
-def get_tags(line: str) -> List[Tag]:
+
+def get_tags(line: str, api_map: ApiMap) -> Tags:
"""Returns a list of all tags on this line."""
_, _, all_tags = line.strip().partition('#')
- return [Tag(e) for e in re.split(r'\s+', all_tags) if e.strip()]
+ return Tags(tuple(
+ decode_api_level_tag(Tag(e), api_map)
+ for e in re.split(r'\s+', all_tags) if e.strip()
+ ))
def is_api_level_tag(tag: Tag) -> bool:
@@ -104,24 +157,21 @@
return api_map[api]
-def decode_api_level_tags(tags: Iterable[Tag], api_map: ApiMap) -> List[Tag]:
- """Decodes API level code names in a list of tags.
+def decode_api_level_tag(tag: Tag, api_map: ApiMap) -> Tag:
+ """Decodes API level code name in a tag.
Raises:
ParseError: An unknown version name was found in a tag.
"""
- decoded_tags = list(tags)
- for idx, tag in enumerate(tags):
- if not is_api_level_tag(tag):
- continue
- name, value = split_tag(tag)
+ if not is_api_level_tag(tag):
+ return tag
- try:
- decoded = str(decode_api_level(value, api_map))
- decoded_tags[idx] = Tag('='.join([name, decoded]))
- except KeyError:
- raise ParseError(f'Unknown version name in tag: {tag}')
- return decoded_tags
+ name, value = split_tag(tag)
+ try:
+ decoded = str(decode_api_level(value, api_map))
+ return Tag(f'{name}={decoded}')
+ except KeyError as ex:
+ raise ParseError(f'Unknown version name in tag: {tag}') from ex
def split_tag(tag: Tag) -> Tuple[str, str]:
@@ -149,55 +199,52 @@
return split_tag(tag)[1]
-def version_is_private(version: str) -> bool:
- """Returns True if the version name should be treated as private."""
- return version.endswith('_PRIVATE') or version.endswith('_PLATFORM')
+def _should_omit_tags(tags: Tags, arch: Arch, api: int, llndk: bool,
+ apex: bool) -> bool:
+ """Returns True if the tagged object should be omitted.
+
+ This defines the rules shared between version tagging and symbol tagging.
+ """
+ # The apex and llndk tags will only exclude APIs from other modes. If in
+ # APEX or LLNDK mode and neither tag is provided, we fall back to the
+ # default behavior because all NDK symbols are implicitly available to APEX
+ # and LLNDK.
+ if tags.has_mode_tags:
+ if not apex and not llndk:
+ return True
+ if apex and not tags.has_apex_tags:
+ return True
+ if llndk and not tags.has_llndk_tags:
+ return True
+ if not symbol_in_arch(tags, arch):
+ return True
+ if not symbol_in_api(tags, arch, api):
+ return True
+ return False
def should_omit_version(version: Version, arch: Arch, api: int, llndk: bool,
apex: bool) -> bool:
- """Returns True if the version section should be ommitted.
+ """Returns True if the version section should be omitted.
We want to omit any sections that do not have any symbols we'll have in the
stub library. Sections that contain entirely future symbols or only symbols
for certain architectures.
"""
- if version_is_private(version.name):
+ if version.is_private:
return True
- if 'platform-only' in version.tags:
+ if version.tags.has_platform_only_tags:
return True
-
- no_llndk_no_apex = ('llndk' not in version.tags
- and 'apex' not in version.tags)
- keep = no_llndk_no_apex or \
- ('llndk' in version.tags and llndk) or \
- ('apex' in version.tags and apex)
- if not keep:
- return True
- if not symbol_in_arch(version.tags, arch):
- return True
- if not symbol_in_api(version.tags, arch, api):
- return True
- return False
+ return _should_omit_tags(version.tags, arch, api, llndk, apex)
def should_omit_symbol(symbol: Symbol, arch: Arch, api: int, llndk: bool,
apex: bool) -> bool:
"""Returns True if the symbol should be omitted."""
- no_llndk_no_apex = 'llndk' not in symbol.tags and 'apex' not in symbol.tags
- keep = no_llndk_no_apex or \
- ('llndk' in symbol.tags and llndk) or \
- ('apex' in symbol.tags and apex)
- if not keep:
- return True
- if not symbol_in_arch(symbol.tags, arch):
- return True
- if not symbol_in_api(symbol.tags, arch, api):
- return True
- return False
+ return _should_omit_tags(symbol.tags, arch, api, llndk, apex)
-def symbol_in_arch(tags: Iterable[Tag], arch: Arch) -> bool:
+def symbol_in_arch(tags: Tags, arch: Arch) -> bool:
"""Returns true if the symbol is present for the given architecture."""
has_arch_tags = False
for tag in tags:
@@ -325,8 +372,7 @@
"""Parses a single version section and returns a Version object."""
assert self.current_line is not None
name = self.current_line.split('{')[0].strip()
- tags = get_tags(self.current_line)
- tags = decode_api_level_tags(tags, self.api_map)
+ tags = get_tags(self.current_line, self.api_map)
symbols: List[Symbol] = []
global_scope = True
cpp_symbols = False
@@ -373,8 +419,7 @@
'Wildcard global symbols are not permitted.')
# Line is now in the format "<symbol-name>; # tags"
name, _, _ = self.current_line.strip().partition(';')
- tags = get_tags(self.current_line)
- tags = decode_api_level_tags(tags, self.api_map)
+ tags = get_tags(self.current_line, self.api_map)
return Symbol(name, tags)
def next_line(self) -> str:
diff --git a/cc/symbolfile/test_symbolfile.py b/cc/symbolfile/test_symbolfile.py
index 92b1399..c1e8219 100644
--- a/cc/symbolfile/test_symbolfile.py
+++ b/cc/symbolfile/test_symbolfile.py
@@ -19,7 +19,7 @@
import unittest
import symbolfile
-from symbolfile import Arch, Tag
+from symbolfile import Arch, Tag, Tags, Version
# pylint: disable=missing-docstring
@@ -35,12 +35,14 @@
class TagsTest(unittest.TestCase):
def test_get_tags_no_tags(self) -> None:
- self.assertEqual([], symbolfile.get_tags(''))
- self.assertEqual([], symbolfile.get_tags('foo bar baz'))
+ self.assertEqual(Tags(), symbolfile.get_tags('', {}))
+ self.assertEqual(Tags(), symbolfile.get_tags('foo bar baz', {}))
def test_get_tags(self) -> None:
- self.assertEqual(['foo', 'bar'], symbolfile.get_tags('# foo bar'))
- self.assertEqual(['bar', 'baz'], symbolfile.get_tags('foo # bar baz'))
+ self.assertEqual(Tags.from_strs(['foo', 'bar']),
+ symbolfile.get_tags('# foo bar', {}))
+ self.assertEqual(Tags.from_strs(['bar', 'baz']),
+ symbolfile.get_tags('foo # bar baz', {}))
def test_split_tag(self) -> None:
self.assertTupleEqual(('foo', 'bar'),
@@ -77,12 +79,14 @@
}
tags = [
- Tag('introduced=9'),
- Tag('introduced-arm=14'),
- Tag('versioned=16'),
- Tag('arm'),
- Tag('introduced=O'),
- Tag('introduced=P'),
+ symbolfile.decode_api_level_tag(t, api_map) for t in (
+ Tag('introduced=9'),
+ Tag('introduced-arm=14'),
+ Tag('versioned=16'),
+ Tag('arm'),
+ Tag('introduced=O'),
+ Tag('introduced=P'),
+ )
]
expected_tags = [
Tag('introduced=9'),
@@ -92,33 +96,37 @@
Tag('introduced=9000'),
Tag('introduced=9001'),
]
- self.assertListEqual(
- expected_tags, symbolfile.decode_api_level_tags(tags, api_map))
+ self.assertListEqual(expected_tags, tags)
with self.assertRaises(symbolfile.ParseError):
- symbolfile.decode_api_level_tags([Tag('introduced=O')], {})
+ symbolfile.decode_api_level_tag(Tag('introduced=O'), {})
class PrivateVersionTest(unittest.TestCase):
def test_version_is_private(self) -> None:
- self.assertFalse(symbolfile.version_is_private('foo'))
- self.assertFalse(symbolfile.version_is_private('PRIVATE'))
- self.assertFalse(symbolfile.version_is_private('PLATFORM'))
- self.assertFalse(symbolfile.version_is_private('foo_private'))
- self.assertFalse(symbolfile.version_is_private('foo_platform'))
- self.assertFalse(symbolfile.version_is_private('foo_PRIVATE_'))
- self.assertFalse(symbolfile.version_is_private('foo_PLATFORM_'))
+ def mock_version(name: str) -> Version:
+ return Version(name, base=None, tags=Tags(), symbols=[])
- self.assertTrue(symbolfile.version_is_private('foo_PRIVATE'))
- self.assertTrue(symbolfile.version_is_private('foo_PLATFORM'))
+ self.assertFalse(mock_version('foo').is_private)
+ self.assertFalse(mock_version('PRIVATE').is_private)
+ self.assertFalse(mock_version('PLATFORM').is_private)
+ self.assertFalse(mock_version('foo_private').is_private)
+ self.assertFalse(mock_version('foo_platform').is_private)
+ self.assertFalse(mock_version('foo_PRIVATE_').is_private)
+ self.assertFalse(mock_version('foo_PLATFORM_').is_private)
+
+ self.assertTrue(mock_version('foo_PRIVATE').is_private)
+ self.assertTrue(mock_version('foo_PLATFORM').is_private)
class SymbolPresenceTest(unittest.TestCase):
def test_symbol_in_arch(self) -> None:
- self.assertTrue(symbolfile.symbol_in_arch([], Arch('arm')))
- self.assertTrue(symbolfile.symbol_in_arch([Tag('arm')], Arch('arm')))
+ self.assertTrue(symbolfile.symbol_in_arch(Tags(), Arch('arm')))
+ self.assertTrue(
+ symbolfile.symbol_in_arch(Tags.from_strs(['arm']), Arch('arm')))
- self.assertFalse(symbolfile.symbol_in_arch([Tag('x86')], Arch('arm')))
+ self.assertFalse(
+ symbolfile.symbol_in_arch(Tags.from_strs(['x86']), Arch('arm')))
def test_symbol_in_api(self) -> None:
self.assertTrue(symbolfile.symbol_in_api([], Arch('arm'), 9))
@@ -197,81 +205,99 @@
def test_omit_private(self) -> None:
self.assertFalse(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [], []), Arch('arm'), 9, False,
- False))
+ symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
+ False, False))
self.assertTrue(
symbolfile.should_omit_version(
- symbolfile.Version('foo_PRIVATE', None, [], []), Arch('arm'),
- 9, False, False))
+ symbolfile.Version('foo_PRIVATE', None, Tags(), []),
+ Arch('arm'), 9, False, False))
self.assertTrue(
symbolfile.should_omit_version(
- symbolfile.Version('foo_PLATFORM', None, [], []), Arch('arm'),
- 9, False, False))
+ symbolfile.Version('foo_PLATFORM', None, Tags(), []),
+ Arch('arm'), 9, False, False))
self.assertTrue(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('platform-only')], []),
+ symbolfile.Version('foo', None,
+ Tags.from_strs(['platform-only']), []),
Arch('arm'), 9, False, False))
def test_omit_llndk(self) -> None:
self.assertTrue(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('llndk')], []),
+ symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
Arch('arm'), 9, False, False))
self.assertFalse(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [], []), Arch('arm'), 9, True,
- False))
+ symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
+ True, False))
self.assertFalse(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('llndk')], []),
+ symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
Arch('arm'), 9, True, False))
def test_omit_apex(self) -> None:
self.assertTrue(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('apex')], []),
+ symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
Arch('arm'), 9, False, False))
self.assertFalse(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [], []), Arch('arm'), 9, False,
- True))
+ symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
+ False, True))
self.assertFalse(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('apex')], []),
+ symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
Arch('arm'), 9, False, True))
+ def test_omit_systemapi(self) -> None:
+ self.assertTrue(
+ symbolfile.should_omit_version(
+ symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
+ []), Arch('arm'), 9, False, False))
+
+ self.assertFalse(
+ symbolfile.should_omit_version(
+ symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
+ False, True))
+ self.assertFalse(
+ symbolfile.should_omit_version(
+ symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
+ []), Arch('arm'), 9, False, True))
+
def test_omit_arch(self) -> None:
self.assertFalse(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [], []), Arch('arm'), 9, False,
- False))
+ symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
+ False, False))
self.assertFalse(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('arm')], []), Arch('arm'),
- 9, False, False))
-
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('x86')], []), Arch('arm'),
- 9, False, False))
-
- def test_omit_api(self) -> None:
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [], []), Arch('arm'), 9, False,
- False))
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('introduced=9')], []),
+ symbolfile.Version('foo', None, Tags.from_strs(['arm']), []),
Arch('arm'), 9, False, False))
self.assertTrue(
symbolfile.should_omit_version(
- symbolfile.Version('foo', None, [Tag('introduced=14')], []),
+ symbolfile.Version('foo', None, Tags.from_strs(['x86']), []),
+ Arch('arm'), 9, False, False))
+
+ def test_omit_api(self) -> None:
+ self.assertFalse(
+ symbolfile.should_omit_version(
+ symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
+ False, False))
+ self.assertFalse(
+ symbolfile.should_omit_version(
+ symbolfile.Version('foo', None,
+ Tags.from_strs(['introduced=9']), []),
+ Arch('arm'), 9, False, False))
+
+ self.assertTrue(
+ symbolfile.should_omit_version(
+ symbolfile.Version('foo', None,
+ Tags.from_strs(['introduced=14']), []),
Arch('arm'), 9, False, False))
@@ -279,58 +305,72 @@
def test_omit_llndk(self) -> None:
self.assertTrue(
symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', [Tag('llndk')]), Arch('arm'), 9,
- False, False))
+ symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
+ Arch('arm'), 9, False, False))
self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', []),
+ symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, True, False))
self.assertFalse(
symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', [Tag('llndk')]), Arch('arm'), 9, True,
- False))
+ symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
+ Arch('arm'), 9, True, False))
def test_omit_apex(self) -> None:
self.assertTrue(
symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', [Tag('apex')]), Arch('arm'), 9, False,
- False))
+ symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
+ Arch('arm'), 9, False, False))
self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', []),
+ symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, True))
self.assertFalse(
symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', [Tag('apex')]), Arch('arm'), 9, False,
- True))
+ symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
+ Arch('arm'), 9, False, True))
+
+ def test_omit_systemapi(self) -> None:
+ self.assertTrue(
+ symbolfile.should_omit_symbol(
+ symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
+ Arch('arm'), 9, False, False))
+
+ self.assertFalse(
+ symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
+ Arch('arm'), 9, False, True))
+ self.assertFalse(
+ symbolfile.should_omit_symbol(
+ symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
+ Arch('arm'), 9, False, True))
def test_omit_arch(self) -> None:
self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', []),
+ symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, False))
self.assertFalse(
symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', [Tag('arm')]), Arch('arm'), 9, False,
- False))
+ symbolfile.Symbol('foo', Tags.from_strs(['arm'])), Arch('arm'),
+ 9, False, False))
self.assertTrue(
symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', [Tag('x86')]), Arch('arm'), 9, False,
- False))
+ symbolfile.Symbol('foo', Tags.from_strs(['x86'])), Arch('arm'),
+ 9, False, False))
def test_omit_api(self) -> None:
self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', []),
+ symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
Arch('arm'), 9, False, False))
self.assertFalse(
symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', [Tag('introduced=9')]), Arch('arm'),
- 9, False, False))
+ symbolfile.Symbol('foo', Tags.from_strs(['introduced=9'])),
+ Arch('arm'), 9, False, False))
self.assertTrue(
symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', [Tag('introduced=14')]), Arch('arm'),
- 9, False, False))
+ symbolfile.Symbol('foo', Tags.from_strs(['introduced=14'])),
+ Arch('arm'), 9, False, False))
class SymbolFileParseTest(unittest.TestCase):
@@ -376,11 +416,11 @@
version = parser.parse_version()
self.assertEqual('VERSION_1', version.name)
self.assertIsNone(version.base)
- self.assertEqual(['foo', 'bar'], version.tags)
+ self.assertEqual(Tags.from_strs(['foo', 'bar']), version.tags)
expected_symbols = [
- symbolfile.Symbol('baz', []),
- symbolfile.Symbol('qux', [Tag('woodly'), Tag('doodly')]),
+ symbolfile.Symbol('baz', Tags()),
+ symbolfile.Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
]
self.assertEqual(expected_symbols, version.symbols)
@@ -388,7 +428,7 @@
version = parser.parse_version()
self.assertEqual('VERSION_2', version.name)
self.assertEqual('VERSION_1', version.base)
- self.assertEqual([], version.tags)
+ self.assertEqual(Tags(), version.tags)
def test_parse_version_eof(self) -> None:
input_file = io.StringIO(textwrap.dedent("""\
@@ -423,12 +463,12 @@
parser.next_line()
symbol = parser.parse_symbol()
self.assertEqual('foo', symbol.name)
- self.assertEqual([], symbol.tags)
+ self.assertEqual(Tags(), symbol.tags)
parser.next_line()
symbol = parser.parse_symbol()
self.assertEqual('bar', symbol.name)
- self.assertEqual(['baz', 'qux'], symbol.tags)
+ self.assertEqual(Tags.from_strs(['baz', 'qux']), symbol.tags)
def test_wildcard_symbol_global(self) -> None:
input_file = io.StringIO(textwrap.dedent("""\
@@ -497,14 +537,15 @@
versions = parser.parse()
expected = [
- symbolfile.Version('VERSION_1', None, [], [
- symbolfile.Symbol('foo', []),
- symbolfile.Symbol('bar', [Tag('baz')]),
+ symbolfile.Version('VERSION_1', None, Tags(), [
+ symbolfile.Symbol('foo', Tags()),
+ symbolfile.Symbol('bar', Tags.from_strs(['baz'])),
]),
- symbolfile.Version('VERSION_2', 'VERSION_1', [Tag('wasd')], [
- symbolfile.Symbol('woodly', []),
- symbolfile.Symbol('doodly', [Tag('asdf')]),
- ]),
+ symbolfile.Version(
+ 'VERSION_2', 'VERSION_1', Tags.from_strs(['wasd']), [
+ symbolfile.Symbol('woodly', Tags()),
+ symbolfile.Symbol('doodly', Tags.from_strs(['asdf'])),
+ ]),
]
self.assertEqual(expected, versions)
@@ -527,10 +568,10 @@
self.assertIsNone(version.base)
expected_symbols = [
- symbolfile.Symbol('foo', []),
- symbolfile.Symbol('bar', [Tag('llndk')]),
- symbolfile.Symbol('baz', [Tag('llndk'), Tag('apex')]),
- symbolfile.Symbol('qux', [Tag('apex')]),
+ symbolfile.Symbol('foo', Tags()),
+ symbolfile.Symbol('bar', Tags.from_strs(['llndk'])),
+ symbolfile.Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
+ symbolfile.Symbol('qux', Tags.from_strs(['apex'])),
]
self.assertEqual(expected_symbols, version.symbols)
diff --git a/cc/testing.go b/cc/testing.go
index 15f7ebb..e8f3481 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -15,8 +15,12 @@
package cc
import (
+ "path/filepath"
+ "testing"
+
"android/soong/android"
"android/soong/genrule"
+ "android/soong/snapshot"
)
func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
@@ -31,6 +35,7 @@
ctx.RegisterModuleType("cc_object", ObjectFactory)
ctx.RegisterModuleType("cc_genrule", genRuleFactory)
ctx.RegisterModuleType("ndk_prebuilt_shared_stl", NdkPrebuiltSharedStlFactory)
+ ctx.RegisterModuleType("ndk_prebuilt_static_stl", NdkPrebuiltStaticStlFactory)
ctx.RegisterModuleType("ndk_prebuilt_object", NdkPrebuiltObjectFactory)
ctx.RegisterModuleType("ndk_library", NdkLibraryFactory)
}
@@ -40,9 +45,6 @@
supportLinuxBionic := false
for _, os := range oses {
- if os == android.Fuchsia {
- ret += withFuchsiaModules()
- }
if os == android.Windows {
ret += withWindowsModules()
}
@@ -363,6 +365,7 @@
stl: "none",
min_sdk_version: "16",
crt: true,
+ system_shared_libs: [],
apex_available: [
"//apex_available:platform",
"//apex_available:anyapex",
@@ -400,7 +403,7 @@
cc_library {
name: "ndk_libunwind",
- sdk_version: "current",
+ sdk_version: "minimum",
stl: "none",
system_shared_libs: [],
}
@@ -425,6 +428,12 @@
ndk_prebuilt_shared_stl {
name: "ndk_libc++_shared",
+ export_include_dirs: ["ndk_libc++_shared"],
+ }
+
+ ndk_prebuilt_static_stl {
+ name: "ndk_libandroid_support",
+ export_include_dirs: ["ndk_libandroid_support"],
}
cc_library_static {
@@ -441,6 +450,25 @@
cc_library_static {
name: "note_memtag_heap_sync",
}
+
+
+ cc_library {
+ name: "libjemalloc5",
+ host_supported: true,
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libc_musl",
+ host_supported: true,
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ }
`
}
@@ -460,19 +488,6 @@
`
}
-func withFuchsiaModules() string {
- return `
- cc_library {
- name: "libbioniccompat",
- stl: "none",
- }
- cc_library {
- name: "libcompiler_rt",
- stl: "none",
- }
- `
-}
-
func withLinuxBionic() string {
return `
cc_binary {
@@ -487,7 +502,7 @@
}
cc_genrule {
- name: "host_bionic_linker_flags",
+ name: "host_bionic_linker_script",
host_supported: true,
device_supported: false,
target: {
@@ -498,7 +513,7 @@
enabled: true,
},
},
- out: ["linker.flags"],
+ out: ["linker.script"],
}
cc_defaults {
@@ -575,9 +590,11 @@
// Additional files needed in tests that disallow non-existent source.
android.MockFS{
- "defaults/cc/common/libc.map.txt": nil,
- "defaults/cc/common/libdl.map.txt": nil,
- "defaults/cc/common/libm.map.txt": nil,
+ "defaults/cc/common/libc.map.txt": nil,
+ "defaults/cc/common/libdl.map.txt": nil,
+ "defaults/cc/common/libm.map.txt": nil,
+ "defaults/cc/common/ndk_libandroid_support": nil,
+ "defaults/cc/common/ndk_libc++_shared": nil,
}.AddToFixture(),
// Place the default cc test modules that are common to all platforms in a location that will not
@@ -612,21 +629,15 @@
android.FixtureOverrideTextFile(linuxBionicDefaultsPath, withLinuxBionic()),
)
-// The preparer to include if running a cc related test for fuchsia.
-var PrepareForTestOnFuchsia = android.GroupFixturePreparers(
- // Place the default cc test modules for fuschia in a location that will not conflict with default
- // test modules defined by other packages.
- android.FixtureAddTextFile("defaults/cc/fuschia/Android.bp", withFuchsiaModules()),
- android.PrepareForTestSetDeviceToFuchsia,
-)
-
// This adds some additional modules and singletons which might negatively impact the performance
// of tests so they are not included in the PrepareForIntegrationTestWithCc.
var PrepareForTestWithCcIncludeVndk = android.GroupFixturePreparers(
PrepareForIntegrationTestWithCc,
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
- vendorSnapshotImageSingleton.init(ctx)
- recoverySnapshotImageSingleton.init(ctx)
+ snapshot.VendorSnapshotImageSingleton.Init(ctx)
+ snapshot.RecoverySnapshotImageSingleton.Init(ctx)
+ RegisterVendorSnapshotModules(ctx)
+ RegisterRecoverySnapshotModules(ctx)
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
}),
)
@@ -650,14 +661,7 @@
mockFS[k] = v
}
- var config android.Config
- if os == android.Fuchsia {
- panic("Fuchsia not supported use test fixture instead")
- } else {
- config = android.TestArchConfig(buildDir, env, bp, mockFS)
- }
-
- return config
+ return android.TestArchConfig(buildDir, env, bp, mockFS)
}
// CreateTestContext is the legacy way of creating a TestContext for testing cc modules.
@@ -674,8 +678,10 @@
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
- vendorSnapshotImageSingleton.init(ctx)
- recoverySnapshotImageSingleton.init(ctx)
+ snapshot.VendorSnapshotImageSingleton.Init(ctx)
+ snapshot.RecoverySnapshotImageSingleton.Init(ctx)
+ RegisterVendorSnapshotModules(ctx)
+ RegisterRecoverySnapshotModules(ctx)
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
RegisterVndkLibraryTxtTypes(ctx)
@@ -685,3 +691,64 @@
return ctx
}
+
+func checkSnapshotIncludeExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string, include bool, fake bool) {
+ t.Helper()
+ mod := ctx.ModuleForTests(moduleName, variant)
+ outputFiles := mod.OutputFiles(t, "")
+ if len(outputFiles) != 1 {
+ t.Errorf("%q must have single output\n", moduleName)
+ return
+ }
+ snapshotPath := filepath.Join(subDir, snapshotFilename)
+
+ if include {
+ out := singleton.Output(snapshotPath)
+ if fake {
+ if out.Rule == nil {
+ t.Errorf("Missing rule for module %q output file %q", moduleName, outputFiles[0])
+ }
+ } else {
+ if out.Input.String() != outputFiles[0].String() {
+ t.Errorf("The input of snapshot %q must be %q, but %q", moduleName, out.Input.String(), outputFiles[0])
+ }
+ }
+ } else {
+ out := singleton.MaybeOutput(snapshotPath)
+ if out.Rule != nil {
+ t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0])
+ }
+ }
+}
+
+func CheckSnapshot(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
+ t.Helper()
+ checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, false)
+}
+
+func CheckSnapshotExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
+ t.Helper()
+ checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, false, false)
+}
+
+func CheckSnapshotRule(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
+ t.Helper()
+ checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, true)
+}
+
+func AssertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool, variant string) {
+ t.Helper()
+ m := ctx.ModuleForTests(name, variant).Module().(LinkableInterface)
+ if m.ExcludeFromVendorSnapshot() != expected {
+ t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
+ }
+}
+
+func GetOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
+ for _, moduleName := range moduleNames {
+ module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
+ output := module.outputFile.Path().RelativeToTop()
+ paths = append(paths, output)
+ }
+ return paths
+}
diff --git a/cc/tidy.go b/cc/tidy.go
index 616cf8a..b2382e8 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -61,13 +61,6 @@
return []interface{}{&tidy.Properties}
}
-func (tidy *tidyFeature) begin(ctx BaseModuleContext) {
-}
-
-func (tidy *tidyFeature) deps(ctx DepsContext, deps Deps) Deps {
- return deps
-}
-
func (tidy *tidyFeature) flags(ctx ModuleContext, flags Flags) Flags {
CheckBadTidyFlags(ctx, "tidy_flags", tidy.Properties.Tidy_flags)
CheckBadTidyChecks(ctx, "tidy_checks", tidy.Properties.Tidy_checks)
diff --git a/cc/util.go b/cc/util.go
index 1220d84..9bba876 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -21,6 +21,7 @@
"strings"
"android/soong/android"
+ "android/soong/snapshot"
)
// Efficiently converts a list of include directories to a single string
@@ -126,20 +127,6 @@
"ln -sf " + target + " " + filepath.Join(dir, linkName)
}
-func copyFileRule(ctx android.SingletonContext, path android.Path, out string) android.OutputPath {
- outPath := android.PathForOutput(ctx, out)
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Input: path,
- Output: outPath,
- Description: "copy " + path.String() + " -> " + out,
- Args: map[string]string{
- "cpFlags": "-f -L",
- },
- })
- return outPath
-}
-
func combineNoticesRule(ctx android.SingletonContext, paths android.Paths, out string) android.OutputPath {
outPath := android.PathForOutput(ctx, out)
ctx.Build(pctx, android.BuildParams{
@@ -151,12 +138,6 @@
return outPath
}
-func writeStringToFileRule(ctx android.SingletonContext, content, out string) android.OutputPath {
- outPath := android.PathForOutput(ctx, out)
- android.WriteFileRule(ctx, outPath, content)
- return outPath
-}
-
// Dump a map to a list file as:
//
// {key1} {value1}
@@ -172,5 +153,5 @@
txtBuilder.WriteString(" ")
txtBuilder.WriteString(m[k])
}
- return writeStringToFileRule(ctx, txtBuilder.String(), path)
+ return snapshot.WriteStringToFileRule(ctx, txtBuilder.String(), path)
}
diff --git a/cc/vendor_public_library_test.go b/cc/vendor_public_library_test.go
index 01959b4..769be09 100644
--- a/cc/vendor_public_library_test.go
+++ b/cc/vendor_public_library_test.go
@@ -79,7 +79,7 @@
// test if libsystem is linked to the stub
ld := ctx.ModuleForTests("libsystem", coreVariant).Rule("ld")
libflags := ld.Args["libFlags"]
- stubPaths := getOutputPaths(ctx, coreVariant, []string{"libvendorpublic"})
+ stubPaths := GetOutputPaths(ctx, coreVariant, []string{"libvendorpublic"})
if !strings.Contains(libflags, stubPaths[0].String()) {
t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
}
@@ -87,7 +87,7 @@
// test if libsystem is linked to the stub
ld = ctx.ModuleForTests("libproduct", productVariant).Rule("ld")
libflags = ld.Args["libFlags"]
- stubPaths = getOutputPaths(ctx, productVariant, []string{"libvendorpublic"})
+ stubPaths = GetOutputPaths(ctx, productVariant, []string{"libvendorpublic"})
if !strings.Contains(libflags, stubPaths[0].String()) {
t.Errorf("libflags for libproduct must contain %#v, but was %#v", stubPaths[0], libflags)
}
@@ -95,7 +95,8 @@
// test if libvendor is linked to the real shared lib
ld = ctx.ModuleForTests("libvendor", vendorVariant).Rule("ld")
libflags = ld.Args["libFlags"]
- stubPaths = getOutputPaths(ctx, vendorVariant, []string{"libvendorpublic"})
+ stubPaths = GetOutputPaths(ctx, vendorVariant, []string{"libvendorpublic"})
+
if !strings.Contains(libflags, stubPaths[0].String()) {
t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
}
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 4e59a95..ba4d79f 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -13,141 +13,46 @@
// limitations under the License.
package cc
-// This file contains singletons to capture vendor and recovery snapshot. They consist of prebuilt
-// modules under AOSP so older vendor and recovery can be built with a newer system in a single
-// source tree.
-
import (
"encoding/json"
"path/filepath"
- "sort"
"strings"
"android/soong/android"
+ "android/soong/snapshot"
)
-var vendorSnapshotSingleton = snapshotSingleton{
- "vendor",
- "SOONG_VENDOR_SNAPSHOT_ZIP",
- android.OptionalPath{},
- true,
- vendorSnapshotImageSingleton,
- false, /* fake */
-}
+// This file defines how to capture cc modules into snapshot package.
-var vendorFakeSnapshotSingleton = snapshotSingleton{
- "vendor",
- "SOONG_VENDOR_FAKE_SNAPSHOT_ZIP",
- android.OptionalPath{},
- true,
- vendorSnapshotImageSingleton,
- true, /* fake */
-}
-
-var recoverySnapshotSingleton = snapshotSingleton{
- "recovery",
- "SOONG_RECOVERY_SNAPSHOT_ZIP",
- android.OptionalPath{},
- false,
- recoverySnapshotImageSingleton,
- false, /* fake */
-}
-
-func VendorSnapshotSingleton() android.Singleton {
- return &vendorSnapshotSingleton
-}
-
-func VendorFakeSnapshotSingleton() android.Singleton {
- return &vendorFakeSnapshotSingleton
-}
-
-func RecoverySnapshotSingleton() android.Singleton {
- return &recoverySnapshotSingleton
-}
-
-type snapshotSingleton struct {
- // Name, e.g., "vendor", "recovery", "ramdisk".
- name string
-
- // Make variable that points to the snapshot file, e.g.,
- // "SOONG_RECOVERY_SNAPSHOT_ZIP".
- makeVar string
-
- // Path to the snapshot zip file.
- snapshotZipFile android.OptionalPath
-
- // Whether the image supports VNDK extension modules.
- supportsVndkExt bool
-
- // Implementation of the image interface specific to the image
- // associated with this snapshot (e.g., specific to the vendor image,
- // recovery image, etc.).
- image snapshotImage
-
- // Whether this singleton is for fake snapshot or not.
- // Fake snapshot is a snapshot whose prebuilt binaries and headers are empty.
- // It is much faster to generate, and can be used to inspect dependencies.
- fake bool
-}
-
-// Determine if a dir under source tree is an SoC-owned proprietary directory based
-// on vendor snapshot configuration
-// Examples: device/, vendor/
-func isVendorProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
- return VendorSnapshotSingleton().(*snapshotSingleton).image.isProprietaryPath(dir, deviceConfig)
-}
-
-// Determine if a dir under source tree is an SoC-owned proprietary directory based
-// on recovery snapshot configuration
-// Examples: device/, vendor/
-func isRecoveryProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
- return RecoverySnapshotSingleton().(*snapshotSingleton).image.isProprietaryPath(dir, deviceConfig)
-}
-
-func isVendorProprietaryModule(ctx android.BaseModuleContext) bool {
- // Any module in a vendor proprietary path is a vendor proprietary
- // module.
- if isVendorProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) {
+// Checks if the target image would contain VNDK
+func includeVndk(image snapshot.SnapshotImage) bool {
+ if image.ImageName() == snapshot.VendorSnapshotImageName {
return true
}
- // However if the module is not in a vendor proprietary path, it may
- // still be a vendor proprietary module. This happens for cc modules
- // that are excluded from the vendor snapshot, and it means that the
- // vendor has assumed control of the framework-provided module.
- if c, ok := ctx.Module().(LinkableInterface); ok {
- if c.ExcludeFromVendorSnapshot() {
- return true
- }
- }
-
return false
}
-func isRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
-
- // Any module in a recovery proprietary path is a recovery proprietary
- // module.
- if isRecoveryProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) {
+// Check if the module is VNDK private
+func isPrivate(image snapshot.SnapshotImage, m LinkableInterface) bool {
+ if image.ImageName() == snapshot.VendorSnapshotImageName && m.IsVndkPrivate() {
return true
}
- // However if the module is not in a recovery proprietary path, it may
- // still be a recovery proprietary module. This happens for cc modules
- // that are excluded from the recovery snapshot, and it means that the
- // vendor has assumed control of the framework-provided module.
+ return false
+}
- if c, ok := ctx.Module().(LinkableInterface); ok {
- if c.ExcludeFromRecoverySnapshot() {
- return true
- }
+// Checks if target image supports VNDK Ext
+func supportsVndkExt(image snapshot.SnapshotImage) bool {
+ if image.ImageName() == snapshot.VendorSnapshotImageName {
+ return true
}
return false
}
// Determines if the module is a candidate for snapshot.
-func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshotImage) bool {
+func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshot.SnapshotImage) bool {
if !m.Enabled() || m.HiddenFromMake() {
return false
}
@@ -158,12 +63,12 @@
}
// skip proprietary modules, but (for the vendor snapshot only)
// include all VNDK (static)
- if inProprietaryPath && (!image.includeVndk() || !m.IsVndk()) {
+ if inProprietaryPath && (!includeVndk(image) || !m.IsVndk()) {
return false
}
// If the module would be included based on its path, check to see if
// the module is marked to be excluded. If so, skip it.
- if image.excludeFromSnapshot(m) {
+ if image.ExcludeFromSnapshot(m) {
return false
}
if m.Target().Os.Class != android.Device {
@@ -173,7 +78,7 @@
return false
}
// the module must be installed in target image
- if !apexInfo.IsForPlatform() || m.IsSnapshotPrebuilt() || !image.inImage(m)() {
+ if !apexInfo.IsForPlatform() || m.IsSnapshotPrebuilt() || !image.InImage(m)() {
return false
}
// skip kernel_headers which always depend on vendor
@@ -203,13 +108,13 @@
}
}
if sanitizable.Static() {
- return sanitizable.OutputFile().Valid() && !image.private(m)
+ return sanitizable.OutputFile().Valid() && !isPrivate(image, m)
}
- if sanitizable.Shared() {
+ if sanitizable.Shared() || sanitizable.Rlib() {
if !sanitizable.OutputFile().Valid() {
return false
}
- if image.includeVndk() {
+ if includeVndk(image) {
if !sanitizable.IsVndk() {
return true
}
@@ -242,10 +147,12 @@
SanitizeUbsanDep bool `json:",omitempty"`
// binary flags
- Symlinks []string `json:",omitempty"`
+ Symlinks []string `json:",omitempty"`
+ StaticExecutable bool `json:",omitempty"`
// dependencies
SharedLibs []string `json:",omitempty"`
+ StaticLibs []string `json:",omitempty"`
RuntimeLibs []string `json:",omitempty"`
Required []string `json:",omitempty"`
@@ -254,15 +161,9 @@
VintfFragments []string `json:",omitempty"`
}
-func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- if !c.image.shouldGenerateSnapshot(ctx) {
- return
- }
-
- var snapshotOutputs android.Paths
-
+var ccSnapshotAction snapshot.GenerateSnapshotAction = func(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) android.Paths {
/*
- Vendor snapshot zipped artifacts directory structure:
+ Vendor snapshot zipped artifacts directory structure for cc modules:
{SNAPSHOT_ARCH}/
arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
shared/
@@ -294,13 +195,7 @@
(header files of same directory structure with source tree)
*/
- snapshotDir := c.name + "-snapshot"
- if c.fake {
- // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
- // collision with real snapshot files
- snapshotDir = filepath.Join("fake", snapshotDir)
- }
- snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
+ var snapshotOutputs android.Paths
includeDir := filepath.Join(snapshotArchDir, "include")
configsDir := filepath.Join(snapshotArchDir, "configs")
@@ -315,9 +210,9 @@
if fake {
// All prebuilt binaries and headers are installed by copyFile function. This makes a fake
// snapshot just touch prebuilts and headers, rather than installing real files.
- return writeStringToFileRule(ctx, "", out)
+ return snapshot.WriteStringToFileRule(ctx, "", out)
} else {
- return copyFileRule(ctx, path, out)
+ return snapshot.CopyFileRule(pctx, ctx, path, out)
}
}
@@ -335,7 +230,7 @@
// Common properties among snapshots.
prop.ModuleName = ctx.ModuleName(m)
- if c.supportsVndkExt && m.IsVndkExt() {
+ if supportsVndkExt(s.Image) && m.IsVndkExt() {
// vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
if m.IsVndkSp() {
prop.RelativeInstallPath = "vndk-sp"
@@ -381,6 +276,8 @@
if m.Shared() {
prop.SharedLibs = m.SnapshotSharedLibs()
}
+ // static libs dependencies are required to collect the NOTICE files.
+ prop.StaticLibs = m.SnapshotStaticLibs()
if sanitizable, ok := m.(PlatformSanitizeable); ok {
if sanitizable.Static() && sanitizable.SanitizePropDefined() {
prop.SanitizeMinimalDep = sanitizable.MinimalRuntimeDep() || sanitizable.MinimalRuntimeNeeded()
@@ -393,6 +290,8 @@
libType = "static"
} else if m.Shared() {
libType = "shared"
+ } else if m.Rlib() {
+ libType = "rlib"
} else {
libType = "header"
}
@@ -404,7 +303,7 @@
libPath := m.OutputFile().Path()
stem = libPath.Base()
if sanitizable, ok := m.(PlatformSanitizeable); ok {
- if sanitizable.Static() && sanitizable.SanitizePropDefined() && sanitizable.IsSanitizerEnabled(cfi) {
+ if (sanitizable.Static() || sanitizable.Rlib()) && sanitizable.SanitizePropDefined() && sanitizable.IsSanitizerEnabled(cfi) {
// both cfi and non-cfi variant for static libraries can exist.
// attach .cfi to distinguish between cfi and non-cfi.
// e.g. libbase.a -> libbase.cfi.a
@@ -424,8 +323,10 @@
} else if m.Binary() {
// binary flags
prop.Symlinks = m.Symlinks()
+ prop.StaticExecutable = m.StaticExecutable()
prop.SharedLibs = m.SnapshotSharedLibs()
-
+ // static libs dependencies are required to collect the NOTICE files.
+ prop.StaticLibs = m.SnapshotStaticLibs()
// install bin
binPath := m.OutputFile().Path()
snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
@@ -449,7 +350,7 @@
ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
return nil
}
- ret = append(ret, writeStringToFileRule(ctx, string(j), propOut))
+ ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
return ret
}
@@ -461,10 +362,10 @@
}
moduleDir := ctx.ModuleDir(module)
- inProprietaryPath := c.image.isProprietaryPath(moduleDir, ctx.DeviceConfig())
+ inProprietaryPath := s.Image.IsProprietaryPath(moduleDir, ctx.DeviceConfig())
apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
- if c.image.excludeFromSnapshot(m) {
+ if s.Image.ExcludeFromSnapshot(m) {
if inProprietaryPath {
// Error: exclude_from_vendor_snapshot applies
// to framework-path modules only.
@@ -473,7 +374,7 @@
}
}
- if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, c.image) {
+ if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, s.Image) {
return
}
@@ -481,8 +382,8 @@
// list, we will still include the module as if it was a fake module.
// The reason is that soong needs all the dependencies to be present, even
// if they are not using during the build.
- installAsFake := c.fake
- if c.image.excludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
+ installAsFake := s.Fake
+ if s.Image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
installAsFake = true
}
@@ -493,60 +394,25 @@
headers = append(headers, m.SnapshotHeaders()...)
}
- if len(m.NoticeFiles()) > 0 {
+ if len(m.EffectiveLicenseFiles()) > 0 {
noticeName := ctx.ModuleName(m) + ".txt"
noticeOut := filepath.Join(noticeDir, noticeName)
// skip already copied notice file
if !installedNotices[noticeOut] {
installedNotices[noticeOut] = true
- snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.NoticeFiles(), noticeOut))
+ snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.EffectiveLicenseFiles(), noticeOut))
}
}
})
// install all headers after removing duplicates
for _, header := range android.FirstUniquePaths(headers) {
- snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String()), c.fake))
+ snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String()), s.Fake))
}
- // All artifacts are ready. Sort them to normalize ninja and then zip.
- sort.Slice(snapshotOutputs, func(i, j int) bool {
- return snapshotOutputs[i].String() < snapshotOutputs[j].String()
- })
-
- zipPath := android.PathForOutput(
- ctx,
- snapshotDir,
- c.name+"-"+ctx.Config().DeviceName()+".zip")
- zipRule := android.NewRuleBuilder(pctx, ctx)
-
- // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
- snapshotOutputList := android.PathForOutput(
- ctx,
- snapshotDir,
- c.name+"-"+ctx.Config().DeviceName()+"_list")
- rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
- zipRule.Command().
- Text("tr").
- FlagWithArg("-d ", "\\'").
- FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
- FlagWithOutput("> ", snapshotOutputList)
-
- zipRule.Temporary(snapshotOutputList)
-
- zipRule.Command().
- BuiltTool("soong_zip").
- FlagWithOutput("-o ", zipPath).
- FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
- FlagWithInput("-l ", snapshotOutputList)
-
- zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
- zipRule.DeleteTemporaryFiles()
- c.snapshotZipFile = android.OptionalPathForPath(zipPath)
+ return snapshotOutputs
}
-func (c *snapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
- ctx.Strict(
- c.makeVar,
- c.snapshotZipFile.String())
+func init() {
+ snapshot.RegisterSnapshotAction(ccSnapshotAction)
}
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
index c3b5e8c..ca2f569 100644
--- a/cc/vendor_snapshot_test.go
+++ b/cc/vendor_snapshot_test.go
@@ -108,27 +108,27 @@
// For shared libraries, only non-VNDK vendor_available modules are captured
sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
jsonFiles = append(jsonFiles,
filepath.Join(sharedDir, "libvendor.so.json"),
filepath.Join(sharedDir, "libvendor_available.so.json"))
// LLNDK modules are not captured
- checkSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant)
+ CheckSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant)
// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
// Also cfi variants are captured, except for prebuilts like toolchain_library
staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant)
staticCfiVariant := fmt.Sprintf("android_vendor.29_%s_%s_static_cfi", archType, archVariant)
staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
- checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
jsonFiles = append(jsonFiles,
filepath.Join(staticDir, "libb.a.json"),
filepath.Join(staticDir, "libvndk.a.json"),
@@ -142,8 +142,8 @@
if archType == "arm64" {
binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
- checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
jsonFiles = append(jsonFiles,
filepath.Join(binaryDir, "vendor_bin.json"),
filepath.Join(binaryDir, "vendor_available_bin.json"))
@@ -156,7 +156,7 @@
// For object modules, all vendor:true and vendor_available modules are captured.
objectVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
- checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
}
@@ -239,15 +239,15 @@
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
// Included modules
- checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
// Check that snapshot captures "prefer: true" prebuilt
- checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
// Excluded modules. Modules not included in the directed vendor snapshot
// are still include as fake modules.
- checkSnapshotRule(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
+ CheckSnapshotRule(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json"))
}
@@ -459,6 +459,19 @@
srcs: ["client.cpp"],
}
+ cc_library_shared {
+ name: "libvndkext",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ vndk: {
+ extends: "libvndk",
+ enabled: true,
+ }
+ }
+
cc_binary {
name: "bin_without_snapshot",
vendor: true,
@@ -839,10 +852,11 @@
[]string{staticVariant, "libvendor.vendor_static.31.arm64"},
[]string{staticVariant, "libvendor_without_snapshot"},
} {
- outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
+ outputPaths := GetOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
}
+
}
libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
@@ -868,7 +882,7 @@
}
libclientCfiLdFlags := ctx.ModuleForTests("libclient_cfi", sharedCfiVariant).Rule("ld").Args["libFlags"]
- libvendorCfiOutputPaths := getOutputPaths(ctx, staticCfiVariant, []string{"libvendor.vendor_static.31.arm64"})
+ libvendorCfiOutputPaths := GetOutputPaths(ctx, staticCfiVariant, []string{"libvendor.vendor_static.31.arm64"})
if !strings.Contains(libclientCfiLdFlags, libvendorCfiOutputPaths[0].String()) {
t.Errorf("libflags for libclientCfi must contain %#v, but was %#v", libvendorCfiOutputPaths[0], libclientCfiLdFlags)
}
@@ -881,7 +895,7 @@
}
binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"]
- libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.31.arm64"})
+ libVndkStaticOutputPaths := GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.31.arm64"})
if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
@@ -1006,14 +1020,6 @@
assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
}
-func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
- t.Helper()
- m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
- if m.ExcludeFromVendorSnapshot() != expected {
- t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
- }
-}
-
func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
t.Helper()
m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module)
@@ -1081,13 +1087,13 @@
android.FailIfErrored(t, errs)
// Test an include and exclude framework module.
- assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false)
- assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true)
- assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true)
+ AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, vendorVariant)
+ AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, vendorVariant)
+ AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, vendorVariant)
// A vendor module is excluded, but by its path, not the
// exclude_from_vendor_snapshot property.
- assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false)
+ AssertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false, vendorVariant)
// Verify the content of the vendor snapshot.
@@ -1110,15 +1116,15 @@
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
// Included modules
- checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
// Excluded modules
- checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
+ CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
- checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
+ CheckSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
- checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
+ CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
}
@@ -1258,9 +1264,9 @@
// For shared libraries, only recovery_available modules are captured.
sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
jsonFiles = append(jsonFiles,
filepath.Join(sharedDir, "libvndk.so.json"),
filepath.Join(sharedDir, "librecovery.so.json"),
@@ -1269,9 +1275,9 @@
// For static libraries, all recovery:true and recovery_available modules are captured.
staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant)
staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
- checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
jsonFiles = append(jsonFiles,
filepath.Join(staticDir, "libb.a.json"),
filepath.Join(staticDir, "librecovery.a.json"),
@@ -1281,8 +1287,8 @@
if archType == "arm64" {
binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
- checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
- checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
jsonFiles = append(jsonFiles,
filepath.Join(binaryDir, "recovery_bin.json"),
filepath.Join(binaryDir, "recovery_available_bin.json"))
@@ -1295,7 +1301,7 @@
// For object modules, all vendor:true and vendor_available modules are captured.
objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
- checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
}
@@ -1393,15 +1399,15 @@
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
// Included modules
- checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
// Excluded modules
- checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
+ CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
- checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
+ CheckSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
- checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
+ CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
}
@@ -1482,15 +1488,15 @@
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
// Included modules
- checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
// Check that snapshot captures "prefer: true" prebuilt
- checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
+ CheckSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
// Excluded modules. Modules not included in the directed recovery snapshot
// are still include as fake modules.
- checkSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
+ CheckSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery_available.so.json"))
}
diff --git a/cc/vndk.go b/cc/vndk.go
index 6a56c34..1ae79de 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -25,6 +25,7 @@
"android/soong/android"
"android/soong/cc/config"
"android/soong/etc"
+ "android/soong/snapshot"
"github.com/google/blueprint"
)
@@ -100,12 +101,6 @@
return []interface{}{&vndk.Properties}
}
-func (vndk *vndkdep) begin(ctx BaseModuleContext) {}
-
-func (vndk *vndkdep) deps(ctx BaseModuleContext, deps Deps) Deps {
- return deps
-}
-
func (vndk *vndkdep) isVndk() bool {
return Bool(vndk.Properties.Vndk.Enabled)
}
@@ -360,7 +355,7 @@
// prebuilt vndk modules should match with device
// TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
// When b/142675459 is landed, remove following check
- if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.matchesWithDevice(mctx.DeviceConfig()) {
+ if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.MatchesWithDevice(mctx.DeviceConfig()) {
return false
}
@@ -371,7 +366,7 @@
if mctx.ModuleName() == "libz" {
return false
}
- return m.ImageVariation().Variation == android.CoreVariation && lib.shared() && m.IsVndkSp()
+ return m.ImageVariation().Variation == android.CoreVariation && lib.shared() && m.IsVndkSp() && !m.IsVndkExt()
}
useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
@@ -704,7 +699,7 @@
libPath := m.outputFile.Path()
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base())
- ret = append(ret, copyFileRule(ctx, libPath, snapshotLibOut))
+ ret = append(ret, snapshot.CopyFileRule(pctx, ctx, libPath, snapshotLibOut))
if ctx.Config().VndkSnapshotBuildArtifacts() {
prop := struct {
@@ -726,7 +721,7 @@
ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
return nil, false
}
- ret = append(ret, writeStringToFileRule(ctx, string(j), propOut))
+ ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
}
return ret, true
}
@@ -784,8 +779,8 @@
// install all headers after removing duplicates
for _, header := range android.FirstUniquePaths(headers) {
- snapshotOutputs = append(snapshotOutputs, copyFileRule(
- ctx, header, filepath.Join(includeDir, header.String())))
+ snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
+ pctx, ctx, header, filepath.Join(includeDir, header.String())))
}
// install *.libraries.txt except vndkcorevariant.libraries.txt
@@ -794,8 +789,8 @@
if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt {
return
}
- snapshotOutputs = append(snapshotOutputs, copyFileRule(
- ctx, m.OutputFile(), filepath.Join(configsDir, m.Name())))
+ snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
+ pctx, ctx, m.OutputFile(), filepath.Join(configsDir, m.Name())))
})
/*
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index fc4412a..da34f36 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -82,7 +82,7 @@
}
func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string {
- suffix := p.version()
+ suffix := p.Version()
if p.arch() != "" {
suffix += "." + p.arch()
}
@@ -92,7 +92,7 @@
return vndkSuffix + suffix
}
-func (p *vndkPrebuiltLibraryDecorator) version() string {
+func (p *vndkPrebuiltLibraryDecorator) Version() string {
return String(p.properties.Version)
}
@@ -107,7 +107,7 @@
return "64"
}
-func (p *vndkPrebuiltLibraryDecorator) snapshotAndroidMkSuffix() string {
+func (p *vndkPrebuiltLibraryDecorator) SnapshotAndroidMkSuffix() string {
return ".vendor"
}
@@ -133,7 +133,7 @@
func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
- if !p.matchesWithDevice(ctx.DeviceConfig()) {
+ if !p.MatchesWithDevice(ctx.DeviceConfig()) {
ctx.Module().HideFromMake()
return nil
}
@@ -163,14 +163,13 @@
p.androidMkSuffix = p.NameSuffix()
vndkVersion := ctx.DeviceConfig().VndkVersion()
- if vndkVersion == p.version() {
+ if vndkVersion == p.Version() {
p.androidMkSuffix = ""
}
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
- SharedLibrary: in,
- UnstrippedSharedLibrary: p.unstrippedOutputFile,
- Target: ctx.Target(),
+ SharedLibrary: in,
+ Target: ctx.Target(),
TableOfContents: p.tocFile,
})
@@ -184,7 +183,7 @@
return nil
}
-func (p *vndkPrebuiltLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
+func (p *vndkPrebuiltLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
arches := config.Arches()
if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
return false
@@ -202,7 +201,7 @@
return false
}
-func (p *vndkPrebuiltLibraryDecorator) isSnapshotPrebuilt() bool {
+func (p *vndkPrebuiltLibraryDecorator) IsSnapshotPrebuilt() bool {
return true
}
diff --git a/cmd/extract_apks/Android.bp b/cmd/extract_apks/Android.bp
index 8a4ed63..21064c0 100644
--- a/cmd/extract_apks/Android.bp
+++ b/cmd/extract_apks/Android.bp
@@ -8,6 +8,7 @@
deps: [
"android-archive-zip",
"golang-protobuf-proto",
+ "golang-protobuf-encoding-prototext",
"soong-cmd-extract_apks-proto",
],
testSrcs: ["main_test.go"],
@@ -16,7 +17,10 @@
bootstrap_go_package {
name: "soong-cmd-extract_apks-proto",
pkgPath: "android/soong/cmd/extract_apks/bundle_proto",
- deps: ["golang-protobuf-proto"],
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
srcs: [
"bundle_proto/commands.pb.go",
"bundle_proto/config.pb.go",
diff --git a/cmd/extract_apks/bundle_proto/commands.pb.go b/cmd/extract_apks/bundle_proto/commands.pb.go
index bbf3314..2cf8e6d 100644
--- a/cmd/extract_apks/bundle_proto/commands.pb.go
+++ b/cmd/extract_apks/bundle_proto/commands.pb.go
@@ -1,24 +1,29 @@
+// Messages describing APK Set's table of contents (toc.pb entry).
+// Please be advised that the ultimate source is at
+// https://github.com/google/bundletool/tree/master/src/main/proto
+// so you have been warned.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: commands.proto
-package android_bundle_proto
+package bundle_proto
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
type DeliveryType int32
@@ -29,26 +34,47 @@
DeliveryType_FAST_FOLLOW DeliveryType = 3
)
-var DeliveryType_name = map[int32]string{
- 0: "UNKNOWN_DELIVERY_TYPE",
- 1: "INSTALL_TIME",
- 2: "ON_DEMAND",
- 3: "FAST_FOLLOW",
-}
+// Enum value maps for DeliveryType.
+var (
+ DeliveryType_name = map[int32]string{
+ 0: "UNKNOWN_DELIVERY_TYPE",
+ 1: "INSTALL_TIME",
+ 2: "ON_DEMAND",
+ 3: "FAST_FOLLOW",
+ }
+ DeliveryType_value = map[string]int32{
+ "UNKNOWN_DELIVERY_TYPE": 0,
+ "INSTALL_TIME": 1,
+ "ON_DEMAND": 2,
+ "FAST_FOLLOW": 3,
+ }
+)
-var DeliveryType_value = map[string]int32{
- "UNKNOWN_DELIVERY_TYPE": 0,
- "INSTALL_TIME": 1,
- "ON_DEMAND": 2,
- "FAST_FOLLOW": 3,
+func (x DeliveryType) Enum() *DeliveryType {
+ p := new(DeliveryType)
+ *p = x
+ return p
}
func (x DeliveryType) String() string {
- return proto.EnumName(DeliveryType_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
+func (DeliveryType) Descriptor() protoreflect.EnumDescriptor {
+ return file_commands_proto_enumTypes[0].Descriptor()
+}
+
+func (DeliveryType) Type() protoreflect.EnumType {
+ return &file_commands_proto_enumTypes[0]
+}
+
+func (x DeliveryType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use DeliveryType.Descriptor instead.
func (DeliveryType) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{0}
+ return file_commands_proto_rawDescGZIP(), []int{0}
}
type SystemApkMetadata_SystemApkType int32
@@ -64,30 +90,55 @@
SystemApkMetadata_SYSTEM_COMPRESSED SystemApkMetadata_SystemApkType = 3
)
-var SystemApkMetadata_SystemApkType_name = map[int32]string{
- 0: "UNSPECIFIED_VALUE",
- 1: "SYSTEM",
- 2: "SYSTEM_STUB",
- 3: "SYSTEM_COMPRESSED",
-}
+// Enum value maps for SystemApkMetadata_SystemApkType.
+var (
+ SystemApkMetadata_SystemApkType_name = map[int32]string{
+ 0: "UNSPECIFIED_VALUE",
+ 1: "SYSTEM",
+ 2: "SYSTEM_STUB",
+ 3: "SYSTEM_COMPRESSED",
+ }
+ SystemApkMetadata_SystemApkType_value = map[string]int32{
+ "UNSPECIFIED_VALUE": 0,
+ "SYSTEM": 1,
+ "SYSTEM_STUB": 2,
+ "SYSTEM_COMPRESSED": 3,
+ }
+)
-var SystemApkMetadata_SystemApkType_value = map[string]int32{
- "UNSPECIFIED_VALUE": 0,
- "SYSTEM": 1,
- "SYSTEM_STUB": 2,
- "SYSTEM_COMPRESSED": 3,
+func (x SystemApkMetadata_SystemApkType) Enum() *SystemApkMetadata_SystemApkType {
+ p := new(SystemApkMetadata_SystemApkType)
+ *p = x
+ return p
}
func (x SystemApkMetadata_SystemApkType) String() string {
- return proto.EnumName(SystemApkMetadata_SystemApkType_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
+func (SystemApkMetadata_SystemApkType) Descriptor() protoreflect.EnumDescriptor {
+ return file_commands_proto_enumTypes[1].Descriptor()
+}
+
+func (SystemApkMetadata_SystemApkType) Type() protoreflect.EnumType {
+ return &file_commands_proto_enumTypes[1]
+}
+
+func (x SystemApkMetadata_SystemApkType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SystemApkMetadata_SystemApkType.Descriptor instead.
func (SystemApkMetadata_SystemApkType) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{10, 0}
+ return file_commands_proto_rawDescGZIP(), []int{10, 0}
}
// Describes the output of the "build-apks" command.
type BuildApksResult struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The package name of this app.
PackageName string `protobuf:"bytes,4,opt,name=package_name,json=packageName,proto3" json:"package_name,omitempty"`
// List of the created variants.
@@ -97,68 +148,72 @@
// List of the created asset slices.
AssetSliceSet []*AssetSliceSet `protobuf:"bytes,3,rep,name=asset_slice_set,json=assetSliceSet,proto3" json:"asset_slice_set,omitempty"`
// Information about local testing mode.
- LocalTestingInfo *LocalTestingInfo `protobuf:"bytes,5,opt,name=local_testing_info,json=localTestingInfo,proto3" json:"local_testing_info,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ LocalTestingInfo *LocalTestingInfo `protobuf:"bytes,5,opt,name=local_testing_info,json=localTestingInfo,proto3" json:"local_testing_info,omitempty"`
}
-func (m *BuildApksResult) Reset() { *m = BuildApksResult{} }
-func (m *BuildApksResult) String() string { return proto.CompactTextString(m) }
-func (*BuildApksResult) ProtoMessage() {}
+func (x *BuildApksResult) Reset() {
+ *x = BuildApksResult{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BuildApksResult) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BuildApksResult) ProtoMessage() {}
+
+func (x *BuildApksResult) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BuildApksResult.ProtoReflect.Descriptor instead.
func (*BuildApksResult) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{0}
+ return file_commands_proto_rawDescGZIP(), []int{0}
}
-func (m *BuildApksResult) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_BuildApksResult.Unmarshal(m, b)
-}
-func (m *BuildApksResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_BuildApksResult.Marshal(b, m, deterministic)
-}
-func (m *BuildApksResult) XXX_Merge(src proto.Message) {
- xxx_messageInfo_BuildApksResult.Merge(m, src)
-}
-func (m *BuildApksResult) XXX_Size() int {
- return xxx_messageInfo_BuildApksResult.Size(m)
-}
-func (m *BuildApksResult) XXX_DiscardUnknown() {
- xxx_messageInfo_BuildApksResult.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BuildApksResult proto.InternalMessageInfo
-
-func (m *BuildApksResult) GetPackageName() string {
- if m != nil {
- return m.PackageName
+func (x *BuildApksResult) GetPackageName() string {
+ if x != nil {
+ return x.PackageName
}
return ""
}
-func (m *BuildApksResult) GetVariant() []*Variant {
- if m != nil {
- return m.Variant
+func (x *BuildApksResult) GetVariant() []*Variant {
+ if x != nil {
+ return x.Variant
}
return nil
}
-func (m *BuildApksResult) GetBundletool() *Bundletool {
- if m != nil {
- return m.Bundletool
+func (x *BuildApksResult) GetBundletool() *Bundletool {
+ if x != nil {
+ return x.Bundletool
}
return nil
}
-func (m *BuildApksResult) GetAssetSliceSet() []*AssetSliceSet {
- if m != nil {
- return m.AssetSliceSet
+func (x *BuildApksResult) GetAssetSliceSet() []*AssetSliceSet {
+ if x != nil {
+ return x.AssetSliceSet
}
return nil
}
-func (m *BuildApksResult) GetLocalTestingInfo() *LocalTestingInfo {
- if m != nil {
- return m.LocalTestingInfo
+func (x *BuildApksResult) GetLocalTestingInfo() *LocalTestingInfo {
+ if x != nil {
+ return x.LocalTestingInfo
}
return nil
}
@@ -166,6 +221,10 @@
// Variant is a group of APKs that covers a part of the device configuration
// space. APKs from multiple variants are never combined on one device.
type Variant struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Variant-level targeting.
// This targeting is fairly high-level and each APK has its own targeting as
// well.
@@ -176,54 +235,58 @@
// A device will receive APKs from the first variant that matches the device
// configuration, with higher variant numbers having priority over lower
// variant numbers.
- VariantNumber uint32 `protobuf:"varint,3,opt,name=variant_number,json=variantNumber,proto3" json:"variant_number,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ VariantNumber uint32 `protobuf:"varint,3,opt,name=variant_number,json=variantNumber,proto3" json:"variant_number,omitempty"`
}
-func (m *Variant) Reset() { *m = Variant{} }
-func (m *Variant) String() string { return proto.CompactTextString(m) }
-func (*Variant) ProtoMessage() {}
+func (x *Variant) Reset() {
+ *x = Variant{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Variant) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Variant) ProtoMessage() {}
+
+func (x *Variant) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Variant.ProtoReflect.Descriptor instead.
func (*Variant) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{1}
+ return file_commands_proto_rawDescGZIP(), []int{1}
}
-func (m *Variant) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Variant.Unmarshal(m, b)
-}
-func (m *Variant) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Variant.Marshal(b, m, deterministic)
-}
-func (m *Variant) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Variant.Merge(m, src)
-}
-func (m *Variant) XXX_Size() int {
- return xxx_messageInfo_Variant.Size(m)
-}
-func (m *Variant) XXX_DiscardUnknown() {
- xxx_messageInfo_Variant.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Variant proto.InternalMessageInfo
-
-func (m *Variant) GetTargeting() *VariantTargeting {
- if m != nil {
- return m.Targeting
+func (x *Variant) GetTargeting() *VariantTargeting {
+ if x != nil {
+ return x.Targeting
}
return nil
}
-func (m *Variant) GetApkSet() []*ApkSet {
- if m != nil {
- return m.ApkSet
+func (x *Variant) GetApkSet() []*ApkSet {
+ if x != nil {
+ return x.ApkSet
}
return nil
}
-func (m *Variant) GetVariantNumber() uint32 {
- if m != nil {
- return m.VariantNumber
+func (x *Variant) GetVariantNumber() uint32 {
+ if x != nil {
+ return x.VariantNumber
}
return 0
}
@@ -231,54 +294,66 @@
// Represents a module.
// For pre-L devices multiple modules (possibly all) may be merged into one.
type ApkSet struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
ModuleMetadata *ModuleMetadata `protobuf:"bytes,1,opt,name=module_metadata,json=moduleMetadata,proto3" json:"module_metadata,omitempty"`
// APKs.
- ApkDescription []*ApkDescription `protobuf:"bytes,2,rep,name=apk_description,json=apkDescription,proto3" json:"apk_description,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ ApkDescription []*ApkDescription `protobuf:"bytes,2,rep,name=apk_description,json=apkDescription,proto3" json:"apk_description,omitempty"`
}
-func (m *ApkSet) Reset() { *m = ApkSet{} }
-func (m *ApkSet) String() string { return proto.CompactTextString(m) }
-func (*ApkSet) ProtoMessage() {}
+func (x *ApkSet) Reset() {
+ *x = ApkSet{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ApkSet) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApkSet) ProtoMessage() {}
+
+func (x *ApkSet) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApkSet.ProtoReflect.Descriptor instead.
func (*ApkSet) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{2}
+ return file_commands_proto_rawDescGZIP(), []int{2}
}
-func (m *ApkSet) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ApkSet.Unmarshal(m, b)
-}
-func (m *ApkSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ApkSet.Marshal(b, m, deterministic)
-}
-func (m *ApkSet) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ApkSet.Merge(m, src)
-}
-func (m *ApkSet) XXX_Size() int {
- return xxx_messageInfo_ApkSet.Size(m)
-}
-func (m *ApkSet) XXX_DiscardUnknown() {
- xxx_messageInfo_ApkSet.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ApkSet proto.InternalMessageInfo
-
-func (m *ApkSet) GetModuleMetadata() *ModuleMetadata {
- if m != nil {
- return m.ModuleMetadata
+func (x *ApkSet) GetModuleMetadata() *ModuleMetadata {
+ if x != nil {
+ return x.ModuleMetadata
}
return nil
}
-func (m *ApkSet) GetApkDescription() []*ApkDescription {
- if m != nil {
- return m.ApkDescription
+func (x *ApkSet) GetApkDescription() []*ApkDescription {
+ if x != nil {
+ return x.ApkDescription
}
return nil
}
type ModuleMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Module name.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Indicates the delivery type (e.g. on-demand) of the module.
@@ -292,131 +367,149 @@
// Relevant only for Split APKs.
Targeting *ModuleTargeting `protobuf:"bytes,5,opt,name=targeting,proto3" json:"targeting,omitempty"`
// Deprecated. Please use delivery_type.
- OnDemandDeprecated bool `protobuf:"varint,2,opt,name=on_demand_deprecated,json=onDemandDeprecated,proto3" json:"on_demand_deprecated,omitempty"` // Deprecated: Do not use.
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ //
+ // Deprecated: Do not use.
+ OnDemandDeprecated bool `protobuf:"varint,2,opt,name=on_demand_deprecated,json=onDemandDeprecated,proto3" json:"on_demand_deprecated,omitempty"`
}
-func (m *ModuleMetadata) Reset() { *m = ModuleMetadata{} }
-func (m *ModuleMetadata) String() string { return proto.CompactTextString(m) }
-func (*ModuleMetadata) ProtoMessage() {}
+func (x *ModuleMetadata) Reset() {
+ *x = ModuleMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ModuleMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ModuleMetadata) ProtoMessage() {}
+
+func (x *ModuleMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ModuleMetadata.ProtoReflect.Descriptor instead.
func (*ModuleMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{3}
+ return file_commands_proto_rawDescGZIP(), []int{3}
}
-func (m *ModuleMetadata) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ModuleMetadata.Unmarshal(m, b)
-}
-func (m *ModuleMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ModuleMetadata.Marshal(b, m, deterministic)
-}
-func (m *ModuleMetadata) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ModuleMetadata.Merge(m, src)
-}
-func (m *ModuleMetadata) XXX_Size() int {
- return xxx_messageInfo_ModuleMetadata.Size(m)
-}
-func (m *ModuleMetadata) XXX_DiscardUnknown() {
- xxx_messageInfo_ModuleMetadata.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ModuleMetadata proto.InternalMessageInfo
-
-func (m *ModuleMetadata) GetName() string {
- if m != nil {
- return m.Name
+func (x *ModuleMetadata) GetName() string {
+ if x != nil {
+ return x.Name
}
return ""
}
-func (m *ModuleMetadata) GetDeliveryType() DeliveryType {
- if m != nil {
- return m.DeliveryType
+func (x *ModuleMetadata) GetDeliveryType() DeliveryType {
+ if x != nil {
+ return x.DeliveryType
}
return DeliveryType_UNKNOWN_DELIVERY_TYPE
}
-func (m *ModuleMetadata) GetIsInstant() bool {
- if m != nil {
- return m.IsInstant
+func (x *ModuleMetadata) GetIsInstant() bool {
+ if x != nil {
+ return x.IsInstant
}
return false
}
-func (m *ModuleMetadata) GetDependencies() []string {
- if m != nil {
- return m.Dependencies
+func (x *ModuleMetadata) GetDependencies() []string {
+ if x != nil {
+ return x.Dependencies
}
return nil
}
-func (m *ModuleMetadata) GetTargeting() *ModuleTargeting {
- if m != nil {
- return m.Targeting
+func (x *ModuleMetadata) GetTargeting() *ModuleTargeting {
+ if x != nil {
+ return x.Targeting
}
return nil
}
// Deprecated: Do not use.
-func (m *ModuleMetadata) GetOnDemandDeprecated() bool {
- if m != nil {
- return m.OnDemandDeprecated
+func (x *ModuleMetadata) GetOnDemandDeprecated() bool {
+ if x != nil {
+ return x.OnDemandDeprecated
}
return false
}
// Set of asset slices belonging to a single asset module.
type AssetSliceSet struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Module level metadata.
AssetModuleMetadata *AssetModuleMetadata `protobuf:"bytes,1,opt,name=asset_module_metadata,json=assetModuleMetadata,proto3" json:"asset_module_metadata,omitempty"`
// Asset slices.
- ApkDescription []*ApkDescription `protobuf:"bytes,2,rep,name=apk_description,json=apkDescription,proto3" json:"apk_description,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ ApkDescription []*ApkDescription `protobuf:"bytes,2,rep,name=apk_description,json=apkDescription,proto3" json:"apk_description,omitempty"`
}
-func (m *AssetSliceSet) Reset() { *m = AssetSliceSet{} }
-func (m *AssetSliceSet) String() string { return proto.CompactTextString(m) }
-func (*AssetSliceSet) ProtoMessage() {}
+func (x *AssetSliceSet) Reset() {
+ *x = AssetSliceSet{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AssetSliceSet) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AssetSliceSet) ProtoMessage() {}
+
+func (x *AssetSliceSet) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AssetSliceSet.ProtoReflect.Descriptor instead.
func (*AssetSliceSet) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{4}
+ return file_commands_proto_rawDescGZIP(), []int{4}
}
-func (m *AssetSliceSet) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_AssetSliceSet.Unmarshal(m, b)
-}
-func (m *AssetSliceSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_AssetSliceSet.Marshal(b, m, deterministic)
-}
-func (m *AssetSliceSet) XXX_Merge(src proto.Message) {
- xxx_messageInfo_AssetSliceSet.Merge(m, src)
-}
-func (m *AssetSliceSet) XXX_Size() int {
- return xxx_messageInfo_AssetSliceSet.Size(m)
-}
-func (m *AssetSliceSet) XXX_DiscardUnknown() {
- xxx_messageInfo_AssetSliceSet.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AssetSliceSet proto.InternalMessageInfo
-
-func (m *AssetSliceSet) GetAssetModuleMetadata() *AssetModuleMetadata {
- if m != nil {
- return m.AssetModuleMetadata
+func (x *AssetSliceSet) GetAssetModuleMetadata() *AssetModuleMetadata {
+ if x != nil {
+ return x.AssetModuleMetadata
}
return nil
}
-func (m *AssetSliceSet) GetApkDescription() []*ApkDescription {
- if m != nil {
- return m.ApkDescription
+func (x *AssetSliceSet) GetApkDescription() []*ApkDescription {
+ if x != nil {
+ return x.ApkDescription
}
return nil
}
type AssetModuleMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Module name.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Indicates the delivery type for persistent install.
@@ -424,133 +517,153 @@
// Metadata for instant installs.
InstantMetadata *InstantMetadata `protobuf:"bytes,3,opt,name=instant_metadata,json=instantMetadata,proto3" json:"instant_metadata,omitempty"`
// Deprecated. Use delivery_type.
- OnDemandDeprecated bool `protobuf:"varint,2,opt,name=on_demand_deprecated,json=onDemandDeprecated,proto3" json:"on_demand_deprecated,omitempty"` // Deprecated: Do not use.
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ //
+ // Deprecated: Do not use.
+ OnDemandDeprecated bool `protobuf:"varint,2,opt,name=on_demand_deprecated,json=onDemandDeprecated,proto3" json:"on_demand_deprecated,omitempty"`
}
-func (m *AssetModuleMetadata) Reset() { *m = AssetModuleMetadata{} }
-func (m *AssetModuleMetadata) String() string { return proto.CompactTextString(m) }
-func (*AssetModuleMetadata) ProtoMessage() {}
+func (x *AssetModuleMetadata) Reset() {
+ *x = AssetModuleMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AssetModuleMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AssetModuleMetadata) ProtoMessage() {}
+
+func (x *AssetModuleMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AssetModuleMetadata.ProtoReflect.Descriptor instead.
func (*AssetModuleMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{5}
+ return file_commands_proto_rawDescGZIP(), []int{5}
}
-func (m *AssetModuleMetadata) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_AssetModuleMetadata.Unmarshal(m, b)
-}
-func (m *AssetModuleMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_AssetModuleMetadata.Marshal(b, m, deterministic)
-}
-func (m *AssetModuleMetadata) XXX_Merge(src proto.Message) {
- xxx_messageInfo_AssetModuleMetadata.Merge(m, src)
-}
-func (m *AssetModuleMetadata) XXX_Size() int {
- return xxx_messageInfo_AssetModuleMetadata.Size(m)
-}
-func (m *AssetModuleMetadata) XXX_DiscardUnknown() {
- xxx_messageInfo_AssetModuleMetadata.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AssetModuleMetadata proto.InternalMessageInfo
-
-func (m *AssetModuleMetadata) GetName() string {
- if m != nil {
- return m.Name
+func (x *AssetModuleMetadata) GetName() string {
+ if x != nil {
+ return x.Name
}
return ""
}
-func (m *AssetModuleMetadata) GetDeliveryType() DeliveryType {
- if m != nil {
- return m.DeliveryType
+func (x *AssetModuleMetadata) GetDeliveryType() DeliveryType {
+ if x != nil {
+ return x.DeliveryType
}
return DeliveryType_UNKNOWN_DELIVERY_TYPE
}
-func (m *AssetModuleMetadata) GetInstantMetadata() *InstantMetadata {
- if m != nil {
- return m.InstantMetadata
+func (x *AssetModuleMetadata) GetInstantMetadata() *InstantMetadata {
+ if x != nil {
+ return x.InstantMetadata
}
return nil
}
// Deprecated: Do not use.
-func (m *AssetModuleMetadata) GetOnDemandDeprecated() bool {
- if m != nil {
- return m.OnDemandDeprecated
+func (x *AssetModuleMetadata) GetOnDemandDeprecated() bool {
+ if x != nil {
+ return x.OnDemandDeprecated
}
return false
}
type InstantMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Indicates whether this module is marked "instant".
IsInstant bool `protobuf:"varint,1,opt,name=is_instant,json=isInstant,proto3" json:"is_instant,omitempty"`
// Indicates the delivery type for instant install.
DeliveryType DeliveryType `protobuf:"varint,3,opt,name=delivery_type,json=deliveryType,proto3,enum=android.bundle.DeliveryType" json:"delivery_type,omitempty"`
// Deprecated. Use delivery_type.
- OnDemandDeprecated bool `protobuf:"varint,2,opt,name=on_demand_deprecated,json=onDemandDeprecated,proto3" json:"on_demand_deprecated,omitempty"` // Deprecated: Do not use.
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ //
+ // Deprecated: Do not use.
+ OnDemandDeprecated bool `protobuf:"varint,2,opt,name=on_demand_deprecated,json=onDemandDeprecated,proto3" json:"on_demand_deprecated,omitempty"`
}
-func (m *InstantMetadata) Reset() { *m = InstantMetadata{} }
-func (m *InstantMetadata) String() string { return proto.CompactTextString(m) }
-func (*InstantMetadata) ProtoMessage() {}
+func (x *InstantMetadata) Reset() {
+ *x = InstantMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *InstantMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InstantMetadata) ProtoMessage() {}
+
+func (x *InstantMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use InstantMetadata.ProtoReflect.Descriptor instead.
func (*InstantMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{6}
+ return file_commands_proto_rawDescGZIP(), []int{6}
}
-func (m *InstantMetadata) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_InstantMetadata.Unmarshal(m, b)
-}
-func (m *InstantMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_InstantMetadata.Marshal(b, m, deterministic)
-}
-func (m *InstantMetadata) XXX_Merge(src proto.Message) {
- xxx_messageInfo_InstantMetadata.Merge(m, src)
-}
-func (m *InstantMetadata) XXX_Size() int {
- return xxx_messageInfo_InstantMetadata.Size(m)
-}
-func (m *InstantMetadata) XXX_DiscardUnknown() {
- xxx_messageInfo_InstantMetadata.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_InstantMetadata proto.InternalMessageInfo
-
-func (m *InstantMetadata) GetIsInstant() bool {
- if m != nil {
- return m.IsInstant
+func (x *InstantMetadata) GetIsInstant() bool {
+ if x != nil {
+ return x.IsInstant
}
return false
}
-func (m *InstantMetadata) GetDeliveryType() DeliveryType {
- if m != nil {
- return m.DeliveryType
+func (x *InstantMetadata) GetDeliveryType() DeliveryType {
+ if x != nil {
+ return x.DeliveryType
}
return DeliveryType_UNKNOWN_DELIVERY_TYPE
}
// Deprecated: Do not use.
-func (m *InstantMetadata) GetOnDemandDeprecated() bool {
- if m != nil {
- return m.OnDemandDeprecated
+func (x *InstantMetadata) GetOnDemandDeprecated() bool {
+ if x != nil {
+ return x.OnDemandDeprecated
}
return false
}
type ApkDescription struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Targeting *ApkTargeting `protobuf:"bytes,1,opt,name=targeting,proto3" json:"targeting,omitempty"`
// Path to the APK file.
// BEGIN-INTERNAL
// The path may be a blobkey if the proto is not constructed by bundletool.
// END-INTERNAL
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
- // Types that are valid to be assigned to ApkMetadataOneofValue:
+ // Types that are assignable to ApkMetadataOneofValue:
// *ApkDescription_SplitApkMetadata
// *ApkDescription_StandaloneApkMetadata
// *ApkDescription_InstantApkMetadata
@@ -558,75 +671,134 @@
// *ApkDescription_AssetSliceMetadata
// *ApkDescription_ApexApkMetadata
ApkMetadataOneofValue isApkDescription_ApkMetadataOneofValue `protobuf_oneof:"apk_metadata_oneof_value"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *ApkDescription) Reset() { *m = ApkDescription{} }
-func (m *ApkDescription) String() string { return proto.CompactTextString(m) }
-func (*ApkDescription) ProtoMessage() {}
+func (x *ApkDescription) Reset() {
+ *x = ApkDescription{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ApkDescription) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApkDescription) ProtoMessage() {}
+
+func (x *ApkDescription) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApkDescription.ProtoReflect.Descriptor instead.
func (*ApkDescription) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{7}
+ return file_commands_proto_rawDescGZIP(), []int{7}
}
-func (m *ApkDescription) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ApkDescription.Unmarshal(m, b)
-}
-func (m *ApkDescription) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ApkDescription.Marshal(b, m, deterministic)
-}
-func (m *ApkDescription) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ApkDescription.Merge(m, src)
-}
-func (m *ApkDescription) XXX_Size() int {
- return xxx_messageInfo_ApkDescription.Size(m)
-}
-func (m *ApkDescription) XXX_DiscardUnknown() {
- xxx_messageInfo_ApkDescription.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ApkDescription proto.InternalMessageInfo
-
-func (m *ApkDescription) GetTargeting() *ApkTargeting {
- if m != nil {
- return m.Targeting
+func (x *ApkDescription) GetTargeting() *ApkTargeting {
+ if x != nil {
+ return x.Targeting
}
return nil
}
-func (m *ApkDescription) GetPath() string {
- if m != nil {
- return m.Path
+func (x *ApkDescription) GetPath() string {
+ if x != nil {
+ return x.Path
}
return ""
}
+func (m *ApkDescription) GetApkMetadataOneofValue() isApkDescription_ApkMetadataOneofValue {
+ if m != nil {
+ return m.ApkMetadataOneofValue
+ }
+ return nil
+}
+
+func (x *ApkDescription) GetSplitApkMetadata() *SplitApkMetadata {
+ if x, ok := x.GetApkMetadataOneofValue().(*ApkDescription_SplitApkMetadata); ok {
+ return x.SplitApkMetadata
+ }
+ return nil
+}
+
+func (x *ApkDescription) GetStandaloneApkMetadata() *StandaloneApkMetadata {
+ if x, ok := x.GetApkMetadataOneofValue().(*ApkDescription_StandaloneApkMetadata); ok {
+ return x.StandaloneApkMetadata
+ }
+ return nil
+}
+
+func (x *ApkDescription) GetInstantApkMetadata() *SplitApkMetadata {
+ if x, ok := x.GetApkMetadataOneofValue().(*ApkDescription_InstantApkMetadata); ok {
+ return x.InstantApkMetadata
+ }
+ return nil
+}
+
+func (x *ApkDescription) GetSystemApkMetadata() *SystemApkMetadata {
+ if x, ok := x.GetApkMetadataOneofValue().(*ApkDescription_SystemApkMetadata); ok {
+ return x.SystemApkMetadata
+ }
+ return nil
+}
+
+func (x *ApkDescription) GetAssetSliceMetadata() *SplitApkMetadata {
+ if x, ok := x.GetApkMetadataOneofValue().(*ApkDescription_AssetSliceMetadata); ok {
+ return x.AssetSliceMetadata
+ }
+ return nil
+}
+
+func (x *ApkDescription) GetApexApkMetadata() *ApexApkMetadata {
+ if x, ok := x.GetApkMetadataOneofValue().(*ApkDescription_ApexApkMetadata); ok {
+ return x.ApexApkMetadata
+ }
+ return nil
+}
+
type isApkDescription_ApkMetadataOneofValue interface {
isApkDescription_ApkMetadataOneofValue()
}
type ApkDescription_SplitApkMetadata struct {
+ // Set only for Split APKs.
SplitApkMetadata *SplitApkMetadata `protobuf:"bytes,3,opt,name=split_apk_metadata,json=splitApkMetadata,proto3,oneof"`
}
type ApkDescription_StandaloneApkMetadata struct {
+ // Set only for standalone APKs.
StandaloneApkMetadata *StandaloneApkMetadata `protobuf:"bytes,4,opt,name=standalone_apk_metadata,json=standaloneApkMetadata,proto3,oneof"`
}
type ApkDescription_InstantApkMetadata struct {
+ // Set only for Instant split APKs.
InstantApkMetadata *SplitApkMetadata `protobuf:"bytes,5,opt,name=instant_apk_metadata,json=instantApkMetadata,proto3,oneof"`
}
type ApkDescription_SystemApkMetadata struct {
+ // Set only for system APKs.
SystemApkMetadata *SystemApkMetadata `protobuf:"bytes,6,opt,name=system_apk_metadata,json=systemApkMetadata,proto3,oneof"`
}
type ApkDescription_AssetSliceMetadata struct {
+ // Set only for asset slices.
AssetSliceMetadata *SplitApkMetadata `protobuf:"bytes,7,opt,name=asset_slice_metadata,json=assetSliceMetadata,proto3,oneof"`
}
type ApkDescription_ApexApkMetadata struct {
+ // Set only for APEX APKs.
ApexApkMetadata *ApexApkMetadata `protobuf:"bytes,8,opt,name=apex_apk_metadata,json=apexApkMetadata,proto3,oneof"`
}
@@ -642,58 +814,708 @@
func (*ApkDescription_ApexApkMetadata) isApkDescription_ApkMetadataOneofValue() {}
-func (m *ApkDescription) GetApkMetadataOneofValue() isApkDescription_ApkMetadataOneofValue {
- if m != nil {
- return m.ApkMetadataOneofValue
+// Holds data specific to Split APKs.
+type SplitApkMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ SplitId string `protobuf:"bytes,1,opt,name=split_id,json=splitId,proto3" json:"split_id,omitempty"`
+ // Indicates whether this APK is the master split of the module.
+ IsMasterSplit bool `protobuf:"varint,2,opt,name=is_master_split,json=isMasterSplit,proto3" json:"is_master_split,omitempty"`
+}
+
+func (x *SplitApkMetadata) Reset() {
+ *x = SplitApkMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SplitApkMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SplitApkMetadata) ProtoMessage() {}
+
+func (x *SplitApkMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[8]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SplitApkMetadata.ProtoReflect.Descriptor instead.
+func (*SplitApkMetadata) Descriptor() ([]byte, []int) {
+ return file_commands_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *SplitApkMetadata) GetSplitId() string {
+ if x != nil {
+ return x.SplitId
+ }
+ return ""
+}
+
+func (x *SplitApkMetadata) GetIsMasterSplit() bool {
+ if x != nil {
+ return x.IsMasterSplit
+ }
+ return false
+}
+
+// Holds data specific to Standalone APKs.
+type StandaloneApkMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Names of the modules fused in this standalone APK.
+ FusedModuleName []string `protobuf:"bytes,1,rep,name=fused_module_name,json=fusedModuleName,proto3" json:"fused_module_name,omitempty"`
+}
+
+func (x *StandaloneApkMetadata) Reset() {
+ *x = StandaloneApkMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *StandaloneApkMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StandaloneApkMetadata) ProtoMessage() {}
+
+func (x *StandaloneApkMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[9]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use StandaloneApkMetadata.ProtoReflect.Descriptor instead.
+func (*StandaloneApkMetadata) Descriptor() ([]byte, []int) {
+ return file_commands_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *StandaloneApkMetadata) GetFusedModuleName() []string {
+ if x != nil {
+ return x.FusedModuleName
}
return nil
}
-func (m *ApkDescription) GetSplitApkMetadata() *SplitApkMetadata {
- if x, ok := m.GetApkMetadataOneofValue().(*ApkDescription_SplitApkMetadata); ok {
- return x.SplitApkMetadata
+// Holds data specific to system APKs.
+type SystemApkMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Names of the modules fused in this system APK.
+ FusedModuleName []string `protobuf:"bytes,1,rep,name=fused_module_name,json=fusedModuleName,proto3" json:"fused_module_name,omitempty"`
+ // Indicates whether the APK is uncompressed system APK, stub APK or
+ // compressed system APK.
+ SystemApkType SystemApkMetadata_SystemApkType `protobuf:"varint,2,opt,name=system_apk_type,json=systemApkType,proto3,enum=android.bundle.SystemApkMetadata_SystemApkType" json:"system_apk_type,omitempty"`
+}
+
+func (x *SystemApkMetadata) Reset() {
+ *x = SystemApkMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[10]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SystemApkMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SystemApkMetadata) ProtoMessage() {}
+
+func (x *SystemApkMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[10]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SystemApkMetadata.ProtoReflect.Descriptor instead.
+func (*SystemApkMetadata) Descriptor() ([]byte, []int) {
+ return file_commands_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *SystemApkMetadata) GetFusedModuleName() []string {
+ if x != nil {
+ return x.FusedModuleName
}
return nil
}
-func (m *ApkDescription) GetStandaloneApkMetadata() *StandaloneApkMetadata {
- if x, ok := m.GetApkMetadataOneofValue().(*ApkDescription_StandaloneApkMetadata); ok {
- return x.StandaloneApkMetadata
+func (x *SystemApkMetadata) GetSystemApkType() SystemApkMetadata_SystemApkType {
+ if x != nil {
+ return x.SystemApkType
+ }
+ return SystemApkMetadata_UNSPECIFIED_VALUE
+}
+
+// Holds data specific to APEX APKs.
+type ApexApkMetadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Configuration for processing of APKs embedded in an APEX image.
+ ApexEmbeddedApkConfig []*ApexEmbeddedApkConfig `protobuf:"bytes,1,rep,name=apex_embedded_apk_config,json=apexEmbeddedApkConfig,proto3" json:"apex_embedded_apk_config,omitempty"`
+}
+
+func (x *ApexApkMetadata) Reset() {
+ *x = ApexApkMetadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[11]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ApexApkMetadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApexApkMetadata) ProtoMessage() {}
+
+func (x *ApexApkMetadata) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[11]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApexApkMetadata.ProtoReflect.Descriptor instead.
+func (*ApexApkMetadata) Descriptor() ([]byte, []int) {
+ return file_commands_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *ApexApkMetadata) GetApexEmbeddedApkConfig() []*ApexEmbeddedApkConfig {
+ if x != nil {
+ return x.ApexEmbeddedApkConfig
}
return nil
}
-func (m *ApkDescription) GetInstantApkMetadata() *SplitApkMetadata {
- if x, ok := m.GetApkMetadataOneofValue().(*ApkDescription_InstantApkMetadata); ok {
- return x.InstantApkMetadata
- }
- return nil
+type LocalTestingInfo struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Indicates if the bundle is built in local testing mode.
+ Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
+ // The local testing path, as specified in the base manifest.
+ // This refers to the relative path on the external directory of the app where
+ // APKs will be pushed for local testing.
+ // Set only if local testing is enabled.
+ LocalTestingPath string `protobuf:"bytes,2,opt,name=local_testing_path,json=localTestingPath,proto3" json:"local_testing_path,omitempty"`
}
-func (m *ApkDescription) GetSystemApkMetadata() *SystemApkMetadata {
- if x, ok := m.GetApkMetadataOneofValue().(*ApkDescription_SystemApkMetadata); ok {
- return x.SystemApkMetadata
+func (x *LocalTestingInfo) Reset() {
+ *x = LocalTestingInfo{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_commands_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
}
- return nil
}
-func (m *ApkDescription) GetAssetSliceMetadata() *SplitApkMetadata {
- if x, ok := m.GetApkMetadataOneofValue().(*ApkDescription_AssetSliceMetadata); ok {
- return x.AssetSliceMetadata
- }
- return nil
+func (x *LocalTestingInfo) String() string {
+ return protoimpl.X.MessageStringOf(x)
}
-func (m *ApkDescription) GetApexApkMetadata() *ApexApkMetadata {
- if x, ok := m.GetApkMetadataOneofValue().(*ApkDescription_ApexApkMetadata); ok {
- return x.ApexApkMetadata
+func (*LocalTestingInfo) ProtoMessage() {}
+
+func (x *LocalTestingInfo) ProtoReflect() protoreflect.Message {
+ mi := &file_commands_proto_msgTypes[12]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
}
- return nil
+ return mi.MessageOf(x)
}
-// XXX_OneofWrappers is for the internal use of the proto package.
-func (*ApkDescription) XXX_OneofWrappers() []interface{} {
- return []interface{}{
+// Deprecated: Use LocalTestingInfo.ProtoReflect.Descriptor instead.
+func (*LocalTestingInfo) Descriptor() ([]byte, []int) {
+ return file_commands_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *LocalTestingInfo) GetEnabled() bool {
+ if x != nil {
+ return x.Enabled
+ }
+ return false
+}
+
+func (x *LocalTestingInfo) GetLocalTestingPath() string {
+ if x != nil {
+ return x.LocalTestingPath
+ }
+ return ""
+}
+
+var File_commands_proto protoreflect.FileDescriptor
+
+var file_commands_proto_rawDesc = []byte{
+ 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x12, 0x0e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x1a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f,
+ 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
+ 0xba, 0x02, 0x0a, 0x0f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x41, 0x70, 0x6b, 0x73, 0x52, 0x65, 0x73,
+ 0x75, 0x6c, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x63, 0x6b, 0x61,
+ 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e,
+ 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74,
+ 0x52, 0x07, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x62, 0x75, 0x6e,
+ 0x64, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x42,
+ 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x52, 0x0a, 0x62, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x45, 0x0a, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73,
+ 0x6c, 0x69, 0x63, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d,
+ 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e,
+ 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x53, 0x65, 0x74, 0x52, 0x0d, 0x61,
+ 0x73, 0x73, 0x65, 0x74, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x53, 0x65, 0x74, 0x12, 0x4e, 0x0a, 0x12,
+ 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e,
+ 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x54,
+ 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x10, 0x6c, 0x6f, 0x63, 0x61,
+ 0x6c, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xa1, 0x01, 0x0a,
+ 0x07, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x3e, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x56, 0x61, 0x72,
+ 0x69, 0x61, 0x6e, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x74,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x07, 0x61, 0x70, 0x6b, 0x5f,
+ 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x70, 0x6b, 0x53, 0x65,
+ 0x74, 0x52, 0x06, 0x61, 0x70, 0x6b, 0x53, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x76, 0x61, 0x72,
+ 0x69, 0x61, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0d, 0x52, 0x0d, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
+ 0x22, 0x9a, 0x01, 0x0a, 0x06, 0x41, 0x70, 0x6b, 0x53, 0x65, 0x74, 0x12, 0x47, 0x0a, 0x0f, 0x6d,
+ 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62,
+ 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x52, 0x0e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x12, 0x47, 0x0a, 0x0f, 0x61, 0x70, 0x6b, 0x5f, 0x64, 0x65, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41,
+ 0x70, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x61,
+ 0x70, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x9f, 0x02,
+ 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+ 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79,
+ 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x6c,
+ 0x69, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x64, 0x65, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x69, 0x6e,
+ 0x73, 0x74, 0x61, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x49,
+ 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64,
+ 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65,
+ 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x09, 0x74, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4d,
+ 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x09,
+ 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x14, 0x6f, 0x6e, 0x5f,
+ 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65,
+ 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x12, 0x6f, 0x6e, 0x44,
+ 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x22,
+ 0xb1, 0x01, 0x0a, 0x0d, 0x41, 0x73, 0x73, 0x65, 0x74, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x53, 0x65,
+ 0x74, 0x12, 0x57, 0x0a, 0x15, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c,
+ 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4d, 0x65, 0x74,
+ 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x13, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75,
+ 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x47, 0x0a, 0x0f, 0x61, 0x70,
+ 0x6b, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75,
+ 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x70, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x61, 0x70, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x22, 0xee, 0x01, 0x0a, 0x13, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64,
+ 0x75, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+ 0x41, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79,
+ 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79,
+ 0x70, 0x65, 0x12, 0x4a, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x5f, 0x6d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x49, 0x6e,
+ 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0f, 0x69,
+ 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x34,
+ 0x0a, 0x14, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x70, 0x72,
+ 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01,
+ 0x52, 0x12, 0x6f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63,
+ 0x61, 0x74, 0x65, 0x64, 0x22, 0xa9, 0x01, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74,
+ 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x69,
+ 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73,
+ 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x69, 0x76,
+ 0x65, 0x72, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c,
+ 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e,
+ 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x64, 0x65,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x14, 0x6f, 0x6e,
+ 0x5f, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74,
+ 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x12, 0x6f, 0x6e,
+ 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64,
+ 0x22, 0xff, 0x04, 0x0a, 0x0e, 0x41, 0x70, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x70, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12,
+ 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70,
+ 0x61, 0x74, 0x68, 0x12, 0x50, 0x0a, 0x12, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x61, 0x70, 0x6b,
+ 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x20, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x2e, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x48, 0x00, 0x52, 0x10, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74,
+ 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x5f, 0x0a, 0x17, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x6c,
+ 0x6f, 0x6e, 0x65, 0x5f, 0x61, 0x70, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6f,
+ 0x6e, 0x65, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52,
+ 0x15, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x41, 0x70, 0x6b, 0x4d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x14, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+ 0x74, 0x5f, 0x61, 0x70, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62,
+ 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x41, 0x70, 0x6b, 0x4d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x12, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+ 0x74, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x53, 0x0a, 0x13,
+ 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x61, 0x70, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65,
+ 0x6d, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x11,
+ 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x12, 0x54, 0x0a, 0x14, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x73, 0x6c, 0x69, 0x63, 0x65,
+ 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x20, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x2e, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+ 0x61, 0x48, 0x00, 0x52, 0x12, 0x61, 0x73, 0x73, 0x65, 0x74, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x4d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4d, 0x0a, 0x11, 0x61, 0x70, 0x65, 0x78, 0x5f,
+ 0x61, 0x70, 0x6b, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e,
+ 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x70, 0x65, 0x78, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x70, 0x65, 0x78, 0x41, 0x70, 0x6b, 0x4d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x1a, 0x0a, 0x18, 0x61, 0x70, 0x6b, 0x5f, 0x6d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x22, 0x55, 0x0a, 0x10, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x41, 0x70, 0x6b, 0x4d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f,
+ 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x49,
+ 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x73, 0x5f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73,
+ 0x70, 0x6c, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x73, 0x4d, 0x61,
+ 0x73, 0x74, 0x65, 0x72, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x22, 0x49, 0x0a, 0x15, 0x53, 0x74, 0x61,
+ 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
+ 0x74, 0x61, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75,
+ 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x66,
+ 0x75, 0x73, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x4a, 0x04,
+ 0x08, 0x02, 0x10, 0x03, 0x22, 0xf4, 0x01, 0x0a, 0x11, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x41,
+ 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x75,
+ 0x73, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75,
+ 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x57, 0x0a, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
+ 0x5f, 0x61, 0x70, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x2f, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
+ 0x74, 0x61, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x41, 0x70, 0x6b, 0x54, 0x79, 0x70, 0x65,
+ 0x52, 0x0d, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x41, 0x70, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x22,
+ 0x5a, 0x0a, 0x0d, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x41, 0x70, 0x6b, 0x54, 0x79, 0x70, 0x65,
+ 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f,
+ 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x59, 0x53, 0x54, 0x45,
+ 0x4d, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x53, 0x54,
+ 0x55, 0x42, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x43,
+ 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x45, 0x44, 0x10, 0x03, 0x22, 0x71, 0x0a, 0x0f, 0x41,
+ 0x70, 0x65, 0x78, 0x41, 0x70, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x5e,
+ 0x0a, 0x18, 0x61, 0x70, 0x65, 0x78, 0x5f, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f,
+ 0x61, 0x70, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x25, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x2e, 0x41, 0x70, 0x65, 0x78, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x41, 0x70,
+ 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x15, 0x61, 0x70, 0x65, 0x78, 0x45, 0x6d, 0x62,
+ 0x65, 0x64, 0x64, 0x65, 0x64, 0x41, 0x70, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x5a,
+ 0x0a, 0x10, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e,
+ 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x12,
+ 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x61,
+ 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x54,
+ 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x74, 0x68, 0x2a, 0x5b, 0x0a, 0x0c, 0x44, 0x65,
+ 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x4e,
+ 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x54,
+ 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c,
+ 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4f, 0x4e, 0x5f, 0x44, 0x45,
+ 0x4d, 0x41, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x41, 0x53, 0x54, 0x5f, 0x46,
+ 0x4f, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x03, 0x42, 0x41, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5a, 0x2b, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d, 0x64,
+ 0x2f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x61, 0x70, 0x6b, 0x73, 0x2f, 0x62, 0x75,
+ 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x33,
+}
+
+var (
+ file_commands_proto_rawDescOnce sync.Once
+ file_commands_proto_rawDescData = file_commands_proto_rawDesc
+)
+
+func file_commands_proto_rawDescGZIP() []byte {
+ file_commands_proto_rawDescOnce.Do(func() {
+ file_commands_proto_rawDescData = protoimpl.X.CompressGZIP(file_commands_proto_rawDescData)
+ })
+ return file_commands_proto_rawDescData
+}
+
+var file_commands_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_commands_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
+var file_commands_proto_goTypes = []interface{}{
+ (DeliveryType)(0), // 0: android.bundle.DeliveryType
+ (SystemApkMetadata_SystemApkType)(0), // 1: android.bundle.SystemApkMetadata.SystemApkType
+ (*BuildApksResult)(nil), // 2: android.bundle.BuildApksResult
+ (*Variant)(nil), // 3: android.bundle.Variant
+ (*ApkSet)(nil), // 4: android.bundle.ApkSet
+ (*ModuleMetadata)(nil), // 5: android.bundle.ModuleMetadata
+ (*AssetSliceSet)(nil), // 6: android.bundle.AssetSliceSet
+ (*AssetModuleMetadata)(nil), // 7: android.bundle.AssetModuleMetadata
+ (*InstantMetadata)(nil), // 8: android.bundle.InstantMetadata
+ (*ApkDescription)(nil), // 9: android.bundle.ApkDescription
+ (*SplitApkMetadata)(nil), // 10: android.bundle.SplitApkMetadata
+ (*StandaloneApkMetadata)(nil), // 11: android.bundle.StandaloneApkMetadata
+ (*SystemApkMetadata)(nil), // 12: android.bundle.SystemApkMetadata
+ (*ApexApkMetadata)(nil), // 13: android.bundle.ApexApkMetadata
+ (*LocalTestingInfo)(nil), // 14: android.bundle.LocalTestingInfo
+ (*Bundletool)(nil), // 15: android.bundle.Bundletool
+ (*VariantTargeting)(nil), // 16: android.bundle.VariantTargeting
+ (*ModuleTargeting)(nil), // 17: android.bundle.ModuleTargeting
+ (*ApkTargeting)(nil), // 18: android.bundle.ApkTargeting
+ (*ApexEmbeddedApkConfig)(nil), // 19: android.bundle.ApexEmbeddedApkConfig
+}
+var file_commands_proto_depIdxs = []int32{
+ 3, // 0: android.bundle.BuildApksResult.variant:type_name -> android.bundle.Variant
+ 15, // 1: android.bundle.BuildApksResult.bundletool:type_name -> android.bundle.Bundletool
+ 6, // 2: android.bundle.BuildApksResult.asset_slice_set:type_name -> android.bundle.AssetSliceSet
+ 14, // 3: android.bundle.BuildApksResult.local_testing_info:type_name -> android.bundle.LocalTestingInfo
+ 16, // 4: android.bundle.Variant.targeting:type_name -> android.bundle.VariantTargeting
+ 4, // 5: android.bundle.Variant.apk_set:type_name -> android.bundle.ApkSet
+ 5, // 6: android.bundle.ApkSet.module_metadata:type_name -> android.bundle.ModuleMetadata
+ 9, // 7: android.bundle.ApkSet.apk_description:type_name -> android.bundle.ApkDescription
+ 0, // 8: android.bundle.ModuleMetadata.delivery_type:type_name -> android.bundle.DeliveryType
+ 17, // 9: android.bundle.ModuleMetadata.targeting:type_name -> android.bundle.ModuleTargeting
+ 7, // 10: android.bundle.AssetSliceSet.asset_module_metadata:type_name -> android.bundle.AssetModuleMetadata
+ 9, // 11: android.bundle.AssetSliceSet.apk_description:type_name -> android.bundle.ApkDescription
+ 0, // 12: android.bundle.AssetModuleMetadata.delivery_type:type_name -> android.bundle.DeliveryType
+ 8, // 13: android.bundle.AssetModuleMetadata.instant_metadata:type_name -> android.bundle.InstantMetadata
+ 0, // 14: android.bundle.InstantMetadata.delivery_type:type_name -> android.bundle.DeliveryType
+ 18, // 15: android.bundle.ApkDescription.targeting:type_name -> android.bundle.ApkTargeting
+ 10, // 16: android.bundle.ApkDescription.split_apk_metadata:type_name -> android.bundle.SplitApkMetadata
+ 11, // 17: android.bundle.ApkDescription.standalone_apk_metadata:type_name -> android.bundle.StandaloneApkMetadata
+ 10, // 18: android.bundle.ApkDescription.instant_apk_metadata:type_name -> android.bundle.SplitApkMetadata
+ 12, // 19: android.bundle.ApkDescription.system_apk_metadata:type_name -> android.bundle.SystemApkMetadata
+ 10, // 20: android.bundle.ApkDescription.asset_slice_metadata:type_name -> android.bundle.SplitApkMetadata
+ 13, // 21: android.bundle.ApkDescription.apex_apk_metadata:type_name -> android.bundle.ApexApkMetadata
+ 1, // 22: android.bundle.SystemApkMetadata.system_apk_type:type_name -> android.bundle.SystemApkMetadata.SystemApkType
+ 19, // 23: android.bundle.ApexApkMetadata.apex_embedded_apk_config:type_name -> android.bundle.ApexEmbeddedApkConfig
+ 24, // [24:24] is the sub-list for method output_type
+ 24, // [24:24] is the sub-list for method input_type
+ 24, // [24:24] is the sub-list for extension type_name
+ 24, // [24:24] is the sub-list for extension extendee
+ 0, // [0:24] is the sub-list for field type_name
+}
+
+func init() { file_commands_proto_init() }
+func file_commands_proto_init() {
+ if File_commands_proto != nil {
+ return
+ }
+ file_config_proto_init()
+ file_targeting_proto_init()
+ if !protoimpl.UnsafeEnabled {
+ file_commands_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BuildApksResult); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Variant); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ApkSet); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ModuleMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AssetSliceSet); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AssetModuleMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*InstantMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ApkDescription); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SplitApkMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*StandaloneApkMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SystemApkMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ApexApkMetadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_commands_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*LocalTestingInfo); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_commands_proto_msgTypes[7].OneofWrappers = []interface{}{
(*ApkDescription_SplitApkMetadata)(nil),
(*ApkDescription_StandaloneApkMetadata)(nil),
(*ApkDescription_InstantApkMetadata)(nil),
@@ -701,333 +1523,23 @@
(*ApkDescription_AssetSliceMetadata)(nil),
(*ApkDescription_ApexApkMetadata)(nil),
}
-}
-
-// Holds data specific to Split APKs.
-type SplitApkMetadata struct {
- SplitId string `protobuf:"bytes,1,opt,name=split_id,json=splitId,proto3" json:"split_id,omitempty"`
- // Indicates whether this APK is the master split of the module.
- IsMasterSplit bool `protobuf:"varint,2,opt,name=is_master_split,json=isMasterSplit,proto3" json:"is_master_split,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *SplitApkMetadata) Reset() { *m = SplitApkMetadata{} }
-func (m *SplitApkMetadata) String() string { return proto.CompactTextString(m) }
-func (*SplitApkMetadata) ProtoMessage() {}
-func (*SplitApkMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{8}
-}
-
-func (m *SplitApkMetadata) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SplitApkMetadata.Unmarshal(m, b)
-}
-func (m *SplitApkMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SplitApkMetadata.Marshal(b, m, deterministic)
-}
-func (m *SplitApkMetadata) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SplitApkMetadata.Merge(m, src)
-}
-func (m *SplitApkMetadata) XXX_Size() int {
- return xxx_messageInfo_SplitApkMetadata.Size(m)
-}
-func (m *SplitApkMetadata) XXX_DiscardUnknown() {
- xxx_messageInfo_SplitApkMetadata.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SplitApkMetadata proto.InternalMessageInfo
-
-func (m *SplitApkMetadata) GetSplitId() string {
- if m != nil {
- return m.SplitId
- }
- return ""
-}
-
-func (m *SplitApkMetadata) GetIsMasterSplit() bool {
- if m != nil {
- return m.IsMasterSplit
- }
- return false
-}
-
-// Holds data specific to Standalone APKs.
-type StandaloneApkMetadata struct {
- // Names of the modules fused in this standalone APK.
- FusedModuleName []string `protobuf:"bytes,1,rep,name=fused_module_name,json=fusedModuleName,proto3" json:"fused_module_name,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *StandaloneApkMetadata) Reset() { *m = StandaloneApkMetadata{} }
-func (m *StandaloneApkMetadata) String() string { return proto.CompactTextString(m) }
-func (*StandaloneApkMetadata) ProtoMessage() {}
-func (*StandaloneApkMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{9}
-}
-
-func (m *StandaloneApkMetadata) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_StandaloneApkMetadata.Unmarshal(m, b)
-}
-func (m *StandaloneApkMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_StandaloneApkMetadata.Marshal(b, m, deterministic)
-}
-func (m *StandaloneApkMetadata) XXX_Merge(src proto.Message) {
- xxx_messageInfo_StandaloneApkMetadata.Merge(m, src)
-}
-func (m *StandaloneApkMetadata) XXX_Size() int {
- return xxx_messageInfo_StandaloneApkMetadata.Size(m)
-}
-func (m *StandaloneApkMetadata) XXX_DiscardUnknown() {
- xxx_messageInfo_StandaloneApkMetadata.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_StandaloneApkMetadata proto.InternalMessageInfo
-
-func (m *StandaloneApkMetadata) GetFusedModuleName() []string {
- if m != nil {
- return m.FusedModuleName
- }
- return nil
-}
-
-// Holds data specific to system APKs.
-type SystemApkMetadata struct {
- // Names of the modules fused in this system APK.
- FusedModuleName []string `protobuf:"bytes,1,rep,name=fused_module_name,json=fusedModuleName,proto3" json:"fused_module_name,omitempty"`
- // Indicates whether the APK is uncompressed system APK, stub APK or
- // compressed system APK.
- SystemApkType SystemApkMetadata_SystemApkType `protobuf:"varint,2,opt,name=system_apk_type,json=systemApkType,proto3,enum=android.bundle.SystemApkMetadata_SystemApkType" json:"system_apk_type,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *SystemApkMetadata) Reset() { *m = SystemApkMetadata{} }
-func (m *SystemApkMetadata) String() string { return proto.CompactTextString(m) }
-func (*SystemApkMetadata) ProtoMessage() {}
-func (*SystemApkMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{10}
-}
-
-func (m *SystemApkMetadata) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SystemApkMetadata.Unmarshal(m, b)
-}
-func (m *SystemApkMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SystemApkMetadata.Marshal(b, m, deterministic)
-}
-func (m *SystemApkMetadata) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SystemApkMetadata.Merge(m, src)
-}
-func (m *SystemApkMetadata) XXX_Size() int {
- return xxx_messageInfo_SystemApkMetadata.Size(m)
-}
-func (m *SystemApkMetadata) XXX_DiscardUnknown() {
- xxx_messageInfo_SystemApkMetadata.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SystemApkMetadata proto.InternalMessageInfo
-
-func (m *SystemApkMetadata) GetFusedModuleName() []string {
- if m != nil {
- return m.FusedModuleName
- }
- return nil
-}
-
-func (m *SystemApkMetadata) GetSystemApkType() SystemApkMetadata_SystemApkType {
- if m != nil {
- return m.SystemApkType
- }
- return SystemApkMetadata_UNSPECIFIED_VALUE
-}
-
-// Holds data specific to APEX APKs.
-type ApexApkMetadata struct {
- // Configuration for processing of APKs embedded in an APEX image.
- ApexEmbeddedApkConfig []*ApexEmbeddedApkConfig `protobuf:"bytes,1,rep,name=apex_embedded_apk_config,json=apexEmbeddedApkConfig,proto3" json:"apex_embedded_apk_config,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *ApexApkMetadata) Reset() { *m = ApexApkMetadata{} }
-func (m *ApexApkMetadata) String() string { return proto.CompactTextString(m) }
-func (*ApexApkMetadata) ProtoMessage() {}
-func (*ApexApkMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{11}
-}
-
-func (m *ApexApkMetadata) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ApexApkMetadata.Unmarshal(m, b)
-}
-func (m *ApexApkMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ApexApkMetadata.Marshal(b, m, deterministic)
-}
-func (m *ApexApkMetadata) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ApexApkMetadata.Merge(m, src)
-}
-func (m *ApexApkMetadata) XXX_Size() int {
- return xxx_messageInfo_ApexApkMetadata.Size(m)
-}
-func (m *ApexApkMetadata) XXX_DiscardUnknown() {
- xxx_messageInfo_ApexApkMetadata.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ApexApkMetadata proto.InternalMessageInfo
-
-func (m *ApexApkMetadata) GetApexEmbeddedApkConfig() []*ApexEmbeddedApkConfig {
- if m != nil {
- return m.ApexEmbeddedApkConfig
- }
- return nil
-}
-
-type LocalTestingInfo struct {
- // Indicates if the bundle is built in local testing mode.
- Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
- // The local testing path, as specified in the base manifest.
- // This refers to the relative path on the external directory of the app where
- // APKs will be pushed for local testing.
- // Set only if local testing is enabled.
- LocalTestingPath string `protobuf:"bytes,2,opt,name=local_testing_path,json=localTestingPath,proto3" json:"local_testing_path,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
-}
-
-func (m *LocalTestingInfo) Reset() { *m = LocalTestingInfo{} }
-func (m *LocalTestingInfo) String() string { return proto.CompactTextString(m) }
-func (*LocalTestingInfo) ProtoMessage() {}
-func (*LocalTestingInfo) Descriptor() ([]byte, []int) {
- return fileDescriptor_0dff099eb2e3dfdb, []int{12}
-}
-
-func (m *LocalTestingInfo) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_LocalTestingInfo.Unmarshal(m, b)
-}
-func (m *LocalTestingInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_LocalTestingInfo.Marshal(b, m, deterministic)
-}
-func (m *LocalTestingInfo) XXX_Merge(src proto.Message) {
- xxx_messageInfo_LocalTestingInfo.Merge(m, src)
-}
-func (m *LocalTestingInfo) XXX_Size() int {
- return xxx_messageInfo_LocalTestingInfo.Size(m)
-}
-func (m *LocalTestingInfo) XXX_DiscardUnknown() {
- xxx_messageInfo_LocalTestingInfo.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_LocalTestingInfo proto.InternalMessageInfo
-
-func (m *LocalTestingInfo) GetEnabled() bool {
- if m != nil {
- return m.Enabled
- }
- return false
-}
-
-func (m *LocalTestingInfo) GetLocalTestingPath() string {
- if m != nil {
- return m.LocalTestingPath
- }
- return ""
-}
-
-func init() {
- proto.RegisterEnum("android.bundle.DeliveryType", DeliveryType_name, DeliveryType_value)
- proto.RegisterEnum("android.bundle.SystemApkMetadata_SystemApkType", SystemApkMetadata_SystemApkType_name, SystemApkMetadata_SystemApkType_value)
- proto.RegisterType((*BuildApksResult)(nil), "android.bundle.BuildApksResult")
- proto.RegisterType((*Variant)(nil), "android.bundle.Variant")
- proto.RegisterType((*ApkSet)(nil), "android.bundle.ApkSet")
- proto.RegisterType((*ModuleMetadata)(nil), "android.bundle.ModuleMetadata")
- proto.RegisterType((*AssetSliceSet)(nil), "android.bundle.AssetSliceSet")
- proto.RegisterType((*AssetModuleMetadata)(nil), "android.bundle.AssetModuleMetadata")
- proto.RegisterType((*InstantMetadata)(nil), "android.bundle.InstantMetadata")
- proto.RegisterType((*ApkDescription)(nil), "android.bundle.ApkDescription")
- proto.RegisterType((*SplitApkMetadata)(nil), "android.bundle.SplitApkMetadata")
- proto.RegisterType((*StandaloneApkMetadata)(nil), "android.bundle.StandaloneApkMetadata")
- proto.RegisterType((*SystemApkMetadata)(nil), "android.bundle.SystemApkMetadata")
- proto.RegisterType((*ApexApkMetadata)(nil), "android.bundle.ApexApkMetadata")
- proto.RegisterType((*LocalTestingInfo)(nil), "android.bundle.LocalTestingInfo")
-}
-
-func init() {
- proto.RegisterFile("commands.proto", fileDescriptor_0dff099eb2e3dfdb)
-}
-
-var fileDescriptor_0dff099eb2e3dfdb = []byte{
- // 1104 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0xe2, 0x46,
- 0x14, 0x5e, 0x03, 0x0b, 0xe1, 0x05, 0xb0, 0x33, 0x1b, 0xba, 0xde, 0x68, 0x77, 0xcb, 0xba, 0x4a,
- 0x85, 0xa2, 0x2a, 0xab, 0xa6, 0x3d, 0xad, 0xd4, 0x4a, 0x10, 0x9c, 0x96, 0x2d, 0x90, 0xc8, 0x26,
- 0x89, 0x92, 0x4a, 0x1d, 0x4d, 0x98, 0x49, 0xd6, 0xc2, 0xbf, 0xca, 0x98, 0x28, 0xf9, 0x57, 0x7a,
- 0xa9, 0x7a, 0xec, 0xb1, 0xd7, 0xfe, 0x51, 0x3d, 0xf5, 0xde, 0xca, 0x63, 0x03, 0xb6, 0xb1, 0xd4,
- 0x64, 0xd5, 0x13, 0x7e, 0x6f, 0xbe, 0xf9, 0xe6, 0xbd, 0xf7, 0xbd, 0x79, 0x0c, 0x34, 0x26, 0x9e,
- 0xe3, 0x10, 0x97, 0xf2, 0x7d, 0x7f, 0xe6, 0x05, 0x1e, 0x6a, 0x10, 0x97, 0xce, 0x3c, 0x8b, 0xee,
- 0x5f, 0xcd, 0x5d, 0x6a, 0xb3, 0x9d, 0xda, 0xc4, 0x73, 0xaf, 0xad, 0x9b, 0x68, 0x75, 0x47, 0x0e,
- 0xc8, 0xec, 0x86, 0x05, 0x96, 0x1b, 0x3b, 0xb4, 0x3f, 0x0b, 0x20, 0x77, 0xe7, 0x96, 0x4d, 0x3b,
- 0xfe, 0x94, 0x1b, 0x8c, 0xcf, 0xed, 0x00, 0xbd, 0x81, 0x9a, 0x4f, 0x26, 0x53, 0x72, 0xc3, 0xb0,
- 0x4b, 0x1c, 0xa6, 0x96, 0x5a, 0x52, 0xbb, 0x6a, 0x6c, 0xc6, 0xbe, 0x11, 0x71, 0x18, 0xfa, 0x12,
- 0x2a, 0xb7, 0x64, 0x66, 0x11, 0x37, 0x50, 0xa5, 0x56, 0xb1, 0xbd, 0x79, 0xf0, 0x7c, 0x3f, 0x7d,
- 0xee, 0xfe, 0x59, 0xb4, 0x6c, 0x2c, 0x70, 0xe8, 0x1d, 0x40, 0xb4, 0x14, 0x78, 0x9e, 0xad, 0x16,
- 0x5a, 0x52, 0x7b, 0xf3, 0x60, 0x27, 0xbb, 0xab, 0xbb, 0x44, 0x18, 0x09, 0x34, 0xd2, 0x41, 0x26,
- 0x9c, 0xb3, 0x00, 0x73, 0xdb, 0x9a, 0x30, 0xcc, 0x59, 0xa0, 0x16, 0xc5, 0xb1, 0xaf, 0xb2, 0x04,
- 0x9d, 0x10, 0x66, 0x86, 0x28, 0x93, 0x05, 0x46, 0x9d, 0x24, 0x4d, 0x34, 0x02, 0x64, 0x7b, 0x13,
- 0x62, 0xe3, 0x80, 0xf1, 0xb0, 0x06, 0xd8, 0x72, 0xaf, 0x3d, 0xf5, 0xa9, 0x08, 0xa5, 0x95, 0x65,
- 0x1a, 0x84, 0xc8, 0x71, 0x04, 0xec, 0xbb, 0xd7, 0x9e, 0xa1, 0xd8, 0x19, 0x8f, 0xf6, 0x9b, 0x04,
- 0x95, 0x38, 0x4f, 0xf4, 0x2d, 0x54, 0x97, 0xb5, 0x55, 0xa5, 0x7c, 0xca, 0x18, 0x3b, 0x5e, 0xe0,
- 0x8c, 0xd5, 0x16, 0xf4, 0x16, 0x2a, 0xc4, 0x9f, 0x8a, 0xd4, 0x0a, 0x22, 0xb5, 0x4f, 0xd6, 0x52,
- 0xf3, 0xa7, 0x61, 0x4e, 0x65, 0x22, 0x7e, 0xd1, 0x2e, 0x34, 0xe2, 0xd2, 0x62, 0x77, 0xee, 0x5c,
- 0xb1, 0x99, 0x5a, 0x6c, 0x49, 0xed, 0xba, 0x51, 0x8f, 0xbd, 0x23, 0xe1, 0xd4, 0x7e, 0x91, 0xa0,
- 0x1c, 0xed, 0x44, 0xdf, 0x81, 0xec, 0x78, 0x74, 0x6e, 0x33, 0xec, 0xb0, 0x80, 0x50, 0x12, 0x90,
- 0x38, 0xd0, 0xd7, 0xd9, 0xa3, 0x86, 0x02, 0x36, 0x8c, 0x51, 0x46, 0xc3, 0x49, 0xd9, 0x21, 0x51,
- 0x18, 0x2b, 0x65, 0x7c, 0x32, 0xb3, 0xfc, 0xc0, 0xf2, 0xdc, 0x38, 0xe6, 0xd7, 0x39, 0x31, 0xf7,
- 0x56, 0x28, 0xa3, 0x41, 0x52, 0xb6, 0xf6, 0x6b, 0x01, 0x1a, 0xe9, 0xb3, 0x10, 0x82, 0x92, 0x68,
- 0x3a, 0x49, 0x34, 0x9d, 0xf8, 0x46, 0x1d, 0xa8, 0x53, 0x66, 0x5b, 0xb7, 0x6c, 0x76, 0x8f, 0x83,
- 0x7b, 0x9f, 0xa9, 0xe5, 0x96, 0xd4, 0x6e, 0x1c, 0xbc, 0xcc, 0x9e, 0xd6, 0x8b, 0x41, 0xe3, 0x7b,
- 0x9f, 0x19, 0x35, 0x9a, 0xb0, 0xd0, 0x2b, 0x00, 0x8b, 0x63, 0xcb, 0xe5, 0x41, 0xd8, 0xb3, 0x61,
- 0xa5, 0x36, 0x8c, 0xaa, 0xc5, 0xfb, 0x91, 0x03, 0x69, 0x50, 0xa3, 0xcc, 0x67, 0x2e, 0x65, 0xee,
- 0xc4, 0x62, 0x5c, 0x2d, 0xb5, 0x8a, 0xed, 0xaa, 0x91, 0xf2, 0xa1, 0x6f, 0x92, 0x0a, 0x47, 0x4d,
- 0xf3, 0x69, 0x7e, 0xe1, 0x72, 0x05, 0xfe, 0x1a, 0xb6, 0x3d, 0x17, 0x53, 0x16, 0x5e, 0x56, 0x4c,
- 0x99, 0x3f, 0x63, 0x13, 0x12, 0x30, 0x2a, 0x6e, 0xc2, 0x46, 0xb7, 0xa0, 0x4a, 0x06, 0xf2, 0xdc,
- 0x9e, 0x58, 0xee, 0x2d, 0x57, 0xb5, 0x3f, 0x24, 0xa8, 0xa7, 0x7a, 0x1a, 0x9d, 0x43, 0x33, 0xba,
- 0x0b, 0xf9, 0x5a, 0x7e, 0x96, 0x7b, 0x23, 0x32, 0x82, 0x3e, 0x23, 0xeb, 0xce, 0xff, 0x4f, 0xd5,
- 0xbf, 0x24, 0x78, 0x96, 0x73, 0xea, 0xc3, 0xa4, 0x2d, 0x3d, 0x5a, 0xda, 0xf7, 0xa0, 0xc4, 0xba,
- 0xae, 0x6a, 0x51, 0xcc, 0x97, 0x27, 0x96, 0x7b, 0x59, 0x07, 0xd9, 0x4a, 0x3b, 0x3e, 0x52, 0xa4,
- 0xdf, 0x25, 0x90, 0x33, 0xd4, 0x99, 0x86, 0x93, 0xb2, 0x0d, 0xb7, 0x96, 0x77, 0xf1, 0xd1, 0x79,
- 0x7f, 0x5c, 0xac, 0xff, 0x94, 0xa0, 0x91, 0xd6, 0x0f, 0xbd, 0x5b, 0x1f, 0x5d, 0x2f, 0x73, 0x24,
- 0xcf, 0xed, 0x6a, 0x04, 0x25, 0x9f, 0x04, 0x1f, 0xc4, 0xa1, 0x55, 0x43, 0x7c, 0xa3, 0x13, 0x40,
- 0xdc, 0xb7, 0xad, 0x00, 0x87, 0xed, 0x94, 0x91, 0x64, 0x6d, 0x26, 0x9a, 0x21, 0xb2, 0xe3, 0x4f,
- 0x17, 0x85, 0xfb, 0xfe, 0x89, 0xa1, 0xf0, 0x8c, 0x0f, 0x61, 0x78, 0x1e, 0x96, 0x8d, 0x12, 0xdb,
- 0x73, 0x59, 0x9a, 0xb6, 0x24, 0x68, 0x77, 0xd7, 0x68, 0x97, 0xf0, 0x34, 0x77, 0x93, 0xe7, 0x2d,
- 0xa0, 0x31, 0x6c, 0x2f, 0x7a, 0x28, 0xc5, 0xfe, 0xf4, 0xc1, 0x41, 0xa3, 0x78, 0x7f, 0x92, 0xd5,
- 0x84, 0x67, 0xfc, 0x9e, 0x07, 0xcc, 0x49, 0x93, 0x96, 0x05, 0xe9, 0x9b, 0x35, 0x52, 0x01, 0x4d,
- 0xb3, 0x6e, 0xf1, 0xac, 0x33, 0x0c, 0x35, 0xf9, 0x5f, 0xb8, 0x64, 0xad, 0x3c, 0x3c, 0xd4, 0xd5,
- 0xbf, 0xe2, 0x92, 0x75, 0x08, 0x5b, 0xc4, 0x67, 0x77, 0xe9, 0x40, 0x37, 0xf2, 0x6f, 0x51, 0xc7,
- 0x67, 0x77, 0x69, 0x46, 0x99, 0xa4, 0x5d, 0xdd, 0x1d, 0x50, 0x93, 0x4c, 0xd8, 0x73, 0x99, 0x77,
- 0x8d, 0x6f, 0x89, 0x3d, 0x67, 0xda, 0x29, 0x28, 0xd9, 0xa0, 0xd0, 0x0b, 0xd8, 0x88, 0x5a, 0xc6,
- 0xa2, 0xf1, 0x78, 0xa8, 0x08, 0xbb, 0x4f, 0xd1, 0xe7, 0x20, 0x5b, 0x1c, 0x3b, 0x84, 0x07, 0x6c,
- 0x86, 0x85, 0x33, 0xea, 0x70, 0xa3, 0x6e, 0xf1, 0xa1, 0xf0, 0x0a, 0x36, 0xad, 0x0f, 0xcd, 0x5c,
- 0xd1, 0xd1, 0x1e, 0x6c, 0x5d, 0xcf, 0x39, 0xa3, 0x8b, 0x81, 0x19, 0xcf, 0xa0, 0x70, 0xc0, 0xcb,
- 0x62, 0x21, 0x1a, 0x53, 0xe1, 0xbb, 0xe6, 0x7d, 0x69, 0xa3, 0xa0, 0x14, 0xb5, 0xbf, 0x25, 0xd8,
- 0x5a, 0x53, 0xe3, 0x31, 0x3c, 0xe8, 0x1c, 0xe4, 0x84, 0xf2, 0xe2, 0x82, 0x17, 0xc4, 0x05, 0x7f,
- 0xfb, 0x9f, 0xaa, 0xaf, 0x3c, 0xe2, 0xce, 0xd7, 0x79, 0xd2, 0xd4, 0x2e, 0xa1, 0x9e, 0x5a, 0x47,
- 0x4d, 0xd8, 0x3a, 0x1d, 0x99, 0x27, 0xfa, 0x61, 0xff, 0xa8, 0xaf, 0xf7, 0xf0, 0x59, 0x67, 0x70,
- 0xaa, 0x2b, 0x4f, 0x10, 0x40, 0xd9, 0xbc, 0x30, 0xc7, 0xfa, 0x50, 0x91, 0x90, 0x0c, 0x9b, 0xd1,
- 0x37, 0x36, 0xc7, 0xa7, 0x5d, 0xa5, 0x10, 0xee, 0x89, 0x1d, 0x87, 0xc7, 0xc3, 0x13, 0x43, 0x37,
- 0x4d, 0xbd, 0xa7, 0x14, 0xb5, 0x9f, 0x41, 0xce, 0x48, 0x8b, 0x7e, 0x0a, 0x75, 0x64, 0x77, 0x98,
- 0x39, 0x57, 0x8c, 0x52, 0x46, 0x45, 0x3a, 0xd1, 0x8b, 0x32, 0x7e, 0xf8, 0xed, 0xe6, 0x75, 0x87,
- 0x1e, 0xc3, 0x3b, 0xfe, 0xf4, 0x50, 0x80, 0x8d, 0x26, 0xc9, 0x73, 0x6b, 0x97, 0xa0, 0x64, 0xdf,
- 0x59, 0x48, 0x85, 0x0a, 0x73, 0xc9, 0x95, 0xcd, 0x68, 0x3c, 0x36, 0x17, 0x26, 0xfa, 0x22, 0xfb,
- 0x7e, 0x4b, 0x8c, 0x9e, 0xd4, 0xeb, 0xec, 0x84, 0x04, 0x1f, 0xf6, 0x7e, 0x84, 0x5a, 0x72, 0x7a,
- 0xa2, 0x17, 0xd0, 0x3c, 0x1d, 0xfd, 0x30, 0x3a, 0x3e, 0x1f, 0xe1, 0x9e, 0x3e, 0xe8, 0x9f, 0xe9,
- 0xc6, 0x05, 0x1e, 0x5f, 0x9c, 0x84, 0xd5, 0x52, 0xa0, 0xd6, 0x1f, 0x99, 0xe3, 0xce, 0x60, 0x80,
- 0xc7, 0xfd, 0xa1, 0xae, 0x48, 0xa8, 0x0e, 0xd5, 0xe3, 0x10, 0x37, 0xec, 0x8c, 0x7a, 0x4a, 0x21,
- 0x2c, 0xe1, 0x51, 0xc7, 0x1c, 0xe3, 0xa3, 0xe3, 0xc1, 0xe0, 0xf8, 0x5c, 0x29, 0x76, 0xf7, 0x00,
- 0x4d, 0x3c, 0x27, 0x93, 0xfb, 0xe5, 0x76, 0x6c, 0xe3, 0xc8, 0xc6, 0xe2, 0x8d, 0x7d, 0x55, 0x16,
- 0x3f, 0x5f, 0xfd, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xe5, 0xcb, 0x87, 0xab, 0x0b, 0x00, 0x00,
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_commands_proto_rawDesc,
+ NumEnums: 2,
+ NumMessages: 13,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_commands_proto_goTypes,
+ DependencyIndexes: file_commands_proto_depIdxs,
+ EnumInfos: file_commands_proto_enumTypes,
+ MessageInfos: file_commands_proto_msgTypes,
+ }.Build()
+ File_commands_proto = out.File
+ file_commands_proto_rawDesc = nil
+ file_commands_proto_goTypes = nil
+ file_commands_proto_depIdxs = nil
}
diff --git a/cmd/extract_apks/bundle_proto/commands.proto b/cmd/extract_apks/bundle_proto/commands.proto
index b36340b..a24e26d 100644
--- a/cmd/extract_apks/bundle_proto/commands.proto
+++ b/cmd/extract_apks/bundle_proto/commands.proto
@@ -9,7 +9,7 @@
import "config.proto";
import "targeting.proto";
-option go_package = "android_bundle_proto";
+option go_package = "android/soong/cmd/extract_apks/bundle_proto";
option java_package = "com.android.bundle";
// Describes the output of the "build-apks" command.
diff --git a/cmd/extract_apks/bundle_proto/config.pb.go b/cmd/extract_apks/bundle_proto/config.pb.go
index a28147a..e358c4b 100644
--- a/cmd/extract_apks/bundle_proto/config.pb.go
+++ b/cmd/extract_apks/bundle_proto/config.pb.go
@@ -1,24 +1,29 @@
+// Messages describing APK Set's table of contents (toc.pb entry).
+// Please be advised that the ultimate source is at
+// https://github.com/google/bundletool/tree/master/src/main/proto
+// so you have been warned.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: config.proto
-package android_bundle_proto
+package bundle_proto
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
type BundleConfig_BundleType int32
@@ -28,24 +33,45 @@
BundleConfig_ASSET_ONLY BundleConfig_BundleType = 2
)
-var BundleConfig_BundleType_name = map[int32]string{
- 0: "REGULAR",
- 1: "APEX",
- 2: "ASSET_ONLY",
-}
+// Enum value maps for BundleConfig_BundleType.
+var (
+ BundleConfig_BundleType_name = map[int32]string{
+ 0: "REGULAR",
+ 1: "APEX",
+ 2: "ASSET_ONLY",
+ }
+ BundleConfig_BundleType_value = map[string]int32{
+ "REGULAR": 0,
+ "APEX": 1,
+ "ASSET_ONLY": 2,
+ }
+)
-var BundleConfig_BundleType_value = map[string]int32{
- "REGULAR": 0,
- "APEX": 1,
- "ASSET_ONLY": 2,
+func (x BundleConfig_BundleType) Enum() *BundleConfig_BundleType {
+ p := new(BundleConfig_BundleType)
+ *p = x
+ return p
}
func (x BundleConfig_BundleType) String() string {
- return proto.EnumName(BundleConfig_BundleType_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
+func (BundleConfig_BundleType) Descriptor() protoreflect.EnumDescriptor {
+ return file_config_proto_enumTypes[0].Descriptor()
+}
+
+func (BundleConfig_BundleType) Type() protoreflect.EnumType {
+ return &file_config_proto_enumTypes[0]
+}
+
+func (x BundleConfig_BundleType) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use BundleConfig_BundleType.Descriptor instead.
func (BundleConfig_BundleType) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{0, 0}
+ return file_config_proto_rawDescGZIP(), []int{0, 0}
}
type SplitDimension_Value int32
@@ -57,36 +83,61 @@
SplitDimension_LANGUAGE SplitDimension_Value = 3
SplitDimension_TEXTURE_COMPRESSION_FORMAT SplitDimension_Value = 4
// BEGIN-INTERNAL
- SplitDimension_GRAPHICS_API SplitDimension_Value = 5
+ SplitDimension_GRAPHICS_API SplitDimension_Value = 5 // END-INTERNAL
)
-var SplitDimension_Value_name = map[int32]string{
- 0: "UNSPECIFIED_VALUE",
- 1: "ABI",
- 2: "SCREEN_DENSITY",
- 3: "LANGUAGE",
- 4: "TEXTURE_COMPRESSION_FORMAT",
- 5: "GRAPHICS_API",
-}
+// Enum value maps for SplitDimension_Value.
+var (
+ SplitDimension_Value_name = map[int32]string{
+ 0: "UNSPECIFIED_VALUE",
+ 1: "ABI",
+ 2: "SCREEN_DENSITY",
+ 3: "LANGUAGE",
+ 4: "TEXTURE_COMPRESSION_FORMAT",
+ 5: "GRAPHICS_API",
+ }
+ SplitDimension_Value_value = map[string]int32{
+ "UNSPECIFIED_VALUE": 0,
+ "ABI": 1,
+ "SCREEN_DENSITY": 2,
+ "LANGUAGE": 3,
+ "TEXTURE_COMPRESSION_FORMAT": 4,
+ "GRAPHICS_API": 5,
+ }
+)
-var SplitDimension_Value_value = map[string]int32{
- "UNSPECIFIED_VALUE": 0,
- "ABI": 1,
- "SCREEN_DENSITY": 2,
- "LANGUAGE": 3,
- "TEXTURE_COMPRESSION_FORMAT": 4,
- "GRAPHICS_API": 5,
+func (x SplitDimension_Value) Enum() *SplitDimension_Value {
+ p := new(SplitDimension_Value)
+ *p = x
+ return p
}
func (x SplitDimension_Value) String() string {
- return proto.EnumName(SplitDimension_Value_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
+func (SplitDimension_Value) Descriptor() protoreflect.EnumDescriptor {
+ return file_config_proto_enumTypes[1].Descriptor()
+}
+
+func (SplitDimension_Value) Type() protoreflect.EnumType {
+ return &file_config_proto_enumTypes[1]
+}
+
+func (x SplitDimension_Value) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use SplitDimension_Value.Descriptor instead.
func (SplitDimension_Value) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{9, 0}
+ return file_config_proto_rawDescGZIP(), []int{9, 0}
}
type BundleConfig struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Bundletool *Bundletool `protobuf:"bytes,1,opt,name=bundletool,proto3" json:"bundletool,omitempty"`
Optimizations *Optimizations `protobuf:"bytes,2,opt,name=optimizations,proto3" json:"optimizations,omitempty"`
Compression *Compression `protobuf:"bytes,3,opt,name=compression,proto3" json:"compression,omitempty"`
@@ -97,226 +148,258 @@
UnsignedEmbeddedApkConfig []*UnsignedEmbeddedApkConfig `protobuf:"bytes,6,rep,name=unsigned_embedded_apk_config,json=unsignedEmbeddedApkConfig,proto3" json:"unsigned_embedded_apk_config,omitempty"`
AssetModulesConfig *AssetModulesConfig `protobuf:"bytes,7,opt,name=asset_modules_config,json=assetModulesConfig,proto3" json:"asset_modules_config,omitempty"`
Type BundleConfig_BundleType `protobuf:"varint,8,opt,name=type,proto3,enum=android.bundle.BundleConfig_BundleType" json:"type,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *BundleConfig) Reset() { *m = BundleConfig{} }
-func (m *BundleConfig) String() string { return proto.CompactTextString(m) }
-func (*BundleConfig) ProtoMessage() {}
+func (x *BundleConfig) Reset() {
+ *x = BundleConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BundleConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BundleConfig) ProtoMessage() {}
+
+func (x *BundleConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BundleConfig.ProtoReflect.Descriptor instead.
func (*BundleConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{0}
+ return file_config_proto_rawDescGZIP(), []int{0}
}
-func (m *BundleConfig) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_BundleConfig.Unmarshal(m, b)
-}
-func (m *BundleConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_BundleConfig.Marshal(b, m, deterministic)
-}
-func (m *BundleConfig) XXX_Merge(src proto.Message) {
- xxx_messageInfo_BundleConfig.Merge(m, src)
-}
-func (m *BundleConfig) XXX_Size() int {
- return xxx_messageInfo_BundleConfig.Size(m)
-}
-func (m *BundleConfig) XXX_DiscardUnknown() {
- xxx_messageInfo_BundleConfig.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BundleConfig proto.InternalMessageInfo
-
-func (m *BundleConfig) GetBundletool() *Bundletool {
- if m != nil {
- return m.Bundletool
+func (x *BundleConfig) GetBundletool() *Bundletool {
+ if x != nil {
+ return x.Bundletool
}
return nil
}
-func (m *BundleConfig) GetOptimizations() *Optimizations {
- if m != nil {
- return m.Optimizations
+func (x *BundleConfig) GetOptimizations() *Optimizations {
+ if x != nil {
+ return x.Optimizations
}
return nil
}
-func (m *BundleConfig) GetCompression() *Compression {
- if m != nil {
- return m.Compression
+func (x *BundleConfig) GetCompression() *Compression {
+ if x != nil {
+ return x.Compression
}
return nil
}
-func (m *BundleConfig) GetMasterResources() *MasterResources {
- if m != nil {
- return m.MasterResources
+func (x *BundleConfig) GetMasterResources() *MasterResources {
+ if x != nil {
+ return x.MasterResources
}
return nil
}
-func (m *BundleConfig) GetApexConfig() *ApexConfig {
- if m != nil {
- return m.ApexConfig
+func (x *BundleConfig) GetApexConfig() *ApexConfig {
+ if x != nil {
+ return x.ApexConfig
}
return nil
}
-func (m *BundleConfig) GetUnsignedEmbeddedApkConfig() []*UnsignedEmbeddedApkConfig {
- if m != nil {
- return m.UnsignedEmbeddedApkConfig
+func (x *BundleConfig) GetUnsignedEmbeddedApkConfig() []*UnsignedEmbeddedApkConfig {
+ if x != nil {
+ return x.UnsignedEmbeddedApkConfig
}
return nil
}
-func (m *BundleConfig) GetAssetModulesConfig() *AssetModulesConfig {
- if m != nil {
- return m.AssetModulesConfig
+func (x *BundleConfig) GetAssetModulesConfig() *AssetModulesConfig {
+ if x != nil {
+ return x.AssetModulesConfig
}
return nil
}
-func (m *BundleConfig) GetType() BundleConfig_BundleType {
- if m != nil {
- return m.Type
+func (x *BundleConfig) GetType() BundleConfig_BundleType {
+ if x != nil {
+ return x.Type
}
return BundleConfig_REGULAR
}
type Bundletool struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Version of BundleTool used to build the Bundle.
- Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
}
-func (m *Bundletool) Reset() { *m = Bundletool{} }
-func (m *Bundletool) String() string { return proto.CompactTextString(m) }
-func (*Bundletool) ProtoMessage() {}
+func (x *Bundletool) Reset() {
+ *x = Bundletool{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Bundletool) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Bundletool) ProtoMessage() {}
+
+func (x *Bundletool) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Bundletool.ProtoReflect.Descriptor instead.
func (*Bundletool) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{1}
+ return file_config_proto_rawDescGZIP(), []int{1}
}
-func (m *Bundletool) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Bundletool.Unmarshal(m, b)
-}
-func (m *Bundletool) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Bundletool.Marshal(b, m, deterministic)
-}
-func (m *Bundletool) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Bundletool.Merge(m, src)
-}
-func (m *Bundletool) XXX_Size() int {
- return xxx_messageInfo_Bundletool.Size(m)
-}
-func (m *Bundletool) XXX_DiscardUnknown() {
- xxx_messageInfo_Bundletool.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Bundletool proto.InternalMessageInfo
-
-func (m *Bundletool) GetVersion() string {
- if m != nil {
- return m.Version
+func (x *Bundletool) GetVersion() string {
+ if x != nil {
+ return x.Version
}
return ""
}
type Compression struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Glob matching the list of files to leave uncompressed in the APKs.
// The matching is done against the path of files in the APK, thus excluding
// the name of the modules, and using forward slash ("/") as a name separator.
// Examples: "res/raw/**", "assets/**/*.uncompressed", etc.
- UncompressedGlob []string `protobuf:"bytes,1,rep,name=uncompressed_glob,json=uncompressedGlob,proto3" json:"uncompressed_glob,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ UncompressedGlob []string `protobuf:"bytes,1,rep,name=uncompressed_glob,json=uncompressedGlob,proto3" json:"uncompressed_glob,omitempty"`
}
-func (m *Compression) Reset() { *m = Compression{} }
-func (m *Compression) String() string { return proto.CompactTextString(m) }
-func (*Compression) ProtoMessage() {}
+func (x *Compression) Reset() {
+ *x = Compression{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Compression) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Compression) ProtoMessage() {}
+
+func (x *Compression) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Compression.ProtoReflect.Descriptor instead.
func (*Compression) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{2}
+ return file_config_proto_rawDescGZIP(), []int{2}
}
-func (m *Compression) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Compression.Unmarshal(m, b)
-}
-func (m *Compression) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Compression.Marshal(b, m, deterministic)
-}
-func (m *Compression) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Compression.Merge(m, src)
-}
-func (m *Compression) XXX_Size() int {
- return xxx_messageInfo_Compression.Size(m)
-}
-func (m *Compression) XXX_DiscardUnknown() {
- xxx_messageInfo_Compression.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Compression proto.InternalMessageInfo
-
-func (m *Compression) GetUncompressedGlob() []string {
- if m != nil {
- return m.UncompressedGlob
+func (x *Compression) GetUncompressedGlob() []string {
+ if x != nil {
+ return x.UncompressedGlob
}
return nil
}
// Resources to keep in the master split.
type MasterResources struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Resource IDs to be kept in master split.
ResourceIds []int32 `protobuf:"varint,1,rep,packed,name=resource_ids,json=resourceIds,proto3" json:"resource_ids,omitempty"`
// Resource names to be kept in master split.
- ResourceNames []string `protobuf:"bytes,2,rep,name=resource_names,json=resourceNames,proto3" json:"resource_names,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ ResourceNames []string `protobuf:"bytes,2,rep,name=resource_names,json=resourceNames,proto3" json:"resource_names,omitempty"`
}
-func (m *MasterResources) Reset() { *m = MasterResources{} }
-func (m *MasterResources) String() string { return proto.CompactTextString(m) }
-func (*MasterResources) ProtoMessage() {}
+func (x *MasterResources) Reset() {
+ *x = MasterResources{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MasterResources) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MasterResources) ProtoMessage() {}
+
+func (x *MasterResources) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MasterResources.ProtoReflect.Descriptor instead.
func (*MasterResources) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{3}
+ return file_config_proto_rawDescGZIP(), []int{3}
}
-func (m *MasterResources) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_MasterResources.Unmarshal(m, b)
-}
-func (m *MasterResources) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_MasterResources.Marshal(b, m, deterministic)
-}
-func (m *MasterResources) XXX_Merge(src proto.Message) {
- xxx_messageInfo_MasterResources.Merge(m, src)
-}
-func (m *MasterResources) XXX_Size() int {
- return xxx_messageInfo_MasterResources.Size(m)
-}
-func (m *MasterResources) XXX_DiscardUnknown() {
- xxx_messageInfo_MasterResources.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_MasterResources proto.InternalMessageInfo
-
-func (m *MasterResources) GetResourceIds() []int32 {
- if m != nil {
- return m.ResourceIds
+func (x *MasterResources) GetResourceIds() []int32 {
+ if x != nil {
+ return x.ResourceIds
}
return nil
}
-func (m *MasterResources) GetResourceNames() []string {
- if m != nil {
- return m.ResourceNames
+func (x *MasterResources) GetResourceNames() []string {
+ if x != nil {
+ return x.ResourceNames
}
return nil
}
type Optimizations struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
SplitsConfig *SplitsConfig `protobuf:"bytes,1,opt,name=splits_config,json=splitsConfig,proto3" json:"splits_config,omitempty"`
// This is for uncompressing native libraries on M+ devices (L+ devices on
// instant apps).
@@ -326,293 +409,341 @@
// Configuration for the generation of standalone APKs.
// If no StandaloneConfig is set, the configuration is inherited from
// splits_config.
- StandaloneConfig *StandaloneConfig `protobuf:"bytes,4,opt,name=standalone_config,json=standaloneConfig,proto3" json:"standalone_config,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ StandaloneConfig *StandaloneConfig `protobuf:"bytes,4,opt,name=standalone_config,json=standaloneConfig,proto3" json:"standalone_config,omitempty"`
}
-func (m *Optimizations) Reset() { *m = Optimizations{} }
-func (m *Optimizations) String() string { return proto.CompactTextString(m) }
-func (*Optimizations) ProtoMessage() {}
+func (x *Optimizations) Reset() {
+ *x = Optimizations{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Optimizations) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Optimizations) ProtoMessage() {}
+
+func (x *Optimizations) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Optimizations.ProtoReflect.Descriptor instead.
func (*Optimizations) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{4}
+ return file_config_proto_rawDescGZIP(), []int{4}
}
-func (m *Optimizations) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Optimizations.Unmarshal(m, b)
-}
-func (m *Optimizations) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Optimizations.Marshal(b, m, deterministic)
-}
-func (m *Optimizations) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Optimizations.Merge(m, src)
-}
-func (m *Optimizations) XXX_Size() int {
- return xxx_messageInfo_Optimizations.Size(m)
-}
-func (m *Optimizations) XXX_DiscardUnknown() {
- xxx_messageInfo_Optimizations.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Optimizations proto.InternalMessageInfo
-
-func (m *Optimizations) GetSplitsConfig() *SplitsConfig {
- if m != nil {
- return m.SplitsConfig
+func (x *Optimizations) GetSplitsConfig() *SplitsConfig {
+ if x != nil {
+ return x.SplitsConfig
}
return nil
}
-func (m *Optimizations) GetUncompressNativeLibraries() *UncompressNativeLibraries {
- if m != nil {
- return m.UncompressNativeLibraries
+func (x *Optimizations) GetUncompressNativeLibraries() *UncompressNativeLibraries {
+ if x != nil {
+ return x.UncompressNativeLibraries
}
return nil
}
-func (m *Optimizations) GetUncompressDexFiles() *UncompressDexFiles {
- if m != nil {
- return m.UncompressDexFiles
+func (x *Optimizations) GetUncompressDexFiles() *UncompressDexFiles {
+ if x != nil {
+ return x.UncompressDexFiles
}
return nil
}
-func (m *Optimizations) GetStandaloneConfig() *StandaloneConfig {
- if m != nil {
- return m.StandaloneConfig
+func (x *Optimizations) GetStandaloneConfig() *StandaloneConfig {
+ if x != nil {
+ return x.StandaloneConfig
}
return nil
}
type UncompressNativeLibraries struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
}
-func (m *UncompressNativeLibraries) Reset() { *m = UncompressNativeLibraries{} }
-func (m *UncompressNativeLibraries) String() string { return proto.CompactTextString(m) }
-func (*UncompressNativeLibraries) ProtoMessage() {}
+func (x *UncompressNativeLibraries) Reset() {
+ *x = UncompressNativeLibraries{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UncompressNativeLibraries) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UncompressNativeLibraries) ProtoMessage() {}
+
+func (x *UncompressNativeLibraries) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UncompressNativeLibraries.ProtoReflect.Descriptor instead.
func (*UncompressNativeLibraries) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{5}
+ return file_config_proto_rawDescGZIP(), []int{5}
}
-func (m *UncompressNativeLibraries) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_UncompressNativeLibraries.Unmarshal(m, b)
-}
-func (m *UncompressNativeLibraries) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_UncompressNativeLibraries.Marshal(b, m, deterministic)
-}
-func (m *UncompressNativeLibraries) XXX_Merge(src proto.Message) {
- xxx_messageInfo_UncompressNativeLibraries.Merge(m, src)
-}
-func (m *UncompressNativeLibraries) XXX_Size() int {
- return xxx_messageInfo_UncompressNativeLibraries.Size(m)
-}
-func (m *UncompressNativeLibraries) XXX_DiscardUnknown() {
- xxx_messageInfo_UncompressNativeLibraries.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_UncompressNativeLibraries proto.InternalMessageInfo
-
-func (m *UncompressNativeLibraries) GetEnabled() bool {
- if m != nil {
- return m.Enabled
+func (x *UncompressNativeLibraries) GetEnabled() bool {
+ if x != nil {
+ return x.Enabled
}
return false
}
type UncompressDexFiles struct {
- Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
}
-func (m *UncompressDexFiles) Reset() { *m = UncompressDexFiles{} }
-func (m *UncompressDexFiles) String() string { return proto.CompactTextString(m) }
-func (*UncompressDexFiles) ProtoMessage() {}
+func (x *UncompressDexFiles) Reset() {
+ *x = UncompressDexFiles{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UncompressDexFiles) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UncompressDexFiles) ProtoMessage() {}
+
+func (x *UncompressDexFiles) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UncompressDexFiles.ProtoReflect.Descriptor instead.
func (*UncompressDexFiles) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{6}
+ return file_config_proto_rawDescGZIP(), []int{6}
}
-func (m *UncompressDexFiles) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_UncompressDexFiles.Unmarshal(m, b)
-}
-func (m *UncompressDexFiles) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_UncompressDexFiles.Marshal(b, m, deterministic)
-}
-func (m *UncompressDexFiles) XXX_Merge(src proto.Message) {
- xxx_messageInfo_UncompressDexFiles.Merge(m, src)
-}
-func (m *UncompressDexFiles) XXX_Size() int {
- return xxx_messageInfo_UncompressDexFiles.Size(m)
-}
-func (m *UncompressDexFiles) XXX_DiscardUnknown() {
- xxx_messageInfo_UncompressDexFiles.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_UncompressDexFiles proto.InternalMessageInfo
-
-func (m *UncompressDexFiles) GetEnabled() bool {
- if m != nil {
- return m.Enabled
+func (x *UncompressDexFiles) GetEnabled() bool {
+ if x != nil {
+ return x.Enabled
}
return false
}
// Optimization configuration used to generate Split APKs.
type SplitsConfig struct {
- SplitDimension []*SplitDimension `protobuf:"bytes,1,rep,name=split_dimension,json=splitDimension,proto3" json:"split_dimension,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ SplitDimension []*SplitDimension `protobuf:"bytes,1,rep,name=split_dimension,json=splitDimension,proto3" json:"split_dimension,omitempty"`
}
-func (m *SplitsConfig) Reset() { *m = SplitsConfig{} }
-func (m *SplitsConfig) String() string { return proto.CompactTextString(m) }
-func (*SplitsConfig) ProtoMessage() {}
+func (x *SplitsConfig) Reset() {
+ *x = SplitsConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SplitsConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SplitsConfig) ProtoMessage() {}
+
+func (x *SplitsConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SplitsConfig.ProtoReflect.Descriptor instead.
func (*SplitsConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{7}
+ return file_config_proto_rawDescGZIP(), []int{7}
}
-func (m *SplitsConfig) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SplitsConfig.Unmarshal(m, b)
-}
-func (m *SplitsConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SplitsConfig.Marshal(b, m, deterministic)
-}
-func (m *SplitsConfig) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SplitsConfig.Merge(m, src)
-}
-func (m *SplitsConfig) XXX_Size() int {
- return xxx_messageInfo_SplitsConfig.Size(m)
-}
-func (m *SplitsConfig) XXX_DiscardUnknown() {
- xxx_messageInfo_SplitsConfig.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SplitsConfig proto.InternalMessageInfo
-
-func (m *SplitsConfig) GetSplitDimension() []*SplitDimension {
- if m != nil {
- return m.SplitDimension
+func (x *SplitsConfig) GetSplitDimension() []*SplitDimension {
+ if x != nil {
+ return x.SplitDimension
}
return nil
}
// Optimization configuration used to generate Standalone APKs.
type StandaloneConfig struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Device targeting dimensions to shard.
SplitDimension []*SplitDimension `protobuf:"bytes,1,rep,name=split_dimension,json=splitDimension,proto3" json:"split_dimension,omitempty"`
// Whether 64 bit libraries should be stripped from Standalone APKs.
- Strip_64BitLibraries bool `protobuf:"varint,2,opt,name=strip_64_bit_libraries,json=strip64BitLibraries,proto3" json:"strip_64_bit_libraries,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Strip_64BitLibraries bool `protobuf:"varint,2,opt,name=strip_64_bit_libraries,json=strip64BitLibraries,proto3" json:"strip_64_bit_libraries,omitempty"`
}
-func (m *StandaloneConfig) Reset() { *m = StandaloneConfig{} }
-func (m *StandaloneConfig) String() string { return proto.CompactTextString(m) }
-func (*StandaloneConfig) ProtoMessage() {}
+func (x *StandaloneConfig) Reset() {
+ *x = StandaloneConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *StandaloneConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StandaloneConfig) ProtoMessage() {}
+
+func (x *StandaloneConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[8]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use StandaloneConfig.ProtoReflect.Descriptor instead.
func (*StandaloneConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{8}
+ return file_config_proto_rawDescGZIP(), []int{8}
}
-func (m *StandaloneConfig) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_StandaloneConfig.Unmarshal(m, b)
-}
-func (m *StandaloneConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_StandaloneConfig.Marshal(b, m, deterministic)
-}
-func (m *StandaloneConfig) XXX_Merge(src proto.Message) {
- xxx_messageInfo_StandaloneConfig.Merge(m, src)
-}
-func (m *StandaloneConfig) XXX_Size() int {
- return xxx_messageInfo_StandaloneConfig.Size(m)
-}
-func (m *StandaloneConfig) XXX_DiscardUnknown() {
- xxx_messageInfo_StandaloneConfig.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_StandaloneConfig proto.InternalMessageInfo
-
-func (m *StandaloneConfig) GetSplitDimension() []*SplitDimension {
- if m != nil {
- return m.SplitDimension
+func (x *StandaloneConfig) GetSplitDimension() []*SplitDimension {
+ if x != nil {
+ return x.SplitDimension
}
return nil
}
-func (m *StandaloneConfig) GetStrip_64BitLibraries() bool {
- if m != nil {
- return m.Strip_64BitLibraries
+func (x *StandaloneConfig) GetStrip_64BitLibraries() bool {
+ if x != nil {
+ return x.Strip_64BitLibraries
}
return false
}
type SplitDimension struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Value SplitDimension_Value `protobuf:"varint,1,opt,name=value,proto3,enum=android.bundle.SplitDimension_Value" json:"value,omitempty"`
// If set to 'true', indicates that APKs should *not* be split by this
// dimension.
Negate bool `protobuf:"varint,2,opt,name=negate,proto3" json:"negate,omitempty"`
// Optional transformation to be applied to asset directories where
// the targeting is encoded in the directory name (e.g: assets/foo#tcf_etc1)
- SuffixStripping *SuffixStripping `protobuf:"bytes,3,opt,name=suffix_stripping,json=suffixStripping,proto3" json:"suffix_stripping,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ SuffixStripping *SuffixStripping `protobuf:"bytes,3,opt,name=suffix_stripping,json=suffixStripping,proto3" json:"suffix_stripping,omitempty"`
}
-func (m *SplitDimension) Reset() { *m = SplitDimension{} }
-func (m *SplitDimension) String() string { return proto.CompactTextString(m) }
-func (*SplitDimension) ProtoMessage() {}
+func (x *SplitDimension) Reset() {
+ *x = SplitDimension{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SplitDimension) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SplitDimension) ProtoMessage() {}
+
+func (x *SplitDimension) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[9]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SplitDimension.ProtoReflect.Descriptor instead.
func (*SplitDimension) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{9}
+ return file_config_proto_rawDescGZIP(), []int{9}
}
-func (m *SplitDimension) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SplitDimension.Unmarshal(m, b)
-}
-func (m *SplitDimension) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SplitDimension.Marshal(b, m, deterministic)
-}
-func (m *SplitDimension) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SplitDimension.Merge(m, src)
-}
-func (m *SplitDimension) XXX_Size() int {
- return xxx_messageInfo_SplitDimension.Size(m)
-}
-func (m *SplitDimension) XXX_DiscardUnknown() {
- xxx_messageInfo_SplitDimension.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SplitDimension proto.InternalMessageInfo
-
-func (m *SplitDimension) GetValue() SplitDimension_Value {
- if m != nil {
- return m.Value
+func (x *SplitDimension) GetValue() SplitDimension_Value {
+ if x != nil {
+ return x.Value
}
return SplitDimension_UNSPECIFIED_VALUE
}
-func (m *SplitDimension) GetNegate() bool {
- if m != nil {
- return m.Negate
+func (x *SplitDimension) GetNegate() bool {
+ if x != nil {
+ return x.Negate
}
return false
}
-func (m *SplitDimension) GetSuffixStripping() *SuffixStripping {
- if m != nil {
- return m.SuffixStripping
+func (x *SplitDimension) GetSuffixStripping() *SuffixStripping {
+ if x != nil {
+ return x.SuffixStripping
}
return nil
}
type SuffixStripping struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// If set to 'true', indicates that the targeting suffix should be removed
// from assets paths for this dimension when splits (or asset slices) are
// generated.
@@ -632,47 +763,51 @@
// used (for example, if both "assets/level1_textures#tcf_etc1" and
// "assets/level1_textures" are present and the default suffix is empty,
// then only "assets/level1_textures" will be used).
- DefaultSuffix string `protobuf:"bytes,2,opt,name=default_suffix,json=defaultSuffix,proto3" json:"default_suffix,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ DefaultSuffix string `protobuf:"bytes,2,opt,name=default_suffix,json=defaultSuffix,proto3" json:"default_suffix,omitempty"`
}
-func (m *SuffixStripping) Reset() { *m = SuffixStripping{} }
-func (m *SuffixStripping) String() string { return proto.CompactTextString(m) }
-func (*SuffixStripping) ProtoMessage() {}
+func (x *SuffixStripping) Reset() {
+ *x = SuffixStripping{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[10]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SuffixStripping) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SuffixStripping) ProtoMessage() {}
+
+func (x *SuffixStripping) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[10]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SuffixStripping.ProtoReflect.Descriptor instead.
func (*SuffixStripping) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{10}
+ return file_config_proto_rawDescGZIP(), []int{10}
}
-func (m *SuffixStripping) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SuffixStripping.Unmarshal(m, b)
-}
-func (m *SuffixStripping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SuffixStripping.Marshal(b, m, deterministic)
-}
-func (m *SuffixStripping) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SuffixStripping.Merge(m, src)
-}
-func (m *SuffixStripping) XXX_Size() int {
- return xxx_messageInfo_SuffixStripping.Size(m)
-}
-func (m *SuffixStripping) XXX_DiscardUnknown() {
- xxx_messageInfo_SuffixStripping.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SuffixStripping proto.InternalMessageInfo
-
-func (m *SuffixStripping) GetEnabled() bool {
- if m != nil {
- return m.Enabled
+func (x *SuffixStripping) GetEnabled() bool {
+ if x != nil {
+ return x.Enabled
}
return false
}
-func (m *SuffixStripping) GetDefaultSuffix() string {
- if m != nil {
- return m.DefaultSuffix
+func (x *SuffixStripping) GetDefaultSuffix() string {
+ if x != nil {
+ return x.DefaultSuffix
}
return ""
}
@@ -680,273 +815,634 @@
// Configuration for processing APEX bundles.
// https://source.android.com/devices/tech/ota/apex
type ApexConfig struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Configuration for processing of APKs embedded in an APEX image.
ApexEmbeddedApkConfig []*ApexEmbeddedApkConfig `protobuf:"bytes,1,rep,name=apex_embedded_apk_config,json=apexEmbeddedApkConfig,proto3" json:"apex_embedded_apk_config,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *ApexConfig) Reset() { *m = ApexConfig{} }
-func (m *ApexConfig) String() string { return proto.CompactTextString(m) }
-func (*ApexConfig) ProtoMessage() {}
+func (x *ApexConfig) Reset() {
+ *x = ApexConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[11]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ApexConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApexConfig) ProtoMessage() {}
+
+func (x *ApexConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[11]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApexConfig.ProtoReflect.Descriptor instead.
func (*ApexConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{11}
+ return file_config_proto_rawDescGZIP(), []int{11}
}
-func (m *ApexConfig) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ApexConfig.Unmarshal(m, b)
-}
-func (m *ApexConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ApexConfig.Marshal(b, m, deterministic)
-}
-func (m *ApexConfig) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ApexConfig.Merge(m, src)
-}
-func (m *ApexConfig) XXX_Size() int {
- return xxx_messageInfo_ApexConfig.Size(m)
-}
-func (m *ApexConfig) XXX_DiscardUnknown() {
- xxx_messageInfo_ApexConfig.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ApexConfig proto.InternalMessageInfo
-
-func (m *ApexConfig) GetApexEmbeddedApkConfig() []*ApexEmbeddedApkConfig {
- if m != nil {
- return m.ApexEmbeddedApkConfig
+func (x *ApexConfig) GetApexEmbeddedApkConfig() []*ApexEmbeddedApkConfig {
+ if x != nil {
+ return x.ApexEmbeddedApkConfig
}
return nil
}
type ApexEmbeddedApkConfig struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Android package name of the APK.
PackageName string `protobuf:"bytes,1,opt,name=package_name,json=packageName,proto3" json:"package_name,omitempty"`
// Path to the APK within the APEX system image.
- Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
}
-func (m *ApexEmbeddedApkConfig) Reset() { *m = ApexEmbeddedApkConfig{} }
-func (m *ApexEmbeddedApkConfig) String() string { return proto.CompactTextString(m) }
-func (*ApexEmbeddedApkConfig) ProtoMessage() {}
+func (x *ApexEmbeddedApkConfig) Reset() {
+ *x = ApexEmbeddedApkConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ApexEmbeddedApkConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApexEmbeddedApkConfig) ProtoMessage() {}
+
+func (x *ApexEmbeddedApkConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[12]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApexEmbeddedApkConfig.ProtoReflect.Descriptor instead.
func (*ApexEmbeddedApkConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{12}
+ return file_config_proto_rawDescGZIP(), []int{12}
}
-func (m *ApexEmbeddedApkConfig) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ApexEmbeddedApkConfig.Unmarshal(m, b)
-}
-func (m *ApexEmbeddedApkConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ApexEmbeddedApkConfig.Marshal(b, m, deterministic)
-}
-func (m *ApexEmbeddedApkConfig) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ApexEmbeddedApkConfig.Merge(m, src)
-}
-func (m *ApexEmbeddedApkConfig) XXX_Size() int {
- return xxx_messageInfo_ApexEmbeddedApkConfig.Size(m)
-}
-func (m *ApexEmbeddedApkConfig) XXX_DiscardUnknown() {
- xxx_messageInfo_ApexEmbeddedApkConfig.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ApexEmbeddedApkConfig proto.InternalMessageInfo
-
-func (m *ApexEmbeddedApkConfig) GetPackageName() string {
- if m != nil {
- return m.PackageName
+func (x *ApexEmbeddedApkConfig) GetPackageName() string {
+ if x != nil {
+ return x.PackageName
}
return ""
}
-func (m *ApexEmbeddedApkConfig) GetPath() string {
- if m != nil {
- return m.Path
+func (x *ApexEmbeddedApkConfig) GetPath() string {
+ if x != nil {
+ return x.Path
}
return ""
}
type UnsignedEmbeddedApkConfig struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Path to the APK inside the module (e.g. if the path inside the bundle
// is split/assets/example.apk, this will be assets/example.apk).
- Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
}
-func (m *UnsignedEmbeddedApkConfig) Reset() { *m = UnsignedEmbeddedApkConfig{} }
-func (m *UnsignedEmbeddedApkConfig) String() string { return proto.CompactTextString(m) }
-func (*UnsignedEmbeddedApkConfig) ProtoMessage() {}
+func (x *UnsignedEmbeddedApkConfig) Reset() {
+ *x = UnsignedEmbeddedApkConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UnsignedEmbeddedApkConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UnsignedEmbeddedApkConfig) ProtoMessage() {}
+
+func (x *UnsignedEmbeddedApkConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[13]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UnsignedEmbeddedApkConfig.ProtoReflect.Descriptor instead.
func (*UnsignedEmbeddedApkConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{13}
+ return file_config_proto_rawDescGZIP(), []int{13}
}
-func (m *UnsignedEmbeddedApkConfig) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_UnsignedEmbeddedApkConfig.Unmarshal(m, b)
-}
-func (m *UnsignedEmbeddedApkConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_UnsignedEmbeddedApkConfig.Marshal(b, m, deterministic)
-}
-func (m *UnsignedEmbeddedApkConfig) XXX_Merge(src proto.Message) {
- xxx_messageInfo_UnsignedEmbeddedApkConfig.Merge(m, src)
-}
-func (m *UnsignedEmbeddedApkConfig) XXX_Size() int {
- return xxx_messageInfo_UnsignedEmbeddedApkConfig.Size(m)
-}
-func (m *UnsignedEmbeddedApkConfig) XXX_DiscardUnknown() {
- xxx_messageInfo_UnsignedEmbeddedApkConfig.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_UnsignedEmbeddedApkConfig proto.InternalMessageInfo
-
-func (m *UnsignedEmbeddedApkConfig) GetPath() string {
- if m != nil {
- return m.Path
+func (x *UnsignedEmbeddedApkConfig) GetPath() string {
+ if x != nil {
+ return x.Path
}
return ""
}
type AssetModulesConfig struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// App versionCodes that will be updated with these asset modules.
// Only relevant for asset-only bundles.
AppVersion []int64 `protobuf:"varint,1,rep,packed,name=app_version,json=appVersion,proto3" json:"app_version,omitempty"`
// Version tag for the asset upload.
// Only relevant for asset-only bundles.
- AssetVersionTag string `protobuf:"bytes,2,opt,name=asset_version_tag,json=assetVersionTag,proto3" json:"asset_version_tag,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ AssetVersionTag string `protobuf:"bytes,2,opt,name=asset_version_tag,json=assetVersionTag,proto3" json:"asset_version_tag,omitempty"`
}
-func (m *AssetModulesConfig) Reset() { *m = AssetModulesConfig{} }
-func (m *AssetModulesConfig) String() string { return proto.CompactTextString(m) }
-func (*AssetModulesConfig) ProtoMessage() {}
+func (x *AssetModulesConfig) Reset() {
+ *x = AssetModulesConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_config_proto_msgTypes[14]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AssetModulesConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AssetModulesConfig) ProtoMessage() {}
+
+func (x *AssetModulesConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_config_proto_msgTypes[14]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AssetModulesConfig.ProtoReflect.Descriptor instead.
func (*AssetModulesConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor_3eaf2c85e69e9ea4, []int{14}
+ return file_config_proto_rawDescGZIP(), []int{14}
}
-func (m *AssetModulesConfig) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_AssetModulesConfig.Unmarshal(m, b)
-}
-func (m *AssetModulesConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_AssetModulesConfig.Marshal(b, m, deterministic)
-}
-func (m *AssetModulesConfig) XXX_Merge(src proto.Message) {
- xxx_messageInfo_AssetModulesConfig.Merge(m, src)
-}
-func (m *AssetModulesConfig) XXX_Size() int {
- return xxx_messageInfo_AssetModulesConfig.Size(m)
-}
-func (m *AssetModulesConfig) XXX_DiscardUnknown() {
- xxx_messageInfo_AssetModulesConfig.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AssetModulesConfig proto.InternalMessageInfo
-
-func (m *AssetModulesConfig) GetAppVersion() []int64 {
- if m != nil {
- return m.AppVersion
+func (x *AssetModulesConfig) GetAppVersion() []int64 {
+ if x != nil {
+ return x.AppVersion
}
return nil
}
-func (m *AssetModulesConfig) GetAssetVersionTag() string {
- if m != nil {
- return m.AssetVersionTag
+func (x *AssetModulesConfig) GetAssetVersionTag() string {
+ if x != nil {
+ return x.AssetVersionTag
}
return ""
}
-func init() {
- proto.RegisterEnum("android.bundle.BundleConfig_BundleType", BundleConfig_BundleType_name, BundleConfig_BundleType_value)
- proto.RegisterEnum("android.bundle.SplitDimension_Value", SplitDimension_Value_name, SplitDimension_Value_value)
- proto.RegisterType((*BundleConfig)(nil), "android.bundle.BundleConfig")
- proto.RegisterType((*Bundletool)(nil), "android.bundle.Bundletool")
- proto.RegisterType((*Compression)(nil), "android.bundle.Compression")
- proto.RegisterType((*MasterResources)(nil), "android.bundle.MasterResources")
- proto.RegisterType((*Optimizations)(nil), "android.bundle.Optimizations")
- proto.RegisterType((*UncompressNativeLibraries)(nil), "android.bundle.UncompressNativeLibraries")
- proto.RegisterType((*UncompressDexFiles)(nil), "android.bundle.UncompressDexFiles")
- proto.RegisterType((*SplitsConfig)(nil), "android.bundle.SplitsConfig")
- proto.RegisterType((*StandaloneConfig)(nil), "android.bundle.StandaloneConfig")
- proto.RegisterType((*SplitDimension)(nil), "android.bundle.SplitDimension")
- proto.RegisterType((*SuffixStripping)(nil), "android.bundle.SuffixStripping")
- proto.RegisterType((*ApexConfig)(nil), "android.bundle.ApexConfig")
- proto.RegisterType((*ApexEmbeddedApkConfig)(nil), "android.bundle.ApexEmbeddedApkConfig")
- proto.RegisterType((*UnsignedEmbeddedApkConfig)(nil), "android.bundle.UnsignedEmbeddedApkConfig")
- proto.RegisterType((*AssetModulesConfig)(nil), "android.bundle.AssetModulesConfig")
+var File_config_proto protoreflect.FileDescriptor
+
+var file_config_proto_rawDesc = []byte{
+ 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x22, 0x8b,
+ 0x05, 0x0a, 0x0c, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x3a, 0x0a, 0x0a, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75,
+ 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x52,
+ 0x0a, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x43, 0x0a, 0x0d, 0x6f,
+ 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e,
+ 0x64, 0x6c, 0x65, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x52, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x12, 0x3d, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+ 0x4a, 0x0a, 0x10, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4d, 0x61, 0x73, 0x74, 0x65,
+ 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x0f, 0x6d, 0x61, 0x73, 0x74,
+ 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x61,
+ 0x70, 0x65, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x1a, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x2e, 0x41, 0x70, 0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x61, 0x70,
+ 0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x6a, 0x0a, 0x1c, 0x75, 0x6e, 0x73, 0x69,
+ 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x61, 0x70,
+ 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29,
+ 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e,
+ 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64,
+ 0x41, 0x70, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x19, 0x75, 0x6e, 0x73, 0x69, 0x67,
+ 0x6e, 0x65, 0x64, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x41, 0x70, 0x6b, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x12, 0x54, 0x0a, 0x14, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x6f,
+ 0x64, 0x75, 0x6c, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e,
+ 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x12, 0x61, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64,
+ 0x75, 0x6c, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79,
+ 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x54, 0x79, 0x70,
+ 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x33, 0x0a, 0x0a, 0x42, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x47, 0x55, 0x4c, 0x41, 0x52,
+ 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x50, 0x45, 0x58, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a,
+ 0x41, 0x53, 0x53, 0x45, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x22, 0x2c, 0x0a, 0x0a,
+ 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x3a, 0x0a, 0x0b, 0x43, 0x6f,
+ 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x75, 0x6e, 0x63,
+ 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x18, 0x01,
+ 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73,
+ 0x65, 0x64, 0x47, 0x6c, 0x6f, 0x62, 0x22, 0x5b, 0x0a, 0x0f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72,
+ 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x73,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x52,
+ 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e,
+ 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61,
+ 0x6d, 0x65, 0x73, 0x22, 0xe2, 0x02, 0x0a, 0x0d, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x5f,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x70,
+ 0x6c, 0x69, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x73, 0x70, 0x6c, 0x69,
+ 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x69, 0x0a, 0x1b, 0x75, 0x6e, 0x63, 0x6f,
+ 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6c, 0x69,
+ 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x55,
+ 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4c,
+ 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x52, 0x19, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70,
+ 0x72, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72,
+ 0x69, 0x65, 0x73, 0x12, 0x54, 0x0a, 0x14, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73,
+ 0x73, 0x5f, 0x64, 0x65, 0x78, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64,
+ 0x6c, 0x65, 0x2e, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x78,
+ 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x12, 0x75, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73,
+ 0x73, 0x44, 0x65, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x11, 0x73, 0x74, 0x61,
+ 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62,
+ 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6f,
+ 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x35, 0x0a, 0x19, 0x55, 0x6e, 0x63, 0x6f,
+ 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4c, 0x69, 0x62, 0x72,
+ 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22,
+ 0x2e, 0x0a, 0x12, 0x55, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x44, 0x65, 0x78,
+ 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22,
+ 0x57, 0x0a, 0x0c, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
+ 0x47, 0x0a, 0x0f, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69,
+ 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x44,
+ 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x44,
+ 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x90, 0x01, 0x0a, 0x10, 0x53, 0x74, 0x61,
+ 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x47, 0x0a,
+ 0x0f, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x44, 0x69, 0x6d,
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x44, 0x69, 0x6d,
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x16, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f,
+ 0x36, 0x34, 0x5f, 0x62, 0x69, 0x74, 0x5f, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x73, 0x74, 0x72, 0x69, 0x70, 0x36, 0x34, 0x42,
+ 0x69, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, 0x73, 0x22, 0xad, 0x02, 0x0a, 0x0e,
+ 0x53, 0x70, 0x6c, 0x69, 0x74, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3a,
+ 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53,
+ 0x70, 0x6c, 0x69, 0x74, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x65,
+ 0x67, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6e, 0x65, 0x67, 0x61,
+ 0x74, 0x65, 0x12, 0x4a, 0x0a, 0x10, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x5f, 0x73, 0x74, 0x72,
+ 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x75,
+ 0x66, 0x66, 0x69, 0x78, 0x53, 0x74, 0x72, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0f, 0x73,
+ 0x75, 0x66, 0x66, 0x69, 0x78, 0x53, 0x74, 0x72, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x7b,
+ 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x53, 0x50, 0x45,
+ 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x00, 0x12, 0x07,
+ 0x0a, 0x03, 0x41, 0x42, 0x49, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x43, 0x52, 0x45, 0x45,
+ 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x53, 0x49, 0x54, 0x59, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x4c,
+ 0x41, 0x4e, 0x47, 0x55, 0x41, 0x47, 0x45, 0x10, 0x03, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x58,
+ 0x54, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e,
+ 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x52, 0x41,
+ 0x50, 0x48, 0x49, 0x43, 0x53, 0x5f, 0x41, 0x50, 0x49, 0x10, 0x05, 0x22, 0x52, 0x0a, 0x0f, 0x53,
+ 0x75, 0x66, 0x66, 0x69, 0x78, 0x53, 0x74, 0x72, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x18,
+ 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x66, 0x61,
+ 0x75, 0x6c, 0x74, 0x5f, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x75, 0x66, 0x66, 0x69, 0x78, 0x22,
+ 0x6c, 0x0a, 0x0a, 0x41, 0x70, 0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5e, 0x0a,
+ 0x18, 0x61, 0x70, 0x65, 0x78, 0x5f, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x61,
+ 0x70, 0x6b, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x25, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x2e, 0x41, 0x70, 0x65, 0x78, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x41, 0x70, 0x6b,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x15, 0x61, 0x70, 0x65, 0x78, 0x45, 0x6d, 0x62, 0x65,
+ 0x64, 0x64, 0x65, 0x64, 0x41, 0x70, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x4e, 0x0a,
+ 0x15, 0x41, 0x70, 0x65, 0x78, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x41, 0x70, 0x6b,
+ 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67,
+ 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61,
+ 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74,
+ 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x2f, 0x0a,
+ 0x19, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65,
+ 0x64, 0x41, 0x70, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61,
+ 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x61,
+ 0x0a, 0x12, 0x41, 0x73, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x73,
+ 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x73, 0x73, 0x65, 0x74, 0x5f, 0x76,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x61,
+ 0x67, 0x42, 0x41, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5a, 0x2b, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x65, 0x78, 0x74, 0x72, 0x61,
+ 0x63, 0x74, 0x5f, 0x61, 0x70, 0x6b, 0x73, 0x2f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
-func init() {
- proto.RegisterFile("config.proto", fileDescriptor_3eaf2c85e69e9ea4)
+var (
+ file_config_proto_rawDescOnce sync.Once
+ file_config_proto_rawDescData = file_config_proto_rawDesc
+)
+
+func file_config_proto_rawDescGZIP() []byte {
+ file_config_proto_rawDescOnce.Do(func() {
+ file_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_config_proto_rawDescData)
+ })
+ return file_config_proto_rawDescData
}
-var fileDescriptor_3eaf2c85e69e9ea4 = []byte{
- // 1001 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdb, 0x6e, 0xdb, 0x46,
- 0x10, 0x0d, 0x75, 0xb1, 0xe5, 0x91, 0x2c, 0xd1, 0xdb, 0x38, 0x50, 0x2e, 0x4d, 0x5c, 0xa2, 0x41,
- 0xdd, 0xb4, 0x50, 0x01, 0x3b, 0xcd, 0x83, 0x83, 0x3e, 0xd0, 0x32, 0xad, 0x2a, 0xd0, 0x0d, 0x4b,
- 0xc9, 0x4d, 0x5a, 0xa0, 0x8b, 0x95, 0xb8, 0x52, 0xb7, 0xa6, 0x48, 0x82, 0x4b, 0x1a, 0x4a, 0xfb,
- 0x09, 0x7d, 0xe9, 0x8f, 0xf4, 0xa7, 0xfa, 0x25, 0x05, 0x97, 0xa4, 0x2c, 0x51, 0x52, 0x9e, 0xfa,
- 0x24, 0xce, 0xec, 0x39, 0xb3, 0x3b, 0xb3, 0x67, 0x67, 0x04, 0x95, 0x89, 0xeb, 0x4c, 0xf9, 0xac,
- 0xe1, 0xf9, 0x6e, 0xe0, 0xa2, 0x2a, 0x75, 0x2c, 0xdf, 0xe5, 0x56, 0x63, 0x1c, 0x3a, 0x96, 0xcd,
- 0xb4, 0xbf, 0x8a, 0x50, 0xb9, 0x94, 0x9f, 0x4d, 0x09, 0x43, 0x17, 0x00, 0xf1, 0x52, 0xe0, 0xba,
- 0x76, 0x5d, 0x39, 0x51, 0x4e, 0xcb, 0x67, 0x4f, 0x1a, 0xeb, 0xac, 0xc6, 0xe5, 0x12, 0x81, 0x57,
- 0xd0, 0xa8, 0x09, 0x87, 0xae, 0x17, 0xf0, 0x39, 0xff, 0x83, 0x06, 0xdc, 0x75, 0x44, 0x3d, 0x27,
- 0xe9, 0x9f, 0x67, 0xe9, 0xfd, 0x55, 0x10, 0x5e, 0xe7, 0xa0, 0x1f, 0xa0, 0x3c, 0x71, 0xe7, 0x9e,
- 0xcf, 0x84, 0xe0, 0xae, 0x53, 0xcf, 0xcb, 0x10, 0x4f, 0xb3, 0x21, 0x9a, 0xf7, 0x10, 0xbc, 0x8a,
- 0x47, 0xef, 0x40, 0x9d, 0x53, 0x11, 0x30, 0x9f, 0xf8, 0x4c, 0xb8, 0xa1, 0x3f, 0x61, 0xa2, 0x5e,
- 0x90, 0x31, 0x5e, 0x64, 0x63, 0x74, 0x25, 0x0e, 0xa7, 0x30, 0x5c, 0x9b, 0xaf, 0x3b, 0xd0, 0x5b,
- 0x28, 0x53, 0x8f, 0x2d, 0x48, 0x5c, 0xc1, 0x7a, 0x71, 0x7b, 0x31, 0x74, 0x8f, 0x2d, 0xe2, 0xe2,
- 0x61, 0xa0, 0xcb, 0x6f, 0xf4, 0x3b, 0x3c, 0x0b, 0x1d, 0xc1, 0x67, 0x0e, 0xb3, 0x08, 0x9b, 0x8f,
- 0x99, 0x65, 0x31, 0x8b, 0x50, 0xef, 0x36, 0x8d, 0xb6, 0x77, 0x92, 0x3f, 0x2d, 0x9f, 0x7d, 0x9d,
- 0x8d, 0x36, 0x4a, 0x38, 0x46, 0x42, 0xd1, 0xbd, 0xdb, 0x24, 0xf8, 0xe3, 0x70, 0xd7, 0x12, 0x1a,
- 0xc2, 0x43, 0x2a, 0x04, 0x0b, 0xc8, 0xdc, 0xb5, 0x42, 0x9b, 0x89, 0x74, 0x8f, 0x7d, 0x79, 0x62,
- 0x6d, 0xe3, 0xc4, 0x11, 0xb6, 0x1b, 0x43, 0x93, 0xe0, 0x88, 0x6e, 0xf8, 0xd0, 0x5b, 0x28, 0x04,
- 0x1f, 0x3d, 0x56, 0x2f, 0x9d, 0x28, 0xa7, 0xd5, 0xb3, 0xaf, 0xb6, 0x8b, 0x20, 0xc6, 0x26, 0xc6,
- 0xf0, 0xa3, 0xc7, 0xb0, 0x24, 0x69, 0xe7, 0x00, 0xf7, 0x3e, 0x54, 0x86, 0x7d, 0x6c, 0xb4, 0x46,
- 0x1d, 0x1d, 0xab, 0x0f, 0x50, 0x09, 0x0a, 0xfa, 0xc0, 0x78, 0xaf, 0x2a, 0xa8, 0x0a, 0xa0, 0x9b,
- 0xa6, 0x31, 0x24, 0xfd, 0x5e, 0xe7, 0x83, 0x9a, 0xd3, 0xbe, 0x4d, 0x49, 0x52, 0x4e, 0x75, 0xd8,
- 0xbf, 0x63, 0xbe, 0x54, 0x41, 0x24, 0xa4, 0x03, 0x9c, 0x9a, 0xef, 0x0a, 0x25, 0x45, 0xcd, 0x69,
- 0x17, 0x50, 0x5e, 0x91, 0x01, 0xfa, 0x06, 0x8e, 0x42, 0x27, 0x95, 0x02, 0xb3, 0xc8, 0xcc, 0x76,
- 0xc7, 0x75, 0xe5, 0x24, 0x7f, 0x7a, 0x80, 0xd5, 0xd5, 0x85, 0x96, 0xed, 0x8e, 0xb5, 0x5f, 0xa0,
- 0x96, 0xb9, 0x7e, 0xf4, 0x05, 0x54, 0x52, 0xc9, 0x10, 0x6e, 0x09, 0x49, 0x2d, 0xe2, 0x72, 0xea,
- 0x6b, 0x5b, 0x02, 0xbd, 0x84, 0xea, 0x12, 0xe2, 0xd0, 0x39, 0x8b, 0x14, 0x1e, 0xc5, 0x3f, 0x4c,
- 0xbd, 0xbd, 0xc8, 0xa9, 0xfd, 0x9b, 0x83, 0xc3, 0x35, 0x8d, 0x23, 0x1d, 0x0e, 0x85, 0x67, 0xf3,
- 0x60, 0x79, 0x33, 0xf1, 0xc3, 0x7a, 0x96, 0xad, 0xa9, 0x29, 0x41, 0xc9, 0x9d, 0x54, 0xc4, 0x8a,
- 0x85, 0x38, 0x3c, 0xbd, 0xcf, 0x82, 0x38, 0x34, 0xe0, 0x77, 0x8c, 0xd8, 0x7c, 0xec, 0x53, 0x9f,
- 0xb3, 0xf4, 0xa9, 0x6d, 0x91, 0x53, 0x4a, 0xe9, 0x49, 0x46, 0x27, 0x25, 0x44, 0x72, 0xda, 0xb1,
- 0x14, 0xc9, 0x69, 0x65, 0x2b, 0x8b, 0x2d, 0xc8, 0x94, 0xdb, 0x4c, 0x24, 0x6f, 0x51, 0xdb, 0xbd,
- 0xc7, 0x15, 0x5b, 0x5c, 0x47, 0x48, 0x8c, 0xc2, 0x0d, 0x1f, 0xea, 0xc2, 0x91, 0x08, 0xa8, 0x63,
- 0x51, 0xdb, 0x75, 0x58, 0x5a, 0x87, 0xf8, 0x69, 0x9e, 0x6c, 0xd4, 0x61, 0x09, 0x4c, 0x6a, 0xa1,
- 0x8a, 0x8c, 0x47, 0xfb, 0x1e, 0x1e, 0xef, 0x4c, 0x2e, 0x92, 0x0e, 0x73, 0xe8, 0xd8, 0x66, 0x96,
- 0xac, 0x74, 0x09, 0xa7, 0xa6, 0xd6, 0x00, 0xb4, 0x79, 0xde, 0x4f, 0xe0, 0x7f, 0x82, 0xca, 0xea,
- 0xa5, 0xa0, 0x16, 0xd4, 0xe4, 0xb5, 0x10, 0x8b, 0xcf, 0x99, 0x23, 0xc5, 0xa9, 0xc8, 0x97, 0xfc,
- 0x7c, 0xeb, 0x5d, 0x5e, 0xa5, 0x28, 0x5c, 0x15, 0x6b, 0xb6, 0xf6, 0xb7, 0x02, 0x6a, 0x36, 0xcd,
- 0xff, 0x2d, 0x3a, 0x3a, 0x87, 0x47, 0x22, 0xf0, 0xb9, 0x47, 0xde, 0xbc, 0x26, 0x63, 0x1e, 0x64,
- 0x84, 0x52, 0xc2, 0x9f, 0xc9, 0xd5, 0x37, 0xaf, 0x2f, 0x79, 0xb0, 0xac, 0x9a, 0xf6, 0x4f, 0x0e,
- 0xaa, 0xeb, 0x71, 0xd1, 0x05, 0x14, 0xef, 0xa8, 0x1d, 0x32, 0x59, 0x96, 0xea, 0xd9, 0x97, 0x9f,
- 0x3e, 0x46, 0xe3, 0x26, 0xc2, 0xe2, 0x98, 0x82, 0x1e, 0xc1, 0x9e, 0xc3, 0x66, 0x34, 0x60, 0xc9,
- 0x9e, 0x89, 0x15, 0xb5, 0x68, 0x11, 0x4e, 0xa7, 0x7c, 0x41, 0xe4, 0x21, 0x3c, 0xee, 0xcc, 0x12,
- 0x69, 0x6d, 0xb4, 0x68, 0x53, 0xe2, 0xcc, 0x14, 0x86, 0x6b, 0x62, 0xdd, 0xa1, 0xfd, 0x09, 0x45,
- 0xb9, 0x27, 0x3a, 0x86, 0xa3, 0x51, 0xcf, 0x1c, 0x18, 0xcd, 0xf6, 0x75, 0xdb, 0xb8, 0x22, 0x37,
- 0x7a, 0x67, 0x64, 0xa8, 0x0f, 0xd0, 0x3e, 0xe4, 0xf5, 0xcb, 0xb6, 0xaa, 0x20, 0x04, 0x55, 0xb3,
- 0x89, 0x0d, 0xa3, 0x47, 0xae, 0x8c, 0x9e, 0xd9, 0x1e, 0x7e, 0x50, 0x73, 0xa8, 0x02, 0xa5, 0x8e,
- 0xde, 0x6b, 0x8d, 0xf4, 0x96, 0xa1, 0xe6, 0xd1, 0x73, 0x78, 0x32, 0x34, 0xde, 0x0f, 0x47, 0xd8,
- 0x20, 0xcd, 0x7e, 0x77, 0x80, 0x0d, 0xd3, 0x6c, 0xf7, 0x7b, 0xe4, 0xba, 0x8f, 0xbb, 0xfa, 0x50,
- 0x2d, 0x20, 0x15, 0x2a, 0x2d, 0xac, 0x0f, 0x7e, 0x6c, 0x37, 0x4d, 0xa2, 0x0f, 0xda, 0x6a, 0x51,
- 0xc3, 0x50, 0xcb, 0x1c, 0x70, 0xb7, 0x90, 0xa2, 0xde, 0x61, 0xb1, 0x29, 0x0d, 0xed, 0x80, 0xc4,
- 0x49, 0x24, 0x4d, 0xed, 0x30, 0xf1, 0xc6, 0x91, 0x34, 0x1b, 0xe0, 0x7e, 0xa0, 0xa0, 0x5f, 0xa1,
- 0x2e, 0x27, 0xd0, 0xb6, 0x01, 0x12, 0x0b, 0xe3, 0xe5, 0xb6, 0x71, 0xb4, 0x39, 0x3c, 0x8e, 0xe9,
- 0x36, 0xb7, 0xd6, 0x83, 0xe3, 0xad, 0xf8, 0xa8, 0x19, 0x7a, 0x74, 0x72, 0x4b, 0x67, 0x71, 0xa3,
- 0x93, 0xc9, 0x1c, 0xe0, 0x72, 0xe2, 0x8b, 0xda, 0x1c, 0x42, 0x50, 0xf0, 0x68, 0xf0, 0x5b, 0x92,
- 0x86, 0xfc, 0xd6, 0xbe, 0x8b, 0x1e, 0xe5, 0xae, 0x29, 0x95, 0x12, 0x94, 0x15, 0x02, 0x05, 0xb4,
- 0x39, 0x8d, 0xd0, 0x8b, 0x68, 0xf0, 0x7a, 0x24, 0xed, 0xfe, 0x51, 0xa6, 0xf9, 0x68, 0xb8, 0x7a,
- 0x37, 0xb1, 0x07, 0xbd, 0x82, 0xa3, 0x78, 0xe0, 0x25, 0x10, 0x12, 0xd0, 0x59, 0x72, 0x90, 0x9a,
- 0x5c, 0x48, 0x80, 0x43, 0x3a, 0xbb, 0x7c, 0x05, 0x68, 0xe2, 0xce, 0x33, 0x65, 0xfa, 0xf9, 0x61,
- 0x62, 0x93, 0xd8, 0x26, 0xf2, 0xef, 0xd1, 0x78, 0x4f, 0xfe, 0x9c, 0xff, 0x17, 0x00, 0x00, 0xff,
- 0xff, 0x6b, 0x05, 0xbf, 0x99, 0x35, 0x09, 0x00, 0x00,
+var file_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_config_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
+var file_config_proto_goTypes = []interface{}{
+ (BundleConfig_BundleType)(0), // 0: android.bundle.BundleConfig.BundleType
+ (SplitDimension_Value)(0), // 1: android.bundle.SplitDimension.Value
+ (*BundleConfig)(nil), // 2: android.bundle.BundleConfig
+ (*Bundletool)(nil), // 3: android.bundle.Bundletool
+ (*Compression)(nil), // 4: android.bundle.Compression
+ (*MasterResources)(nil), // 5: android.bundle.MasterResources
+ (*Optimizations)(nil), // 6: android.bundle.Optimizations
+ (*UncompressNativeLibraries)(nil), // 7: android.bundle.UncompressNativeLibraries
+ (*UncompressDexFiles)(nil), // 8: android.bundle.UncompressDexFiles
+ (*SplitsConfig)(nil), // 9: android.bundle.SplitsConfig
+ (*StandaloneConfig)(nil), // 10: android.bundle.StandaloneConfig
+ (*SplitDimension)(nil), // 11: android.bundle.SplitDimension
+ (*SuffixStripping)(nil), // 12: android.bundle.SuffixStripping
+ (*ApexConfig)(nil), // 13: android.bundle.ApexConfig
+ (*ApexEmbeddedApkConfig)(nil), // 14: android.bundle.ApexEmbeddedApkConfig
+ (*UnsignedEmbeddedApkConfig)(nil), // 15: android.bundle.UnsignedEmbeddedApkConfig
+ (*AssetModulesConfig)(nil), // 16: android.bundle.AssetModulesConfig
+}
+var file_config_proto_depIdxs = []int32{
+ 3, // 0: android.bundle.BundleConfig.bundletool:type_name -> android.bundle.Bundletool
+ 6, // 1: android.bundle.BundleConfig.optimizations:type_name -> android.bundle.Optimizations
+ 4, // 2: android.bundle.BundleConfig.compression:type_name -> android.bundle.Compression
+ 5, // 3: android.bundle.BundleConfig.master_resources:type_name -> android.bundle.MasterResources
+ 13, // 4: android.bundle.BundleConfig.apex_config:type_name -> android.bundle.ApexConfig
+ 15, // 5: android.bundle.BundleConfig.unsigned_embedded_apk_config:type_name -> android.bundle.UnsignedEmbeddedApkConfig
+ 16, // 6: android.bundle.BundleConfig.asset_modules_config:type_name -> android.bundle.AssetModulesConfig
+ 0, // 7: android.bundle.BundleConfig.type:type_name -> android.bundle.BundleConfig.BundleType
+ 9, // 8: android.bundle.Optimizations.splits_config:type_name -> android.bundle.SplitsConfig
+ 7, // 9: android.bundle.Optimizations.uncompress_native_libraries:type_name -> android.bundle.UncompressNativeLibraries
+ 8, // 10: android.bundle.Optimizations.uncompress_dex_files:type_name -> android.bundle.UncompressDexFiles
+ 10, // 11: android.bundle.Optimizations.standalone_config:type_name -> android.bundle.StandaloneConfig
+ 11, // 12: android.bundle.SplitsConfig.split_dimension:type_name -> android.bundle.SplitDimension
+ 11, // 13: android.bundle.StandaloneConfig.split_dimension:type_name -> android.bundle.SplitDimension
+ 1, // 14: android.bundle.SplitDimension.value:type_name -> android.bundle.SplitDimension.Value
+ 12, // 15: android.bundle.SplitDimension.suffix_stripping:type_name -> android.bundle.SuffixStripping
+ 14, // 16: android.bundle.ApexConfig.apex_embedded_apk_config:type_name -> android.bundle.ApexEmbeddedApkConfig
+ 17, // [17:17] is the sub-list for method output_type
+ 17, // [17:17] is the sub-list for method input_type
+ 17, // [17:17] is the sub-list for extension type_name
+ 17, // [17:17] is the sub-list for extension extendee
+ 0, // [0:17] is the sub-list for field type_name
+}
+
+func init() { file_config_proto_init() }
+func file_config_proto_init() {
+ if File_config_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BundleConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Bundletool); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Compression); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MasterResources); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Optimizations); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UncompressNativeLibraries); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UncompressDexFiles); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SplitsConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*StandaloneConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SplitDimension); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SuffixStripping); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ApexConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ApexEmbeddedApkConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UnsignedEmbeddedApkConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_config_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AssetModulesConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_config_proto_rawDesc,
+ NumEnums: 2,
+ NumMessages: 15,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_config_proto_goTypes,
+ DependencyIndexes: file_config_proto_depIdxs,
+ EnumInfos: file_config_proto_enumTypes,
+ MessageInfos: file_config_proto_msgTypes,
+ }.Build()
+ File_config_proto = out.File
+ file_config_proto_rawDesc = nil
+ file_config_proto_goTypes = nil
+ file_config_proto_depIdxs = nil
}
diff --git a/cmd/extract_apks/bundle_proto/config.proto b/cmd/extract_apks/bundle_proto/config.proto
index 1c161aa..d6fac03 100644
--- a/cmd/extract_apks/bundle_proto/config.proto
+++ b/cmd/extract_apks/bundle_proto/config.proto
@@ -6,7 +6,7 @@
package android.bundle;
-option go_package = "android_bundle_proto";
+option go_package = "android/soong/cmd/extract_apks/bundle_proto";
option java_package = "com.android.bundle";
message BundleConfig {
diff --git a/cmd/extract_apks/bundle_proto/targeting.pb.go b/cmd/extract_apks/bundle_proto/targeting.pb.go
index 187bc44..66e6f0d 100644
--- a/cmd/extract_apks/bundle_proto/targeting.pb.go
+++ b/cmd/extract_apks/bundle_proto/targeting.pb.go
@@ -1,24 +1,29 @@
+// Messages describing APK Set's table of contents (toc.pb entry).
+// Please be advised that the ultimate source is at
+// https://github.com/google/bundletool/tree/master/src/main/proto
+// so you have been warned.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: targeting.proto
-package android_bundle_proto
+package bundle_proto
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
type ScreenDensity_DensityAlias int32
@@ -34,36 +39,57 @@
ScreenDensity_XXXHDPI ScreenDensity_DensityAlias = 8
)
-var ScreenDensity_DensityAlias_name = map[int32]string{
- 0: "DENSITY_UNSPECIFIED",
- 1: "NODPI",
- 2: "LDPI",
- 3: "MDPI",
- 4: "TVDPI",
- 5: "HDPI",
- 6: "XHDPI",
- 7: "XXHDPI",
- 8: "XXXHDPI",
-}
+// Enum value maps for ScreenDensity_DensityAlias.
+var (
+ ScreenDensity_DensityAlias_name = map[int32]string{
+ 0: "DENSITY_UNSPECIFIED",
+ 1: "NODPI",
+ 2: "LDPI",
+ 3: "MDPI",
+ 4: "TVDPI",
+ 5: "HDPI",
+ 6: "XHDPI",
+ 7: "XXHDPI",
+ 8: "XXXHDPI",
+ }
+ ScreenDensity_DensityAlias_value = map[string]int32{
+ "DENSITY_UNSPECIFIED": 0,
+ "NODPI": 1,
+ "LDPI": 2,
+ "MDPI": 3,
+ "TVDPI": 4,
+ "HDPI": 5,
+ "XHDPI": 6,
+ "XXHDPI": 7,
+ "XXXHDPI": 8,
+ }
+)
-var ScreenDensity_DensityAlias_value = map[string]int32{
- "DENSITY_UNSPECIFIED": 0,
- "NODPI": 1,
- "LDPI": 2,
- "MDPI": 3,
- "TVDPI": 4,
- "HDPI": 5,
- "XHDPI": 6,
- "XXHDPI": 7,
- "XXXHDPI": 8,
+func (x ScreenDensity_DensityAlias) Enum() *ScreenDensity_DensityAlias {
+ p := new(ScreenDensity_DensityAlias)
+ *p = x
+ return p
}
func (x ScreenDensity_DensityAlias) String() string {
- return proto.EnumName(ScreenDensity_DensityAlias_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
+func (ScreenDensity_DensityAlias) Descriptor() protoreflect.EnumDescriptor {
+ return file_targeting_proto_enumTypes[0].Descriptor()
+}
+
+func (ScreenDensity_DensityAlias) Type() protoreflect.EnumType {
+ return &file_targeting_proto_enumTypes[0]
+}
+
+func (x ScreenDensity_DensityAlias) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use ScreenDensity_DensityAlias.Descriptor instead.
func (ScreenDensity_DensityAlias) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{4, 0}
+ return file_targeting_proto_rawDescGZIP(), []int{4, 0}
}
type TextureCompressionFormat_TextureCompressionFormatAlias int32
@@ -82,40 +108,61 @@
TextureCompressionFormat_ETC2 TextureCompressionFormat_TextureCompressionFormatAlias = 10
)
-var TextureCompressionFormat_TextureCompressionFormatAlias_name = map[int32]string{
- 0: "UNSPECIFIED_TEXTURE_COMPRESSION_FORMAT",
- 1: "ETC1_RGB8",
- 2: "PALETTED",
- 3: "THREE_DC",
- 4: "ATC",
- 5: "LATC",
- 6: "DXT1",
- 7: "S3TC",
- 8: "PVRTC",
- 9: "ASTC",
- 10: "ETC2",
-}
+// Enum value maps for TextureCompressionFormat_TextureCompressionFormatAlias.
+var (
+ TextureCompressionFormat_TextureCompressionFormatAlias_name = map[int32]string{
+ 0: "UNSPECIFIED_TEXTURE_COMPRESSION_FORMAT",
+ 1: "ETC1_RGB8",
+ 2: "PALETTED",
+ 3: "THREE_DC",
+ 4: "ATC",
+ 5: "LATC",
+ 6: "DXT1",
+ 7: "S3TC",
+ 8: "PVRTC",
+ 9: "ASTC",
+ 10: "ETC2",
+ }
+ TextureCompressionFormat_TextureCompressionFormatAlias_value = map[string]int32{
+ "UNSPECIFIED_TEXTURE_COMPRESSION_FORMAT": 0,
+ "ETC1_RGB8": 1,
+ "PALETTED": 2,
+ "THREE_DC": 3,
+ "ATC": 4,
+ "LATC": 5,
+ "DXT1": 6,
+ "S3TC": 7,
+ "PVRTC": 8,
+ "ASTC": 9,
+ "ETC2": 10,
+ }
+)
-var TextureCompressionFormat_TextureCompressionFormatAlias_value = map[string]int32{
- "UNSPECIFIED_TEXTURE_COMPRESSION_FORMAT": 0,
- "ETC1_RGB8": 1,
- "PALETTED": 2,
- "THREE_DC": 3,
- "ATC": 4,
- "LATC": 5,
- "DXT1": 6,
- "S3TC": 7,
- "PVRTC": 8,
- "ASTC": 9,
- "ETC2": 10,
+func (x TextureCompressionFormat_TextureCompressionFormatAlias) Enum() *TextureCompressionFormat_TextureCompressionFormatAlias {
+ p := new(TextureCompressionFormat_TextureCompressionFormatAlias)
+ *p = x
+ return p
}
func (x TextureCompressionFormat_TextureCompressionFormatAlias) String() string {
- return proto.EnumName(TextureCompressionFormat_TextureCompressionFormatAlias_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
+func (TextureCompressionFormat_TextureCompressionFormatAlias) Descriptor() protoreflect.EnumDescriptor {
+ return file_targeting_proto_enumTypes[1].Descriptor()
+}
+
+func (TextureCompressionFormat_TextureCompressionFormatAlias) Type() protoreflect.EnumType {
+ return &file_targeting_proto_enumTypes[1]
+}
+
+func (x TextureCompressionFormat_TextureCompressionFormatAlias) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use TextureCompressionFormat_TextureCompressionFormatAlias.Descriptor instead.
func (TextureCompressionFormat_TextureCompressionFormatAlias) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{10, 0}
+ return file_targeting_proto_rawDescGZIP(), []int{10, 0}
}
type Abi_AbiAlias int32
@@ -131,34 +178,55 @@
Abi_MIPS64 Abi_AbiAlias = 7
)
-var Abi_AbiAlias_name = map[int32]string{
- 0: "UNSPECIFIED_CPU_ARCHITECTURE",
- 1: "ARMEABI",
- 2: "ARMEABI_V7A",
- 3: "ARM64_V8A",
- 4: "X86",
- 5: "X86_64",
- 6: "MIPS",
- 7: "MIPS64",
-}
+// Enum value maps for Abi_AbiAlias.
+var (
+ Abi_AbiAlias_name = map[int32]string{
+ 0: "UNSPECIFIED_CPU_ARCHITECTURE",
+ 1: "ARMEABI",
+ 2: "ARMEABI_V7A",
+ 3: "ARM64_V8A",
+ 4: "X86",
+ 5: "X86_64",
+ 6: "MIPS",
+ 7: "MIPS64",
+ }
+ Abi_AbiAlias_value = map[string]int32{
+ "UNSPECIFIED_CPU_ARCHITECTURE": 0,
+ "ARMEABI": 1,
+ "ARMEABI_V7A": 2,
+ "ARM64_V8A": 3,
+ "X86": 4,
+ "X86_64": 5,
+ "MIPS": 6,
+ "MIPS64": 7,
+ }
+)
-var Abi_AbiAlias_value = map[string]int32{
- "UNSPECIFIED_CPU_ARCHITECTURE": 0,
- "ARMEABI": 1,
- "ARMEABI_V7A": 2,
- "ARM64_V8A": 3,
- "X86": 4,
- "X86_64": 5,
- "MIPS": 6,
- "MIPS64": 7,
+func (x Abi_AbiAlias) Enum() *Abi_AbiAlias {
+ p := new(Abi_AbiAlias)
+ *p = x
+ return p
}
func (x Abi_AbiAlias) String() string {
- return proto.EnumName(Abi_AbiAlias_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
+func (Abi_AbiAlias) Descriptor() protoreflect.EnumDescriptor {
+ return file_targeting_proto_enumTypes[2].Descriptor()
+}
+
+func (Abi_AbiAlias) Type() protoreflect.EnumType {
+ return &file_targeting_proto_enumTypes[2]
+}
+
+func (x Abi_AbiAlias) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Abi_AbiAlias.Descriptor instead.
func (Abi_AbiAlias) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{11, 0}
+ return file_targeting_proto_rawDescGZIP(), []int{11, 0}
}
type Sanitizer_SanitizerAlias int32
@@ -168,98 +236,131 @@
Sanitizer_HWADDRESS Sanitizer_SanitizerAlias = 1
)
-var Sanitizer_SanitizerAlias_name = map[int32]string{
- 0: "NONE",
- 1: "HWADDRESS",
-}
+// Enum value maps for Sanitizer_SanitizerAlias.
+var (
+ Sanitizer_SanitizerAlias_name = map[int32]string{
+ 0: "NONE",
+ 1: "HWADDRESS",
+ }
+ Sanitizer_SanitizerAlias_value = map[string]int32{
+ "NONE": 0,
+ "HWADDRESS": 1,
+ }
+)
-var Sanitizer_SanitizerAlias_value = map[string]int32{
- "NONE": 0,
- "HWADDRESS": 1,
+func (x Sanitizer_SanitizerAlias) Enum() *Sanitizer_SanitizerAlias {
+ p := new(Sanitizer_SanitizerAlias)
+ *p = x
+ return p
}
func (x Sanitizer_SanitizerAlias) String() string {
- return proto.EnumName(Sanitizer_SanitizerAlias_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
+func (Sanitizer_SanitizerAlias) Descriptor() protoreflect.EnumDescriptor {
+ return file_targeting_proto_enumTypes[3].Descriptor()
+}
+
+func (Sanitizer_SanitizerAlias) Type() protoreflect.EnumType {
+ return &file_targeting_proto_enumTypes[3]
+}
+
+func (x Sanitizer_SanitizerAlias) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Sanitizer_SanitizerAlias.Descriptor instead.
func (Sanitizer_SanitizerAlias) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{13, 0}
+ return file_targeting_proto_rawDescGZIP(), []int{13, 0}
}
// Targeting on the level of variants.
type VariantTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
SdkVersionTargeting *SdkVersionTargeting `protobuf:"bytes,1,opt,name=sdk_version_targeting,json=sdkVersionTargeting,proto3" json:"sdk_version_targeting,omitempty"`
AbiTargeting *AbiTargeting `protobuf:"bytes,2,opt,name=abi_targeting,json=abiTargeting,proto3" json:"abi_targeting,omitempty"`
ScreenDensityTargeting *ScreenDensityTargeting `protobuf:"bytes,3,opt,name=screen_density_targeting,json=screenDensityTargeting,proto3" json:"screen_density_targeting,omitempty"`
MultiAbiTargeting *MultiAbiTargeting `protobuf:"bytes,4,opt,name=multi_abi_targeting,json=multiAbiTargeting,proto3" json:"multi_abi_targeting,omitempty"`
TextureCompressionFormatTargeting *TextureCompressionFormatTargeting `protobuf:"bytes,5,opt,name=texture_compression_format_targeting,json=textureCompressionFormatTargeting,proto3" json:"texture_compression_format_targeting,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *VariantTargeting) Reset() { *m = VariantTargeting{} }
-func (m *VariantTargeting) String() string { return proto.CompactTextString(m) }
-func (*VariantTargeting) ProtoMessage() {}
+func (x *VariantTargeting) Reset() {
+ *x = VariantTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *VariantTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*VariantTargeting) ProtoMessage() {}
+
+func (x *VariantTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use VariantTargeting.ProtoReflect.Descriptor instead.
func (*VariantTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{0}
+ return file_targeting_proto_rawDescGZIP(), []int{0}
}
-func (m *VariantTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_VariantTargeting.Unmarshal(m, b)
-}
-func (m *VariantTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_VariantTargeting.Marshal(b, m, deterministic)
-}
-func (m *VariantTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_VariantTargeting.Merge(m, src)
-}
-func (m *VariantTargeting) XXX_Size() int {
- return xxx_messageInfo_VariantTargeting.Size(m)
-}
-func (m *VariantTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_VariantTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_VariantTargeting proto.InternalMessageInfo
-
-func (m *VariantTargeting) GetSdkVersionTargeting() *SdkVersionTargeting {
- if m != nil {
- return m.SdkVersionTargeting
+func (x *VariantTargeting) GetSdkVersionTargeting() *SdkVersionTargeting {
+ if x != nil {
+ return x.SdkVersionTargeting
}
return nil
}
-func (m *VariantTargeting) GetAbiTargeting() *AbiTargeting {
- if m != nil {
- return m.AbiTargeting
+func (x *VariantTargeting) GetAbiTargeting() *AbiTargeting {
+ if x != nil {
+ return x.AbiTargeting
}
return nil
}
-func (m *VariantTargeting) GetScreenDensityTargeting() *ScreenDensityTargeting {
- if m != nil {
- return m.ScreenDensityTargeting
+func (x *VariantTargeting) GetScreenDensityTargeting() *ScreenDensityTargeting {
+ if x != nil {
+ return x.ScreenDensityTargeting
}
return nil
}
-func (m *VariantTargeting) GetMultiAbiTargeting() *MultiAbiTargeting {
- if m != nil {
- return m.MultiAbiTargeting
+func (x *VariantTargeting) GetMultiAbiTargeting() *MultiAbiTargeting {
+ if x != nil {
+ return x.MultiAbiTargeting
}
return nil
}
-func (m *VariantTargeting) GetTextureCompressionFormatTargeting() *TextureCompressionFormatTargeting {
- if m != nil {
- return m.TextureCompressionFormatTargeting
+func (x *VariantTargeting) GetTextureCompressionFormatTargeting() *TextureCompressionFormatTargeting {
+ if x != nil {
+ return x.TextureCompressionFormatTargeting
}
return nil
}
// Targeting on the level of individual APKs.
type ApkTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
AbiTargeting *AbiTargeting `protobuf:"bytes,1,opt,name=abi_targeting,json=abiTargeting,proto3" json:"abi_targeting,omitempty"`
GraphicsApiTargeting *GraphicsApiTargeting `protobuf:"bytes,2,opt,name=graphics_api_targeting,json=graphicsApiTargeting,proto3" json:"graphics_api_targeting,omitempty"`
LanguageTargeting *LanguageTargeting `protobuf:"bytes,3,opt,name=language_targeting,json=languageTargeting,proto3" json:"language_targeting,omitempty"`
@@ -268,88 +369,92 @@
TextureCompressionFormatTargeting *TextureCompressionFormatTargeting `protobuf:"bytes,6,opt,name=texture_compression_format_targeting,json=textureCompressionFormatTargeting,proto3" json:"texture_compression_format_targeting,omitempty"`
MultiAbiTargeting *MultiAbiTargeting `protobuf:"bytes,7,opt,name=multi_abi_targeting,json=multiAbiTargeting,proto3" json:"multi_abi_targeting,omitempty"`
SanitizerTargeting *SanitizerTargeting `protobuf:"bytes,8,opt,name=sanitizer_targeting,json=sanitizerTargeting,proto3" json:"sanitizer_targeting,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *ApkTargeting) Reset() { *m = ApkTargeting{} }
-func (m *ApkTargeting) String() string { return proto.CompactTextString(m) }
-func (*ApkTargeting) ProtoMessage() {}
+func (x *ApkTargeting) Reset() {
+ *x = ApkTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ApkTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApkTargeting) ProtoMessage() {}
+
+func (x *ApkTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApkTargeting.ProtoReflect.Descriptor instead.
func (*ApkTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{1}
+ return file_targeting_proto_rawDescGZIP(), []int{1}
}
-func (m *ApkTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ApkTargeting.Unmarshal(m, b)
-}
-func (m *ApkTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ApkTargeting.Marshal(b, m, deterministic)
-}
-func (m *ApkTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ApkTargeting.Merge(m, src)
-}
-func (m *ApkTargeting) XXX_Size() int {
- return xxx_messageInfo_ApkTargeting.Size(m)
-}
-func (m *ApkTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_ApkTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ApkTargeting proto.InternalMessageInfo
-
-func (m *ApkTargeting) GetAbiTargeting() *AbiTargeting {
- if m != nil {
- return m.AbiTargeting
+func (x *ApkTargeting) GetAbiTargeting() *AbiTargeting {
+ if x != nil {
+ return x.AbiTargeting
}
return nil
}
-func (m *ApkTargeting) GetGraphicsApiTargeting() *GraphicsApiTargeting {
- if m != nil {
- return m.GraphicsApiTargeting
+func (x *ApkTargeting) GetGraphicsApiTargeting() *GraphicsApiTargeting {
+ if x != nil {
+ return x.GraphicsApiTargeting
}
return nil
}
-func (m *ApkTargeting) GetLanguageTargeting() *LanguageTargeting {
- if m != nil {
- return m.LanguageTargeting
+func (x *ApkTargeting) GetLanguageTargeting() *LanguageTargeting {
+ if x != nil {
+ return x.LanguageTargeting
}
return nil
}
-func (m *ApkTargeting) GetScreenDensityTargeting() *ScreenDensityTargeting {
- if m != nil {
- return m.ScreenDensityTargeting
+func (x *ApkTargeting) GetScreenDensityTargeting() *ScreenDensityTargeting {
+ if x != nil {
+ return x.ScreenDensityTargeting
}
return nil
}
-func (m *ApkTargeting) GetSdkVersionTargeting() *SdkVersionTargeting {
- if m != nil {
- return m.SdkVersionTargeting
+func (x *ApkTargeting) GetSdkVersionTargeting() *SdkVersionTargeting {
+ if x != nil {
+ return x.SdkVersionTargeting
}
return nil
}
-func (m *ApkTargeting) GetTextureCompressionFormatTargeting() *TextureCompressionFormatTargeting {
- if m != nil {
- return m.TextureCompressionFormatTargeting
+func (x *ApkTargeting) GetTextureCompressionFormatTargeting() *TextureCompressionFormatTargeting {
+ if x != nil {
+ return x.TextureCompressionFormatTargeting
}
return nil
}
-func (m *ApkTargeting) GetMultiAbiTargeting() *MultiAbiTargeting {
- if m != nil {
- return m.MultiAbiTargeting
+func (x *ApkTargeting) GetMultiAbiTargeting() *MultiAbiTargeting {
+ if x != nil {
+ return x.MultiAbiTargeting
}
return nil
}
-func (m *ApkTargeting) GetSanitizerTargeting() *SanitizerTargeting {
- if m != nil {
- return m.SanitizerTargeting
+func (x *ApkTargeting) GetSanitizerTargeting() *SanitizerTargeting {
+ if x != nil {
+ return x.SanitizerTargeting
}
return nil
}
@@ -357,56 +462,64 @@
// Targeting on the module level.
// The semantic of the targeting is the "AND" rule on all immediate values.
type ModuleTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
SdkVersionTargeting *SdkVersionTargeting `protobuf:"bytes,1,opt,name=sdk_version_targeting,json=sdkVersionTargeting,proto3" json:"sdk_version_targeting,omitempty"`
DeviceFeatureTargeting []*DeviceFeatureTargeting `protobuf:"bytes,2,rep,name=device_feature_targeting,json=deviceFeatureTargeting,proto3" json:"device_feature_targeting,omitempty"`
UserCountriesTargeting *UserCountriesTargeting `protobuf:"bytes,3,opt,name=user_countries_targeting,json=userCountriesTargeting,proto3" json:"user_countries_targeting,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *ModuleTargeting) Reset() { *m = ModuleTargeting{} }
-func (m *ModuleTargeting) String() string { return proto.CompactTextString(m) }
-func (*ModuleTargeting) ProtoMessage() {}
+func (x *ModuleTargeting) Reset() {
+ *x = ModuleTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ModuleTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ModuleTargeting) ProtoMessage() {}
+
+func (x *ModuleTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ModuleTargeting.ProtoReflect.Descriptor instead.
func (*ModuleTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{2}
+ return file_targeting_proto_rawDescGZIP(), []int{2}
}
-func (m *ModuleTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ModuleTargeting.Unmarshal(m, b)
-}
-func (m *ModuleTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ModuleTargeting.Marshal(b, m, deterministic)
-}
-func (m *ModuleTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ModuleTargeting.Merge(m, src)
-}
-func (m *ModuleTargeting) XXX_Size() int {
- return xxx_messageInfo_ModuleTargeting.Size(m)
-}
-func (m *ModuleTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_ModuleTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ModuleTargeting proto.InternalMessageInfo
-
-func (m *ModuleTargeting) GetSdkVersionTargeting() *SdkVersionTargeting {
- if m != nil {
- return m.SdkVersionTargeting
+func (x *ModuleTargeting) GetSdkVersionTargeting() *SdkVersionTargeting {
+ if x != nil {
+ return x.SdkVersionTargeting
}
return nil
}
-func (m *ModuleTargeting) GetDeviceFeatureTargeting() []*DeviceFeatureTargeting {
- if m != nil {
- return m.DeviceFeatureTargeting
+func (x *ModuleTargeting) GetDeviceFeatureTargeting() []*DeviceFeatureTargeting {
+ if x != nil {
+ return x.DeviceFeatureTargeting
}
return nil
}
-func (m *ModuleTargeting) GetUserCountriesTargeting() *UserCountriesTargeting {
- if m != nil {
- return m.UserCountriesTargeting
+func (x *ModuleTargeting) GetUserCountriesTargeting() *UserCountriesTargeting {
+ if x != nil {
+ return x.UserCountriesTargeting
}
return nil
}
@@ -414,88 +527,125 @@
// User Countries targeting describing an inclusive/exclusive list of country
// codes that module targets.
type UserCountriesTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// List of country codes in the two-letter CLDR territory format.
CountryCodes []string `protobuf:"bytes,1,rep,name=country_codes,json=countryCodes,proto3" json:"country_codes,omitempty"`
// Indicates if the list above is exclusive.
- Exclude bool `protobuf:"varint,2,opt,name=exclude,proto3" json:"exclude,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Exclude bool `protobuf:"varint,2,opt,name=exclude,proto3" json:"exclude,omitempty"`
}
-func (m *UserCountriesTargeting) Reset() { *m = UserCountriesTargeting{} }
-func (m *UserCountriesTargeting) String() string { return proto.CompactTextString(m) }
-func (*UserCountriesTargeting) ProtoMessage() {}
+func (x *UserCountriesTargeting) Reset() {
+ *x = UserCountriesTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UserCountriesTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UserCountriesTargeting) ProtoMessage() {}
+
+func (x *UserCountriesTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UserCountriesTargeting.ProtoReflect.Descriptor instead.
func (*UserCountriesTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{3}
+ return file_targeting_proto_rawDescGZIP(), []int{3}
}
-func (m *UserCountriesTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_UserCountriesTargeting.Unmarshal(m, b)
-}
-func (m *UserCountriesTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_UserCountriesTargeting.Marshal(b, m, deterministic)
-}
-func (m *UserCountriesTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_UserCountriesTargeting.Merge(m, src)
-}
-func (m *UserCountriesTargeting) XXX_Size() int {
- return xxx_messageInfo_UserCountriesTargeting.Size(m)
-}
-func (m *UserCountriesTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_UserCountriesTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_UserCountriesTargeting proto.InternalMessageInfo
-
-func (m *UserCountriesTargeting) GetCountryCodes() []string {
- if m != nil {
- return m.CountryCodes
+func (x *UserCountriesTargeting) GetCountryCodes() []string {
+ if x != nil {
+ return x.CountryCodes
}
return nil
}
-func (m *UserCountriesTargeting) GetExclude() bool {
- if m != nil {
- return m.Exclude
+func (x *UserCountriesTargeting) GetExclude() bool {
+ if x != nil {
+ return x.Exclude
}
return false
}
type ScreenDensity struct {
- // Types that are valid to be assigned to DensityOneof:
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Types that are assignable to DensityOneof:
// *ScreenDensity_DensityAlias_
// *ScreenDensity_DensityDpi
- DensityOneof isScreenDensity_DensityOneof `protobuf_oneof:"density_oneof"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ DensityOneof isScreenDensity_DensityOneof `protobuf_oneof:"density_oneof"`
}
-func (m *ScreenDensity) Reset() { *m = ScreenDensity{} }
-func (m *ScreenDensity) String() string { return proto.CompactTextString(m) }
-func (*ScreenDensity) ProtoMessage() {}
+func (x *ScreenDensity) Reset() {
+ *x = ScreenDensity{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ScreenDensity) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ScreenDensity) ProtoMessage() {}
+
+func (x *ScreenDensity) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ScreenDensity.ProtoReflect.Descriptor instead.
func (*ScreenDensity) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{4}
+ return file_targeting_proto_rawDescGZIP(), []int{4}
}
-func (m *ScreenDensity) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ScreenDensity.Unmarshal(m, b)
-}
-func (m *ScreenDensity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ScreenDensity.Marshal(b, m, deterministic)
-}
-func (m *ScreenDensity) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ScreenDensity.Merge(m, src)
-}
-func (m *ScreenDensity) XXX_Size() int {
- return xxx_messageInfo_ScreenDensity.Size(m)
-}
-func (m *ScreenDensity) XXX_DiscardUnknown() {
- xxx_messageInfo_ScreenDensity.DiscardUnknown(m)
+func (m *ScreenDensity) GetDensityOneof() isScreenDensity_DensityOneof {
+ if m != nil {
+ return m.DensityOneof
+ }
+ return nil
}
-var xxx_messageInfo_ScreenDensity proto.InternalMessageInfo
+func (x *ScreenDensity) GetDensityAlias() ScreenDensity_DensityAlias {
+ if x, ok := x.GetDensityOneof().(*ScreenDensity_DensityAlias_); ok {
+ return x.DensityAlias
+ }
+ return ScreenDensity_DENSITY_UNSPECIFIED
+}
+
+func (x *ScreenDensity) GetDensityDpi() int32 {
+ if x, ok := x.GetDensityOneof().(*ScreenDensity_DensityDpi); ok {
+ return x.DensityDpi
+ }
+ return 0
+}
type isScreenDensity_DensityOneof interface {
isScreenDensity_DensityOneof()
@@ -513,169 +663,148 @@
func (*ScreenDensity_DensityDpi) isScreenDensity_DensityOneof() {}
-func (m *ScreenDensity) GetDensityOneof() isScreenDensity_DensityOneof {
- if m != nil {
- return m.DensityOneof
- }
- return nil
-}
-
-func (m *ScreenDensity) GetDensityAlias() ScreenDensity_DensityAlias {
- if x, ok := m.GetDensityOneof().(*ScreenDensity_DensityAlias_); ok {
- return x.DensityAlias
- }
- return ScreenDensity_DENSITY_UNSPECIFIED
-}
-
-func (m *ScreenDensity) GetDensityDpi() int32 {
- if x, ok := m.GetDensityOneof().(*ScreenDensity_DensityDpi); ok {
- return x.DensityDpi
- }
- return 0
-}
-
-// XXX_OneofWrappers is for the internal use of the proto package.
-func (*ScreenDensity) XXX_OneofWrappers() []interface{} {
- return []interface{}{
- (*ScreenDensity_DensityAlias_)(nil),
- (*ScreenDensity_DensityDpi)(nil),
- }
-}
-
// Wrapper message for `int32`.
//
// The JSON representation for `Int32Value` is JSON number.
type Int32Value struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The int32 value.
- Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}
-func (m *Int32Value) Reset() { *m = Int32Value{} }
-func (m *Int32Value) String() string { return proto.CompactTextString(m) }
-func (*Int32Value) ProtoMessage() {}
+func (x *Int32Value) Reset() {
+ *x = Int32Value{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Int32Value) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Int32Value) ProtoMessage() {}
+
+func (x *Int32Value) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Int32Value.ProtoReflect.Descriptor instead.
func (*Int32Value) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{5}
+ return file_targeting_proto_rawDescGZIP(), []int{5}
}
-func (m *Int32Value) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Int32Value.Unmarshal(m, b)
-}
-func (m *Int32Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Int32Value.Marshal(b, m, deterministic)
-}
-func (m *Int32Value) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Int32Value.Merge(m, src)
-}
-func (m *Int32Value) XXX_Size() int {
- return xxx_messageInfo_Int32Value.Size(m)
-}
-func (m *Int32Value) XXX_DiscardUnknown() {
- xxx_messageInfo_Int32Value.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Int32Value proto.InternalMessageInfo
-
-func (m *Int32Value) GetValue() int32 {
- if m != nil {
- return m.Value
+func (x *Int32Value) GetValue() int32 {
+ if x != nil {
+ return x.Value
}
return 0
}
type SdkVersion struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Inclusive.
- Min *Int32Value `protobuf:"bytes,1,opt,name=min,proto3" json:"min,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Min *Int32Value `protobuf:"bytes,1,opt,name=min,proto3" json:"min,omitempty"`
}
-func (m *SdkVersion) Reset() { *m = SdkVersion{} }
-func (m *SdkVersion) String() string { return proto.CompactTextString(m) }
-func (*SdkVersion) ProtoMessage() {}
+func (x *SdkVersion) Reset() {
+ *x = SdkVersion{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SdkVersion) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SdkVersion) ProtoMessage() {}
+
+func (x *SdkVersion) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SdkVersion.ProtoReflect.Descriptor instead.
func (*SdkVersion) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{6}
+ return file_targeting_proto_rawDescGZIP(), []int{6}
}
-func (m *SdkVersion) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SdkVersion.Unmarshal(m, b)
-}
-func (m *SdkVersion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SdkVersion.Marshal(b, m, deterministic)
-}
-func (m *SdkVersion) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SdkVersion.Merge(m, src)
-}
-func (m *SdkVersion) XXX_Size() int {
- return xxx_messageInfo_SdkVersion.Size(m)
-}
-func (m *SdkVersion) XXX_DiscardUnknown() {
- xxx_messageInfo_SdkVersion.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SdkVersion proto.InternalMessageInfo
-
-func (m *SdkVersion) GetMin() *Int32Value {
- if m != nil {
- return m.Min
+func (x *SdkVersion) GetMin() *Int32Value {
+ if x != nil {
+ return x.Min
}
return nil
}
type GraphicsApi struct {
- // Types that are valid to be assigned to ApiOneof:
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Types that are assignable to ApiOneof:
// *GraphicsApi_MinOpenGlVersion
// *GraphicsApi_MinVulkanVersion
- ApiOneof isGraphicsApi_ApiOneof `protobuf_oneof:"api_oneof"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ ApiOneof isGraphicsApi_ApiOneof `protobuf_oneof:"api_oneof"`
}
-func (m *GraphicsApi) Reset() { *m = GraphicsApi{} }
-func (m *GraphicsApi) String() string { return proto.CompactTextString(m) }
-func (*GraphicsApi) ProtoMessage() {}
+func (x *GraphicsApi) Reset() {
+ *x = GraphicsApi{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GraphicsApi) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GraphicsApi) ProtoMessage() {}
+
+func (x *GraphicsApi) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GraphicsApi.ProtoReflect.Descriptor instead.
func (*GraphicsApi) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{7}
+ return file_targeting_proto_rawDescGZIP(), []int{7}
}
-func (m *GraphicsApi) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_GraphicsApi.Unmarshal(m, b)
-}
-func (m *GraphicsApi) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_GraphicsApi.Marshal(b, m, deterministic)
-}
-func (m *GraphicsApi) XXX_Merge(src proto.Message) {
- xxx_messageInfo_GraphicsApi.Merge(m, src)
-}
-func (m *GraphicsApi) XXX_Size() int {
- return xxx_messageInfo_GraphicsApi.Size(m)
-}
-func (m *GraphicsApi) XXX_DiscardUnknown() {
- xxx_messageInfo_GraphicsApi.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GraphicsApi proto.InternalMessageInfo
-
-type isGraphicsApi_ApiOneof interface {
- isGraphicsApi_ApiOneof()
-}
-
-type GraphicsApi_MinOpenGlVersion struct {
- MinOpenGlVersion *OpenGlVersion `protobuf:"bytes,1,opt,name=min_open_gl_version,json=minOpenGlVersion,proto3,oneof"`
-}
-
-type GraphicsApi_MinVulkanVersion struct {
- MinVulkanVersion *VulkanVersion `protobuf:"bytes,2,opt,name=min_vulkan_version,json=minVulkanVersion,proto3,oneof"`
-}
-
-func (*GraphicsApi_MinOpenGlVersion) isGraphicsApi_ApiOneof() {}
-
-func (*GraphicsApi_MinVulkanVersion) isGraphicsApi_ApiOneof() {}
-
func (m *GraphicsApi) GetApiOneof() isGraphicsApi_ApiOneof {
if m != nil {
return m.ApiOneof
@@ -683,874 +812,1028 @@
return nil
}
-func (m *GraphicsApi) GetMinOpenGlVersion() *OpenGlVersion {
- if x, ok := m.GetApiOneof().(*GraphicsApi_MinOpenGlVersion); ok {
+func (x *GraphicsApi) GetMinOpenGlVersion() *OpenGlVersion {
+ if x, ok := x.GetApiOneof().(*GraphicsApi_MinOpenGlVersion); ok {
return x.MinOpenGlVersion
}
return nil
}
-func (m *GraphicsApi) GetMinVulkanVersion() *VulkanVersion {
- if x, ok := m.GetApiOneof().(*GraphicsApi_MinVulkanVersion); ok {
+func (x *GraphicsApi) GetMinVulkanVersion() *VulkanVersion {
+ if x, ok := x.GetApiOneof().(*GraphicsApi_MinVulkanVersion); ok {
return x.MinVulkanVersion
}
return nil
}
-// XXX_OneofWrappers is for the internal use of the proto package.
-func (*GraphicsApi) XXX_OneofWrappers() []interface{} {
- return []interface{}{
- (*GraphicsApi_MinOpenGlVersion)(nil),
- (*GraphicsApi_MinVulkanVersion)(nil),
+type isGraphicsApi_ApiOneof interface {
+ isGraphicsApi_ApiOneof()
+}
+
+type GraphicsApi_MinOpenGlVersion struct {
+ // Inclusive.
+ MinOpenGlVersion *OpenGlVersion `protobuf:"bytes,1,opt,name=min_open_gl_version,json=minOpenGlVersion,proto3,oneof"`
+}
+
+type GraphicsApi_MinVulkanVersion struct {
+ // Inclusive.
+ MinVulkanVersion *VulkanVersion `protobuf:"bytes,2,opt,name=min_vulkan_version,json=minVulkanVersion,proto3,oneof"`
+}
+
+func (*GraphicsApi_MinOpenGlVersion) isGraphicsApi_ApiOneof() {}
+
+func (*GraphicsApi_MinVulkanVersion) isGraphicsApi_ApiOneof() {}
+
+type VulkanVersion struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Major int32 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"` // VK_VERSION_MAJOR
+ Minor int32 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"` // VK_VERSION_MINOR
+}
+
+func (x *VulkanVersion) Reset() {
+ *x = VulkanVersion{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
}
}
-type VulkanVersion struct {
- Major int32 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
- Minor int32 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+func (x *VulkanVersion) String() string {
+ return protoimpl.X.MessageStringOf(x)
}
-func (m *VulkanVersion) Reset() { *m = VulkanVersion{} }
-func (m *VulkanVersion) String() string { return proto.CompactTextString(m) }
-func (*VulkanVersion) ProtoMessage() {}
+func (*VulkanVersion) ProtoMessage() {}
+
+func (x *VulkanVersion) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[8]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use VulkanVersion.ProtoReflect.Descriptor instead.
func (*VulkanVersion) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{8}
+ return file_targeting_proto_rawDescGZIP(), []int{8}
}
-func (m *VulkanVersion) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_VulkanVersion.Unmarshal(m, b)
-}
-func (m *VulkanVersion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_VulkanVersion.Marshal(b, m, deterministic)
-}
-func (m *VulkanVersion) XXX_Merge(src proto.Message) {
- xxx_messageInfo_VulkanVersion.Merge(m, src)
-}
-func (m *VulkanVersion) XXX_Size() int {
- return xxx_messageInfo_VulkanVersion.Size(m)
-}
-func (m *VulkanVersion) XXX_DiscardUnknown() {
- xxx_messageInfo_VulkanVersion.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_VulkanVersion proto.InternalMessageInfo
-
-func (m *VulkanVersion) GetMajor() int32 {
- if m != nil {
- return m.Major
+func (x *VulkanVersion) GetMajor() int32 {
+ if x != nil {
+ return x.Major
}
return 0
}
-func (m *VulkanVersion) GetMinor() int32 {
- if m != nil {
- return m.Minor
+func (x *VulkanVersion) GetMinor() int32 {
+ if x != nil {
+ return x.Minor
}
return 0
}
type OpenGlVersion struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// e.g. OpenGL ES 3.2 is represented as { major: 3, minor: 2 }
- Major int32 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"`
- Minor int32 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Major int32 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"` // GL_MAJOR_VERSION
+ Minor int32 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"` // GL_MINOR_VERSION
}
-func (m *OpenGlVersion) Reset() { *m = OpenGlVersion{} }
-func (m *OpenGlVersion) String() string { return proto.CompactTextString(m) }
-func (*OpenGlVersion) ProtoMessage() {}
+func (x *OpenGlVersion) Reset() {
+ *x = OpenGlVersion{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *OpenGlVersion) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OpenGlVersion) ProtoMessage() {}
+
+func (x *OpenGlVersion) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[9]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use OpenGlVersion.ProtoReflect.Descriptor instead.
func (*OpenGlVersion) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{9}
+ return file_targeting_proto_rawDescGZIP(), []int{9}
}
-func (m *OpenGlVersion) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_OpenGlVersion.Unmarshal(m, b)
-}
-func (m *OpenGlVersion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_OpenGlVersion.Marshal(b, m, deterministic)
-}
-func (m *OpenGlVersion) XXX_Merge(src proto.Message) {
- xxx_messageInfo_OpenGlVersion.Merge(m, src)
-}
-func (m *OpenGlVersion) XXX_Size() int {
- return xxx_messageInfo_OpenGlVersion.Size(m)
-}
-func (m *OpenGlVersion) XXX_DiscardUnknown() {
- xxx_messageInfo_OpenGlVersion.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_OpenGlVersion proto.InternalMessageInfo
-
-func (m *OpenGlVersion) GetMajor() int32 {
- if m != nil {
- return m.Major
+func (x *OpenGlVersion) GetMajor() int32 {
+ if x != nil {
+ return x.Major
}
return 0
}
-func (m *OpenGlVersion) GetMinor() int32 {
- if m != nil {
- return m.Minor
+func (x *OpenGlVersion) GetMinor() int32 {
+ if x != nil {
+ return x.Minor
}
return 0
}
type TextureCompressionFormat struct {
- Alias TextureCompressionFormat_TextureCompressionFormatAlias `protobuf:"varint,1,opt,name=alias,proto3,enum=android.bundle.TextureCompressionFormat_TextureCompressionFormatAlias" json:"alias,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Alias TextureCompressionFormat_TextureCompressionFormatAlias `protobuf:"varint,1,opt,name=alias,proto3,enum=android.bundle.TextureCompressionFormat_TextureCompressionFormatAlias" json:"alias,omitempty"`
}
-func (m *TextureCompressionFormat) Reset() { *m = TextureCompressionFormat{} }
-func (m *TextureCompressionFormat) String() string { return proto.CompactTextString(m) }
-func (*TextureCompressionFormat) ProtoMessage() {}
+func (x *TextureCompressionFormat) Reset() {
+ *x = TextureCompressionFormat{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[10]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *TextureCompressionFormat) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TextureCompressionFormat) ProtoMessage() {}
+
+func (x *TextureCompressionFormat) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[10]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use TextureCompressionFormat.ProtoReflect.Descriptor instead.
func (*TextureCompressionFormat) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{10}
+ return file_targeting_proto_rawDescGZIP(), []int{10}
}
-func (m *TextureCompressionFormat) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_TextureCompressionFormat.Unmarshal(m, b)
-}
-func (m *TextureCompressionFormat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_TextureCompressionFormat.Marshal(b, m, deterministic)
-}
-func (m *TextureCompressionFormat) XXX_Merge(src proto.Message) {
- xxx_messageInfo_TextureCompressionFormat.Merge(m, src)
-}
-func (m *TextureCompressionFormat) XXX_Size() int {
- return xxx_messageInfo_TextureCompressionFormat.Size(m)
-}
-func (m *TextureCompressionFormat) XXX_DiscardUnknown() {
- xxx_messageInfo_TextureCompressionFormat.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_TextureCompressionFormat proto.InternalMessageInfo
-
-func (m *TextureCompressionFormat) GetAlias() TextureCompressionFormat_TextureCompressionFormatAlias {
- if m != nil {
- return m.Alias
+func (x *TextureCompressionFormat) GetAlias() TextureCompressionFormat_TextureCompressionFormatAlias {
+ if x != nil {
+ return x.Alias
}
return TextureCompressionFormat_UNSPECIFIED_TEXTURE_COMPRESSION_FORMAT
}
type Abi struct {
- Alias Abi_AbiAlias `protobuf:"varint,1,opt,name=alias,proto3,enum=android.bundle.Abi_AbiAlias" json:"alias,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Alias Abi_AbiAlias `protobuf:"varint,1,opt,name=alias,proto3,enum=android.bundle.Abi_AbiAlias" json:"alias,omitempty"`
}
-func (m *Abi) Reset() { *m = Abi{} }
-func (m *Abi) String() string { return proto.CompactTextString(m) }
-func (*Abi) ProtoMessage() {}
+func (x *Abi) Reset() {
+ *x = Abi{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[11]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Abi) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Abi) ProtoMessage() {}
+
+func (x *Abi) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[11]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Abi.ProtoReflect.Descriptor instead.
func (*Abi) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{11}
+ return file_targeting_proto_rawDescGZIP(), []int{11}
}
-func (m *Abi) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Abi.Unmarshal(m, b)
-}
-func (m *Abi) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Abi.Marshal(b, m, deterministic)
-}
-func (m *Abi) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Abi.Merge(m, src)
-}
-func (m *Abi) XXX_Size() int {
- return xxx_messageInfo_Abi.Size(m)
-}
-func (m *Abi) XXX_DiscardUnknown() {
- xxx_messageInfo_Abi.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Abi proto.InternalMessageInfo
-
-func (m *Abi) GetAlias() Abi_AbiAlias {
- if m != nil {
- return m.Alias
+func (x *Abi) GetAlias() Abi_AbiAlias {
+ if x != nil {
+ return x.Alias
}
return Abi_UNSPECIFIED_CPU_ARCHITECTURE
}
type MultiAbi struct {
- Abi []*Abi `protobuf:"bytes,1,rep,name=abi,proto3" json:"abi,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Abi []*Abi `protobuf:"bytes,1,rep,name=abi,proto3" json:"abi,omitempty"`
}
-func (m *MultiAbi) Reset() { *m = MultiAbi{} }
-func (m *MultiAbi) String() string { return proto.CompactTextString(m) }
-func (*MultiAbi) ProtoMessage() {}
+func (x *MultiAbi) Reset() {
+ *x = MultiAbi{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MultiAbi) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MultiAbi) ProtoMessage() {}
+
+func (x *MultiAbi) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[12]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MultiAbi.ProtoReflect.Descriptor instead.
func (*MultiAbi) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{12}
+ return file_targeting_proto_rawDescGZIP(), []int{12}
}
-func (m *MultiAbi) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_MultiAbi.Unmarshal(m, b)
-}
-func (m *MultiAbi) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_MultiAbi.Marshal(b, m, deterministic)
-}
-func (m *MultiAbi) XXX_Merge(src proto.Message) {
- xxx_messageInfo_MultiAbi.Merge(m, src)
-}
-func (m *MultiAbi) XXX_Size() int {
- return xxx_messageInfo_MultiAbi.Size(m)
-}
-func (m *MultiAbi) XXX_DiscardUnknown() {
- xxx_messageInfo_MultiAbi.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_MultiAbi proto.InternalMessageInfo
-
-func (m *MultiAbi) GetAbi() []*Abi {
- if m != nil {
- return m.Abi
+func (x *MultiAbi) GetAbi() []*Abi {
+ if x != nil {
+ return x.Abi
}
return nil
}
type Sanitizer struct {
- Alias Sanitizer_SanitizerAlias `protobuf:"varint,1,opt,name=alias,proto3,enum=android.bundle.Sanitizer_SanitizerAlias" json:"alias,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Alias Sanitizer_SanitizerAlias `protobuf:"varint,1,opt,name=alias,proto3,enum=android.bundle.Sanitizer_SanitizerAlias" json:"alias,omitempty"`
}
-func (m *Sanitizer) Reset() { *m = Sanitizer{} }
-func (m *Sanitizer) String() string { return proto.CompactTextString(m) }
-func (*Sanitizer) ProtoMessage() {}
+func (x *Sanitizer) Reset() {
+ *x = Sanitizer{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Sanitizer) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Sanitizer) ProtoMessage() {}
+
+func (x *Sanitizer) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[13]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Sanitizer.ProtoReflect.Descriptor instead.
func (*Sanitizer) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{13}
+ return file_targeting_proto_rawDescGZIP(), []int{13}
}
-func (m *Sanitizer) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Sanitizer.Unmarshal(m, b)
-}
-func (m *Sanitizer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Sanitizer.Marshal(b, m, deterministic)
-}
-func (m *Sanitizer) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Sanitizer.Merge(m, src)
-}
-func (m *Sanitizer) XXX_Size() int {
- return xxx_messageInfo_Sanitizer.Size(m)
-}
-func (m *Sanitizer) XXX_DiscardUnknown() {
- xxx_messageInfo_Sanitizer.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Sanitizer proto.InternalMessageInfo
-
-func (m *Sanitizer) GetAlias() Sanitizer_SanitizerAlias {
- if m != nil {
- return m.Alias
+func (x *Sanitizer) GetAlias() Sanitizer_SanitizerAlias {
+ if x != nil {
+ return x.Alias
}
return Sanitizer_NONE
}
type DeviceFeature struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
FeatureName string `protobuf:"bytes,1,opt,name=feature_name,json=featureName,proto3" json:"feature_name,omitempty"`
// Equivalent of android:glEsVersion or android:version in <uses-feature>.
- FeatureVersion int32 `protobuf:"varint,2,opt,name=feature_version,json=featureVersion,proto3" json:"feature_version,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ FeatureVersion int32 `protobuf:"varint,2,opt,name=feature_version,json=featureVersion,proto3" json:"feature_version,omitempty"`
}
-func (m *DeviceFeature) Reset() { *m = DeviceFeature{} }
-func (m *DeviceFeature) String() string { return proto.CompactTextString(m) }
-func (*DeviceFeature) ProtoMessage() {}
+func (x *DeviceFeature) Reset() {
+ *x = DeviceFeature{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[14]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DeviceFeature) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeviceFeature) ProtoMessage() {}
+
+func (x *DeviceFeature) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[14]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeviceFeature.ProtoReflect.Descriptor instead.
func (*DeviceFeature) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{14}
+ return file_targeting_proto_rawDescGZIP(), []int{14}
}
-func (m *DeviceFeature) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_DeviceFeature.Unmarshal(m, b)
-}
-func (m *DeviceFeature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_DeviceFeature.Marshal(b, m, deterministic)
-}
-func (m *DeviceFeature) XXX_Merge(src proto.Message) {
- xxx_messageInfo_DeviceFeature.Merge(m, src)
-}
-func (m *DeviceFeature) XXX_Size() int {
- return xxx_messageInfo_DeviceFeature.Size(m)
-}
-func (m *DeviceFeature) XXX_DiscardUnknown() {
- xxx_messageInfo_DeviceFeature.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_DeviceFeature proto.InternalMessageInfo
-
-func (m *DeviceFeature) GetFeatureName() string {
- if m != nil {
- return m.FeatureName
+func (x *DeviceFeature) GetFeatureName() string {
+ if x != nil {
+ return x.FeatureName
}
return ""
}
-func (m *DeviceFeature) GetFeatureVersion() int32 {
- if m != nil {
- return m.FeatureVersion
+func (x *DeviceFeature) GetFeatureVersion() int32 {
+ if x != nil {
+ return x.FeatureVersion
}
return 0
}
// Targeting specific for directories under assets/.
type AssetsDirectoryTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Abi *AbiTargeting `protobuf:"bytes,1,opt,name=abi,proto3" json:"abi,omitempty"`
GraphicsApi *GraphicsApiTargeting `protobuf:"bytes,2,opt,name=graphics_api,json=graphicsApi,proto3" json:"graphics_api,omitempty"`
TextureCompressionFormat *TextureCompressionFormatTargeting `protobuf:"bytes,3,opt,name=texture_compression_format,json=textureCompressionFormat,proto3" json:"texture_compression_format,omitempty"`
Language *LanguageTargeting `protobuf:"bytes,4,opt,name=language,proto3" json:"language,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *AssetsDirectoryTargeting) Reset() { *m = AssetsDirectoryTargeting{} }
-func (m *AssetsDirectoryTargeting) String() string { return proto.CompactTextString(m) }
-func (*AssetsDirectoryTargeting) ProtoMessage() {}
+func (x *AssetsDirectoryTargeting) Reset() {
+ *x = AssetsDirectoryTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[15]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AssetsDirectoryTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AssetsDirectoryTargeting) ProtoMessage() {}
+
+func (x *AssetsDirectoryTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[15]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AssetsDirectoryTargeting.ProtoReflect.Descriptor instead.
func (*AssetsDirectoryTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{15}
+ return file_targeting_proto_rawDescGZIP(), []int{15}
}
-func (m *AssetsDirectoryTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_AssetsDirectoryTargeting.Unmarshal(m, b)
-}
-func (m *AssetsDirectoryTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_AssetsDirectoryTargeting.Marshal(b, m, deterministic)
-}
-func (m *AssetsDirectoryTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_AssetsDirectoryTargeting.Merge(m, src)
-}
-func (m *AssetsDirectoryTargeting) XXX_Size() int {
- return xxx_messageInfo_AssetsDirectoryTargeting.Size(m)
-}
-func (m *AssetsDirectoryTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_AssetsDirectoryTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AssetsDirectoryTargeting proto.InternalMessageInfo
-
-func (m *AssetsDirectoryTargeting) GetAbi() *AbiTargeting {
- if m != nil {
- return m.Abi
+func (x *AssetsDirectoryTargeting) GetAbi() *AbiTargeting {
+ if x != nil {
+ return x.Abi
}
return nil
}
-func (m *AssetsDirectoryTargeting) GetGraphicsApi() *GraphicsApiTargeting {
- if m != nil {
- return m.GraphicsApi
+func (x *AssetsDirectoryTargeting) GetGraphicsApi() *GraphicsApiTargeting {
+ if x != nil {
+ return x.GraphicsApi
}
return nil
}
-func (m *AssetsDirectoryTargeting) GetTextureCompressionFormat() *TextureCompressionFormatTargeting {
- if m != nil {
- return m.TextureCompressionFormat
+func (x *AssetsDirectoryTargeting) GetTextureCompressionFormat() *TextureCompressionFormatTargeting {
+ if x != nil {
+ return x.TextureCompressionFormat
}
return nil
}
-func (m *AssetsDirectoryTargeting) GetLanguage() *LanguageTargeting {
- if m != nil {
- return m.Language
+func (x *AssetsDirectoryTargeting) GetLanguage() *LanguageTargeting {
+ if x != nil {
+ return x.Language
}
return nil
}
// Targeting specific for directories under lib/.
type NativeDirectoryTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Abi *Abi `protobuf:"bytes,1,opt,name=abi,proto3" json:"abi,omitempty"`
GraphicsApi *GraphicsApi `protobuf:"bytes,2,opt,name=graphics_api,json=graphicsApi,proto3" json:"graphics_api,omitempty"`
TextureCompressionFormat *TextureCompressionFormat `protobuf:"bytes,3,opt,name=texture_compression_format,json=textureCompressionFormat,proto3" json:"texture_compression_format,omitempty"`
Sanitizer *Sanitizer `protobuf:"bytes,4,opt,name=sanitizer,proto3" json:"sanitizer,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *NativeDirectoryTargeting) Reset() { *m = NativeDirectoryTargeting{} }
-func (m *NativeDirectoryTargeting) String() string { return proto.CompactTextString(m) }
-func (*NativeDirectoryTargeting) ProtoMessage() {}
+func (x *NativeDirectoryTargeting) Reset() {
+ *x = NativeDirectoryTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[16]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *NativeDirectoryTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*NativeDirectoryTargeting) ProtoMessage() {}
+
+func (x *NativeDirectoryTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[16]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use NativeDirectoryTargeting.ProtoReflect.Descriptor instead.
func (*NativeDirectoryTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{16}
+ return file_targeting_proto_rawDescGZIP(), []int{16}
}
-func (m *NativeDirectoryTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_NativeDirectoryTargeting.Unmarshal(m, b)
-}
-func (m *NativeDirectoryTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_NativeDirectoryTargeting.Marshal(b, m, deterministic)
-}
-func (m *NativeDirectoryTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_NativeDirectoryTargeting.Merge(m, src)
-}
-func (m *NativeDirectoryTargeting) XXX_Size() int {
- return xxx_messageInfo_NativeDirectoryTargeting.Size(m)
-}
-func (m *NativeDirectoryTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_NativeDirectoryTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_NativeDirectoryTargeting proto.InternalMessageInfo
-
-func (m *NativeDirectoryTargeting) GetAbi() *Abi {
- if m != nil {
- return m.Abi
+func (x *NativeDirectoryTargeting) GetAbi() *Abi {
+ if x != nil {
+ return x.Abi
}
return nil
}
-func (m *NativeDirectoryTargeting) GetGraphicsApi() *GraphicsApi {
- if m != nil {
- return m.GraphicsApi
+func (x *NativeDirectoryTargeting) GetGraphicsApi() *GraphicsApi {
+ if x != nil {
+ return x.GraphicsApi
}
return nil
}
-func (m *NativeDirectoryTargeting) GetTextureCompressionFormat() *TextureCompressionFormat {
- if m != nil {
- return m.TextureCompressionFormat
+func (x *NativeDirectoryTargeting) GetTextureCompressionFormat() *TextureCompressionFormat {
+ if x != nil {
+ return x.TextureCompressionFormat
}
return nil
}
-func (m *NativeDirectoryTargeting) GetSanitizer() *Sanitizer {
- if m != nil {
- return m.Sanitizer
+func (x *NativeDirectoryTargeting) GetSanitizer() *Sanitizer {
+ if x != nil {
+ return x.Sanitizer
}
return nil
}
// Targeting specific for image files under apex/.
type ApexImageTargeting struct {
- MultiAbi *MultiAbiTargeting `protobuf:"bytes,1,opt,name=multi_abi,json=multiAbi,proto3" json:"multi_abi,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ MultiAbi *MultiAbiTargeting `protobuf:"bytes,1,opt,name=multi_abi,json=multiAbi,proto3" json:"multi_abi,omitempty"`
}
-func (m *ApexImageTargeting) Reset() { *m = ApexImageTargeting{} }
-func (m *ApexImageTargeting) String() string { return proto.CompactTextString(m) }
-func (*ApexImageTargeting) ProtoMessage() {}
+func (x *ApexImageTargeting) Reset() {
+ *x = ApexImageTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[17]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ApexImageTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ApexImageTargeting) ProtoMessage() {}
+
+func (x *ApexImageTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[17]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ApexImageTargeting.ProtoReflect.Descriptor instead.
func (*ApexImageTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{17}
+ return file_targeting_proto_rawDescGZIP(), []int{17}
}
-func (m *ApexImageTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ApexImageTargeting.Unmarshal(m, b)
-}
-func (m *ApexImageTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ApexImageTargeting.Marshal(b, m, deterministic)
-}
-func (m *ApexImageTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ApexImageTargeting.Merge(m, src)
-}
-func (m *ApexImageTargeting) XXX_Size() int {
- return xxx_messageInfo_ApexImageTargeting.Size(m)
-}
-func (m *ApexImageTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_ApexImageTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ApexImageTargeting proto.InternalMessageInfo
-
-func (m *ApexImageTargeting) GetMultiAbi() *MultiAbiTargeting {
- if m != nil {
- return m.MultiAbi
+func (x *ApexImageTargeting) GetMultiAbi() *MultiAbiTargeting {
+ if x != nil {
+ return x.MultiAbi
}
return nil
}
type AbiTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Value []*Abi `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
// Targeting of other sibling directories that were in the Bundle.
// For master splits this is targeting of other master splits.
- Alternatives []*Abi `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Alternatives []*Abi `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
}
-func (m *AbiTargeting) Reset() { *m = AbiTargeting{} }
-func (m *AbiTargeting) String() string { return proto.CompactTextString(m) }
-func (*AbiTargeting) ProtoMessage() {}
+func (x *AbiTargeting) Reset() {
+ *x = AbiTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[18]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AbiTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AbiTargeting) ProtoMessage() {}
+
+func (x *AbiTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[18]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AbiTargeting.ProtoReflect.Descriptor instead.
func (*AbiTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{18}
+ return file_targeting_proto_rawDescGZIP(), []int{18}
}
-func (m *AbiTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_AbiTargeting.Unmarshal(m, b)
-}
-func (m *AbiTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_AbiTargeting.Marshal(b, m, deterministic)
-}
-func (m *AbiTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_AbiTargeting.Merge(m, src)
-}
-func (m *AbiTargeting) XXX_Size() int {
- return xxx_messageInfo_AbiTargeting.Size(m)
-}
-func (m *AbiTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_AbiTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_AbiTargeting proto.InternalMessageInfo
-
-func (m *AbiTargeting) GetValue() []*Abi {
- if m != nil {
- return m.Value
+func (x *AbiTargeting) GetValue() []*Abi {
+ if x != nil {
+ return x.Value
}
return nil
}
-func (m *AbiTargeting) GetAlternatives() []*Abi {
- if m != nil {
- return m.Alternatives
+func (x *AbiTargeting) GetAlternatives() []*Abi {
+ if x != nil {
+ return x.Alternatives
}
return nil
}
type MultiAbiTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Value []*MultiAbi `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
// Targeting of other sibling directories that were in the Bundle.
// For master splits this is targeting of other master splits.
- Alternatives []*MultiAbi `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Alternatives []*MultiAbi `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
}
-func (m *MultiAbiTargeting) Reset() { *m = MultiAbiTargeting{} }
-func (m *MultiAbiTargeting) String() string { return proto.CompactTextString(m) }
-func (*MultiAbiTargeting) ProtoMessage() {}
+func (x *MultiAbiTargeting) Reset() {
+ *x = MultiAbiTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[19]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MultiAbiTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MultiAbiTargeting) ProtoMessage() {}
+
+func (x *MultiAbiTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[19]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MultiAbiTargeting.ProtoReflect.Descriptor instead.
func (*MultiAbiTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{19}
+ return file_targeting_proto_rawDescGZIP(), []int{19}
}
-func (m *MultiAbiTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_MultiAbiTargeting.Unmarshal(m, b)
-}
-func (m *MultiAbiTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_MultiAbiTargeting.Marshal(b, m, deterministic)
-}
-func (m *MultiAbiTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_MultiAbiTargeting.Merge(m, src)
-}
-func (m *MultiAbiTargeting) XXX_Size() int {
- return xxx_messageInfo_MultiAbiTargeting.Size(m)
-}
-func (m *MultiAbiTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_MultiAbiTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_MultiAbiTargeting proto.InternalMessageInfo
-
-func (m *MultiAbiTargeting) GetValue() []*MultiAbi {
- if m != nil {
- return m.Value
+func (x *MultiAbiTargeting) GetValue() []*MultiAbi {
+ if x != nil {
+ return x.Value
}
return nil
}
-func (m *MultiAbiTargeting) GetAlternatives() []*MultiAbi {
- if m != nil {
- return m.Alternatives
+func (x *MultiAbiTargeting) GetAlternatives() []*MultiAbi {
+ if x != nil {
+ return x.Alternatives
}
return nil
}
type ScreenDensityTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Value []*ScreenDensity `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
// Targeting of other sibling directories that were in the Bundle.
// For master splits this is targeting of other master splits.
- Alternatives []*ScreenDensity `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Alternatives []*ScreenDensity `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
}
-func (m *ScreenDensityTargeting) Reset() { *m = ScreenDensityTargeting{} }
-func (m *ScreenDensityTargeting) String() string { return proto.CompactTextString(m) }
-func (*ScreenDensityTargeting) ProtoMessage() {}
+func (x *ScreenDensityTargeting) Reset() {
+ *x = ScreenDensityTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[20]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ScreenDensityTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ScreenDensityTargeting) ProtoMessage() {}
+
+func (x *ScreenDensityTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[20]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ScreenDensityTargeting.ProtoReflect.Descriptor instead.
func (*ScreenDensityTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{20}
+ return file_targeting_proto_rawDescGZIP(), []int{20}
}
-func (m *ScreenDensityTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ScreenDensityTargeting.Unmarshal(m, b)
-}
-func (m *ScreenDensityTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ScreenDensityTargeting.Marshal(b, m, deterministic)
-}
-func (m *ScreenDensityTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ScreenDensityTargeting.Merge(m, src)
-}
-func (m *ScreenDensityTargeting) XXX_Size() int {
- return xxx_messageInfo_ScreenDensityTargeting.Size(m)
-}
-func (m *ScreenDensityTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_ScreenDensityTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ScreenDensityTargeting proto.InternalMessageInfo
-
-func (m *ScreenDensityTargeting) GetValue() []*ScreenDensity {
- if m != nil {
- return m.Value
+func (x *ScreenDensityTargeting) GetValue() []*ScreenDensity {
+ if x != nil {
+ return x.Value
}
return nil
}
-func (m *ScreenDensityTargeting) GetAlternatives() []*ScreenDensity {
- if m != nil {
- return m.Alternatives
+func (x *ScreenDensityTargeting) GetAlternatives() []*ScreenDensity {
+ if x != nil {
+ return x.Alternatives
}
return nil
}
type LanguageTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// ISO-639: 2 or 3 letter language code.
Value []string `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
// Targeting of other sibling directories that were in the Bundle.
// For master splits this is targeting of other master splits.
- Alternatives []string `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Alternatives []string `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
}
-func (m *LanguageTargeting) Reset() { *m = LanguageTargeting{} }
-func (m *LanguageTargeting) String() string { return proto.CompactTextString(m) }
-func (*LanguageTargeting) ProtoMessage() {}
+func (x *LanguageTargeting) Reset() {
+ *x = LanguageTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[21]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *LanguageTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LanguageTargeting) ProtoMessage() {}
+
+func (x *LanguageTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[21]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use LanguageTargeting.ProtoReflect.Descriptor instead.
func (*LanguageTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{21}
+ return file_targeting_proto_rawDescGZIP(), []int{21}
}
-func (m *LanguageTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_LanguageTargeting.Unmarshal(m, b)
-}
-func (m *LanguageTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_LanguageTargeting.Marshal(b, m, deterministic)
-}
-func (m *LanguageTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_LanguageTargeting.Merge(m, src)
-}
-func (m *LanguageTargeting) XXX_Size() int {
- return xxx_messageInfo_LanguageTargeting.Size(m)
-}
-func (m *LanguageTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_LanguageTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_LanguageTargeting proto.InternalMessageInfo
-
-func (m *LanguageTargeting) GetValue() []string {
- if m != nil {
- return m.Value
+func (x *LanguageTargeting) GetValue() []string {
+ if x != nil {
+ return x.Value
}
return nil
}
-func (m *LanguageTargeting) GetAlternatives() []string {
- if m != nil {
- return m.Alternatives
+func (x *LanguageTargeting) GetAlternatives() []string {
+ if x != nil {
+ return x.Alternatives
}
return nil
}
type GraphicsApiTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Value []*GraphicsApi `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
// Targeting of other sibling directories that were in the Bundle.
// For master splits this is targeting of other master splits.
- Alternatives []*GraphicsApi `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Alternatives []*GraphicsApi `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
}
-func (m *GraphicsApiTargeting) Reset() { *m = GraphicsApiTargeting{} }
-func (m *GraphicsApiTargeting) String() string { return proto.CompactTextString(m) }
-func (*GraphicsApiTargeting) ProtoMessage() {}
+func (x *GraphicsApiTargeting) Reset() {
+ *x = GraphicsApiTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[22]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GraphicsApiTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GraphicsApiTargeting) ProtoMessage() {}
+
+func (x *GraphicsApiTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[22]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GraphicsApiTargeting.ProtoReflect.Descriptor instead.
func (*GraphicsApiTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{22}
+ return file_targeting_proto_rawDescGZIP(), []int{22}
}
-func (m *GraphicsApiTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_GraphicsApiTargeting.Unmarshal(m, b)
-}
-func (m *GraphicsApiTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_GraphicsApiTargeting.Marshal(b, m, deterministic)
-}
-func (m *GraphicsApiTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_GraphicsApiTargeting.Merge(m, src)
-}
-func (m *GraphicsApiTargeting) XXX_Size() int {
- return xxx_messageInfo_GraphicsApiTargeting.Size(m)
-}
-func (m *GraphicsApiTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_GraphicsApiTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_GraphicsApiTargeting proto.InternalMessageInfo
-
-func (m *GraphicsApiTargeting) GetValue() []*GraphicsApi {
- if m != nil {
- return m.Value
+func (x *GraphicsApiTargeting) GetValue() []*GraphicsApi {
+ if x != nil {
+ return x.Value
}
return nil
}
-func (m *GraphicsApiTargeting) GetAlternatives() []*GraphicsApi {
- if m != nil {
- return m.Alternatives
+func (x *GraphicsApiTargeting) GetAlternatives() []*GraphicsApi {
+ if x != nil {
+ return x.Alternatives
}
return nil
}
type SdkVersionTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Value []*SdkVersion `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
// Targeting of other sibling directories that were in the Bundle.
// For master splits this is targeting of other master splits.
- Alternatives []*SdkVersion `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Alternatives []*SdkVersion `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
}
-func (m *SdkVersionTargeting) Reset() { *m = SdkVersionTargeting{} }
-func (m *SdkVersionTargeting) String() string { return proto.CompactTextString(m) }
-func (*SdkVersionTargeting) ProtoMessage() {}
+func (x *SdkVersionTargeting) Reset() {
+ *x = SdkVersionTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[23]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SdkVersionTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SdkVersionTargeting) ProtoMessage() {}
+
+func (x *SdkVersionTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[23]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SdkVersionTargeting.ProtoReflect.Descriptor instead.
func (*SdkVersionTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{23}
+ return file_targeting_proto_rawDescGZIP(), []int{23}
}
-func (m *SdkVersionTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SdkVersionTargeting.Unmarshal(m, b)
-}
-func (m *SdkVersionTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SdkVersionTargeting.Marshal(b, m, deterministic)
-}
-func (m *SdkVersionTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SdkVersionTargeting.Merge(m, src)
-}
-func (m *SdkVersionTargeting) XXX_Size() int {
- return xxx_messageInfo_SdkVersionTargeting.Size(m)
-}
-func (m *SdkVersionTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_SdkVersionTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SdkVersionTargeting proto.InternalMessageInfo
-
-func (m *SdkVersionTargeting) GetValue() []*SdkVersion {
- if m != nil {
- return m.Value
+func (x *SdkVersionTargeting) GetValue() []*SdkVersion {
+ if x != nil {
+ return x.Value
}
return nil
}
-func (m *SdkVersionTargeting) GetAlternatives() []*SdkVersion {
- if m != nil {
- return m.Alternatives
+func (x *SdkVersionTargeting) GetAlternatives() []*SdkVersion {
+ if x != nil {
+ return x.Alternatives
}
return nil
}
type TextureCompressionFormatTargeting struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
Value []*TextureCompressionFormat `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
// Targeting of other sibling directories that were in the Bundle.
// For master splits this is targeting of other master splits.
- Alternatives []*TextureCompressionFormat `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Alternatives []*TextureCompressionFormat `protobuf:"bytes,2,rep,name=alternatives,proto3" json:"alternatives,omitempty"`
}
-func (m *TextureCompressionFormatTargeting) Reset() { *m = TextureCompressionFormatTargeting{} }
-func (m *TextureCompressionFormatTargeting) String() string { return proto.CompactTextString(m) }
-func (*TextureCompressionFormatTargeting) ProtoMessage() {}
+func (x *TextureCompressionFormatTargeting) Reset() {
+ *x = TextureCompressionFormatTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[24]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *TextureCompressionFormatTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TextureCompressionFormatTargeting) ProtoMessage() {}
+
+func (x *TextureCompressionFormatTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[24]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use TextureCompressionFormatTargeting.ProtoReflect.Descriptor instead.
func (*TextureCompressionFormatTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{24}
+ return file_targeting_proto_rawDescGZIP(), []int{24}
}
-func (m *TextureCompressionFormatTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_TextureCompressionFormatTargeting.Unmarshal(m, b)
-}
-func (m *TextureCompressionFormatTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_TextureCompressionFormatTargeting.Marshal(b, m, deterministic)
-}
-func (m *TextureCompressionFormatTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_TextureCompressionFormatTargeting.Merge(m, src)
-}
-func (m *TextureCompressionFormatTargeting) XXX_Size() int {
- return xxx_messageInfo_TextureCompressionFormatTargeting.Size(m)
-}
-func (m *TextureCompressionFormatTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_TextureCompressionFormatTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_TextureCompressionFormatTargeting proto.InternalMessageInfo
-
-func (m *TextureCompressionFormatTargeting) GetValue() []*TextureCompressionFormat {
- if m != nil {
- return m.Value
+func (x *TextureCompressionFormatTargeting) GetValue() []*TextureCompressionFormat {
+ if x != nil {
+ return x.Value
}
return nil
}
-func (m *TextureCompressionFormatTargeting) GetAlternatives() []*TextureCompressionFormat {
- if m != nil {
- return m.Alternatives
+func (x *TextureCompressionFormatTargeting) GetAlternatives() []*TextureCompressionFormat {
+ if x != nil {
+ return x.Alternatives
}
return nil
}
type SanitizerTargeting struct {
- Value []*Sanitizer `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Value []*Sanitizer `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
}
-func (m *SanitizerTargeting) Reset() { *m = SanitizerTargeting{} }
-func (m *SanitizerTargeting) String() string { return proto.CompactTextString(m) }
-func (*SanitizerTargeting) ProtoMessage() {}
+func (x *SanitizerTargeting) Reset() {
+ *x = SanitizerTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[25]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SanitizerTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SanitizerTargeting) ProtoMessage() {}
+
+func (x *SanitizerTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[25]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SanitizerTargeting.ProtoReflect.Descriptor instead.
func (*SanitizerTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{25}
+ return file_targeting_proto_rawDescGZIP(), []int{25}
}
-func (m *SanitizerTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SanitizerTargeting.Unmarshal(m, b)
-}
-func (m *SanitizerTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SanitizerTargeting.Marshal(b, m, deterministic)
-}
-func (m *SanitizerTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SanitizerTargeting.Merge(m, src)
-}
-func (m *SanitizerTargeting) XXX_Size() int {
- return xxx_messageInfo_SanitizerTargeting.Size(m)
-}
-func (m *SanitizerTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_SanitizerTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SanitizerTargeting proto.InternalMessageInfo
-
-func (m *SanitizerTargeting) GetValue() []*Sanitizer {
- if m != nil {
- return m.Value
+func (x *SanitizerTargeting) GetValue() []*Sanitizer {
+ if x != nil {
+ return x.Value
}
return nil
}
@@ -1559,176 +1842,829 @@
// the DeviceFeatureTargeting represents only one device feature to retain
// that convention.
type DeviceFeatureTargeting struct {
- RequiredFeature *DeviceFeature `protobuf:"bytes,1,opt,name=required_feature,json=requiredFeature,proto3" json:"required_feature,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ RequiredFeature *DeviceFeature `protobuf:"bytes,1,opt,name=required_feature,json=requiredFeature,proto3" json:"required_feature,omitempty"`
}
-func (m *DeviceFeatureTargeting) Reset() { *m = DeviceFeatureTargeting{} }
-func (m *DeviceFeatureTargeting) String() string { return proto.CompactTextString(m) }
-func (*DeviceFeatureTargeting) ProtoMessage() {}
+func (x *DeviceFeatureTargeting) Reset() {
+ *x = DeviceFeatureTargeting{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_targeting_proto_msgTypes[26]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DeviceFeatureTargeting) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DeviceFeatureTargeting) ProtoMessage() {}
+
+func (x *DeviceFeatureTargeting) ProtoReflect() protoreflect.Message {
+ mi := &file_targeting_proto_msgTypes[26]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DeviceFeatureTargeting.ProtoReflect.Descriptor instead.
func (*DeviceFeatureTargeting) Descriptor() ([]byte, []int) {
- return fileDescriptor_df45b505afdf471e, []int{26}
+ return file_targeting_proto_rawDescGZIP(), []int{26}
}
-func (m *DeviceFeatureTargeting) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_DeviceFeatureTargeting.Unmarshal(m, b)
-}
-func (m *DeviceFeatureTargeting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_DeviceFeatureTargeting.Marshal(b, m, deterministic)
-}
-func (m *DeviceFeatureTargeting) XXX_Merge(src proto.Message) {
- xxx_messageInfo_DeviceFeatureTargeting.Merge(m, src)
-}
-func (m *DeviceFeatureTargeting) XXX_Size() int {
- return xxx_messageInfo_DeviceFeatureTargeting.Size(m)
-}
-func (m *DeviceFeatureTargeting) XXX_DiscardUnknown() {
- xxx_messageInfo_DeviceFeatureTargeting.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_DeviceFeatureTargeting proto.InternalMessageInfo
-
-func (m *DeviceFeatureTargeting) GetRequiredFeature() *DeviceFeature {
- if m != nil {
- return m.RequiredFeature
+func (x *DeviceFeatureTargeting) GetRequiredFeature() *DeviceFeature {
+ if x != nil {
+ return x.RequiredFeature
}
return nil
}
-func init() {
- proto.RegisterEnum("android.bundle.ScreenDensity_DensityAlias", ScreenDensity_DensityAlias_name, ScreenDensity_DensityAlias_value)
- proto.RegisterEnum("android.bundle.TextureCompressionFormat_TextureCompressionFormatAlias", TextureCompressionFormat_TextureCompressionFormatAlias_name, TextureCompressionFormat_TextureCompressionFormatAlias_value)
- proto.RegisterEnum("android.bundle.Abi_AbiAlias", Abi_AbiAlias_name, Abi_AbiAlias_value)
- proto.RegisterEnum("android.bundle.Sanitizer_SanitizerAlias", Sanitizer_SanitizerAlias_name, Sanitizer_SanitizerAlias_value)
- proto.RegisterType((*VariantTargeting)(nil), "android.bundle.VariantTargeting")
- proto.RegisterType((*ApkTargeting)(nil), "android.bundle.ApkTargeting")
- proto.RegisterType((*ModuleTargeting)(nil), "android.bundle.ModuleTargeting")
- proto.RegisterType((*UserCountriesTargeting)(nil), "android.bundle.UserCountriesTargeting")
- proto.RegisterType((*ScreenDensity)(nil), "android.bundle.ScreenDensity")
- proto.RegisterType((*Int32Value)(nil), "android.bundle.Int32Value")
- proto.RegisterType((*SdkVersion)(nil), "android.bundle.SdkVersion")
- proto.RegisterType((*GraphicsApi)(nil), "android.bundle.GraphicsApi")
- proto.RegisterType((*VulkanVersion)(nil), "android.bundle.VulkanVersion")
- proto.RegisterType((*OpenGlVersion)(nil), "android.bundle.OpenGlVersion")
- proto.RegisterType((*TextureCompressionFormat)(nil), "android.bundle.TextureCompressionFormat")
- proto.RegisterType((*Abi)(nil), "android.bundle.Abi")
- proto.RegisterType((*MultiAbi)(nil), "android.bundle.MultiAbi")
- proto.RegisterType((*Sanitizer)(nil), "android.bundle.Sanitizer")
- proto.RegisterType((*DeviceFeature)(nil), "android.bundle.DeviceFeature")
- proto.RegisterType((*AssetsDirectoryTargeting)(nil), "android.bundle.AssetsDirectoryTargeting")
- proto.RegisterType((*NativeDirectoryTargeting)(nil), "android.bundle.NativeDirectoryTargeting")
- proto.RegisterType((*ApexImageTargeting)(nil), "android.bundle.ApexImageTargeting")
- proto.RegisterType((*AbiTargeting)(nil), "android.bundle.AbiTargeting")
- proto.RegisterType((*MultiAbiTargeting)(nil), "android.bundle.MultiAbiTargeting")
- proto.RegisterType((*ScreenDensityTargeting)(nil), "android.bundle.ScreenDensityTargeting")
- proto.RegisterType((*LanguageTargeting)(nil), "android.bundle.LanguageTargeting")
- proto.RegisterType((*GraphicsApiTargeting)(nil), "android.bundle.GraphicsApiTargeting")
- proto.RegisterType((*SdkVersionTargeting)(nil), "android.bundle.SdkVersionTargeting")
- proto.RegisterType((*TextureCompressionFormatTargeting)(nil), "android.bundle.TextureCompressionFormatTargeting")
- proto.RegisterType((*SanitizerTargeting)(nil), "android.bundle.SanitizerTargeting")
- proto.RegisterType((*DeviceFeatureTargeting)(nil), "android.bundle.DeviceFeatureTargeting")
+var File_targeting_proto protoreflect.FileDescriptor
+
+var file_targeting_proto_rawDesc = []byte{
+ 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x12, 0x0e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x22, 0xe8, 0x03, 0x0a, 0x10, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x57, 0x0a, 0x15, 0x73, 0x64, 0x6b, 0x5f, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x73, 0x64, 0x6b, 0x56,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12,
+ 0x41, 0x0a, 0x0d, 0x61, 0x62, 0x69, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x61, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69,
+ 0x6e, 0x67, 0x12, 0x60, 0x0a, 0x18, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x65, 0x6e,
+ 0x73, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62,
+ 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x44, 0x65, 0x6e, 0x73,
+ 0x69, 0x74, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x16, 0x73, 0x63,
+ 0x72, 0x65, 0x65, 0x6e, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x69, 0x6e, 0x67, 0x12, 0x51, 0x0a, 0x13, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x61, 0x62,
+ 0x69, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64,
+ 0x6c, 0x65, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x69, 0x6e, 0x67, 0x52, 0x11, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x62, 0x69, 0x54, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x82, 0x01, 0x0a, 0x24, 0x74, 0x65, 0x78, 0x74,
+ 0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
+ 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43,
+ 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+ 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x21, 0x74, 0x65, 0x78, 0x74, 0x75,
+ 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72,
+ 0x6d, 0x61, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x22, 0xe7, 0x05, 0x0a,
+ 0x0c, 0x41, 0x70, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x41, 0x0a,
+ 0x0d, 0x61, 0x62, 0x69, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62,
+ 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69,
+ 0x6e, 0x67, 0x52, 0x0c, 0x61, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67,
+ 0x12, 0x5a, 0x0a, 0x16, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x5f, 0x61, 0x70, 0x69,
+ 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x24, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x41, 0x70, 0x69, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x14, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73,
+ 0x41, 0x70, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x50, 0x0a, 0x12,
+ 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69,
+ 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61,
+ 0x67, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x11, 0x6c, 0x61, 0x6e,
+ 0x67, 0x75, 0x61, 0x67, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x60,
+ 0x0a, 0x18, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x5f, 0x64, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79,
+ 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x54,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x16, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e,
+ 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67,
+ 0x12, 0x57, 0x0a, 0x15, 0x73, 0x64, 0x6b, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
+ 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x2e, 0x53, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x82, 0x01, 0x0a, 0x24, 0x74, 0x65,
+ 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69,
+ 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72,
+ 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d,
+ 0x61, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x21, 0x74, 0x65, 0x78,
+ 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46,
+ 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x51,
+ 0x0a, 0x13, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f, 0x61, 0x62, 0x69, 0x5f, 0x74, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4d, 0x75, 0x6c,
+ 0x74, 0x69, 0x41, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x11,
+ 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e,
+ 0x67, 0x12, 0x53, 0x0a, 0x13, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72, 0x5f, 0x74,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
+ 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e,
+ 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69,
+ 0x6e, 0x67, 0x52, 0x12, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x22, 0xae, 0x02, 0x0a, 0x0f, 0x4d, 0x6f, 0x64, 0x75, 0x6c,
+ 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x57, 0x0a, 0x15, 0x73, 0x64,
+ 0x6b, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
+ 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x64, 0x6b, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x13,
+ 0x73, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
+ 0x69, 0x6e, 0x67, 0x12, 0x60, 0x0a, 0x18, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x66, 0x65,
+ 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x18,
+ 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x46, 0x65, 0x61,
+ 0x74, 0x75, 0x72, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x16, 0x64,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x54, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x60, 0x0a, 0x18, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x63, 0x6f,
+ 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e,
+ 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x75,
+ 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52,
+ 0x16, 0x75, 0x73, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x54, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x57, 0x0a, 0x16, 0x55, 0x73, 0x65, 0x72, 0x43,
+ 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e,
+ 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64,
+ 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72,
+ 0x79, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65,
+ 0x22, 0x97, 0x02, 0x0a, 0x0d, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x44, 0x65, 0x6e, 0x73, 0x69,
+ 0x74, 0x79, 0x12, 0x51, 0x0a, 0x0d, 0x64, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x6c,
+ 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65,
+ 0x6e, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x2e, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79,
+ 0x41, 0x6c, 0x69, 0x61, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79,
+ 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x21, 0x0a, 0x0b, 0x64, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79,
+ 0x5f, 0x64, 0x70, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0a, 0x64, 0x65,
+ 0x6e, 0x73, 0x69, 0x74, 0x79, 0x44, 0x70, 0x69, 0x22, 0x7f, 0x0a, 0x0c, 0x44, 0x65, 0x6e, 0x73,
+ 0x69, 0x74, 0x79, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x17, 0x0a, 0x13, 0x44, 0x45, 0x4e, 0x53,
+ 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+ 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4e, 0x4f, 0x44, 0x50, 0x49, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04,
+ 0x4c, 0x44, 0x50, 0x49, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x44, 0x50, 0x49, 0x10, 0x03,
+ 0x12, 0x09, 0x0a, 0x05, 0x54, 0x56, 0x44, 0x50, 0x49, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x48,
+ 0x44, 0x50, 0x49, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x58, 0x48, 0x44, 0x50, 0x49, 0x10, 0x06,
+ 0x12, 0x0a, 0x0a, 0x06, 0x58, 0x58, 0x48, 0x44, 0x50, 0x49, 0x10, 0x07, 0x12, 0x0b, 0x0a, 0x07,
+ 0x58, 0x58, 0x58, 0x48, 0x44, 0x50, 0x49, 0x10, 0x08, 0x42, 0x0f, 0x0a, 0x0d, 0x64, 0x65, 0x6e,
+ 0x73, 0x69, 0x74, 0x79, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x22, 0x0a, 0x0a, 0x49, 0x6e,
+ 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a,
+ 0x0a, 0x0a, 0x53, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x03,
+ 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x22, 0xb9, 0x01, 0x0a, 0x0b, 0x47,
+ 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x41, 0x70, 0x69, 0x12, 0x4e, 0x0a, 0x13, 0x6d, 0x69,
+ 0x6e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x67, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x6e, 0x47, 0x6c, 0x56,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x4f, 0x70, 0x65,
+ 0x6e, 0x47, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x12, 0x6d, 0x69,
+ 0x6e, 0x5f, 0x76, 0x75, 0x6c, 0x6b, 0x61, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x56, 0x75, 0x6c, 0x6b, 0x61, 0x6e, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x56, 0x75, 0x6c, 0x6b,
+ 0x61, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x61, 0x70, 0x69,
+ 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x3b, 0x0a, 0x0d, 0x56, 0x75, 0x6c, 0x6b, 0x61, 0x6e,
+ 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a,
+ 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x69,
+ 0x6e, 0x6f, 0x72, 0x22, 0x3b, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x6e, 0x47, 0x6c, 0x56, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69,
+ 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72,
+ 0x22, 0xb7, 0x02, 0x0a, 0x18, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70,
+ 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x5c, 0x0a,
+ 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x46, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x54, 0x65,
+ 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+ 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f,
+ 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x41,
+ 0x6c, 0x69, 0x61, 0x73, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x22, 0xbc, 0x01, 0x0a, 0x1d,
+ 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2a, 0x0a,
+ 0x26, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x45, 0x58,
+ 0x54, 0x55, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e,
+ 0x5f, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x54, 0x43,
+ 0x31, 0x5f, 0x52, 0x47, 0x42, 0x38, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x41, 0x4c, 0x45,
+ 0x54, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x48, 0x52, 0x45, 0x45, 0x5f,
+ 0x44, 0x43, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x54, 0x43, 0x10, 0x04, 0x12, 0x08, 0x0a,
+ 0x04, 0x4c, 0x41, 0x54, 0x43, 0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x58, 0x54, 0x31, 0x10,
+ 0x06, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x33, 0x54, 0x43, 0x10, 0x07, 0x12, 0x09, 0x0a, 0x05, 0x50,
+ 0x56, 0x52, 0x54, 0x43, 0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x53, 0x54, 0x43, 0x10, 0x09,
+ 0x12, 0x08, 0x0a, 0x04, 0x45, 0x54, 0x43, 0x32, 0x10, 0x0a, 0x22, 0xc0, 0x01, 0x0a, 0x03, 0x41,
+ 0x62, 0x69, 0x12, 0x32, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x1c, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64,
+ 0x6c, 0x65, 0x2e, 0x41, 0x62, 0x69, 0x2e, 0x41, 0x62, 0x69, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52,
+ 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x08, 0x41, 0x62, 0x69, 0x41, 0x6c,
+ 0x69, 0x61, 0x73, 0x12, 0x20, 0x0a, 0x1c, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
+ 0x45, 0x44, 0x5f, 0x43, 0x50, 0x55, 0x5f, 0x41, 0x52, 0x43, 0x48, 0x49, 0x54, 0x45, 0x43, 0x54,
+ 0x55, 0x52, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x52, 0x4d, 0x45, 0x41, 0x42, 0x49,
+ 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x52, 0x4d, 0x45, 0x41, 0x42, 0x49, 0x5f, 0x56, 0x37,
+ 0x41, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x52, 0x4d, 0x36, 0x34, 0x5f, 0x56, 0x38, 0x41,
+ 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x58, 0x38, 0x36, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x58,
+ 0x38, 0x36, 0x5f, 0x36, 0x34, 0x10, 0x05, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x49, 0x50, 0x53, 0x10,
+ 0x06, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x49, 0x50, 0x53, 0x36, 0x34, 0x10, 0x07, 0x22, 0x31, 0x0a,
+ 0x08, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x62, 0x69, 0x12, 0x25, 0x0a, 0x03, 0x61, 0x62, 0x69,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x62, 0x69, 0x52, 0x03, 0x61, 0x62, 0x69,
+ 0x22, 0x76, 0x0a, 0x09, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72, 0x12, 0x3e, 0x0a,
+ 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x61,
+ 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72, 0x2e, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65,
+ 0x72, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x29, 0x0a,
+ 0x0e, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12,
+ 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x57, 0x41,
+ 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x22, 0x5b, 0x0a, 0x0d, 0x44, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x65, 0x61,
+ 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0b, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f,
+ 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc3, 0x02, 0x0a, 0x18, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73,
+ 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69,
+ 0x6e, 0x67, 0x12, 0x2e, 0x0a, 0x03, 0x61, 0x62, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x1c, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x2e, 0x41, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x03, 0x61,
+ 0x62, 0x69, 0x12, 0x47, 0x0a, 0x0c, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x5f, 0x61,
+ 0x70, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69,
+ 0x63, 0x73, 0x41, 0x70, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x0b,
+ 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x41, 0x70, 0x69, 0x12, 0x6f, 0x0a, 0x1a, 0x74,
+ 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69,
+ 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x31, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x2e, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69,
+ 0x6e, 0x67, 0x52, 0x18, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72,
+ 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x3d, 0x0a, 0x08,
+ 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21,
+ 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e,
+ 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e,
+ 0x67, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x22, 0xa2, 0x02, 0x0a, 0x18,
+ 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x54,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x25, 0x0a, 0x03, 0x61, 0x62, 0x69, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x62, 0x69, 0x52, 0x03, 0x61, 0x62, 0x69, 0x12,
+ 0x3e, 0x0a, 0x0c, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x5f, 0x61, 0x70, 0x69, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x41,
+ 0x70, 0x69, 0x52, 0x0b, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x41, 0x70, 0x69, 0x12,
+ 0x66, 0x0a, 0x1a, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72,
+ 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75,
+ 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70,
+ 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x18, 0x74,
+ 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x73, 0x61, 0x6e, 0x69, 0x74,
+ 0x69, 0x7a, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x6e, 0x64,
+ 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x61, 0x6e, 0x69,
+ 0x74, 0x69, 0x7a, 0x65, 0x72, 0x52, 0x09, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72,
+ 0x22, 0x54, 0x0a, 0x12, 0x41, 0x70, 0x65, 0x78, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x5f,
+ 0x61, 0x62, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x6e, 0x64, 0x72,
+ 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69,
+ 0x41, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x6d, 0x75,
+ 0x6c, 0x74, 0x69, 0x41, 0x62, 0x69, 0x22, 0x72, 0x0a, 0x0c, 0x41, 0x62, 0x69, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x62, 0x69, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65,
+ 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x41, 0x62, 0x69, 0x52, 0x0c, 0x61, 0x6c,
+ 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x22, 0x81, 0x01, 0x0a, 0x11, 0x4d,
+ 0x75, 0x6c, 0x74, 0x69, 0x41, 0x62, 0x69, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67,
+ 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x18, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65,
+ 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x62, 0x69, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x12, 0x3c, 0x0a, 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73,
+ 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x41, 0x62, 0x69,
+ 0x52, 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x22, 0x90,
+ 0x01, 0x0a, 0x16, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79,
+ 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e,
+ 0x44, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41,
+ 0x0a, 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62,
+ 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x44, 0x65, 0x6e, 0x73,
+ 0x69, 0x74, 0x79, 0x52, 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65,
+ 0x73, 0x22, 0x4d, 0x0a, 0x11, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x54, 0x61, 0x72,
+ 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x22, 0x0a, 0x0c,
+ 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
+ 0x28, 0x09, 0x52, 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73,
+ 0x22, 0x8a, 0x01, 0x0a, 0x14, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x41, 0x70, 0x69,
+ 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69,
+ 0x63, 0x73, 0x41, 0x70, 0x69, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x0c,
+ 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e,
+ 0x64, 0x6c, 0x65, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x41, 0x70, 0x69, 0x52,
+ 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x22, 0x87, 0x01,
+ 0x0a, 0x13, 0x53, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62,
+ 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53, 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+ 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
+ 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x53,
+ 0x64, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72,
+ 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x21, 0x54, 0x65, 0x78, 0x74,
+ 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f,
+ 0x72, 0x6d, 0x61, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x54, 0x65,
+ 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
+ 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4c, 0x0a,
+ 0x0c, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x18, 0x02, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75,
+ 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6d, 0x70,
+ 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x0c, 0x61,
+ 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x73, 0x22, 0x45, 0x0a, 0x12, 0x53,
+ 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e,
+ 0x67, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x19, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c,
+ 0x65, 0x2e, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x22, 0x62, 0x0a, 0x16, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x46, 0x65, 0x61, 0x74,
+ 0x75, 0x72, 0x65, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x48, 0x0a, 0x10,
+ 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x46, 0x65,
+ 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x46,
+ 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x41, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5a, 0x2b, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f,
+ 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x61, 0x70, 0x6b, 0x73, 0x2f, 0x62, 0x75, 0x6e,
+ 0x64, 0x6c, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x33,
}
-func init() {
- proto.RegisterFile("targeting.proto", fileDescriptor_df45b505afdf471e)
+var (
+ file_targeting_proto_rawDescOnce sync.Once
+ file_targeting_proto_rawDescData = file_targeting_proto_rawDesc
+)
+
+func file_targeting_proto_rawDescGZIP() []byte {
+ file_targeting_proto_rawDescOnce.Do(func() {
+ file_targeting_proto_rawDescData = protoimpl.X.CompressGZIP(file_targeting_proto_rawDescData)
+ })
+ return file_targeting_proto_rawDescData
}
-var fileDescriptor_df45b505afdf471e = []byte{
- // 1504 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x5b, 0x6f, 0xe3, 0xc4,
- 0x17, 0xaf, 0x93, 0xa6, 0x4d, 0x4e, 0x92, 0xd6, 0x3b, 0xe9, 0xbf, 0xff, 0xb0, 0xec, 0x4a, 0x5b,
- 0xef, 0x85, 0xee, 0x0a, 0x05, 0xda, 0xae, 0xba, 0x15, 0x97, 0x22, 0xd7, 0x71, 0x9b, 0x48, 0x4d,
- 0x9a, 0x75, 0xdc, 0x6c, 0x59, 0x90, 0xbc, 0x4e, 0x3c, 0x0d, 0xa6, 0x89, 0x1d, 0x6c, 0xa7, 0xda,
- 0xe5, 0x05, 0x81, 0x90, 0x90, 0x78, 0xe2, 0x8d, 0x77, 0x3e, 0x00, 0x12, 0x4f, 0x08, 0x89, 0x07,
- 0x24, 0x3e, 0x0c, 0x7c, 0x0c, 0x34, 0xbe, 0x24, 0x9e, 0xc4, 0x4e, 0xb3, 0x2c, 0xf0, 0x50, 0xe5,
- 0xcc, 0xf1, 0x39, 0xbf, 0x73, 0x99, 0x73, 0x66, 0xce, 0x14, 0x56, 0x1d, 0xd5, 0xea, 0x62, 0x47,
- 0x37, 0xba, 0xa5, 0x81, 0x65, 0x3a, 0x26, 0x5a, 0x51, 0x0d, 0xcd, 0x32, 0x75, 0xad, 0xd4, 0x1e,
- 0x1a, 0x5a, 0x0f, 0x73, 0x7f, 0x26, 0x81, 0x6d, 0xa9, 0x96, 0xae, 0x1a, 0x8e, 0x1c, 0x88, 0xa2,
- 0x27, 0xf0, 0x3f, 0x5b, 0xbb, 0x50, 0x2e, 0xb1, 0x65, 0xeb, 0xa6, 0xa1, 0x8c, 0x30, 0x8a, 0xcc,
- 0x2d, 0x66, 0x33, 0xbb, 0x7d, 0xbb, 0x44, 0x83, 0x94, 0x9a, 0xda, 0x45, 0xcb, 0x93, 0x1d, 0x61,
- 0x48, 0x05, 0x7b, 0x9a, 0x89, 0x78, 0xc8, 0xab, 0x6d, 0x3d, 0x04, 0x98, 0x70, 0x01, 0x6f, 0x4c,
- 0x02, 0xf2, 0x6d, 0x7d, 0x8c, 0x94, 0x53, 0x43, 0x2b, 0xf4, 0x0c, 0x8a, 0x76, 0xc7, 0xc2, 0xd8,
- 0x50, 0x34, 0x6c, 0xd8, 0xba, 0xf3, 0x22, 0x84, 0x96, 0x74, 0xd1, 0xee, 0x4d, 0xb9, 0xe7, 0xca,
- 0x97, 0x3d, 0xf1, 0x31, 0xee, 0xba, 0x1d, 0xc9, 0x47, 0x8f, 0xa1, 0xd0, 0x1f, 0xf6, 0x1c, 0x5d,
- 0xa1, 0x5d, 0x5d, 0x74, 0xc1, 0x37, 0x26, 0xc1, 0x6b, 0x44, 0x94, 0xf2, 0xf7, 0x5a, 0x7f, 0x92,
- 0x85, 0xbe, 0x62, 0xe0, 0x8e, 0x83, 0x9f, 0x3b, 0x43, 0x0b, 0x2b, 0x1d, 0xb3, 0x3f, 0xb0, 0xb0,
- 0xed, 0x66, 0xf6, 0xdc, 0xb4, 0xfa, 0xaa, 0x13, 0x32, 0x92, 0x72, 0x8d, 0x6c, 0x4d, 0x1a, 0x91,
- 0x3d, 0x5d, 0x61, 0xac, 0x7a, 0xe8, 0x6a, 0x8e, 0x8d, 0x6e, 0x38, 0x57, 0x89, 0x70, 0x7f, 0xa4,
- 0x20, 0xc7, 0x0f, 0x2e, 0x66, 0xec, 0x06, 0xf3, 0xd2, 0xbb, 0xf1, 0x14, 0xd6, 0xbb, 0x96, 0x3a,
- 0xf8, 0x44, 0xef, 0xd8, 0x8a, 0x3a, 0x98, 0xde, 0xd9, 0x3b, 0x93, 0x58, 0x47, 0xbe, 0x34, 0x3f,
- 0x08, 0x61, 0xae, 0x75, 0x23, 0xb8, 0xa8, 0x01, 0xa8, 0xa7, 0x1a, 0xdd, 0xa1, 0xda, 0xc5, 0x53,
- 0x7b, 0x3c, 0xb5, 0x0d, 0xc7, 0xbe, 0x64, 0x68, 0x1b, 0x7a, 0x93, 0xac, 0x99, 0xb5, 0xb3, 0xf8,
- 0x8f, 0xd4, 0x4e, 0x6c, 0xe7, 0xa4, 0x5e, 0xb1, 0x73, 0xe6, 0xae, 0xa0, 0xa5, 0x7f, 0xaf, 0x82,
- 0xe2, 0x3a, 0x63, 0xf9, 0x15, 0x3a, 0xa3, 0x09, 0x05, 0x5b, 0x35, 0x74, 0x47, 0xff, 0x1c, 0x5b,
- 0x21, 0xc8, 0xb4, 0x0b, 0xc9, 0x4d, 0xa5, 0x2b, 0x10, 0x1d, 0x63, 0x22, 0x7b, 0x8a, 0xc7, 0xfd,
- 0x98, 0x80, 0xd5, 0x9a, 0xa9, 0x0d, 0x7b, 0xf8, 0x3f, 0x38, 0xd3, 0x9e, 0x41, 0x51, 0xc3, 0x97,
- 0x7a, 0x07, 0x2b, 0xe7, 0x58, 0x75, 0xf7, 0x27, 0xdc, 0x04, 0xc9, 0xa8, 0xa2, 0x2a, 0xbb, 0xf2,
- 0x87, 0x9e, 0x78, 0xa8, 0xa8, 0xb4, 0x48, 0x3e, 0xb1, 0x30, 0xb4, 0xb1, 0xa5, 0x74, 0xcc, 0xa1,
- 0xe1, 0x58, 0x3a, 0xb6, 0xaf, 0x3e, 0xf2, 0x4e, 0x6d, 0x6c, 0x09, 0x81, 0x78, 0xc8, 0xc2, 0x30,
- 0x92, 0xcf, 0x3d, 0x81, 0xf5, 0x68, 0x0d, 0x74, 0x1b, 0xf2, 0x9e, 0xd9, 0x17, 0x4a, 0xc7, 0xd4,
- 0xb0, 0x5d, 0x64, 0x6e, 0x25, 0x37, 0x33, 0x52, 0xce, 0x67, 0x0a, 0x84, 0x87, 0x8a, 0xb0, 0x8c,
- 0x9f, 0x77, 0x7a, 0x43, 0x0d, 0xbb, 0x6d, 0x9f, 0x96, 0x82, 0x25, 0xf7, 0x7d, 0x02, 0xf2, 0x54,
- 0x0b, 0xa1, 0xc7, 0x90, 0x0f, 0x9a, 0x4f, 0xed, 0xe9, 0xaa, 0xed, 0xe6, 0x7f, 0x65, 0xfb, 0xc1,
- 0xcc, 0xc6, 0x2b, 0xf9, 0xbf, 0x3c, 0xd1, 0xa8, 0x2c, 0x48, 0x39, 0x2d, 0xb4, 0x46, 0x1b, 0x90,
- 0x0d, 0x20, 0xb5, 0x81, 0xee, 0xba, 0x90, 0xaa, 0x2c, 0x48, 0xe0, 0x33, 0xcb, 0x03, 0x9d, 0xfb,
- 0x02, 0x72, 0x61, 0x08, 0xf4, 0x7f, 0x28, 0x94, 0xc5, 0x7a, 0xb3, 0x2a, 0x7f, 0xa8, 0x9c, 0xd6,
- 0x9b, 0x0d, 0x51, 0xa8, 0x1e, 0x56, 0xc5, 0x32, 0xbb, 0x80, 0x32, 0x90, 0xaa, 0x9f, 0x94, 0x1b,
- 0x55, 0x96, 0x41, 0x69, 0x58, 0x3c, 0x26, 0x54, 0x82, 0x50, 0x35, 0x42, 0x25, 0xc9, 0x67, 0xb9,
- 0x45, 0xc8, 0x45, 0xc2, 0xac, 0x10, 0x2a, 0x45, 0x98, 0x67, 0x2e, 0xb9, 0x84, 0x00, 0x96, 0xce,
- 0x3c, 0x7a, 0x19, 0x65, 0x61, 0xf9, 0xcc, 0x5f, 0xa4, 0x0f, 0x56, 0xc7, 0x61, 0x9b, 0x06, 0x36,
- 0xcf, 0x39, 0x0e, 0xa0, 0x6a, 0x38, 0x3b, 0xdb, 0x2d, 0xb5, 0x37, 0xc4, 0x68, 0x0d, 0x52, 0x97,
- 0x84, 0x70, 0xb3, 0x91, 0x92, 0xbc, 0x05, 0xf7, 0x0e, 0xc0, 0xb8, 0x0c, 0xd1, 0x9b, 0x90, 0xec,
- 0xeb, 0x86, 0x5f, 0xaf, 0xd7, 0x27, 0xf3, 0x35, 0x06, 0x93, 0x88, 0x18, 0xf7, 0x0b, 0x03, 0xd9,
- 0xd0, 0x61, 0x8b, 0xea, 0x50, 0xe8, 0xeb, 0x86, 0x62, 0x0e, 0xb0, 0xa1, 0x74, 0x7b, 0x41, 0x1f,
- 0xf8, 0x68, 0x37, 0x27, 0xd1, 0x4e, 0x06, 0xd8, 0x38, 0xea, 0xf9, 0x96, 0x2b, 0x0b, 0x12, 0xdb,
- 0xd7, 0x0d, 0x8a, 0x87, 0x6a, 0x80, 0x08, 0xde, 0xe5, 0xb0, 0x77, 0xa1, 0x1a, 0x23, 0xb8, 0x44,
- 0x34, 0x5c, 0xcb, 0x95, 0xa2, 0xe1, 0x28, 0xde, 0x41, 0x16, 0x32, 0xe4, 0xfe, 0xf0, 0x72, 0xf3,
- 0x2e, 0xe4, 0xa9, 0xaf, 0x24, 0x3d, 0x7d, 0xf5, 0x53, 0xd3, 0x0a, 0xd2, 0xe3, 0x2e, 0x5c, 0xae,
- 0x6e, 0x98, 0x96, 0xb7, 0xe3, 0x92, 0xb7, 0x20, 0xca, 0xb4, 0xa7, 0x2f, 0xa3, 0xfc, 0x73, 0x02,
- 0x8a, 0x71, 0x47, 0x25, 0xfa, 0x18, 0x52, 0xe1, 0x92, 0x3d, 0x9c, 0xf7, 0x8c, 0x8d, 0xfd, 0xe0,
- 0xd6, 0xa2, 0xe4, 0x81, 0x72, 0xbf, 0x32, 0x70, 0x73, 0xa6, 0x20, 0x7a, 0x00, 0xf7, 0x42, 0xc5,
- 0xaa, 0xc8, 0xe2, 0x99, 0x7c, 0x2a, 0x89, 0x8a, 0x70, 0x52, 0x6b, 0x48, 0x62, 0xb3, 0x59, 0x3d,
- 0xa9, 0x2b, 0x87, 0x27, 0x52, 0x8d, 0x97, 0xd9, 0x05, 0x94, 0x87, 0x8c, 0x28, 0x0b, 0x5b, 0x8a,
- 0x74, 0x74, 0xb0, 0xc7, 0x32, 0x28, 0x07, 0xe9, 0x06, 0x7f, 0x2c, 0xca, 0xb2, 0x58, 0x66, 0x13,
- 0x64, 0x25, 0x57, 0x24, 0x51, 0x54, 0xca, 0x02, 0x9b, 0x44, 0xcb, 0x90, 0xe4, 0x65, 0xc1, 0xab,
- 0xe8, 0x63, 0x42, 0xa5, 0x08, 0x55, 0x3e, 0x93, 0xb7, 0xd8, 0x25, 0x42, 0x35, 0x77, 0x64, 0x81,
- 0x5d, 0x26, 0x55, 0xde, 0x68, 0x49, 0xb2, 0xc0, 0xa6, 0x09, 0x93, 0x6f, 0xca, 0x02, 0x9b, 0x21,
- 0x94, 0x28, 0x0b, 0xdb, 0x2c, 0x70, 0xbf, 0x31, 0x90, 0xe4, 0xdb, 0x3a, 0xda, 0xa6, 0x93, 0x14,
- 0x35, 0x4c, 0x90, 0x3f, 0x2a, 0xf4, 0xaf, 0x19, 0x48, 0x07, 0x3c, 0x74, 0x0b, 0x6e, 0x84, 0xa3,
- 0x14, 0x1a, 0xa7, 0x0a, 0x2f, 0x09, 0x95, 0xaa, 0x2c, 0x0a, 0x24, 0x5c, 0x76, 0x81, 0x34, 0x16,
- 0x2f, 0xd5, 0x44, 0xfe, 0x80, 0x74, 0xe9, 0x2a, 0x64, 0xfd, 0x85, 0xd2, 0x7a, 0xc4, 0xb3, 0x09,
- 0x12, 0x39, 0x2f, 0xd5, 0x76, 0x1f, 0x2a, 0xad, 0x3d, 0xde, 0x8b, 0xee, 0x6c, 0x6f, 0x97, 0x5d,
- 0x74, 0x5b, 0x73, 0x6f, 0x57, 0xd9, 0x7d, 0xe8, 0xc5, 0x57, 0xab, 0x36, 0x9a, 0x5e, 0xc3, 0x12,
- 0x6a, 0xf7, 0x21, 0xbb, 0xcc, 0x6d, 0x41, 0x3a, 0xb8, 0xb3, 0xd0, 0x5d, 0x48, 0xaa, 0x6d, 0xdd,
- 0x3d, 0xed, 0xb2, 0xdb, 0x85, 0x88, 0x20, 0x24, 0xf2, 0x9d, 0xbb, 0x84, 0xcc, 0xe8, 0x4e, 0x42,
- 0xfb, 0x74, 0xe8, 0x9b, 0xb1, 0xb7, 0xd7, 0x98, 0xa2, 0xd2, 0x70, 0x1f, 0x56, 0xe8, 0x0f, 0xc4,
- 0xcf, 0xfa, 0x49, 0x5d, 0xf4, 0xf6, 0xb3, 0xf2, 0x84, 0x2f, 0x97, 0xc9, 0x46, 0xb3, 0x0c, 0xf7,
- 0x11, 0xe4, 0xa9, 0x4b, 0x04, 0x6d, 0x40, 0x2e, 0xb8, 0x7e, 0x0c, 0xb5, 0xef, 0x9d, 0x23, 0x19,
- 0x29, 0xeb, 0xf3, 0xea, 0x6a, 0x1f, 0xa3, 0x37, 0x60, 0x35, 0x10, 0x09, 0xb7, 0x6b, 0x4a, 0x5a,
- 0xf1, 0xd9, 0x7e, 0xc3, 0x70, 0xbf, 0x27, 0xa0, 0xc8, 0xdb, 0x36, 0x76, 0xec, 0xb2, 0x6e, 0xe1,
- 0x8e, 0x63, 0x5a, 0xa1, 0x09, 0xa7, 0x14, 0x24, 0xe6, 0xea, 0x51, 0x91, 0x08, 0xa2, 0x23, 0xc8,
- 0x85, 0x27, 0xc4, 0x97, 0x9a, 0x0b, 0xb3, 0xa1, 0xb9, 0x10, 0x99, 0x70, 0x3d, 0x7e, 0x00, 0xf2,
- 0xef, 0xc1, 0xbf, 0x31, 0xf6, 0x14, 0xe3, 0xc6, 0x1e, 0xf4, 0x3e, 0xa4, 0x83, 0x11, 0x32, 0x6e,
- 0xf8, 0x9f, 0x9e, 0x3a, 0x47, 0x2a, 0xdc, 0x0f, 0x09, 0x28, 0xd6, 0x55, 0x47, 0xbf, 0xc4, 0x11,
- 0x59, 0xbc, 0x1b, 0xce, 0x62, 0x6c, 0x79, 0xa1, 0xfd, 0xc8, 0xe4, 0xbd, 0x3e, 0x23, 0x79, 0x74,
- 0xce, 0xce, 0xe7, 0xc8, 0xd9, 0xe6, 0xbc, 0x39, 0x9b, 0x91, 0xaa, 0x47, 0x90, 0x19, 0x8d, 0x61,
- 0x7e, 0xae, 0x5e, 0x8b, 0xad, 0x7e, 0x69, 0x2c, 0xcb, 0xc9, 0x80, 0xf8, 0x01, 0x7e, 0x5e, 0xed,
- 0x53, 0x73, 0xfa, 0x3e, 0x64, 0x46, 0x73, 0xa6, 0x9f, 0xa3, 0x39, 0xa6, 0xcb, 0x74, 0x30, 0x5d,
- 0x72, 0x16, 0xe4, 0xa8, 0x21, 0xf3, 0xfe, 0xf8, 0x76, 0x8d, 0x6d, 0x67, 0x4f, 0x02, 0x3d, 0x82,
- 0x9c, 0xda, 0x73, 0xb0, 0x65, 0xb8, 0x3b, 0x67, 0xfb, 0x13, 0x5c, 0xa4, 0x06, 0x25, 0xc8, 0x7d,
- 0xc9, 0xc0, 0xb5, 0x29, 0x9f, 0x50, 0x89, 0xb6, 0x5c, 0x8c, 0x8b, 0x22, 0x30, 0xff, 0x5e, 0xa4,
- 0xf9, 0x78, 0x35, 0xda, 0x87, 0xef, 0x18, 0x58, 0x8f, 0x7e, 0xb0, 0xa0, 0x1d, 0xda, 0x91, 0x9b,
- 0x33, 0xc7, 0xad, 0xc0, 0x1b, 0x3e, 0xd2, 0x9b, 0x2b, 0x74, 0x69, 0x97, 0x6a, 0x70, 0x6d, 0xaa,
- 0x49, 0xc2, 0xd3, 0x0e, 0x19, 0x26, 0x7d, 0x6b, 0x5c, 0x84, 0xb5, 0xcc, 0x04, 0xdc, 0xb7, 0x0c,
- 0xac, 0x45, 0x1d, 0x15, 0x68, 0x8b, 0x8e, 0x6f, 0x66, 0x8b, 0xf8, 0xf6, 0x3e, 0x88, 0x8c, 0x6e,
- 0xa6, 0x26, 0xed, 0xcc, 0x37, 0x0c, 0x14, 0x22, 0x9e, 0x09, 0xe8, 0x6d, 0xda, 0x97, 0xeb, 0xf1,
- 0x4f, 0x8b, 0xc0, 0x95, 0xfd, 0x48, 0x57, 0x66, 0x29, 0xd2, 0x9e, 0xfc, 0xc4, 0xc0, 0xc6, 0x95,
- 0x47, 0x1d, 0xb9, 0x9f, 0xc2, 0x7e, 0xcd, 0xdf, 0xf8, 0xbe, 0x97, 0xc7, 0x91, 0x5e, 0xce, 0x0f,
- 0x43, 0xfb, 0x2c, 0x02, 0x9a, 0x7e, 0xce, 0xa1, 0xb7, 0x68, 0x1f, 0x67, 0x9c, 0x22, 0xfe, 0x8c,
- 0xdc, 0x86, 0xf5, 0xe8, 0xe7, 0x14, 0xaa, 0x00, 0x6b, 0xe1, 0xcf, 0x86, 0xba, 0x85, 0xb5, 0xe0,
- 0x69, 0x16, 0x37, 0xee, 0x52, 0x08, 0xd2, 0x6a, 0xa0, 0xe6, 0x33, 0x0e, 0x1e, 0x00, 0xea, 0x98,
- 0xfd, 0x09, 0xa5, 0xa7, 0x6b, 0xfe, 0x5a, 0xf1, 0xd6, 0x8a, 0xfb, 0x0f, 0xb6, 0xf6, 0x92, 0xfb,
- 0xb3, 0xf3, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x47, 0xe0, 0x85, 0xa8, 0x7a, 0x13, 0x00, 0x00,
+var file_targeting_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
+var file_targeting_proto_msgTypes = make([]protoimpl.MessageInfo, 27)
+var file_targeting_proto_goTypes = []interface{}{
+ (ScreenDensity_DensityAlias)(0), // 0: android.bundle.ScreenDensity.DensityAlias
+ (TextureCompressionFormat_TextureCompressionFormatAlias)(0), // 1: android.bundle.TextureCompressionFormat.TextureCompressionFormatAlias
+ (Abi_AbiAlias)(0), // 2: android.bundle.Abi.AbiAlias
+ (Sanitizer_SanitizerAlias)(0), // 3: android.bundle.Sanitizer.SanitizerAlias
+ (*VariantTargeting)(nil), // 4: android.bundle.VariantTargeting
+ (*ApkTargeting)(nil), // 5: android.bundle.ApkTargeting
+ (*ModuleTargeting)(nil), // 6: android.bundle.ModuleTargeting
+ (*UserCountriesTargeting)(nil), // 7: android.bundle.UserCountriesTargeting
+ (*ScreenDensity)(nil), // 8: android.bundle.ScreenDensity
+ (*Int32Value)(nil), // 9: android.bundle.Int32Value
+ (*SdkVersion)(nil), // 10: android.bundle.SdkVersion
+ (*GraphicsApi)(nil), // 11: android.bundle.GraphicsApi
+ (*VulkanVersion)(nil), // 12: android.bundle.VulkanVersion
+ (*OpenGlVersion)(nil), // 13: android.bundle.OpenGlVersion
+ (*TextureCompressionFormat)(nil), // 14: android.bundle.TextureCompressionFormat
+ (*Abi)(nil), // 15: android.bundle.Abi
+ (*MultiAbi)(nil), // 16: android.bundle.MultiAbi
+ (*Sanitizer)(nil), // 17: android.bundle.Sanitizer
+ (*DeviceFeature)(nil), // 18: android.bundle.DeviceFeature
+ (*AssetsDirectoryTargeting)(nil), // 19: android.bundle.AssetsDirectoryTargeting
+ (*NativeDirectoryTargeting)(nil), // 20: android.bundle.NativeDirectoryTargeting
+ (*ApexImageTargeting)(nil), // 21: android.bundle.ApexImageTargeting
+ (*AbiTargeting)(nil), // 22: android.bundle.AbiTargeting
+ (*MultiAbiTargeting)(nil), // 23: android.bundle.MultiAbiTargeting
+ (*ScreenDensityTargeting)(nil), // 24: android.bundle.ScreenDensityTargeting
+ (*LanguageTargeting)(nil), // 25: android.bundle.LanguageTargeting
+ (*GraphicsApiTargeting)(nil), // 26: android.bundle.GraphicsApiTargeting
+ (*SdkVersionTargeting)(nil), // 27: android.bundle.SdkVersionTargeting
+ (*TextureCompressionFormatTargeting)(nil), // 28: android.bundle.TextureCompressionFormatTargeting
+ (*SanitizerTargeting)(nil), // 29: android.bundle.SanitizerTargeting
+ (*DeviceFeatureTargeting)(nil), // 30: android.bundle.DeviceFeatureTargeting
+}
+var file_targeting_proto_depIdxs = []int32{
+ 27, // 0: android.bundle.VariantTargeting.sdk_version_targeting:type_name -> android.bundle.SdkVersionTargeting
+ 22, // 1: android.bundle.VariantTargeting.abi_targeting:type_name -> android.bundle.AbiTargeting
+ 24, // 2: android.bundle.VariantTargeting.screen_density_targeting:type_name -> android.bundle.ScreenDensityTargeting
+ 23, // 3: android.bundle.VariantTargeting.multi_abi_targeting:type_name -> android.bundle.MultiAbiTargeting
+ 28, // 4: android.bundle.VariantTargeting.texture_compression_format_targeting:type_name -> android.bundle.TextureCompressionFormatTargeting
+ 22, // 5: android.bundle.ApkTargeting.abi_targeting:type_name -> android.bundle.AbiTargeting
+ 26, // 6: android.bundle.ApkTargeting.graphics_api_targeting:type_name -> android.bundle.GraphicsApiTargeting
+ 25, // 7: android.bundle.ApkTargeting.language_targeting:type_name -> android.bundle.LanguageTargeting
+ 24, // 8: android.bundle.ApkTargeting.screen_density_targeting:type_name -> android.bundle.ScreenDensityTargeting
+ 27, // 9: android.bundle.ApkTargeting.sdk_version_targeting:type_name -> android.bundle.SdkVersionTargeting
+ 28, // 10: android.bundle.ApkTargeting.texture_compression_format_targeting:type_name -> android.bundle.TextureCompressionFormatTargeting
+ 23, // 11: android.bundle.ApkTargeting.multi_abi_targeting:type_name -> android.bundle.MultiAbiTargeting
+ 29, // 12: android.bundle.ApkTargeting.sanitizer_targeting:type_name -> android.bundle.SanitizerTargeting
+ 27, // 13: android.bundle.ModuleTargeting.sdk_version_targeting:type_name -> android.bundle.SdkVersionTargeting
+ 30, // 14: android.bundle.ModuleTargeting.device_feature_targeting:type_name -> android.bundle.DeviceFeatureTargeting
+ 7, // 15: android.bundle.ModuleTargeting.user_countries_targeting:type_name -> android.bundle.UserCountriesTargeting
+ 0, // 16: android.bundle.ScreenDensity.density_alias:type_name -> android.bundle.ScreenDensity.DensityAlias
+ 9, // 17: android.bundle.SdkVersion.min:type_name -> android.bundle.Int32Value
+ 13, // 18: android.bundle.GraphicsApi.min_open_gl_version:type_name -> android.bundle.OpenGlVersion
+ 12, // 19: android.bundle.GraphicsApi.min_vulkan_version:type_name -> android.bundle.VulkanVersion
+ 1, // 20: android.bundle.TextureCompressionFormat.alias:type_name -> android.bundle.TextureCompressionFormat.TextureCompressionFormatAlias
+ 2, // 21: android.bundle.Abi.alias:type_name -> android.bundle.Abi.AbiAlias
+ 15, // 22: android.bundle.MultiAbi.abi:type_name -> android.bundle.Abi
+ 3, // 23: android.bundle.Sanitizer.alias:type_name -> android.bundle.Sanitizer.SanitizerAlias
+ 22, // 24: android.bundle.AssetsDirectoryTargeting.abi:type_name -> android.bundle.AbiTargeting
+ 26, // 25: android.bundle.AssetsDirectoryTargeting.graphics_api:type_name -> android.bundle.GraphicsApiTargeting
+ 28, // 26: android.bundle.AssetsDirectoryTargeting.texture_compression_format:type_name -> android.bundle.TextureCompressionFormatTargeting
+ 25, // 27: android.bundle.AssetsDirectoryTargeting.language:type_name -> android.bundle.LanguageTargeting
+ 15, // 28: android.bundle.NativeDirectoryTargeting.abi:type_name -> android.bundle.Abi
+ 11, // 29: android.bundle.NativeDirectoryTargeting.graphics_api:type_name -> android.bundle.GraphicsApi
+ 14, // 30: android.bundle.NativeDirectoryTargeting.texture_compression_format:type_name -> android.bundle.TextureCompressionFormat
+ 17, // 31: android.bundle.NativeDirectoryTargeting.sanitizer:type_name -> android.bundle.Sanitizer
+ 23, // 32: android.bundle.ApexImageTargeting.multi_abi:type_name -> android.bundle.MultiAbiTargeting
+ 15, // 33: android.bundle.AbiTargeting.value:type_name -> android.bundle.Abi
+ 15, // 34: android.bundle.AbiTargeting.alternatives:type_name -> android.bundle.Abi
+ 16, // 35: android.bundle.MultiAbiTargeting.value:type_name -> android.bundle.MultiAbi
+ 16, // 36: android.bundle.MultiAbiTargeting.alternatives:type_name -> android.bundle.MultiAbi
+ 8, // 37: android.bundle.ScreenDensityTargeting.value:type_name -> android.bundle.ScreenDensity
+ 8, // 38: android.bundle.ScreenDensityTargeting.alternatives:type_name -> android.bundle.ScreenDensity
+ 11, // 39: android.bundle.GraphicsApiTargeting.value:type_name -> android.bundle.GraphicsApi
+ 11, // 40: android.bundle.GraphicsApiTargeting.alternatives:type_name -> android.bundle.GraphicsApi
+ 10, // 41: android.bundle.SdkVersionTargeting.value:type_name -> android.bundle.SdkVersion
+ 10, // 42: android.bundle.SdkVersionTargeting.alternatives:type_name -> android.bundle.SdkVersion
+ 14, // 43: android.bundle.TextureCompressionFormatTargeting.value:type_name -> android.bundle.TextureCompressionFormat
+ 14, // 44: android.bundle.TextureCompressionFormatTargeting.alternatives:type_name -> android.bundle.TextureCompressionFormat
+ 17, // 45: android.bundle.SanitizerTargeting.value:type_name -> android.bundle.Sanitizer
+ 18, // 46: android.bundle.DeviceFeatureTargeting.required_feature:type_name -> android.bundle.DeviceFeature
+ 47, // [47:47] is the sub-list for method output_type
+ 47, // [47:47] is the sub-list for method input_type
+ 47, // [47:47] is the sub-list for extension type_name
+ 47, // [47:47] is the sub-list for extension extendee
+ 0, // [0:47] is the sub-list for field type_name
+}
+
+func init() { file_targeting_proto_init() }
+func file_targeting_proto_init() {
+ if File_targeting_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_targeting_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*VariantTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ApkTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ModuleTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UserCountriesTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ScreenDensity); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Int32Value); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SdkVersion); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GraphicsApi); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*VulkanVersion); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*OpenGlVersion); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*TextureCompressionFormat); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Abi); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MultiAbi); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Sanitizer); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DeviceFeature); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AssetsDirectoryTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*NativeDirectoryTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ApexImageTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AbiTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MultiAbiTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ScreenDensityTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*LanguageTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GraphicsApiTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SdkVersionTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*TextureCompressionFormatTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SanitizerTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_targeting_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DeviceFeatureTargeting); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_targeting_proto_msgTypes[4].OneofWrappers = []interface{}{
+ (*ScreenDensity_DensityAlias_)(nil),
+ (*ScreenDensity_DensityDpi)(nil),
+ }
+ file_targeting_proto_msgTypes[7].OneofWrappers = []interface{}{
+ (*GraphicsApi_MinOpenGlVersion)(nil),
+ (*GraphicsApi_MinVulkanVersion)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_targeting_proto_rawDesc,
+ NumEnums: 4,
+ NumMessages: 27,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_targeting_proto_goTypes,
+ DependencyIndexes: file_targeting_proto_depIdxs,
+ EnumInfos: file_targeting_proto_enumTypes,
+ MessageInfos: file_targeting_proto_msgTypes,
+ }.Build()
+ File_targeting_proto = out.File
+ file_targeting_proto_rawDesc = nil
+ file_targeting_proto_goTypes = nil
+ file_targeting_proto_depIdxs = nil
}
diff --git a/cmd/extract_apks/bundle_proto/targeting.proto b/cmd/extract_apks/bundle_proto/targeting.proto
index cdc910b..a33edc7 100644
--- a/cmd/extract_apks/bundle_proto/targeting.proto
+++ b/cmd/extract_apks/bundle_proto/targeting.proto
@@ -6,7 +6,7 @@
package android.bundle;
-option go_package = "android_bundle_proto";
+option go_package = "android/soong/cmd/extract_apks/bundle_proto";
option java_package = "com.android.bundle";
// Targeting on the level of variants.
diff --git a/cmd/extract_apks/main.go b/cmd/extract_apks/main.go
index db54ffb..6e51a28 100644
--- a/cmd/extract_apks/main.go
+++ b/cmd/extract_apks/main.go
@@ -27,9 +27,9 @@
"sort"
"strings"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
- "android/soong/cmd/extract_apks/bundle_proto"
+ android_bundle_proto "android/soong/cmd/extract_apks/bundle_proto"
"android/soong/third_party/zip"
)
diff --git a/cmd/extract_apks/main_test.go b/cmd/extract_apks/main_test.go
index c3e6a2d..9fcf324 100644
--- a/cmd/extract_apks/main_test.go
+++ b/cmd/extract_apks/main_test.go
@@ -19,7 +19,7 @@
"reflect"
"testing"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/encoding/prototext"
bp "android/soong/cmd/extract_apks/bundle_proto"
"android/soong/third_party/zip"
@@ -253,7 +253,7 @@
}
for _, testCase := range testCases {
var toc bp.BuildApksResult
- if err := proto.UnmarshalText(testCase.protoText, &toc); err != nil {
+ if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil {
t.Fatal(err)
}
for _, config := range testCase.configs {
@@ -407,7 +407,7 @@
}
for _, testCase := range testCases {
var toc bp.BuildApksResult
- if err := proto.UnmarshalText(testCase.protoText, &toc); err != nil {
+ if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil {
t.Fatal(err)
}
for _, config := range testCase.configs {
diff --git a/cmd/extract_linker/main.go b/cmd/extract_linker/main.go
index ea0bf4e..f1f7bc7 100644
--- a/cmd/extract_linker/main.go
+++ b/cmd/extract_linker/main.go
@@ -13,7 +13,7 @@
// limitations under the License.
// This tool extracts ELF LOAD segments from our linker binary, and produces an
-// assembly file and linker flags which will embed those segments as sections
+// assembly file and linker script which will embed those segments as sections
// in another binary.
package main
@@ -31,10 +31,10 @@
func main() {
var asmPath string
- var flagsPath string
+ var scriptPath string
flag.StringVar(&asmPath, "s", "", "Path to save the assembly file")
- flag.StringVar(&flagsPath, "f", "", "Path to save the linker flags")
+ flag.StringVar(&scriptPath, "T", "", "Path to save the linker script")
flag.Parse()
f, err := os.Open(flag.Arg(0))
@@ -49,20 +49,30 @@
}
asm := &bytes.Buffer{}
+ script := &bytes.Buffer{}
baseLoadAddr := uint64(0x1000)
load := 0
- linkFlags := []string{}
fmt.Fprintln(asm, ".globl __dlwrap_linker_offset")
fmt.Fprintf(asm, ".set __dlwrap_linker_offset, 0x%x\n", baseLoadAddr)
+ fmt.Fprintln(script, "ENTRY(__dlwrap__start)")
+ fmt.Fprintln(script, "SECTIONS {")
+
for _, prog := range ef.Progs {
if prog.Type != elf.PT_LOAD {
continue
}
- sectionName := fmt.Sprintf(".linker.sect%d", load)
- symName := fmt.Sprintf("__dlwrap_linker_sect%d", load)
+ var progName string
+ progSection := progToFirstSection(prog, ef.Sections)
+ if progSection != nil {
+ progName = progSection.Name
+ } else {
+ progName = fmt.Sprintf(".sect%d", load)
+ }
+ sectionName := ".linker" + progName
+ symName := "__dlwrap_linker" + strings.ReplaceAll(progName, ".", "_")
flags := ""
if prog.Flags&elf.PF_W != 0 {
@@ -75,10 +85,9 @@
fmt.Fprintf(asm, ".globl %s\n%s:\n\n", symName, symName)
- linkFlags = append(linkFlags,
- fmt.Sprintf("-Wl,--undefined=%s", symName),
- fmt.Sprintf("-Wl,--section-start=%s=0x%x",
- sectionName, baseLoadAddr+prog.Vaddr))
+ fmt.Fprintf(script, " %s 0x%x : {\n", sectionName, baseLoadAddr+prog.Vaddr)
+ fmt.Fprintf(script, " KEEP(*(%s));\n", sectionName)
+ fmt.Fprintln(script, " }")
buffer, _ := ioutil.ReadAll(prog.Open())
bytesToAsm(asm, buffer)
@@ -97,16 +106,20 @@
load += 1
}
+ fmt.Fprintln(asm, `.section .note.android.embedded_linker,"a",%note`)
+
+ fmt.Fprintln(script, "}")
+ fmt.Fprintln(script, "INSERT BEFORE .note.android.embedded_linker;")
+
if asmPath != "" {
if err := ioutil.WriteFile(asmPath, asm.Bytes(), 0777); err != nil {
log.Fatalf("Unable to write %q: %v", asmPath, err)
}
}
- if flagsPath != "" {
- flags := strings.Join(linkFlags, " ")
- if err := ioutil.WriteFile(flagsPath, []byte(flags), 0777); err != nil {
- log.Fatalf("Unable to write %q: %v", flagsPath, err)
+ if scriptPath != "" {
+ if err := ioutil.WriteFile(scriptPath, script.Bytes(), 0777); err != nil {
+ log.Fatalf("Unable to write %q: %v", scriptPath, err)
}
}
}
@@ -125,3 +138,12 @@
}
fmt.Fprintln(asm)
}
+
+func progToFirstSection(prog *elf.Prog, sections []*elf.Section) *elf.Section {
+ for _, section := range sections {
+ if section.Addr == prog.Vaddr {
+ return section
+ }
+ }
+ return nil
+}
diff --git a/cmd/host_bionic_inject/Android.bp b/cmd/go2bp/Android.bp
similarity index 76%
copy from cmd/host_bionic_inject/Android.bp
copy to cmd/go2bp/Android.bp
index 16bc179..53d70b6 100644
--- a/cmd/host_bionic_inject/Android.bp
+++ b/cmd/go2bp/Android.bp
@@ -1,4 +1,4 @@
-// Copyright 2018 Google Inc. All rights reserved.
+// 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.
@@ -17,8 +17,10 @@
}
blueprint_go_binary {
- name: "host_bionic_inject",
- deps: ["soong-symbol_inject"],
- srcs: ["host_bionic_inject.go"],
- testSrcs: ["host_bionic_inject_test.go"],
+ name: "go2bp",
+ deps: [
+ "blueprint-proptools",
+ "bpfix-lib",
+ ],
+ srcs: ["go2bp.go"],
}
diff --git a/cmd/go2bp/go2bp.go b/cmd/go2bp/go2bp.go
new file mode 100644
index 0000000..07cb5df
--- /dev/null
+++ b/cmd/go2bp/go2bp.go
@@ -0,0 +1,410 @@
+// 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 main
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "sort"
+ "strings"
+ "text/template"
+
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/bpfix/bpfix"
+)
+
+type RewriteNames []RewriteName
+type RewriteName struct {
+ prefix string
+ repl string
+}
+
+func (r *RewriteNames) String() string {
+ return ""
+}
+
+func (r *RewriteNames) Set(v string) error {
+ split := strings.SplitN(v, "=", 2)
+ if len(split) != 2 {
+ return fmt.Errorf("Must be in the form of <prefix>=<replace>")
+ }
+ *r = append(*r, RewriteName{
+ prefix: split[0],
+ repl: split[1],
+ })
+ return nil
+}
+
+func (r *RewriteNames) GoToBp(name string) string {
+ ret := name
+ for _, r := range *r {
+ prefix := r.prefix
+ if name == prefix {
+ ret = r.repl
+ break
+ }
+ prefix += "/"
+ if strings.HasPrefix(name, prefix) {
+ ret = r.repl + "-" + strings.TrimPrefix(name, prefix)
+ }
+ }
+ return strings.ReplaceAll(ret, "/", "-")
+}
+
+var rewriteNames = RewriteNames{}
+
+type Exclude map[string]bool
+
+func (e Exclude) String() string {
+ return ""
+}
+
+func (e Exclude) Set(v string) error {
+ e[v] = true
+ return nil
+}
+
+var excludes = make(Exclude)
+var excludeDeps = make(Exclude)
+var excludeSrcs = make(Exclude)
+
+type StringList []string
+
+func (l *StringList) String() string {
+ return strings.Join(*l, " ")
+}
+
+func (l *StringList) Set(v string) error {
+ *l = append(*l, strings.Fields(v)...)
+ return nil
+}
+
+type GoModule struct {
+ Dir string
+}
+
+type GoPackage struct {
+ ExportToAndroid bool
+
+ Dir string
+ ImportPath string
+ Name string
+ Imports []string
+ GoFiles []string
+ TestGoFiles []string
+ TestImports []string
+
+ Module *GoModule
+}
+
+func (g GoPackage) IsCommand() bool {
+ return g.Name == "main"
+}
+
+func (g GoPackage) BpModuleType() string {
+ if g.IsCommand() {
+ return "blueprint_go_binary"
+ }
+ return "bootstrap_go_package"
+}
+
+func (g GoPackage) BpName() string {
+ if g.IsCommand() {
+ return rewriteNames.GoToBp(filepath.Base(g.ImportPath))
+ }
+ return rewriteNames.GoToBp(g.ImportPath)
+}
+
+func (g GoPackage) BpDeps(deps []string) []string {
+ var ret []string
+ for _, d := range deps {
+ // Ignore stdlib dependencies
+ if !strings.Contains(d, ".") {
+ continue
+ }
+ if _, ok := excludeDeps[d]; ok {
+ continue
+ }
+ name := rewriteNames.GoToBp(d)
+ ret = append(ret, name)
+ }
+ return ret
+}
+
+func (g GoPackage) BpSrcs(srcs []string) []string {
+ var ret []string
+ prefix, err := filepath.Rel(g.Module.Dir, g.Dir)
+ if err != nil {
+ panic(err)
+ }
+ for _, f := range srcs {
+ f = filepath.Join(prefix, f)
+ if _, ok := excludeSrcs[f]; ok {
+ continue
+ }
+ ret = append(ret, f)
+ }
+ return ret
+}
+
+// AllImports combines Imports and TestImports, as blueprint does not differentiate these.
+func (g GoPackage) AllImports() []string {
+ imports := append([]string(nil), g.Imports...)
+ imports = append(imports, g.TestImports...)
+
+ if len(imports) == 0 {
+ return nil
+ }
+
+ // Sort and de-duplicate
+ sort.Strings(imports)
+ j := 0
+ for i := 1; i < len(imports); i++ {
+ if imports[i] == imports[j] {
+ continue
+ }
+ j++
+ imports[j] = imports[i]
+ }
+ return imports[:j+1]
+}
+
+var bpTemplate = template.Must(template.New("bp").Parse(`
+{{.BpModuleType}} {
+ name: "{{.BpName}}",
+ {{- if not .IsCommand}}
+ pkgPath: "{{.ImportPath}}",
+ {{- end}}
+ {{- if .BpDeps .AllImports}}
+ deps: [
+ {{- range .BpDeps .AllImports}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
+ {{- if .BpSrcs .GoFiles}}
+ srcs: [
+ {{- range .BpSrcs .GoFiles}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
+ {{- if .BpSrcs .TestGoFiles}}
+ testSrcs: [
+ {{- range .BpSrcs .TestGoFiles}}
+ "{{.}}",
+ {{- end}}
+ ],
+ {{- end}}
+}
+`))
+
+func rerunForRegen(filename string) error {
+ buf, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return err
+ }
+
+ scanner := bufio.NewScanner(bytes.NewBuffer(buf))
+
+ // Skip the first line in the file
+ for i := 0; i < 2; i++ {
+ if !scanner.Scan() {
+ if scanner.Err() != nil {
+ return scanner.Err()
+ } else {
+ return fmt.Errorf("unexpected EOF")
+ }
+ }
+ }
+
+ // Extract the old args from the file
+ line := scanner.Text()
+ if strings.HasPrefix(line, "// go2bp ") {
+ line = strings.TrimPrefix(line, "// go2bp ")
+ } else {
+ return fmt.Errorf("unexpected second line: %q", line)
+ }
+ args := strings.Split(line, " ")
+ lastArg := args[len(args)-1]
+ args = args[:len(args)-1]
+
+ // Append all current command line args except -regen <file> to the ones from the file
+ for i := 1; i < len(os.Args); i++ {
+ if os.Args[i] == "-regen" || os.Args[i] == "--regen" {
+ i++
+ } else {
+ args = append(args, os.Args[i])
+ }
+ }
+ args = append(args, lastArg)
+
+ cmd := os.Args[0] + " " + strings.Join(args, " ")
+ // Re-exec pom2bp with the new arguments
+ output, err := exec.Command("/bin/sh", "-c", cmd).Output()
+ if exitErr, _ := err.(*exec.ExitError); exitErr != nil {
+ return fmt.Errorf("failed to run %s\n%s", cmd, string(exitErr.Stderr))
+ } else if err != nil {
+ return err
+ }
+
+ return ioutil.WriteFile(filename, output, 0666)
+}
+
+func main() {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, `go2bp, a tool to create Android.bp files from go modules
+
+The tool will extract the necessary information from Go files to create an Android.bp that can
+compile them. This needs to be run from the same directory as the go.mod file.
+
+Usage: %s [--rewrite <pkg-prefix>=<replace>] [-exclude <package>] [-regen <file>]
+
+ -rewrite <pkg-prefix>=<replace>
+ rewrite can be used to specify mappings between go package paths and Android.bp modules. The -rewrite
+ option can be specified multiple times. When determining the Android.bp module for a given Go
+ package, mappings are searched in the order they were specified. The first <pkg-prefix> matching
+ either the package directly, or as the prefix '<pkg-prefix>/' will be replaced with <replace>.
+ After all replacements are finished, all '/' characters are replaced with '-'.
+ -exclude <package>
+ Don't put the specified go package in the Android.bp file.
+ -exclude-deps <package>
+ Don't put the specified go package in the dependency lists.
+ -exclude-srcs <module>
+ Don't put the specified source files in srcs or testSrcs lists.
+ -limit <package>
+ If set, limit the output to the specified packages and their dependencies.
+ -skip-tests
+ If passed, don't write out any test srcs or dependencies to the Android.bp output.
+ -regen <file>
+ Read arguments from <file> and overwrite it.
+
+`, os.Args[0])
+ }
+
+ var regen string
+ var skipTests bool
+ limit := StringList{}
+
+ flag.Var(&excludes, "exclude", "Exclude go package")
+ flag.Var(&excludeDeps, "exclude-dep", "Exclude go package from deps")
+ flag.Var(&excludeSrcs, "exclude-src", "Exclude go file from source lists")
+ flag.Var(&rewriteNames, "rewrite", "Regex(es) to rewrite artifact names")
+ flag.Var(&limit, "limit", "If set, only includes the dependencies of the listed packages")
+ flag.BoolVar(&skipTests, "skip-tests", false, "Whether to skip test sources")
+ flag.StringVar(®en, "regen", "", "Rewrite specified file")
+ flag.Parse()
+
+ if regen != "" {
+ err := rerunForRegen(regen)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ os.Exit(0)
+ }
+
+ if flag.NArg() != 0 {
+ fmt.Fprintf(os.Stderr, "Unused argument detected: %v\n", flag.Args())
+ os.Exit(1)
+ }
+
+ if _, err := os.Stat("go.mod"); err != nil {
+ fmt.Fprintln(os.Stderr, "go.mod file not found")
+ os.Exit(1)
+ }
+
+ cmd := exec.Command("go", "list", "-json", "./...")
+ output, err := cmd.Output()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to dump the go packages: %v\n", err)
+ os.Exit(1)
+ }
+ decoder := json.NewDecoder(bytes.NewReader(output))
+
+ pkgs := []*GoPackage{}
+ pkgMap := map[string]*GoPackage{}
+ for decoder.More() {
+ pkg := GoPackage{}
+ err := decoder.Decode(&pkg)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to parse json: %v\n", err)
+ os.Exit(1)
+ }
+ if len(limit) == 0 {
+ pkg.ExportToAndroid = true
+ }
+ if skipTests {
+ pkg.TestGoFiles = nil
+ pkg.TestImports = nil
+ }
+ pkgs = append(pkgs, &pkg)
+ pkgMap[pkg.ImportPath] = &pkg
+ }
+
+ buf := &bytes.Buffer{}
+
+ fmt.Fprintln(buf, "// Automatically generated with:")
+ fmt.Fprintln(buf, "// go2bp", strings.Join(proptools.ShellEscapeList(os.Args[1:]), " "))
+
+ var mark func(string)
+ mark = func(pkgName string) {
+ if excludes[pkgName] {
+ return
+ }
+ if pkg, ok := pkgMap[pkgName]; ok && !pkg.ExportToAndroid {
+ pkg.ExportToAndroid = true
+ for _, dep := range pkg.AllImports() {
+ if !excludeDeps[dep] {
+ mark(dep)
+ }
+ }
+ }
+ }
+
+ for _, pkgName := range limit {
+ mark(pkgName)
+ }
+
+ for _, pkg := range pkgs {
+ if !pkg.ExportToAndroid || excludes[pkg.ImportPath] {
+ continue
+ }
+ if len(pkg.BpSrcs(pkg.GoFiles)) == 0 && len(pkg.BpSrcs(pkg.TestGoFiles)) == 0 {
+ continue
+ }
+ err := bpTemplate.Execute(buf, pkg)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error writing", pkg.Name, err)
+ os.Exit(1)
+ }
+ }
+
+ out, err := bpfix.Reformat(buf.String())
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error formatting output", err)
+ os.Exit(1)
+ }
+
+ os.Stdout.WriteString(out)
+}
diff --git a/cmd/host_bionic_inject/Android.bp b/cmd/host_bionic_verify/Android.bp
similarity index 82%
rename from cmd/host_bionic_inject/Android.bp
rename to cmd/host_bionic_verify/Android.bp
index 16bc179..4e7c379 100644
--- a/cmd/host_bionic_inject/Android.bp
+++ b/cmd/host_bionic_verify/Android.bp
@@ -17,8 +17,7 @@
}
blueprint_go_binary {
- name: "host_bionic_inject",
- deps: ["soong-symbol_inject"],
- srcs: ["host_bionic_inject.go"],
- testSrcs: ["host_bionic_inject_test.go"],
+ name: "host_bionic_verify",
+ srcs: ["host_bionic_verify.go"],
+ testSrcs: ["host_bionic_verify_test.go"],
}
diff --git a/cmd/host_bionic_inject/host_bionic_inject.go b/cmd/host_bionic_verify/host_bionic_verify.go
similarity index 68%
rename from cmd/host_bionic_inject/host_bionic_inject.go
rename to cmd/host_bionic_verify/host_bionic_verify.go
index ce8b062..52400a3 100644
--- a/cmd/host_bionic_inject/host_bionic_inject.go
+++ b/cmd/host_bionic_verify/host_bionic_verify.go
@@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// Verifies a host bionic executable with an embedded linker, then injects
-// the address of the _start function for the linker_wrapper to use.
+// Verifies a host bionic executable with an embedded linker.
package main
import (
@@ -22,19 +21,16 @@
"fmt"
"io"
"os"
-
- "android/soong/symbol_inject"
)
func main() {
- var inputFile, linkerFile, outputFile string
+ var inputFile, linkerFile string
flag.StringVar(&inputFile, "i", "", "Input file")
flag.StringVar(&linkerFile, "l", "", "Linker file")
- flag.StringVar(&outputFile, "o", "", "Output file")
flag.Parse()
- if inputFile == "" || linkerFile == "" || outputFile == "" || flag.NArg() != 0 {
+ if inputFile == "" || linkerFile == "" || flag.NArg() != 0 {
flag.Usage()
os.Exit(1)
}
@@ -46,75 +42,52 @@
}
defer r.Close()
- file, err := symbol_inject.OpenFile(r)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(3)
- }
-
linker, err := elf.Open(linkerFile)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(4)
}
- startAddr, err := parseElf(r, linker)
+ err = checkElf(r, linker)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(5)
}
-
- w, err := os.OpenFile(outputFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(6)
- }
- defer w.Close()
-
- err = symbol_inject.InjectUint64Symbol(file, w, "__dlwrap_original_start", startAddr)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(7)
- }
}
// Check the ELF file, and return the address to the _start function
-func parseElf(r io.ReaderAt, linker *elf.File) (uint64, error) {
+func checkElf(r io.ReaderAt, linker *elf.File) error {
file, err := elf.NewFile(r)
if err != nil {
- return 0, err
+ return err
}
symbols, err := file.Symbols()
if err != nil {
- return 0, err
+ return err
}
for _, prog := range file.Progs {
if prog.Type == elf.PT_INTERP {
- return 0, fmt.Errorf("File should not have a PT_INTERP header")
+ return fmt.Errorf("File should not have a PT_INTERP header")
}
}
if dlwrap_start, err := findSymbol(symbols, "__dlwrap__start"); err != nil {
- return 0, err
+ return err
} else if dlwrap_start.Value != file.Entry {
- return 0, fmt.Errorf("Expected file entry(0x%x) to point to __dlwrap_start(0x%x)",
+ return fmt.Errorf("Expected file entry(0x%x) to point to __dlwrap_start(0x%x)",
file.Entry, dlwrap_start.Value)
}
err = checkLinker(file, linker, symbols)
if err != nil {
- return 0, fmt.Errorf("Linker executable failed verification against app embedded linker: %s\n"+
+ return fmt.Errorf("Linker executable failed verification against app embedded linker: %s\n"+
"linker might not be in sync with crtbegin_dynamic.o.",
err)
}
- start, err := findSymbol(symbols, "_start")
- if err != nil {
- return 0, fmt.Errorf("Failed to find _start symbol")
- }
- return start.Value, nil
+ return nil
}
func findSymbol(symbols []elf.Symbol, name string) (elf.Symbol, error) {
diff --git a/cmd/host_bionic_inject/host_bionic_inject_test.go b/cmd/host_bionic_verify/host_bionic_verify_test.go
similarity index 100%
rename from cmd/host_bionic_inject/host_bionic_inject_test.go
rename to cmd/host_bionic_verify/host_bionic_verify_test.go
diff --git a/cmd/run_with_timeout/run_with_timeout.go b/cmd/run_with_timeout/run_with_timeout.go
index f2caaab..deaa842 100644
--- a/cmd/run_with_timeout/run_with_timeout.go
+++ b/cmd/run_with_timeout/run_with_timeout.go
@@ -47,7 +47,7 @@
flag.Parse()
if flag.NArg() < 1 {
- fmt.Fprintln(os.Stderr, "command is required")
+ fmt.Fprintf(os.Stderr, "%s: error: command is required\n", os.Args[0])
usage()
}
@@ -55,9 +55,9 @@
os.Stdin, os.Stdout, os.Stderr)
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
- fmt.Fprintln(os.Stderr, "process exited with error:", exitErr.Error())
+ fmt.Fprintf(os.Stderr, "%s: process exited with error: %s\n", os.Args[0], exitErr.Error())
} else {
- fmt.Fprintln(os.Stderr, "error:", err.Error())
+ fmt.Fprintf(os.Stderr, "%s: error: %s\n", os.Args[0], err.Error())
}
os.Exit(1)
}
@@ -115,6 +115,7 @@
if timeout > 0 {
timeoutCh = time.After(timeout)
}
+ startTime := time.Now()
select {
case err := <-waitCh:
@@ -126,10 +127,12 @@
// Continue below.
}
+ fmt.Fprintf(concurrentStderr, "%s: process timed out after %s\n", os.Args[0], time.Since(startTime))
// Process timed out before exiting.
defer cmd.Process.Signal(syscall.SIGKILL)
if onTimeoutCmdStr != "" {
+ fmt.Fprintf(concurrentStderr, "%s: running on_timeout command `%s`\n", os.Args[0], onTimeoutCmdStr)
onTimeoutCmd := exec.Command("sh", "-c", onTimeoutCmdStr)
onTimeoutCmd.Stdin, onTimeoutCmd.Stdout, onTimeoutCmd.Stderr = stdin, concurrentStdout, concurrentStderr
onTimeoutCmd.Env = append(os.Environ(), fmt.Sprintf("PID=%d", cmd.Process.Pid))
diff --git a/cmd/run_with_timeout/run_with_timeout_test.go b/cmd/run_with_timeout/run_with_timeout_test.go
index aebd336..ed6ec11 100644
--- a/cmd/run_with_timeout/run_with_timeout_test.go
+++ b/cmd/run_with_timeout/run_with_timeout_test.go
@@ -17,6 +17,7 @@
import (
"bytes"
"io"
+ "regexp"
"testing"
"time"
)
@@ -60,7 +61,8 @@
args: []string{"-c", "sleep 1 && echo foo"},
timeout: 1 * time.Millisecond,
},
- wantErr: true,
+ wantStderr: ".*: process timed out after .*\n",
+ wantErr: true,
},
{
name: "on_timeout command",
@@ -71,6 +73,7 @@
onTimeoutCmd: "echo bar",
},
wantStdout: "bar\n",
+ wantStderr: ".*: process timed out after .*\n.*: running on_timeout command `echo bar`\n",
wantErr: true,
},
}
@@ -86,7 +89,7 @@
if gotStdout := stdout.String(); gotStdout != tt.wantStdout {
t.Errorf("runWithTimeout() gotStdout = %v, want %v", gotStdout, tt.wantStdout)
}
- if gotStderr := stderr.String(); gotStderr != tt.wantStderr {
+ if gotStderr := stderr.String(); !regexp.MustCompile(tt.wantStderr).MatchString(gotStderr) {
t.Errorf("runWithTimeout() gotStderr = %v, want %v", gotStderr, tt.wantStderr)
}
})
diff --git a/cmd/sbox/Android.bp b/cmd/sbox/Android.bp
index b8d75ed..454cfd8 100644
--- a/cmd/sbox/Android.bp
+++ b/cmd/sbox/Android.bp
@@ -19,6 +19,7 @@
blueprint_go_binary {
name: "sbox",
deps: [
+ "golang-protobuf-encoding-prototext",
"sbox_proto",
"soong-makedeps",
"soong-response",
@@ -31,7 +32,10 @@
bootstrap_go_package {
name: "sbox_proto",
pkgPath: "android/soong/cmd/sbox/sbox_proto",
- deps: ["golang-protobuf-proto"],
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
srcs: [
"sbox_proto/sbox.pb.go",
],
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index f124e40..c7f3f6a 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -34,7 +34,7 @@
"android/soong/makedeps"
"android/soong/response"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/encoding/prototext"
)
var (
@@ -203,7 +203,7 @@
manifest := sbox_proto.Manifest{}
- err = proto.UnmarshalText(string(manifestData), &manifest)
+ err = prototext.Unmarshal(manifestData, &manifest)
if err != nil {
return nil, fmt.Errorf("error parsing manifest %q: %w", file, err)
}
diff --git a/cmd/sbox/sbox_proto/sbox.pb.go b/cmd/sbox/sbox_proto/sbox.pb.go
index b996481..7c84f2c 100644
--- a/cmd/sbox/sbox_proto/sbox.pb.go
+++ b/cmd/sbox/sbox_proto/sbox.pb.go
@@ -1,78 +1,104 @@
+// Copyright 2020 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: sbox.proto
package sbox_proto
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
// A set of commands to run in a sandbox.
type Manifest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// A list of commands to run in the sandbox.
Commands []*Command `protobuf:"bytes,1,rep,name=commands" json:"commands,omitempty"`
// If set, GCC-style dependency files from any command that references __SBOX_DEPFILE__ will be
// merged into the given output file relative to the $PWD when sbox was started.
- OutputDepfile *string `protobuf:"bytes,2,opt,name=output_depfile,json=outputDepfile" json:"output_depfile,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ OutputDepfile *string `protobuf:"bytes,2,opt,name=output_depfile,json=outputDepfile" json:"output_depfile,omitempty"`
}
-func (m *Manifest) Reset() { *m = Manifest{} }
-func (m *Manifest) String() string { return proto.CompactTextString(m) }
-func (*Manifest) ProtoMessage() {}
+func (x *Manifest) Reset() {
+ *x = Manifest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sbox_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Manifest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Manifest) ProtoMessage() {}
+
+func (x *Manifest) ProtoReflect() protoreflect.Message {
+ mi := &file_sbox_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Manifest.ProtoReflect.Descriptor instead.
func (*Manifest) Descriptor() ([]byte, []int) {
- return fileDescriptor_9d0425bf0de86ed1, []int{0}
+ return file_sbox_proto_rawDescGZIP(), []int{0}
}
-func (m *Manifest) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Manifest.Unmarshal(m, b)
-}
-func (m *Manifest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Manifest.Marshal(b, m, deterministic)
-}
-func (m *Manifest) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Manifest.Merge(m, src)
-}
-func (m *Manifest) XXX_Size() int {
- return xxx_messageInfo_Manifest.Size(m)
-}
-func (m *Manifest) XXX_DiscardUnknown() {
- xxx_messageInfo_Manifest.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Manifest proto.InternalMessageInfo
-
-func (m *Manifest) GetCommands() []*Command {
- if m != nil {
- return m.Commands
+func (x *Manifest) GetCommands() []*Command {
+ if x != nil {
+ return x.Commands
}
return nil
}
-func (m *Manifest) GetOutputDepfile() string {
- if m != nil && m.OutputDepfile != nil {
- return *m.OutputDepfile
+func (x *Manifest) GetOutputDepfile() string {
+ if x != nil && x.OutputDepfile != nil {
+ return *x.OutputDepfile
}
return ""
}
// SandboxManifest describes a command to run in the sandbox.
type Command struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// A list of copy rules to run before the sandboxed command. The from field is relative to the
// $PWD when sbox was run, the to field is relative to the top of the temporary sandbox directory.
CopyBefore []*Copy `protobuf:"bytes,1,rep,name=copy_before,json=copyBefore" json:"copy_before,omitempty"`
@@ -89,75 +115,79 @@
InputHash *string `protobuf:"bytes,5,opt,name=input_hash,json=inputHash" json:"input_hash,omitempty"`
// A list of files that will be copied before the sandboxed command, and whose contents should be
// copied as if they were listed in copy_before.
- RspFiles []*RspFile `protobuf:"bytes,6,rep,name=rsp_files,json=rspFiles" json:"rsp_files,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ RspFiles []*RspFile `protobuf:"bytes,6,rep,name=rsp_files,json=rspFiles" json:"rsp_files,omitempty"`
}
-func (m *Command) Reset() { *m = Command{} }
-func (m *Command) String() string { return proto.CompactTextString(m) }
-func (*Command) ProtoMessage() {}
+func (x *Command) Reset() {
+ *x = Command{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sbox_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Command) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Command) ProtoMessage() {}
+
+func (x *Command) ProtoReflect() protoreflect.Message {
+ mi := &file_sbox_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Command.ProtoReflect.Descriptor instead.
func (*Command) Descriptor() ([]byte, []int) {
- return fileDescriptor_9d0425bf0de86ed1, []int{1}
+ return file_sbox_proto_rawDescGZIP(), []int{1}
}
-func (m *Command) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Command.Unmarshal(m, b)
-}
-func (m *Command) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Command.Marshal(b, m, deterministic)
-}
-func (m *Command) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Command.Merge(m, src)
-}
-func (m *Command) XXX_Size() int {
- return xxx_messageInfo_Command.Size(m)
-}
-func (m *Command) XXX_DiscardUnknown() {
- xxx_messageInfo_Command.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Command proto.InternalMessageInfo
-
-func (m *Command) GetCopyBefore() []*Copy {
- if m != nil {
- return m.CopyBefore
+func (x *Command) GetCopyBefore() []*Copy {
+ if x != nil {
+ return x.CopyBefore
}
return nil
}
-func (m *Command) GetChdir() bool {
- if m != nil && m.Chdir != nil {
- return *m.Chdir
+func (x *Command) GetChdir() bool {
+ if x != nil && x.Chdir != nil {
+ return *x.Chdir
}
return false
}
-func (m *Command) GetCommand() string {
- if m != nil && m.Command != nil {
- return *m.Command
+func (x *Command) GetCommand() string {
+ if x != nil && x.Command != nil {
+ return *x.Command
}
return ""
}
-func (m *Command) GetCopyAfter() []*Copy {
- if m != nil {
- return m.CopyAfter
+func (x *Command) GetCopyAfter() []*Copy {
+ if x != nil {
+ return x.CopyAfter
}
return nil
}
-func (m *Command) GetInputHash() string {
- if m != nil && m.InputHash != nil {
- return *m.InputHash
+func (x *Command) GetInputHash() string {
+ if x != nil && x.InputHash != nil {
+ return *x.InputHash
}
return ""
}
-func (m *Command) GetRspFiles() []*RspFile {
- if m != nil {
- return m.RspFiles
+func (x *Command) GetRspFiles() []*RspFile {
+ if x != nil {
+ return x.RspFiles
}
return nil
}
@@ -166,193 +196,341 @@
// are relative to is specific to the context the Copy is used in and will be different for
// from and to.
type Copy struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
From *string `protobuf:"bytes,1,req,name=from" json:"from,omitempty"`
To *string `protobuf:"bytes,2,req,name=to" json:"to,omitempty"`
// If true, make the file executable after copying it.
- Executable *bool `protobuf:"varint,3,opt,name=executable" json:"executable,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Executable *bool `protobuf:"varint,3,opt,name=executable" json:"executable,omitempty"`
}
-func (m *Copy) Reset() { *m = Copy{} }
-func (m *Copy) String() string { return proto.CompactTextString(m) }
-func (*Copy) ProtoMessage() {}
+func (x *Copy) Reset() {
+ *x = Copy{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sbox_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Copy) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Copy) ProtoMessage() {}
+
+func (x *Copy) ProtoReflect() protoreflect.Message {
+ mi := &file_sbox_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Copy.ProtoReflect.Descriptor instead.
func (*Copy) Descriptor() ([]byte, []int) {
- return fileDescriptor_9d0425bf0de86ed1, []int{2}
+ return file_sbox_proto_rawDescGZIP(), []int{2}
}
-func (m *Copy) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Copy.Unmarshal(m, b)
-}
-func (m *Copy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Copy.Marshal(b, m, deterministic)
-}
-func (m *Copy) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Copy.Merge(m, src)
-}
-func (m *Copy) XXX_Size() int {
- return xxx_messageInfo_Copy.Size(m)
-}
-func (m *Copy) XXX_DiscardUnknown() {
- xxx_messageInfo_Copy.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Copy proto.InternalMessageInfo
-
-func (m *Copy) GetFrom() string {
- if m != nil && m.From != nil {
- return *m.From
+func (x *Copy) GetFrom() string {
+ if x != nil && x.From != nil {
+ return *x.From
}
return ""
}
-func (m *Copy) GetTo() string {
- if m != nil && m.To != nil {
- return *m.To
+func (x *Copy) GetTo() string {
+ if x != nil && x.To != nil {
+ return *x.To
}
return ""
}
-func (m *Copy) GetExecutable() bool {
- if m != nil && m.Executable != nil {
- return *m.Executable
+func (x *Copy) GetExecutable() bool {
+ if x != nil && x.Executable != nil {
+ return *x.Executable
}
return false
}
// RspFile describes an rspfile that should be copied into the sandbox directory.
type RspFile struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The path to the rsp file.
File *string `protobuf:"bytes,1,req,name=file" json:"file,omitempty"`
// A list of path mappings that should be applied to each file listed in the rsp file.
- PathMappings []*PathMapping `protobuf:"bytes,2,rep,name=path_mappings,json=pathMappings" json:"path_mappings,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ PathMappings []*PathMapping `protobuf:"bytes,2,rep,name=path_mappings,json=pathMappings" json:"path_mappings,omitempty"`
}
-func (m *RspFile) Reset() { *m = RspFile{} }
-func (m *RspFile) String() string { return proto.CompactTextString(m) }
-func (*RspFile) ProtoMessage() {}
+func (x *RspFile) Reset() {
+ *x = RspFile{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sbox_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *RspFile) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RspFile) ProtoMessage() {}
+
+func (x *RspFile) ProtoReflect() protoreflect.Message {
+ mi := &file_sbox_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use RspFile.ProtoReflect.Descriptor instead.
func (*RspFile) Descriptor() ([]byte, []int) {
- return fileDescriptor_9d0425bf0de86ed1, []int{3}
+ return file_sbox_proto_rawDescGZIP(), []int{3}
}
-func (m *RspFile) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_RspFile.Unmarshal(m, b)
-}
-func (m *RspFile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_RspFile.Marshal(b, m, deterministic)
-}
-func (m *RspFile) XXX_Merge(src proto.Message) {
- xxx_messageInfo_RspFile.Merge(m, src)
-}
-func (m *RspFile) XXX_Size() int {
- return xxx_messageInfo_RspFile.Size(m)
-}
-func (m *RspFile) XXX_DiscardUnknown() {
- xxx_messageInfo_RspFile.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_RspFile proto.InternalMessageInfo
-
-func (m *RspFile) GetFile() string {
- if m != nil && m.File != nil {
- return *m.File
+func (x *RspFile) GetFile() string {
+ if x != nil && x.File != nil {
+ return *x.File
}
return ""
}
-func (m *RspFile) GetPathMappings() []*PathMapping {
- if m != nil {
- return m.PathMappings
+func (x *RspFile) GetPathMappings() []*PathMapping {
+ if x != nil {
+ return x.PathMappings
}
return nil
}
// PathMapping describes a mapping from a path outside the sandbox to the path inside the sandbox.
type PathMapping struct {
- From *string `protobuf:"bytes,1,req,name=from" json:"from,omitempty"`
- To *string `protobuf:"bytes,2,req,name=to" json:"to,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ From *string `protobuf:"bytes,1,req,name=from" json:"from,omitempty"`
+ To *string `protobuf:"bytes,2,req,name=to" json:"to,omitempty"`
}
-func (m *PathMapping) Reset() { *m = PathMapping{} }
-func (m *PathMapping) String() string { return proto.CompactTextString(m) }
-func (*PathMapping) ProtoMessage() {}
+func (x *PathMapping) Reset() {
+ *x = PathMapping{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_sbox_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PathMapping) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PathMapping) ProtoMessage() {}
+
+func (x *PathMapping) ProtoReflect() protoreflect.Message {
+ mi := &file_sbox_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use PathMapping.ProtoReflect.Descriptor instead.
func (*PathMapping) Descriptor() ([]byte, []int) {
- return fileDescriptor_9d0425bf0de86ed1, []int{4}
+ return file_sbox_proto_rawDescGZIP(), []int{4}
}
-func (m *PathMapping) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_PathMapping.Unmarshal(m, b)
-}
-func (m *PathMapping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_PathMapping.Marshal(b, m, deterministic)
-}
-func (m *PathMapping) XXX_Merge(src proto.Message) {
- xxx_messageInfo_PathMapping.Merge(m, src)
-}
-func (m *PathMapping) XXX_Size() int {
- return xxx_messageInfo_PathMapping.Size(m)
-}
-func (m *PathMapping) XXX_DiscardUnknown() {
- xxx_messageInfo_PathMapping.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PathMapping proto.InternalMessageInfo
-
-func (m *PathMapping) GetFrom() string {
- if m != nil && m.From != nil {
- return *m.From
+func (x *PathMapping) GetFrom() string {
+ if x != nil && x.From != nil {
+ return *x.From
}
return ""
}
-func (m *PathMapping) GetTo() string {
- if m != nil && m.To != nil {
- return *m.To
+func (x *PathMapping) GetTo() string {
+ if x != nil && x.To != nil {
+ return *x.To
}
return ""
}
-func init() {
- proto.RegisterType((*Manifest)(nil), "sbox.Manifest")
- proto.RegisterType((*Command)(nil), "sbox.Command")
- proto.RegisterType((*Copy)(nil), "sbox.Copy")
- proto.RegisterType((*RspFile)(nil), "sbox.RspFile")
- proto.RegisterType((*PathMapping)(nil), "sbox.PathMapping")
+var File_sbox_proto protoreflect.FileDescriptor
+
+var file_sbox_proto_rawDesc = []byte{
+ 0x0a, 0x0a, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x73, 0x62,
+ 0x6f, 0x78, 0x22, 0x5c, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x29,
+ 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x0d, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52,
+ 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x75, 0x74,
+ 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x70, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x44, 0x65, 0x70, 0x66, 0x69, 0x6c, 0x65,
+ 0x22, 0xdc, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2b, 0x0a, 0x0b,
+ 0x63, 0x6f, 0x70, 0x79, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x0a, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x52, 0x0a, 0x63,
+ 0x6f, 0x70, 0x79, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x68, 0x64,
+ 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x63, 0x68, 0x64, 0x69, 0x72, 0x12,
+ 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x02, 0x28, 0x09,
+ 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x29, 0x0a, 0x0a, 0x63, 0x6f, 0x70,
+ 0x79, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e,
+ 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x52, 0x09, 0x63, 0x6f, 0x70, 0x79, 0x41,
+ 0x66, 0x74, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61,
+ 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x48,
+ 0x61, 0x73, 0x68, 0x12, 0x2a, 0x0a, 0x09, 0x72, 0x73, 0x70, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73,
+ 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x52, 0x73,
+ 0x70, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x72, 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x22,
+ 0x4a, 0x0a, 0x04, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18,
+ 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74,
+ 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x65,
+ 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
+ 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x55, 0x0a, 0x07, 0x52,
+ 0x73, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01,
+ 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x61,
+ 0x74, 0x68, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x11, 0x2e, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70,
+ 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x70, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
+ 0x67, 0x73, 0x22, 0x31, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
+ 0x67, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52,
+ 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x02, 0x28,
+ 0x09, 0x52, 0x02, 0x74, 0x6f, 0x42, 0x23, 0x5a, 0x21, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x73, 0x62, 0x6f, 0x78, 0x2f,
+ 0x73, 0x62, 0x6f, 0x78, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
}
-func init() {
- proto.RegisterFile("sbox.proto", fileDescriptor_9d0425bf0de86ed1)
+var (
+ file_sbox_proto_rawDescOnce sync.Once
+ file_sbox_proto_rawDescData = file_sbox_proto_rawDesc
+)
+
+func file_sbox_proto_rawDescGZIP() []byte {
+ file_sbox_proto_rawDescOnce.Do(func() {
+ file_sbox_proto_rawDescData = protoimpl.X.CompressGZIP(file_sbox_proto_rawDescData)
+ })
+ return file_sbox_proto_rawDescData
}
-var fileDescriptor_9d0425bf0de86ed1 = []byte{
- // 342 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x5f, 0x4b, 0xc3, 0x30,
- 0x14, 0xc5, 0x69, 0xd7, 0xb9, 0xf6, 0xee, 0x0f, 0x18, 0x7c, 0xc8, 0x8b, 0x32, 0x0a, 0xc2, 0xa6,
- 0x30, 0xd0, 0x07, 0xdf, 0x9d, 0x22, 0x22, 0x0c, 0x24, 0xe0, 0x8b, 0x08, 0x25, 0xeb, 0x52, 0x5b,
- 0x58, 0x9b, 0x90, 0x64, 0xb0, 0x7d, 0x57, 0x3f, 0x8c, 0xe4, 0xa6, 0xd3, 0x82, 0x2f, 0xbe, 0xdd,
- 0x7b, 0x0e, 0xf7, 0xdc, 0x5f, 0xc2, 0x05, 0x30, 0x6b, 0xb9, 0x5f, 0x28, 0x2d, 0xad, 0x24, 0x91,
- 0xab, 0xd3, 0x0f, 0x88, 0x57, 0xbc, 0xa9, 0x0a, 0x61, 0x2c, 0x99, 0x43, 0x9c, 0xcb, 0xba, 0xe6,
- 0xcd, 0xc6, 0xd0, 0x60, 0xda, 0x9b, 0x0d, 0x6f, 0xc7, 0x0b, 0x1c, 0x78, 0xf0, 0x2a, 0xfb, 0xb1,
- 0xc9, 0x25, 0x4c, 0xe4, 0xce, 0xaa, 0x9d, 0xcd, 0x36, 0x42, 0x15, 0xd5, 0x56, 0xd0, 0x70, 0x1a,
- 0xcc, 0x12, 0x36, 0xf6, 0xea, 0xa3, 0x17, 0xd3, 0xaf, 0x00, 0x06, 0xed, 0x30, 0xb9, 0x86, 0x61,
- 0x2e, 0xd5, 0x21, 0x5b, 0x8b, 0x42, 0x6a, 0xd1, 0x2e, 0x80, 0xe3, 0x02, 0x75, 0x60, 0xe0, 0xec,
- 0x25, 0xba, 0xe4, 0x0c, 0xfa, 0x79, 0xb9, 0xa9, 0x34, 0xc6, 0xc6, 0xcc, 0x37, 0x84, 0xc2, 0xa0,
- 0x25, 0xa0, 0xbd, 0x69, 0x38, 0x4b, 0xd8, 0xb1, 0x25, 0x73, 0xc0, 0xe9, 0x8c, 0x17, 0x56, 0x68,
- 0x1a, 0xfd, 0xc9, 0x4e, 0x9c, 0x7b, 0xef, 0x4c, 0x72, 0x0e, 0x50, 0x35, 0x8e, 0xbc, 0xe4, 0xa6,
- 0xa4, 0x7d, 0xc4, 0x4e, 0x50, 0x79, 0xe6, 0xa6, 0x24, 0x57, 0x90, 0x68, 0xa3, 0x32, 0x87, 0x6f,
- 0xe8, 0x49, 0xf7, 0x17, 0x98, 0x51, 0x4f, 0xd5, 0x56, 0xb0, 0x58, 0xfb, 0xc2, 0xa4, 0x2f, 0x10,
- 0xb9, 0x74, 0x42, 0x20, 0x2a, 0xb4, 0xac, 0x69, 0x80, 0x50, 0x58, 0x93, 0x09, 0x84, 0x56, 0xd2,
- 0x10, 0x95, 0xd0, 0x4a, 0x72, 0x01, 0x20, 0xf6, 0x22, 0xdf, 0x59, 0xbe, 0xde, 0x0a, 0xda, 0xc3,
- 0x67, 0x75, 0x94, 0xf4, 0x0d, 0x06, 0xed, 0x02, 0x8c, 0x73, 0x5f, 0x7a, 0x8c, 0x73, 0xda, 0x1d,
- 0x8c, 0x15, 0xb7, 0x65, 0x56, 0x73, 0xa5, 0xaa, 0xe6, 0xd3, 0xd0, 0x10, 0xd1, 0x4e, 0x3d, 0xda,
- 0x2b, 0xb7, 0xe5, 0xca, 0x3b, 0x6c, 0xa4, 0x7e, 0x1b, 0x93, 0xde, 0xc0, 0xb0, 0x63, 0xfe, 0x87,
- 0x74, 0x39, 0x7a, 0xc7, 0x33, 0xc9, 0xf0, 0x4c, 0xbe, 0x03, 0x00, 0x00, 0xff, 0xff, 0x83, 0x82,
- 0xb0, 0xc3, 0x33, 0x02, 0x00, 0x00,
+var file_sbox_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_sbox_proto_goTypes = []interface{}{
+ (*Manifest)(nil), // 0: sbox.Manifest
+ (*Command)(nil), // 1: sbox.Command
+ (*Copy)(nil), // 2: sbox.Copy
+ (*RspFile)(nil), // 3: sbox.RspFile
+ (*PathMapping)(nil), // 4: sbox.PathMapping
+}
+var file_sbox_proto_depIdxs = []int32{
+ 1, // 0: sbox.Manifest.commands:type_name -> sbox.Command
+ 2, // 1: sbox.Command.copy_before:type_name -> sbox.Copy
+ 2, // 2: sbox.Command.copy_after:type_name -> sbox.Copy
+ 3, // 3: sbox.Command.rsp_files:type_name -> sbox.RspFile
+ 4, // 4: sbox.RspFile.path_mappings:type_name -> sbox.PathMapping
+ 5, // [5:5] is the sub-list for method output_type
+ 5, // [5:5] is the sub-list for method input_type
+ 5, // [5:5] is the sub-list for extension type_name
+ 5, // [5:5] is the sub-list for extension extendee
+ 0, // [0:5] is the sub-list for field type_name
+}
+
+func init() { file_sbox_proto_init() }
+func file_sbox_proto_init() {
+ if File_sbox_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_sbox_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Manifest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_sbox_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Command); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_sbox_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Copy); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_sbox_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*RspFile); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_sbox_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PathMapping); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_sbox_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 5,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_sbox_proto_goTypes,
+ DependencyIndexes: file_sbox_proto_depIdxs,
+ MessageInfos: file_sbox_proto_msgTypes,
+ }.Build()
+ File_sbox_proto = out.File
+ file_sbox_proto_rawDesc = nil
+ file_sbox_proto_goTypes = nil
+ file_sbox_proto_depIdxs = nil
}
diff --git a/cmd/sbox/sbox_proto/sbox.proto b/cmd/sbox/sbox_proto/sbox.proto
index bdf92c6..2f0dcf0 100644
--- a/cmd/sbox/sbox_proto/sbox.proto
+++ b/cmd/sbox/sbox_proto/sbox.proto
@@ -15,7 +15,7 @@
syntax = "proto2";
package sbox;
-option go_package = "sbox_proto";
+option go_package = "android/soong/cmd/sbox/sbox_proto";
// A set of commands to run in a sandbox.
message Manifest {
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 044689e..0336fb6 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -174,6 +174,9 @@
writeFakeNinjaFile(extraNinjaDeps, configuration.BuildDir())
}
+// doChosenActivity runs Soong for a specific activity, like bp2build, queryview
+// or the actual Soong build for the build.ninja file. Returns the top level
+// output file of the specific activity.
func doChosenActivity(configuration android.Config, extraNinjaDeps []string) string {
bazelConversionRequested := bp2buildMarker != ""
mixedModeBuild := configuration.BazelContext.BazelEnabled()
@@ -186,11 +189,7 @@
// Run the alternate pipeline of bp2build mutators and singleton to convert
// Blueprint to BUILD files before everything else.
runBp2Build(configuration, extraNinjaDeps)
- if bp2buildMarker != "" {
- return bp2buildMarker
- } else {
- return bootstrap.CmdlineArgs.OutFile
- }
+ return bp2buildMarker
}
ctx := newContext(configuration, prepareBuildActions)
@@ -326,13 +325,13 @@
ninjaFileName := "build.ninja"
ninjaFile := shared.JoinPath(topDir, buildDir, ninjaFileName)
- ninjaFileD := shared.JoinPath(topDir, buildDir, ninjaFileName)
+ ninjaFileD := shared.JoinPath(topDir, buildDir, ninjaFileName+".d")
// A workaround to create the 'nothing' ninja target so `m nothing` works,
// since bp2build runs without Kati, and the 'nothing' target is declared in
// a Makefile.
ioutil.WriteFile(ninjaFile, []byte("build nothing: phony\n phony_output = true\n"), 0666)
ioutil.WriteFile(ninjaFileD,
- []byte(fmt.Sprintf("%s: \\\n %s\n", ninjaFileName, extraNinjaDepsString)),
+ []byte(fmt.Sprintf("%s: \\\n %s\n", ninjaFile, extraNinjaDepsString)),
0666)
}
@@ -357,6 +356,83 @@
}
}
+// Find BUILD files in the srcDir which...
+//
+// - are not on the allow list (android/bazel.go#ShouldKeepExistingBuildFileForDir())
+//
+// - won't be overwritten by corresponding bp2build generated files
+//
+// And return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
+func getPathsToIgnoredBuildFiles(topDir string, generatedRoot string, srcDirBazelFiles []string) []string {
+ paths := make([]string, 0)
+
+ for _, srcDirBazelFileRelativePath := range srcDirBazelFiles {
+ srcDirBazelFileFullPath := shared.JoinPath(topDir, srcDirBazelFileRelativePath)
+ fileInfo, err := os.Stat(srcDirBazelFileFullPath)
+ if err != nil {
+ // Warn about error, but continue trying to check files
+ fmt.Fprintf(os.Stderr, "WARNING: Error accessing path '%s', err: %s\n", srcDirBazelFileFullPath, err)
+ continue
+ }
+ if fileInfo.IsDir() {
+ // Don't ignore entire directories
+ continue
+ }
+ if !(fileInfo.Name() == "BUILD" || fileInfo.Name() == "BUILD.bazel") {
+ // Don't ignore this file - it is not a build file
+ continue
+ }
+ srcDirBazelFileDir := filepath.Dir(srcDirBazelFileRelativePath)
+ if android.ShouldKeepExistingBuildFileForDir(srcDirBazelFileDir) {
+ // Don't ignore this existing build file
+ continue
+ }
+ correspondingBp2BuildFile := shared.JoinPath(topDir, generatedRoot, srcDirBazelFileRelativePath)
+ if _, err := os.Stat(correspondingBp2BuildFile); err == nil {
+ // If bp2build generated an alternate BUILD file, don't exclude this workspace path
+ // BUILD file clash resolution happens later in the symlink forest creation
+ continue
+ }
+ fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", srcDirBazelFileRelativePath)
+ paths = append(paths, srcDirBazelFileRelativePath)
+ }
+
+ return paths
+}
+
+// Returns temporary symlink forest excludes necessary for bazel build //external/... (and bazel build //frameworks/...) to work
+func getTemporaryExcludes() []string {
+ excludes := make([]string, 0)
+
+ // FIXME: 'autotest_lib' is a symlink back to external/autotest, and this causes an infinite symlink expansion error for Bazel
+ excludes = append(excludes, "external/autotest/venv/autotest_lib")
+
+ // FIXME: The external/google-fruit/extras/bazel_root/third_party/fruit dir is poison
+ // It contains several symlinks back to real source dirs, and those source dirs contain BUILD files we want to ignore
+ excludes = append(excludes, "external/google-fruit/extras/bazel_root/third_party/fruit")
+
+ // FIXME: 'frameworks/compile/slang' has a filegroup error due to an escaping issue
+ excludes = append(excludes, "frameworks/compile/slang")
+
+ return excludes
+}
+
+// Read the bazel.list file that the Soong Finder already dumped earlier (hopefully)
+// It contains the locations of BUILD files, BUILD.bazel files, etc. in the source dir
+func getExistingBazelRelatedFiles(topDir string) ([]string, error) {
+ bazelFinderFile := filepath.Join(filepath.Dir(bootstrap.CmdlineArgs.ModuleListFile), "bazel.list")
+ if !filepath.IsAbs(bazelFinderFile) {
+ // Assume this was a relative path under topDir
+ bazelFinderFile = filepath.Join(topDir, bazelFinderFile)
+ }
+ data, err := ioutil.ReadFile(bazelFinderFile)
+ if err != nil {
+ return nil, err
+ }
+ files := strings.Split(strings.TrimSpace(string(data)), "\n")
+ return files, nil
+}
+
// Run Soong in the bp2build mode. This creates a standalone context that registers
// an alternate pipeline of mutators and singletons specifically for generating
// Bazel BUILD files instead of Ninja files.
@@ -415,6 +491,17 @@
excludes = append(excludes, bootstrap.CmdlineArgs.NinjaBuildDir)
}
+ existingBazelRelatedFiles, err := getExistingBazelRelatedFiles(topDir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error determining existing Bazel-related files: %s\n", err)
+ os.Exit(1)
+ }
+
+ pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(topDir, generatedRoot, existingBazelRelatedFiles)
+ excludes = append(excludes, pathsToIgnoredBuildFiles...)
+
+ excludes = append(excludes, getTemporaryExcludes()...)
+
symlinkForestDeps := bp2build.PlantSymlinkForest(
topDir, workspaceRoot, generatedRoot, configuration.SrcDir(), excludes)
@@ -433,9 +520,14 @@
os.Exit(1)
}
- if bp2buildMarker != "" {
- touch(shared.JoinPath(topDir, bp2buildMarker))
- } else {
- writeFakeNinjaFile(extraNinjaDeps, codegenContext.Config().BuildDir())
- }
+ // Create an empty bp2build marker file.
+ touch(shared.JoinPath(topDir, bp2buildMarker))
+
+ // bp2build *always* writes a fake Ninja file containing just the nothing
+ // phony target if it ever re-runs. This allows bp2build to exit early with
+ // GENERATE_BAZEL_FILES=1 m nothing.
+ //
+ // If bp2build is invoked as part of an integrated mixed build, the fake
+ // build.ninja file will be rewritten later into the real file anyway.
+ writeFakeNinjaFile(extraNinjaDeps, codegenContext.Config().BuildDir())
}
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index e2ce772..a8602de 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -25,9 +25,10 @@
func createBazelQueryView(ctx *bp2build.CodegenContext, bazelQueryViewDir string) error {
ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories())
- // Ignore metrics reporting for queryview, since queryview is already a full-repo
- // conversion and can use data from bazel query directly.
- buildToTargets, _ := bp2build.GenerateBazelTargets(ctx, true)
+ // Ignore metrics reporting and compat layers for queryview, since queryview
+ // is already a full-repo conversion and can use data from bazel query
+ // directly.
+ buildToTargets, _, _ := bp2build.GenerateBazelTargets(ctx, true)
filesToWrite := bp2build.CreateBazelFiles(ruleShims, buildToTargets, bp2build.QueryView)
for _, f := range filesToWrite {
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 8bcc712..02c5229 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -205,13 +205,12 @@
Status: stat,
}}
- config := c.config(buildCtx, args...)
-
if err := loadEnvConfig(); err != nil {
fmt.Fprintf(os.Stderr, "failed to parse env config files: %v", err)
os.Exit(1)
}
+ config := c.config(buildCtx, args...)
build.SetupOutDir(buildCtx, config)
diff --git a/dexpreopt/OWNERS b/dexpreopt/OWNERS
index 166472f..5a2a198 100644
--- a/dexpreopt/OWNERS
+++ b/dexpreopt/OWNERS
@@ -1 +1 @@
-per-file * = ngeoffray@google.com,calin@google.com,mathieuc@google.com
+per-file * = ngeoffray@google.com,calin@google.com,skvadrik@google.com
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index 57b4c4f..245af2c 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -15,6 +15,7 @@
package dexpreopt
import (
+ "encoding/json"
"fmt"
"sort"
"strconv"
@@ -285,11 +286,19 @@
}
subcontexts := nestedClcMap[AnySdkVersion]
- // If the library with this name is already present as one of the unconditional top-level
- // components, do not re-add it.
+ // Check if the library with this name is already present in unconditional top-level CLC.
for _, clc := range clcMap[sdkVer] {
- if clc.Name == lib {
+ if clc.Name != lib {
+ // Ok, a different library.
+ } else if clc.Host == hostPath && clc.Device == devicePath {
+ // Ok, the same library with the same paths. Don't re-add it, but don't raise an error
+ // either, as the same library may be reachable via different transitional dependencies.
return nil
+ } else {
+ // Fail, as someone is trying to add the same library with different paths. This likely
+ // indicates an error somewhere else, like trying to add a stub library.
+ return fmt.Errorf("a <uses-library> named %q is already in class loader context,"+
+ "but the library paths are different:\t\n", lib)
}
}
@@ -363,6 +372,15 @@
return ulibs
}
+func (clcMap ClassLoaderContextMap) Dump() string {
+ jsonCLC := toJsonClassLoaderContext(clcMap)
+ bytes, err := json.MarshalIndent(jsonCLC, "", " ")
+ if err != nil {
+ panic(err)
+ }
+ return string(bytes)
+}
+
// Now that the full unconditional context is known, reconstruct conditional context.
// Apply filters for individual libraries, mirroring what the PackageManager does when it
// constructs class loader context on device.
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 0bcec17..7a74506 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -44,15 +44,15 @@
DisableGenerateProfile bool // don't generate profiles
ProfileDir string // directory to find profiles in
- BootJars android.ConfiguredJarList // modules for jars that form the boot class path
- UpdatableBootJars android.ConfiguredJarList // jars within apex that form the boot class path
+ BootJars android.ConfiguredJarList // modules for jars that form the boot class path
+ ApexBootJars android.ConfiguredJarList // jars within apex that form the boot class path
ArtApexJars android.ConfiguredJarList // modules for jars that are in the ART APEX
- SystemServerJars android.ConfiguredJarList // jars that form the system server
- SystemServerApps []string // apps that are loaded into system server
- UpdatableSystemServerJars android.ConfiguredJarList // jars within apex that are loaded into system server
- SpeedApps []string // apps that should be speed optimized
+ SystemServerJars android.ConfiguredJarList // jars that form the system server
+ SystemServerApps []string // apps that are loaded into system server
+ ApexSystemServerJars android.ConfiguredJarList // jars within apex that are loaded into system server
+ SpeedApps []string // apps that should be speed optimized
BrokenSuboptimalOrderOfSystemServerJars bool // if true, sub-optimal order does not cause a build error
@@ -531,7 +531,7 @@
return config, nil
}
-// checkBootJarsConfigConsistency checks the consistency of BootJars and UpdatableBootJars fields in
+// checkBootJarsConfigConsistency checks the consistency of BootJars and ApexBootJars fields in
// DexpreoptGlobalConfig and Config.productVariables.
func checkBootJarsConfigConsistency(ctx android.SingletonContext, dexpreoptConfig *GlobalConfig, config android.Config) {
compareBootJars := func(property string, dexpreoptJars, variableJars android.ConfiguredJarList) {
@@ -545,8 +545,8 @@
}
}
- compareBootJars("BootJars", dexpreoptConfig.BootJars, config.NonUpdatableBootJars())
- compareBootJars("UpdatableBootJars", dexpreoptConfig.UpdatableBootJars, config.UpdatableBootJars())
+ compareBootJars("BootJars", dexpreoptConfig.BootJars, config.NonApexBootJars())
+ compareBootJars("ApexBootJars", dexpreoptConfig.ApexBootJars, config.ApexBootJars())
}
func (s *globalSoongConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
@@ -614,11 +614,11 @@
DisableGenerateProfile: false,
ProfileDir: "",
BootJars: android.EmptyConfiguredJarList(),
- UpdatableBootJars: android.EmptyConfiguredJarList(),
+ ApexBootJars: android.EmptyConfiguredJarList(),
ArtApexJars: android.EmptyConfiguredJarList(),
SystemServerJars: android.EmptyConfiguredJarList(),
SystemServerApps: nil,
- UpdatableSystemServerJars: android.EmptyConfiguredJarList(),
+ ApexSystemServerJars: android.EmptyConfiguredJarList(),
SpeedApps: nil,
PreoptFlags: nil,
DefaultCompilerFilter: "",
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index da015a3..4c6ae82 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -111,7 +111,7 @@
}
// Don't preopt system server jars that are updatable.
- if global.UpdatableSystemServerJars.ContainsJar(module.Name) {
+ if global.ApexSystemServerJars.ContainsJar(module.Name) {
return true
}
@@ -234,7 +234,7 @@
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
- systemServerJars := NonUpdatableSystemServerJars(ctx, global)
+ systemServerJars := NonApexSystemServerJars(ctx, global)
rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
rule.Command().FlagWithOutput("rm -f ", odexPath)
@@ -523,13 +523,13 @@
}
}
-var nonUpdatableSystemServerJarsKey = android.NewOnceKey("nonUpdatableSystemServerJars")
+var nonApexSystemServerJarsKey = android.NewOnceKey("nonApexSystemServerJars")
// TODO: eliminate the superficial global config parameter by moving global config definition
// from java subpackage to dexpreopt.
-func NonUpdatableSystemServerJars(ctx android.PathContext, global *GlobalConfig) []string {
- return ctx.Config().Once(nonUpdatableSystemServerJarsKey, func() interface{} {
- return android.RemoveListFromList(global.SystemServerJars.CopyOfJars(), global.UpdatableSystemServerJars.CopyOfJars())
+func NonApexSystemServerJars(ctx android.PathContext, global *GlobalConfig) []string {
+ return ctx.Config().Once(nonApexSystemServerJarsKey, func() interface{} {
+ return android.RemoveListFromList(global.SystemServerJars.CopyOfJars(), global.ApexSystemServerJars.CopyOfJars())
}).([]string)
}
@@ -556,7 +556,7 @@
mctx, isModule := ctx.(android.ModuleContext)
if isModule {
config := GetGlobalConfig(ctx)
- jars := NonUpdatableSystemServerJars(ctx, config)
+ jars := NonApexSystemServerJars(ctx, config)
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
depIndex := android.IndexList(dep.Name(), jars)
if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
diff --git a/dexpreopt/testing.go b/dexpreopt/testing.go
index c0ba5ca..2f99655 100644
--- a/dexpreopt/testing.go
+++ b/dexpreopt/testing.go
@@ -118,10 +118,10 @@
})
}
-// FixtureSetUpdatableBootJars sets the UpdatableBootJars property in the global config.
-func FixtureSetUpdatableBootJars(bootJars ...string) android.FixturePreparer {
+// FixtureSetApexBootJars sets the ApexBootJars property in the global config.
+func FixtureSetApexBootJars(bootJars ...string) android.FixturePreparer {
return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
- dexpreoptConfig.UpdatableBootJars = android.CreateTestConfiguredJarList(bootJars)
+ dexpreoptConfig.ApexBootJars = android.CreateTestConfiguredJarList(bootJars)
})
}
diff --git a/docs/map_files.md b/docs/map_files.md
index 192530f..1388059 100644
--- a/docs/map_files.md
+++ b/docs/map_files.md
@@ -70,9 +70,11 @@
### apex
-Indicates that the version or symbol is to be exposed in the APEX stubs rather
-than the NDK. May be used in combination with `llndk` if the symbol is exposed
-to both APEX and the LL-NDK.
+Indicates that the version or symbol is to be exposed by an APEX rather than the
+NDK. For APIs exposed by the platform *for* APEX, use `systemapi`.
+
+May be used in combination with `llndk` if the symbol is exposed to both APEX
+and the LL-NDK.
### future
@@ -144,6 +146,12 @@
preferable to keep such APIs in an entirely separate library to protect them
from access via `dlsym`, but this is not always possible.
+### systemapi
+
+This is a synonym of the `apex` tag. It should be used to clarify that the API
+is an API exposed by the system for an APEX, whereas `apex` should be used for
+APIs exposed by an APEX to the platform or another APEX.
+
### var
Used to define a public global variable. By default all symbols are exposed as
diff --git a/etc/Android.bp b/etc/Android.bp
index cab7389..c670236 100644
--- a/etc/Android.bp
+++ b/etc/Android.bp
@@ -9,12 +9,15 @@
"blueprint",
"soong",
"soong-android",
+ "soong-snapshot",
],
srcs: [
"prebuilt_etc.go",
+ "snapshot_etc.go",
],
testSrcs: [
"prebuilt_etc_test.go",
+ "snapshot_etc_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 4dd383d..8aeb0dd 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -28,12 +28,16 @@
// various `prebuilt_*` mutators.
import (
+ "encoding/json"
"fmt"
+ "path/filepath"
"strings"
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/bazel"
+ "android/soong/snapshot"
)
var pctx = android.NewPackageContext("android/soong/etc")
@@ -43,6 +47,7 @@
func init() {
pctx.Import("android/soong/android")
RegisterPrebuiltEtcBuildComponents(android.InitRegistrationContext)
+ snapshot.RegisterSnapshotAction(generatePrebuiltSnapshot)
}
func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) {
@@ -57,6 +62,8 @@
ctx.RegisterModuleType("prebuilt_rfsa", PrebuiltRFSAFactory)
ctx.RegisterModuleType("prebuilt_defaults", defaultsFactory)
+
+ android.RegisterBp2BuildMutator("prebuilt_etc", PrebuiltEtcBp2Build)
}
var PrepareForTestWithPrebuiltEtc = android.FixtureRegisterWithContext(RegisterPrebuiltEtcBuildComponents)
@@ -127,6 +134,10 @@
type PrebuiltEtc struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.BazelModuleBase
+
+ snapshot.VendorSnapshotModuleInterface
+ snapshot.RecoverySnapshotModuleInterface
properties prebuiltEtcProperties
subdirProperties prebuiltSubdirProperties
@@ -183,7 +194,7 @@
return p.inDebugRamdisk()
}
-func (p *PrebuiltEtc) inRecovery() bool {
+func (p *PrebuiltEtc) InRecovery() bool {
return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery()
}
@@ -192,7 +203,7 @@
}
func (p *PrebuiltEtc) InstallInRecovery() bool {
- return p.inRecovery()
+ return p.InRecovery()
}
var _ android.ImageInterface = (*PrebuiltEtc)(nil)
@@ -271,6 +282,18 @@
return p.properties.Installable == nil || proptools.Bool(p.properties.Installable)
}
+func (p *PrebuiltEtc) InVendor() bool {
+ return p.ModuleBase.InstallInVendor()
+}
+
+func (p *PrebuiltEtc) ExcludeFromVendorSnapshot() bool {
+ return false
+}
+
+func (p *PrebuiltEtc) ExcludeFromRecoverySnapshot() bool {
+ return false
+}
+
func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if p.properties.Src == nil {
ctx.PropertyErrorf("src", "missing prebuilt source file")
@@ -344,7 +367,7 @@
if p.inDebugRamdisk() && !p.onlyInDebugRamdisk() {
nameSuffix = ".debug_ramdisk"
}
- if p.inRecovery() && !p.onlyInRecovery() {
+ if p.InRecovery() && !p.onlyInRecovery() {
nameSuffix = ".recovery"
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
@@ -387,6 +410,7 @@
// This module is device-only
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
android.InitDefaultableModule(module)
+ android.InitBazelModule(module)
return module
}
@@ -494,3 +518,216 @@
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
return module
}
+
+// Flags to be included in the snapshot
+type snapshotJsonFlags struct {
+ ModuleName string `json:",omitempty"`
+ Filename string `json:",omitempty"`
+ RelativeInstallPath string `json:",omitempty"`
+}
+
+// Copy file into the snapshot
+func copyFile(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath {
+ if fake {
+ // Create empty file instead for the fake snapshot
+ return snapshot.WriteStringToFileRule(ctx, "", out)
+ } else {
+ return snapshot.CopyFileRule(pctx, ctx, path, out)
+ }
+}
+
+// Check if the module is target of the snapshot
+func isSnapshotAware(ctx android.SingletonContext, m *PrebuiltEtc, image snapshot.SnapshotImage) bool {
+ if !m.Enabled() {
+ return false
+ }
+
+ // Skip if the module is not included in the image
+ if !image.InImage(m)() {
+ return false
+ }
+
+ // When android/prebuilt.go selects between source and prebuilt, it sets
+ // HideFromMake on the other one to avoid duplicate install rules in make.
+ if m.IsHideFromMake() {
+ return false
+ }
+
+ // There are some prebuilt_etc module with multiple definition of same name.
+ // Check if the target would be included from the build
+ if !m.ExportedToMake() {
+ return false
+ }
+
+ // Skip if the module is in the predefined path list to skip
+ if image.IsProprietaryPath(ctx.ModuleDir(m), ctx.DeviceConfig()) {
+ return false
+ }
+
+ // Skip if the module should be excluded
+ if image.ExcludeFromSnapshot(m) || image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
+ return false
+ }
+
+ // Skip from other exceptional cases
+ if m.Target().Os.Class != android.Device {
+ return false
+ }
+ if m.Target().NativeBridge == android.NativeBridgeEnabled {
+ return false
+ }
+
+ return true
+}
+
+func generatePrebuiltSnapshot(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) android.Paths {
+ /*
+ Snapshot zipped artifacts directory structure for etc modules:
+ {SNAPSHOT_ARCH}/
+ arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
+ etc/
+ (prebuilt etc files)
+ arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
+ etc/
+ (prebuilt etc files)
+ NOTICE_FILES/
+ (notice files)
+ */
+ var snapshotOutputs android.Paths
+ noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
+ installedNotices := make(map[string]bool)
+
+ ctx.VisitAllModules(func(module android.Module) {
+ m, ok := module.(*PrebuiltEtc)
+ if !ok {
+ return
+ }
+
+ if !isSnapshotAware(ctx, m, s.Image) {
+ return
+ }
+
+ targetArch := "arch-" + m.Target().Arch.ArchType.String()
+
+ snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "etc", m.BaseModuleName())
+ snapshotOutputs = append(snapshotOutputs, copyFile(ctx, m.OutputFile(), snapshotLibOut, s.Fake))
+
+ prop := snapshotJsonFlags{}
+ propOut := snapshotLibOut + ".json"
+ prop.ModuleName = m.BaseModuleName()
+ if m.subdirProperties.Relative_install_path != nil {
+ prop.RelativeInstallPath = *m.subdirProperties.Relative_install_path
+ }
+
+ if m.properties.Filename != nil {
+ prop.Filename = *m.properties.Filename
+ }
+
+ j, err := json.Marshal(prop)
+ if err != nil {
+ ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
+ return
+ }
+ snapshotOutputs = append(snapshotOutputs, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
+
+ if len(m.EffectiveLicenseFiles()) > 0 {
+ noticeName := ctx.ModuleName(m) + ".txt"
+ noticeOut := filepath.Join(noticeDir, noticeName)
+ // skip already copied notice file
+ if !installedNotices[noticeOut] {
+ installedNotices[noticeOut] = true
+
+ noticeOutPath := android.PathForOutput(ctx, noticeOut)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cat,
+ Inputs: m.EffectiveLicenseFiles(),
+ Output: noticeOutPath,
+ Description: "combine notices for " + noticeOut,
+ })
+ snapshotOutputs = append(snapshotOutputs, noticeOutPath)
+ }
+ }
+
+ })
+
+ return snapshotOutputs
+}
+
+// For Bazel / bp2build
+
+type bazelPrebuiltEtcAttributes struct {
+ Src bazel.LabelAttribute
+ Filename string
+ Sub_dir string
+ Installable bazel.BoolAttribute
+}
+
+type bazelPrebuiltEtc struct {
+ android.BazelTargetModuleBase
+ bazelPrebuiltEtcAttributes
+}
+
+func BazelPrebuiltEtcFactory() android.Module {
+ module := &bazelPrebuiltEtc{}
+ module.AddProperties(&module.bazelPrebuiltEtcAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+func PrebuiltEtcBp2Build(ctx android.TopDownMutatorContext) {
+ module, ok := ctx.Module().(*PrebuiltEtc)
+ if !ok {
+ // Not an prebuilt_etc
+ return
+ }
+ if !module.ConvertWithBp2build(ctx) {
+ return
+ }
+ if ctx.ModuleType() != "prebuilt_etc" {
+ return
+ }
+
+ prebuiltEtcBp2BuildInternal(ctx, module)
+}
+
+func prebuiltEtcBp2BuildInternal(ctx android.TopDownMutatorContext, module *PrebuiltEtc) {
+ var srcLabelAttribute bazel.LabelAttribute
+ if module.properties.Src != nil {
+ srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.Src))
+ }
+
+ var filename string
+ if module.properties.Filename != nil {
+ filename = *module.properties.Filename
+ }
+
+ var subDir string
+ if module.subdirProperties.Sub_dir != nil {
+ subDir = *module.subdirProperties.Sub_dir
+ }
+
+ var installableBoolAttribute bazel.BoolAttribute
+ if module.properties.Installable != nil {
+ installableBoolAttribute.Value = module.properties.Installable
+ }
+
+ attrs := &bazelPrebuiltEtcAttributes{
+ Src: srcLabelAttribute,
+ Filename: filename,
+ Sub_dir: subDir,
+ Installable: installableBoolAttribute,
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "prebuilt_etc",
+ Bzl_load_location: "//build/bazel/rules:prebuilt_etc.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(BazelPrebuiltEtcFactory, module.Name(), props, attrs)
+}
+
+func (m *bazelPrebuiltEtc) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelPrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index 354f6bb..cf1f6d7 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -15,11 +15,15 @@
package etc
import (
+ "fmt"
"os"
"path/filepath"
"testing"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
+ "android/soong/snapshot"
)
func TestMain(m *testing.M) {
@@ -36,6 +40,18 @@
}),
)
+var prepareForPrebuiltEtcSnapshotTest = android.GroupFixturePreparers(
+ prepareForPrebuiltEtcTest,
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ snapshot.VendorSnapshotImageSingleton.Init(ctx)
+ snapshot.RecoverySnapshotImageSingleton.Init(ctx)
+ }),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
+ config.TestProductVariables.RecoverySnapshotVersion = proptools.StringPtr("current")
+ }),
+)
+
func TestPrebuiltEtcVariants(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
prebuilt_etc {
@@ -172,7 +188,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := result.Config.BuildOS.String()
p := result.Module("foo.conf", buildOS+"_common").(*PrebuiltEtc)
if !p.Host() {
t.Errorf("host bit is not set for a prebuilt_etc_host module.")
@@ -226,7 +242,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := result.Config.BuildOS.String()
p := result.Module("foo.conf", buildOS+"_common").(*PrebuiltEtc)
expected := filepath.Join("out/soong/host", result.Config.PrebuiltOS(), "usr", "share", "bar")
android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
@@ -346,3 +362,110 @@
})
}
}
+
+func checkIfSnapshotTaken(t *testing.T, result *android.TestResult, image string, moduleName string) {
+ checkIfSnapshotExistAsExpected(t, result, image, moduleName, true)
+}
+
+func checkIfSnapshotNotTaken(t *testing.T, result *android.TestResult, image string, moduleName string) {
+ checkIfSnapshotExistAsExpected(t, result, image, moduleName, false)
+}
+
+func checkIfSnapshotExistAsExpected(t *testing.T, result *android.TestResult, image string, moduleName string, expectToExist bool) {
+ snapshotSingleton := result.SingletonForTests(image + "-snapshot")
+ archType := "arm64"
+ archVariant := "armv8-a"
+ archDir := fmt.Sprintf("arch-%s", archType)
+
+ snapshotDir := fmt.Sprintf("%s-snapshot", image)
+ snapshotVariantPath := filepath.Join(snapshotDir, archType)
+ outputDir := filepath.Join(snapshotVariantPath, archDir, "etc")
+ imageVariant := ""
+ if image == "recovery" {
+ imageVariant = "recovery_"
+ }
+ mod := result.ModuleForTests(moduleName, fmt.Sprintf("android_%s%s_%s", imageVariant, archType, archVariant))
+ outputFiles := mod.OutputFiles(t, "")
+ if len(outputFiles) != 1 {
+ t.Errorf("%q must have single output\n", moduleName)
+ return
+ }
+ snapshotPath := filepath.Join(outputDir, moduleName)
+
+ if expectToExist {
+ out := snapshotSingleton.Output(snapshotPath)
+
+ if out.Input.String() != outputFiles[0].String() {
+ t.Errorf("The input of snapshot %q must be %q, but %q", "prebuilt_vendor", out.Input.String(), outputFiles[0])
+ }
+
+ snapshotJsonPath := snapshotPath + ".json"
+
+ if snapshotSingleton.MaybeOutput(snapshotJsonPath).Rule == nil {
+ t.Errorf("%q expected but not found", snapshotJsonPath)
+ }
+ } else {
+ out := snapshotSingleton.MaybeOutput(snapshotPath)
+ if out.Rule != nil {
+ t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0])
+ }
+ }
+}
+
+func TestPrebuiltTakeSnapshot(t *testing.T) {
+ var testBp = `
+ prebuilt_etc {
+ name: "prebuilt_vendor",
+ src: "foo.conf",
+ vendor: true,
+ }
+
+ prebuilt_etc {
+ name: "prebuilt_vendor_indirect",
+ src: "foo.conf",
+ vendor: true,
+ }
+
+ prebuilt_etc {
+ name: "prebuilt_recovery",
+ src: "bar.conf",
+ recovery: true,
+ }
+
+ prebuilt_etc {
+ name: "prebuilt_recovery_indirect",
+ src: "bar.conf",
+ recovery: true,
+ }
+ `
+
+ t.Run("prebuilt: vendor and recovery snapshot", func(t *testing.T) {
+ result := prepareForPrebuiltEtcSnapshotTest.RunTestWithBp(t, testBp)
+
+ checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor")
+ checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor_indirect")
+ checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery")
+ checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery_indirect")
+ })
+
+ t.Run("prebuilt: directed snapshot", func(t *testing.T) {
+ prepareForPrebuiltEtcDirectedSnapshotTest := android.GroupFixturePreparers(
+ prepareForPrebuiltEtcSnapshotTest,
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.TestProductVariables.DirectedVendorSnapshot = true
+ config.TestProductVariables.VendorSnapshotModules = make(map[string]bool)
+ config.TestProductVariables.VendorSnapshotModules["prebuilt_vendor"] = true
+ config.TestProductVariables.DirectedRecoverySnapshot = true
+ config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool)
+ config.TestProductVariables.RecoverySnapshotModules["prebuilt_recovery"] = true
+ }),
+ )
+
+ result := prepareForPrebuiltEtcDirectedSnapshotTest.RunTestWithBp(t, testBp)
+
+ checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor")
+ checkIfSnapshotNotTaken(t, result, "vendor", "prebuilt_vendor_indirect")
+ checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery")
+ checkIfSnapshotNotTaken(t, result, "recovery", "prebuilt_recovery_indirect")
+ })
+}
diff --git a/etc/snapshot_etc.go b/etc/snapshot_etc.go
new file mode 100644
index 0000000..9a25d5a
--- /dev/null
+++ b/etc/snapshot_etc.go
@@ -0,0 +1,186 @@
+// Copyright 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 etc
+
+// This file implements snapshot module of 'prebuilt_etc' type
+// 'snapshot_etc' module defines android.PrebuiltInterface so it can be handled
+// as prebuilt of 'prebuilt_etc' type.
+// Properties of 'snapshot_etc' follows properties from snapshotJsonFlags type
+
+import (
+ "android/soong/android"
+ "fmt"
+ "strings"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+func RegisterSnapshotEtcModule(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("snapshot_etc", SnapshotEtcFactory)
+}
+
+func init() {
+ RegisterSnapshotEtcModule(android.InitRegistrationContext)
+}
+
+// snapshot_etc is a prebuilt module type to be installed under etc which is auto-generated by
+// development/vendor_snapshot/update.py. This module will override prebuilt_etc module with same
+// name when 'prefer' property is true.
+func SnapshotEtcFactory() android.Module {
+ module := &SnapshotEtc{}
+ module.AddProperties(&module.properties)
+
+ var srcsSupplier = func(_ android.BaseModuleContext, prebuilt android.Module) []string {
+ s, ok := prebuilt.(*SnapshotEtc)
+ if !ok || s.properties.Src == nil {
+ return []string{}
+ }
+
+ return []string{*s.properties.Src}
+ }
+
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "src")
+ return module
+}
+
+type snapshotEtcProperties struct {
+ Src *string `android:"path,arch_variant"` // Source of snapshot_etc file
+ Filename *string `android:"arch_variant"` // Target file name when it differs from module name
+ Relative_install_path *string `android:"arch_variant"` // Relative install path when it should be installed subdirectory of etc
+}
+
+type SnapshotEtc struct {
+ android.ModuleBase
+ prebuilt android.Prebuilt
+ properties snapshotEtcProperties
+
+ outputFilePath android.OutputPath
+ installDirPath android.InstallPath
+}
+
+func (s *SnapshotEtc) Prebuilt() *android.Prebuilt {
+ return &s.prebuilt
+}
+
+func (s *SnapshotEtc) Name() string {
+ return s.prebuilt.Name(s.BaseModuleName())
+}
+
+func (s *SnapshotEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if s.properties.Src == nil {
+ ctx.PropertyErrorf("src", "missing prebuilt source file")
+ return
+ }
+
+ sourceFilePath := s.prebuilt.SingleSourcePath(ctx)
+
+ // Determine the output file basename.
+ // If Filename is set, use the name specified by the property.
+ // Otherwise use the module name.
+ filename := proptools.String(s.properties.Filename)
+ if filename == "" {
+ filename = ctx.ModuleName()
+ }
+
+ s.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
+
+ if strings.Contains(filename, "/") {
+ ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
+ return
+ }
+
+ subDir := ""
+ if s.properties.Relative_install_path != nil {
+ subDir = *s.properties.Relative_install_path
+ }
+
+ s.installDirPath = android.PathForModuleInstall(ctx, "etc", subDir)
+
+ // This ensures that outputFilePath has the correct name for others to
+ // use, as the source file may have a different name.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: sourceFilePath,
+ Output: s.outputFilePath,
+ Description: "Install snapshot etc module " + s.BaseModuleName(),
+ })
+
+ ctx.InstallFile(s.installDirPath, s.outputFilePath.Base(), sourceFilePath)
+}
+
+func (p *SnapshotEtc) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{{
+ Class: "ETC",
+ OutputFile: android.OptionalPathForPath(p.outputFilePath),
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE_TAGS", "optional")
+ entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String())
+ entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
+ },
+ },
+ }}
+}
+
+type snapshotEtcDependencyTag struct {
+ blueprint.DependencyTag
+}
+
+var tag = snapshotEtcDependencyTag{}
+
+func (s *SnapshotEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+ return !s.ModuleBase.InstallInRecovery() && !s.ModuleBase.InstallInRamdisk() &&
+ !s.ModuleBase.InstallInVendorRamdisk() && !s.ModuleBase.InstallInDebugRamdisk()
+}
+
+func (p *SnapshotEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+ return p.ModuleBase.InstallInRamdisk()
+}
+
+func (p *SnapshotEtc) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+ return p.ModuleBase.InstallInVendorRamdisk()
+}
+
+func (p *SnapshotEtc) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+ return p.ModuleBase.InstallInDebugRamdisk()
+}
+
+func (p *SnapshotEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+ return p.ModuleBase.InstallInRecovery()
+}
+
+func (p *SnapshotEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+ return nil
+}
+
+func (p *SnapshotEtc) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
+}
+
+func (p *SnapshotEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+
+func (p *SnapshotEtc) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return android.Paths{p.outputFilePath}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+
+}
+
+var _ android.PrebuiltInterface = (*SnapshotEtc)(nil)
+var _ android.ImageInterface = (*SnapshotEtc)(nil)
+var _ android.OutputFileProducer = (*SnapshotEtc)(nil)
diff --git a/etc/snapshot_etc_test.go b/etc/snapshot_etc_test.go
new file mode 100644
index 0000000..b9d5504
--- /dev/null
+++ b/etc/snapshot_etc_test.go
@@ -0,0 +1,185 @@
+// Copyright 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 etc
+
+import (
+ "android/soong/android"
+ "testing"
+
+ "github.com/google/blueprint"
+)
+
+var registerSourceModule = func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("source", newSourceModule)
+}
+
+type sourceModuleProperties struct {
+ Deps []string `android:"path,arch_variant"`
+}
+
+type sourceModule struct {
+ android.ModuleBase
+ android.OverridableModuleBase
+
+ properties sourceModuleProperties
+ dependsOnSourceModule, dependsOnPrebuiltModule bool
+ deps android.Paths
+ src android.Path
+}
+
+func newSourceModule() android.Module {
+ m := &sourceModule{}
+ m.AddProperties(&m.properties)
+ android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibFirst)
+ android.InitOverridableModule(m, nil)
+ return m
+}
+
+func (s *sourceModule) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
+ // s.properties.Deps are annotated with android:path, so they are
+ // automatically added to the dependency by pathDeps mutator
+}
+
+func (s *sourceModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ s.deps = android.PathsForModuleSrc(ctx, s.properties.Deps)
+ s.src = android.PathForModuleSrc(ctx, "source_file")
+}
+
+func (s *sourceModule) Srcs() android.Paths {
+ return android.Paths{s.src}
+}
+
+var prepareForSnapshotEtcTest = android.GroupFixturePreparers(
+ android.PrepareForTestWithArchMutator,
+ android.PrepareForTestWithPrebuilts,
+ PrepareForTestWithPrebuiltEtc,
+ android.FixtureRegisterWithContext(RegisterSnapshotEtcModule),
+ android.FixtureRegisterWithContext(registerSourceModule),
+ android.FixtureMergeMockFs(android.MockFS{
+ "foo.conf": nil,
+ "bar.conf": nil,
+ }),
+)
+
+func TestSnapshotWithFilename(t *testing.T) {
+ var androidBp = `
+ snapshot_etc {
+ name: "etc_module",
+ src: "foo.conf",
+ filename: "bar.conf",
+ }
+ `
+
+ result := prepareForSnapshotEtcTest.RunTestWithBp(t, androidBp)
+ for _, variant := range result.ModuleVariantsForTests("etc_module") {
+ module := result.ModuleForTests("etc_module", variant)
+ s, ok := module.Module().(*SnapshotEtc)
+ if !ok {
+ t.Errorf("Expected snapshot_etc module type")
+ }
+ if s.outputFilePath.Base() != "bar.conf" {
+ t.Errorf("Output file path does not match with specified filename")
+ }
+ }
+}
+
+func TestSnapshotEtcWithOrigin(t *testing.T) {
+ var androidBp = `
+ prebuilt_etc {
+ name: "etc_module",
+ src: "foo.conf",
+ }
+
+ snapshot_etc {
+ name: "etc_module",
+ src: "bar.conf",
+ }
+
+ source {
+ name: "source",
+ deps: [":etc_module"],
+ }
+ `
+
+ result := prepareForSnapshotEtcTest.RunTestWithBp(t, androidBp)
+
+ for _, variant := range result.ModuleVariantsForTests("source") {
+ source := result.ModuleForTests("source", variant)
+
+ result.VisitDirectDeps(source.Module(), func(m blueprint.Module) {
+ if _, ok := m.(*PrebuiltEtc); !ok {
+ t.Errorf("Original prebuilt_etc module expected.")
+ }
+ })
+ }
+}
+
+func TestSnapshotEtcWithOriginAndPrefer(t *testing.T) {
+ var androidBp = `
+ prebuilt_etc {
+ name: "etc_module",
+ src: "foo.conf",
+ }
+
+ snapshot_etc {
+ name: "etc_module",
+ src: "bar.conf",
+ prefer: true,
+ }
+
+ source {
+ name: "source",
+ deps: [":etc_module"],
+ }
+ `
+
+ result := prepareForSnapshotEtcTest.RunTestWithBp(t, androidBp)
+
+ for _, variant := range result.ModuleVariantsForTests("source") {
+ source := result.ModuleForTests("source", variant)
+
+ result.VisitDirectDeps(source.Module(), func(m blueprint.Module) {
+ if _, ok := m.(*SnapshotEtc); !ok {
+ t.Errorf("Preferred snapshot_etc module expected.")
+ }
+ })
+ }
+}
+
+func TestSnapshotEtcWithoutOrigin(t *testing.T) {
+ var androidBp = `
+ snapshot_etc {
+ name: "etc_module",
+ src: "bar.conf",
+ }
+
+ source {
+ name: "source",
+ deps: [":etc_module"],
+ }
+ `
+
+ result := prepareForSnapshotEtcTest.RunTestWithBp(t, androidBp)
+
+ for _, variant := range result.ModuleVariantsForTests("source") {
+ source := result.ModuleForTests("source", variant)
+
+ result.VisitDirectDeps(source.Module(), func(m blueprint.Module) {
+ if _, ok := m.(*SnapshotEtc); !ok {
+ t.Errorf("Only source snapshot_etc module expected.")
+ }
+ })
+ }
+}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 77dae75..71a8780 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -68,7 +68,6 @@
ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel()
})
- android.DepsBp2BuildMutators(RegisterGenruleBp2BuildDeps)
android.RegisterBp2BuildMutator("genrule", GenruleBp2Build)
}
@@ -113,16 +112,17 @@
label string
}
type generatorProperties struct {
- // The command to run on one or more input files. Cmd supports substitution of a few variables
+ // The command to run on one or more input files. Cmd supports substitution of a few variables.
//
// Available variables for substitution:
//
- // $(location): the path to the first entry in tools or tool_files
- // $(location <label>): the path to the tool, tool_file, input or output with name <label>
- // $(in): one or more input files
- // $(out): a single output file
- // $(depfile): a file to which dependencies will be written, if the depfile property is set to true
- // $(genDir): the sandbox directory for this tool; contains $(out)
+ // $(location): the path to the first entry in tools or tool_files.
+ // $(location <label>): the path to the tool, tool_file, input or output with name <label>. Use $(location) if <label> refers to a rule that outputs exactly one file.
+ // $(locations <label>): the paths to the tools, tool_files, inputs or outputs with name <label>. Use $(locations) if <label> refers to a rule that outputs two or more files.
+ // $(in): one or more input files.
+ // $(out): a single output file.
+ // $(depfile): a file to which dependencies will be written, if the depfile property is set to true.
+ // $(genDir): the sandbox directory for this tool; contains $(out).
// $$: a literal $
Cmd *string
@@ -211,6 +211,22 @@
return g.outputDeps
}
+func (g *Module) OutputFiles(tag string) (android.Paths, error) {
+ if tag == "" {
+ return append(android.Paths{}, g.outputFiles...), nil
+ }
+ // otherwise, tag should match one of outputs
+ for _, outputFile := range g.outputFiles {
+ if outputFile.Rel() == tag {
+ return android.Paths{outputFile}, nil
+ }
+ }
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+}
+
+var _ android.SourceFileProducer = (*Module)(nil)
+var _ android.OutputFileProducer = (*Module)(nil)
+
func toolDepsMutator(ctx android.BottomUpMutatorContext) {
if g, ok := ctx.Module().(*Module); ok {
for _, tool := range g.properties.Tools {
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index 3ce4f85..714d2f8 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -31,12 +31,12 @@
var prepareForGenRuleTest = android.GroupFixturePreparers(
android.PrepareForTestWithArchMutator,
android.PrepareForTestWithDefaults,
-
android.PrepareForTestWithFilegroup,
PrepareForTestWithGenRuleBuildComponents,
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("tool", toolFactory)
ctx.RegisterModuleType("output", outputProducerFactory)
+ ctx.RegisterModuleType("use_source", useSourceFactory)
}),
android.FixtureMergeMockFs(android.MockFS{
"tool": nil,
@@ -684,6 +684,42 @@
}
}
+func TestGenruleOutputFiles(t *testing.T) {
+ bp := `
+ genrule {
+ name: "gen",
+ out: ["foo", "sub/bar"],
+ cmd: "echo foo > $(location foo) && echo bar > $(location sub/bar)",
+ }
+ use_source {
+ name: "gen_foo",
+ srcs: [":gen{foo}"],
+ }
+ use_source {
+ name: "gen_bar",
+ srcs: [":gen{sub/bar}"],
+ }
+ use_source {
+ name: "gen_all",
+ srcs: [":gen"],
+ }
+ `
+
+ result := prepareForGenRuleTest.RunTestWithBp(t, testGenruleBp()+bp)
+ android.AssertPathsRelativeToTopEquals(t,
+ "genrule.tag with output",
+ []string{"out/soong/.intermediates/gen/gen/foo"},
+ result.ModuleForTests("gen_foo", "").Module().(*useSource).srcs)
+ android.AssertPathsRelativeToTopEquals(t,
+ "genrule.tag with output in subdir",
+ []string{"out/soong/.intermediates/gen/gen/sub/bar"},
+ result.ModuleForTests("gen_bar", "").Module().(*useSource).srcs)
+ android.AssertPathsRelativeToTopEquals(t,
+ "genrule.tag with all",
+ []string{"out/soong/.intermediates/gen/gen/foo", "out/soong/.intermediates/gen/gen/sub/bar"},
+ result.ModuleForTests("gen_all", "").Module().(*useSource).srcs)
+}
+
func TestGenruleWithBazel(t *testing.T) {
bp := `
genrule {
@@ -750,3 +786,22 @@
}
var _ android.OutputFileProducer = (*testOutputProducer)(nil)
+
+type useSource struct {
+ android.ModuleBase
+ props struct {
+ Srcs []string `android:"path"`
+ }
+ srcs android.Paths
+}
+
+func (s *useSource) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ s.srcs = android.PathsForModuleSrc(ctx, s.props.Srcs)
+}
+
+func useSourceFactory() android.Module {
+ module := &useSource{}
+ module.AddProperties(&module.props)
+ android.InitAndroidModule(module)
+ return module
+}
diff --git a/go.mod b/go.mod
index 7297dea..14444b3 100644
--- a/go.mod
+++ b/go.mod
@@ -1,11 +1,19 @@
module android/soong
-require github.com/golang/protobuf v0.0.0
+require google.golang.org/protobuf v0.0.0
require github.com/google/blueprint v0.0.0
-replace github.com/golang/protobuf v0.0.0 => ../../external/golang-protobuf
+replace google.golang.org/protobuf v0.0.0 => ../../external/golang-protobuf
replace github.com/google/blueprint v0.0.0 => ../blueprint
+// Indirect deps from golang-protobuf
+exclude github.com/golang/protobuf v1.5.0
+
+replace github.com/google/go-cmp v0.5.5 => ../../external/go-cmp
+
+// Indirect dep from go-cmp
+exclude golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
+
go 1.15
diff --git a/java/Android.bp b/java/Android.bp
index 5952602..9ffa123 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -10,6 +10,7 @@
"blueprint-pathtools",
"soong",
"soong-android",
+ "soong-bazel",
"soong-cc",
"soong-dexpreopt",
"soong-genrule",
@@ -93,6 +94,7 @@
"plugin_test.go",
"rro_test.go",
"sdk_test.go",
+ "sdk_library_test.go",
"system_modules_test.go",
"systemserver_classpath_fragment_test.go",
],
diff --git a/java/OWNERS b/java/OWNERS
index 16ef4d8..5242712 100644
--- a/java/OWNERS
+++ b/java/OWNERS
@@ -1 +1 @@
-per-file dexpreopt*.go = ngeoffray@google.com,calin@google.com,mathieuc@google.com
+per-file dexpreopt*.go = ngeoffray@google.com,calin@google.com,skvadrik@google.com
diff --git a/java/app.go b/java/app.go
index fc1ace0..35ed27f 100755
--- a/java/app.go
+++ b/java/app.go
@@ -26,6 +26,7 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/cc"
"android/soong/dexpreopt"
"android/soong/tradefed"
@@ -42,6 +43,8 @@
ctx.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
ctx.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
+
+ android.RegisterBp2BuildMutator("android_app_certificate", AndroidAppCertificateBp2Build)
}
// AndroidManifest.xml merging
@@ -1104,6 +1107,8 @@
type AndroidAppCertificate struct {
android.ModuleBase
+ android.BazelModuleBase
+
properties AndroidAppCertificateProperties
Certificate Certificate
}
@@ -1119,6 +1124,7 @@
module := &AndroidAppCertificate{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
+ android.InitBazelModule(module)
return module
}
@@ -1213,7 +1219,7 @@
}
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
- if !ctx.Config().UnbundledBuild() {
+ if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...)
// Only add these extra dependencies if the module depends on framework libs. This avoids
@@ -1245,36 +1251,52 @@
}
}
-// Returns a map of module names of shared library dependencies to the paths
-// to their dex jars on host and on device.
+// Returns a map of module names of shared library dependencies to the paths to their dex jars on
+// host and on device.
func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
clcMap := make(dexpreopt.ClassLoaderContextMap)
- if !ctx.Config().UnbundledBuild() {
- ctx.VisitDirectDeps(func(m android.Module) {
- if tag, ok := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag); ok {
- dep := ctx.OtherModuleName(m)
- if lib, ok := m.(UsesLibraryDependency); ok {
- libName := dep
- if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
- libName = *ulib.ProvidesUsesLib()
- // Replace module name with library name in `uses_libs`/`optional_uses_libs`
- // in order to pass verify_uses_libraries check (which compares these
- // properties against library names written in the manifest).
- replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
- replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
- }
- clcMap.AddContext(ctx, tag.sdkVersion, libName,
- lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts())
- } else if ctx.Config().AllowMissingDependencies() {
- ctx.AddMissingDependencies([]string{dep})
- } else {
- ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
- }
- }
- })
+ // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With
+ // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting.
+ if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() {
+ return clcMap
}
+ ctx.VisitDirectDeps(func(m android.Module) {
+ tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag)
+ if !isUsesLibTag {
+ return
+ }
+
+ dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m))
+
+ // Skip stub libraries. A dependency on the implementation library has been added earlier,
+ // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed
+ // from implementation libraries by their name, which is different as it has a suffix.
+ if comp, ok := m.(SdkLibraryComponentDependency); ok {
+ if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep {
+ return
+ }
+ }
+
+ if lib, ok := m.(UsesLibraryDependency); ok {
+ libName := dep
+ if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
+ libName = *ulib.ProvidesUsesLib()
+ // Replace module name with library name in `uses_libs`/`optional_uses_libs` in
+ // order to pass verify_uses_libraries check (which compares these properties
+ // against library names written in the manifest).
+ replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
+ replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
+ }
+ clcMap.AddContext(ctx, tag.sdkVersion, libName,
+ lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts())
+ } else if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{dep})
+ } else {
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep)
+ }
+ })
return clcMap
}
@@ -1352,3 +1374,61 @@
outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
return outputFile
}
+
+// For Bazel / bp2build
+
+type bazelAndroidAppCertificateAttributes struct {
+ Certificate string
+}
+
+type bazelAndroidAppCertificate struct {
+ android.BazelTargetModuleBase
+ bazelAndroidAppCertificateAttributes
+}
+
+func BazelAndroidAppCertificateFactory() android.Module {
+ module := &bazelAndroidAppCertificate{}
+ module.AddProperties(&module.bazelAndroidAppCertificateAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+func AndroidAppCertificateBp2Build(ctx android.TopDownMutatorContext) {
+ module, ok := ctx.Module().(*AndroidAppCertificate)
+ if !ok {
+ // Not an Android app certificate
+ return
+ }
+ if !module.ConvertWithBp2build(ctx) {
+ return
+ }
+ if ctx.ModuleType() != "android_app_certificate" {
+ return
+ }
+
+ androidAppCertificateBp2BuildInternal(ctx, module)
+}
+
+func androidAppCertificateBp2BuildInternal(ctx android.TopDownMutatorContext, module *AndroidAppCertificate) {
+ var certificate string
+ if module.properties.Certificate != nil {
+ certificate = *module.properties.Certificate
+ }
+
+ attrs := &bazelAndroidAppCertificateAttributes{
+ Certificate: certificate,
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "android_app_certificate",
+ Bzl_load_location: "//build/bazel/rules:android_app_certificate.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(BazelAndroidAppCertificateFactory, module.Name(), props, attrs)
+}
+
+func (m *bazelAndroidAppCertificate) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelAndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/java/app_import.go b/java/app_import.go
index 839051e..5a87b07 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -61,7 +61,7 @@
type AndroidAppImportProperties struct {
// A prebuilt apk to import
- Apk *string
+ Apk *string `android:"path"`
// The name of a certificate in the default certificate directory or an android_app_certificate
// module name in the form ":module". Should be empty if presigned or default_dev_cert is set.
@@ -99,6 +99,9 @@
// If set, create package-export.apk, which other packages can
// use to get PRODUCT-agnostic resource data like IDs and type definitions.
Export_package_resources *bool
+
+ // Optional. Install to a subdirectory of the default install path for the module
+ Relative_install_path *string
}
func (a *AndroidAppImport) IsInstallable() bool {
@@ -263,20 +266,25 @@
jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk")
a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed.OutputPath)
- var installDir android.InstallPath
+ var pathFragments []string
+ relInstallPath := String(a.properties.Relative_install_path)
if a.isPrebuiltFrameworkRes() {
// framework-res.apk is installed as system/framework/framework-res.apk
- installDir = android.PathForModuleInstall(ctx, "framework")
+ if relInstallPath != "" {
+ ctx.PropertyErrorf("relative_install_path", "Relative_install_path cannot be set for framework-res")
+ }
+ pathFragments = []string{"framework"}
a.preprocessed = true
} else if Bool(a.properties.Privileged) {
- installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName())
+ pathFragments = []string{"priv-app", relInstallPath, a.BaseModuleName()}
} else if ctx.InstallInTestcases() {
- installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
+ pathFragments = []string{relInstallPath, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch()}
} else {
- installDir = android.PathForModuleInstall(ctx, "app", a.BaseModuleName())
+ pathFragments = []string{"app", relInstallPath, a.BaseModuleName()}
}
+ installDir := android.PathForModuleInstall(ctx, pathFragments...)
a.dexpreopter.isApp = true
a.dexpreopter.installPath = installDir.Join(ctx, a.BaseModuleName()+".apk")
a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
diff --git a/java/app_import_test.go b/java/app_import_test.go
index 147ae45..024a3df 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -493,6 +493,69 @@
}
}
+func TestAndroidAppImport_relativeInstallPath(t *testing.T) {
+ bp := `
+ android_app_import {
+ name: "no_relative_install_path",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ }
+
+ android_app_import {
+ name: "relative_install_path",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ relative_install_path: "my/path",
+ }
+
+ android_app_import {
+ name: "framework-res",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ prefer: true,
+ }
+
+ android_app_import {
+ name: "privileged_relative_install_path",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ privileged: true,
+ relative_install_path: "my/path"
+ }
+ `
+ testCases := []struct {
+ name string
+ expectedInstallPath string
+ errorMessage string
+ }{
+ {
+ name: "no_relative_install_path",
+ expectedInstallPath: "out/soong/target/product/test_device/system/app/no_relative_install_path/no_relative_install_path.apk",
+ errorMessage: "Install path is not correct when relative_install_path is missing",
+ },
+ {
+ name: "relative_install_path",
+ expectedInstallPath: "out/soong/target/product/test_device/system/app/my/path/relative_install_path/relative_install_path.apk",
+ errorMessage: "Install path is not correct for app when relative_install_path is present",
+ },
+ {
+ name: "prebuilt_framework-res",
+ expectedInstallPath: "out/soong/target/product/test_device/system/framework/framework-res.apk",
+ errorMessage: "Install path is not correct for framework-res",
+ },
+ {
+ name: "privileged_relative_install_path",
+ expectedInstallPath: "out/soong/target/product/test_device/system/priv-app/my/path/privileged_relative_install_path/privileged_relative_install_path.apk",
+ errorMessage: "Install path is not correct for privileged app when relative_install_path is present",
+ },
+ }
+ for _, testCase := range testCases {
+ ctx, _ := testJava(t, bp)
+ mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*AndroidAppImport)
+ android.AssertPathRelativeToTopEquals(t, testCase.errorMessage, testCase.expectedInstallPath, mod.installPath)
+ }
+}
+
func TestAndroidTestImport(t *testing.T) {
ctx, _ := testJava(t, `
android_test_import {
diff --git a/java/app_test.go b/java/app_test.go
index a99ac62..7997f7a 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2471,7 +2471,7 @@
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("runtime-library", "foo", "bar"),
dexpreopt.FixtureSetBootJars("platform:foo"),
- dexpreopt.FixtureSetUpdatableBootJars("platform:bar"),
+ dexpreopt.FixtureSetApexBootJars("platform:bar"),
dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with),
).RunTestWithBp(t, bp)
diff --git a/java/base.go b/java/base.go
index df70efb..d8cd6b3 100644
--- a/java/base.go
+++ b/java/base.go
@@ -155,6 +155,13 @@
// List of java_plugin modules that provide extra errorprone checks.
Extra_check_modules []string
+
+ // This property can be in 3 states. When set to true, errorprone will
+ // be run during the regular build. When set to false, errorprone will
+ // never be run. When unset, errorprone will be run when the RUN_ERROR_PRONE
+ // environment variable is true. Setting this to false will improve build
+ // performance more than adding -XepDisableAllChecks in javacflags.
+ Enabled *bool
}
Proto struct {
@@ -701,7 +708,8 @@
// javaVersion flag.
flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))
- if ctx.Config().RunErrorProne() {
+ epEnabled := j.properties.Errorprone.Enabled
+ if (ctx.Config().RunErrorProne() && epEnabled == nil) || Bool(epEnabled) {
if config.ErrorProneClasspath == nil && ctx.Config().TestProductVariables == nil {
ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
}
@@ -862,6 +870,7 @@
if aaptSrcJar != nil {
srcJars = append(srcJars, aaptSrcJar)
}
+ srcFiles = srcFiles.FilterOutByExt(".srcjar")
if j.properties.Jarjar_rules != nil {
j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
@@ -889,8 +898,8 @@
kotlincFlags := j.properties.Kotlincflags
CheckKotlincFlags(ctx, kotlincFlags)
- // Dogfood the JVM_IR backend.
- kotlincFlags = append(kotlincFlags, "-Xuse-ir")
+ // Workaround for KT-46512
+ kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class")
// If there are kotlin files, compile them first but pass all the kotlin and java files
// kotlinc will use the java files to resolve types referenced by the kotlin files, but
@@ -972,14 +981,23 @@
}
if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
var extraJarDeps android.Paths
- if ctx.Config().RunErrorProne() {
- // If error-prone is enabled, add an additional rule to compile the java files into
- // a separate set of classes (so that they don't overwrite the normal ones and require
- // a rebuild when error-prone is turned off).
- // TODO(ccross): Once we always compile with javac9 we may be able to conditionally
- // enable error-prone without affecting the output class files.
+ if Bool(j.properties.Errorprone.Enabled) {
+ // If error-prone is enabled, enable errorprone flags on the regular
+ // build.
+ flags = enableErrorproneFlags(flags)
+ } else if ctx.Config().RunErrorProne() && j.properties.Errorprone.Enabled == nil {
+ // Otherwise, if the RUN_ERROR_PRONE environment variable is set, create
+ // a new jar file just for compiling with the errorprone compiler to.
+ // This is because we don't want to cause the java files to get completely
+ // rebuilt every time the state of the RUN_ERROR_PRONE variable changes.
+ // We also don't want to run this if errorprone is enabled by default for
+ // this module, or else we could have duplicated errorprone messages.
+ errorproneFlags := enableErrorproneFlags(flags)
errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
- RunErrorProne(ctx, errorprone, uniqueSrcFiles, srcJars, flags)
+
+ transformJavaToClasses(ctx, errorprone, -1, uniqueSrcFiles, srcJars, errorproneFlags, nil,
+ "errorprone", "errorprone")
+
extraJarDeps = append(extraJarDeps, errorprone)
}
@@ -1212,7 +1230,7 @@
}
// Dex compilation
var dexOutputFile android.OutputPath
- dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), outputFile, jarName)
+ dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), implementationAndResourcesJar, jarName)
if ctx.Failed() {
return
}
@@ -1304,6 +1322,21 @@
j.outputFile = outputFile.WithoutRel()
}
+// Returns a copy of the supplied flags, but with all the errorprone-related
+// fields copied to the regular build's fields.
+func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags {
+ flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...)
+
+ if len(flags.errorProneExtraJavacFlags) > 0 {
+ if len(flags.javacFlags) > 0 {
+ flags.javacFlags += " " + flags.errorProneExtraJavacFlags
+ } else {
+ flags.javacFlags = flags.errorProneExtraJavacFlags
+ }
+ }
+ return flags
+}
+
func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath {
@@ -1482,12 +1515,8 @@
if sdkSpec.Kind == android.SdkCore {
return nil
}
- ver, err := sdkSpec.EffectiveVersion(ctx)
- if err != nil {
- return err
- }
- if ver.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", ver)
+ if sdkSpec.ApiLevel.GreaterThan(sdkVersion) {
+ return fmt.Errorf("newer SDK(%v)", sdkSpec.ApiLevel)
}
return nil
}
diff --git a/java/boot_jars.go b/java/boot_jars.go
index 86ebe36..5d40ec3 100644
--- a/java/boot_jars.go
+++ b/java/boot_jars.go
@@ -31,13 +31,18 @@
// buildRuleForBootJarsPackageCheck generates the build rule to perform the boot jars package
// check.
func buildRuleForBootJarsPackageCheck(ctx android.ModuleContext, bootDexJarByModule bootDexJarByModule) {
+ bootDexJars := bootDexJarByModule.bootDexJarsWithoutCoverage()
+ if len(bootDexJars) == 0 {
+ return
+ }
+
timestamp := android.PathForOutput(ctx, "boot-jars-package-check/stamp")
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().BuiltTool("check_boot_jars").
Input(ctx.Config().HostToolPath(ctx, "dexdump")).
Input(android.PathForSource(ctx, "build/soong/scripts/check_boot_jars/package_allowed_list.txt")).
- Inputs(bootDexJarByModule.bootDexJarsWithoutCoverage()).
+ Inputs(bootDexJars).
Text("&& touch").Output(timestamp)
rule.Build("boot_jars_package_check", "check boot jar packages")
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index d754fe6..4108770 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -144,6 +144,8 @@
// ApexVariantReference specifies a particular apex variant of a module.
type ApexVariantReference struct {
+ android.BpPrintableBase
+
// The name of the module apex variant, i.e. the apex containing the module variant.
//
// If this is not specified then it defaults to "platform" which will cause a dependency to be
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index a039964..bb542c4 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -146,6 +146,9 @@
ClasspathFragmentBase
properties bootclasspathFragmentProperties
+
+ // Collect the module directory for IDE info in java/jdeps.go.
+ modulePaths []string
}
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
@@ -422,6 +425,9 @@
// Generate classpaths.proto config
b.generateClasspathProtoBuildActions(ctx)
+ // Collect the module directory for IDE info in java/jdeps.go.
+ b.modulePaths = append(b.modulePaths, ctx.ModuleDir())
+
// Gather the bootclasspath fragment's contents.
var contents []android.Module
ctx.VisitDirectDeps(func(module android.Module) {
@@ -514,31 +520,28 @@
// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
var classpathJars []classpathJar
+ configuredJars := b.configuredJars(ctx)
if "art" == proptools.String(b.properties.Image_name) {
// ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
- classpathJars = configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
+ classpathJars = configuredJarListToClasspathJars(ctx, configuredJars, BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
} else {
- classpathJars = configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), b.classpathType)
+ classpathJars = configuredJarListToClasspathJars(ctx, configuredJars, b.classpathType)
}
- b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
+ b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
}
-func (b *BootclasspathFragmentModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
+func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
if "art" == proptools.String(b.properties.Image_name) {
return b.getImageConfig(ctx).modules
}
global := dexpreopt.GetGlobalConfig(ctx)
- possibleUpdatableModules := gatherPossibleUpdatableModuleNamesAndStems(ctx, b.properties.Contents, bootclasspathFragmentContentDepTag)
-
- // Only create configs for updatable boot jars. Non-updatable boot jars must be part of the
- // platform_bootclasspath's classpath proto config to guarantee that they come before any
- // updatable jars at runtime.
- jars := global.UpdatableBootJars.Filter(possibleUpdatableModules)
+ possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, b.properties.Contents, bootclasspathFragmentContentDepTag)
+ jars := global.ApexBootJars.Filter(possibleUpdatableModules)
// TODO(satayev): for apex_test we want to include all contents unconditionally to classpaths
- // config. However, any test specific jars would not be present in UpdatableBootJars. Instead,
+ // config. However, any test specific jars would not be present in ApexBootJars. Instead,
// we should check if we are creating a config for apex_test via ApexInfo and amend the values.
// This is an exception to support end-to-end test for SdkExtensions, until such support exists.
if android.InList("test_framework-sdkextensions", possibleUpdatableModules) {
@@ -576,6 +579,14 @@
common := ctx.Module().(commonBootclasspathFragment)
output := common.produceHiddenAPIOutput(ctx, contents, input)
+ // If the source or prebuilts module does not provide a signature patterns file then generate one
+ // from the flags.
+ // 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)
+ }
+
// Initialize a HiddenAPIInfo structure.
hiddenAPIInfo := HiddenAPIInfo{
// The monolithic hidden API processing needs access to the flag files that override the default
@@ -592,7 +603,7 @@
// The monolithic hidden API processing also needs access to all the output files produced by
// hidden API processing of this fragment.
- hiddenAPIInfo.HiddenAPIFlagOutput = (*output).HiddenAPIFlagOutput
+ hiddenAPIInfo.HiddenAPIFlagOutput = output.HiddenAPIFlagOutput
// Provide it for use by other modules.
ctx.SetProvider(HiddenAPIInfoProvider, hiddenAPIInfo)
@@ -691,6 +702,12 @@
return androidBootImageFilesByArch
}
+// Collect information for opening IDE project files in java/jdeps.go.
+func (b *BootclasspathFragmentModule) IDEInfo(dpInfo *android.IdeInfo) {
+ dpInfo.Deps = append(dpInfo.Deps, b.properties.Contents...)
+ dpInfo.Paths = append(dpInfo.Paths, b.modulePaths...)
+}
+
type bootclasspathFragmentMemberType struct {
android.SdkMemberTypeBase
}
@@ -729,12 +746,12 @@
Stub_libs []string
Core_platform_stub_libs []string
+ // Fragment properties
+ Fragments []ApexVariantReference
+
// Flag files by *hiddenAPIFlagFileCategory
Flag_files_by_category FlagFilesByCategory
- // The path to the generated stub-flags.csv file.
- Stub_flags_path android.OptionalPath
-
// The path to the generated annotation-flags.csv file.
Annotation_flags_path android.OptionalPath
@@ -744,6 +761,12 @@
// 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
+
// The path to the generated all-flags.csv file.
All_flags_path android.OptionalPath
}
@@ -760,15 +783,20 @@
b.Flag_files_by_category = hiddenAPIInfo.FlagFilesByCategory
// Copy all the generated file paths.
- b.Stub_flags_path = android.OptionalPathForPath(hiddenAPIInfo.StubFlagsPath)
b.Annotation_flags_path = android.OptionalPathForPath(hiddenAPIInfo.AnnotationFlagsPath)
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)
// Copy stub_libs properties.
b.Stub_libs = module.properties.Api.Stub_libs
b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs
+
+ // Copy fragment properties.
+ b.Fragments = module.properties.Fragments
}
func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -791,6 +819,9 @@
corePlatformApiPropertySet := propertySet.AddPropertySet("core_platform_api")
corePlatformApiPropertySet.AddPropertyWithTag("stub_libs", b.Core_platform_stub_libs, requiredMemberDependency)
}
+ if len(b.Fragments) > 0 {
+ propertySet.AddProperty("fragments", b.Fragments)
+ }
hiddenAPISet := propertySet.AddPropertySet("hidden_api")
hiddenAPIDir := "hiddenapi"
@@ -821,10 +852,11 @@
}
// Copy all the generated files, if available.
- copyOptionalPath(b.Stub_flags_path, "stub_flags")
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")
}
@@ -834,9 +866,6 @@
// specific properties.
type prebuiltBootclasspathFragmentProperties struct {
Hidden_api struct {
- // The path to the stub-flags.csv file created by the bootclasspath_fragment.
- Stub_flags *string `android:"path"`
-
// The path to the annotation-flags.csv file created by the bootclasspath_fragment.
Annotation_flags *string `android:"path"`
@@ -846,6 +875,12 @@
// The path to the index.csv file created by the bootclasspath_fragment.
Index *string `android:"path"`
+ // The path to the signature-patterns.csv file created by the bootclasspath_fragment.
+ Signature_patterns *string `android:"path"`
+
+ // The path to the stub-flags.csv file created by the bootclasspath_fragment.
+ Stub_flags *string `android:"path"`
+
// The path to the all-flags.csv file created by the bootclasspath_fragment.
All_flags *string `android:"path"`
}
@@ -876,11 +911,17 @@
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
pathForOptionalSrc := func(src *string) android.Path {
if src == nil {
- // TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.
return nil
}
return android.PathForModuleSrc(ctx, *src)
}
+ pathForSrc := func(property string, src *string) android.Path {
+ if src == nil {
+ ctx.PropertyErrorf(property, "is required but was not specified")
+ return android.PathForModuleSrc(ctx, "missing", property)
+ }
+ return android.PathForModuleSrc(ctx, *src)
+ }
// Retrieve the dex files directly from the content modules. They in turn should retrieve the
// encoded dex jars from the prebuilt .apex files.
@@ -888,11 +929,12 @@
output := HiddenAPIOutput{
HiddenAPIFlagOutput: HiddenAPIFlagOutput{
- StubFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags),
- AnnotationFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Annotation_flags),
- MetadataPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Metadata),
- IndexPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Index),
- AllFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags),
+ 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),
},
EncodedBootDexFilesByModule: encodedBootDexJarsByModule,
}
@@ -907,15 +949,11 @@
}
var deapexerModule android.Module
- ctx.VisitDirectDeps(func(to android.Module) {
- tag := ctx.OtherModuleDependencyTag(to)
+ ctx.VisitDirectDeps(func(module android.Module) {
+ tag := ctx.OtherModuleDependencyTag(module)
// Save away the `deapexer` module on which this depends, if any.
if tag == android.DeapexerTag {
- if deapexerModule != nil {
- ctx.ModuleErrorf("Ambiguous duplicate deapexer module dependencies %q and %q",
- deapexerModule.Name(), to.Name())
- }
- deapexerModule = to
+ deapexerModule = module
}
})
diff --git a/java/builder.go b/java/builder.go
index cde8731..ea011b8 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -279,23 +279,6 @@
transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, flags, deps, "javac", desc)
}
-func RunErrorProne(ctx android.ModuleContext, outputFile android.WritablePath,
- srcFiles, srcJars android.Paths, flags javaBuilderFlags) {
-
- flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...)
-
- if len(flags.errorProneExtraJavacFlags) > 0 {
- if len(flags.javacFlags) > 0 {
- flags.javacFlags += " " + flags.errorProneExtraJavacFlags
- } else {
- flags.javacFlags = flags.errorProneExtraJavacFlags
- }
- }
-
- transformJavaToClasses(ctx, outputFile, -1, srcFiles, srcJars, flags, nil,
- "errorprone", "errorprone")
-}
-
// Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars
// to compile with given set of builder flags, etc.
func emitXrefRule(ctx android.ModuleContext, xrefFile android.WritablePath, idx int,
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index ecfdfb7..f63d81d 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -19,6 +19,7 @@
import (
"fmt"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"strings"
"android/soong/android"
@@ -44,6 +45,11 @@
}
type classpathFragmentProperties struct {
+ // Whether to generated classpaths.proto config instance for the fragment. If the config is not
+ // generated, then relevant boot jars are added to platform classpath, i.e. platform_bootclasspath
+ // or platform_systemserverclasspath. This is useful for non-updatable APEX boot jars, to keep
+ // them as part of dexopt on device. Defaults to true.
+ Generate_classpaths_proto *bool
}
// classpathFragment interface is implemented by a module that contributes jars to a *CLASSPATH
@@ -52,10 +58,6 @@
android.Module
classpathFragmentBase() *ClasspathFragmentBase
-
- // ClasspathFragmentToConfiguredJarList returns android.ConfiguredJarList representation of all
- // the jars in this classpath fragment.
- ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList
}
// ClasspathFragmentBase is meant to be embedded in any module types that implement classpathFragment;
@@ -89,8 +91,8 @@
maxSdkVersion int32
}
-// gatherPossibleUpdatableModuleNamesAndStems returns a set of module and stem names from the
-// supplied contents that may be in the updatable boot jars.
+// gatherPossibleApexModuleNamesAndStems returns a set of module and stem names from the
+// supplied contents that may be in the apex boot jars.
//
// The module names are included because sometimes the stem is set to just change the name of
// the installed file and it expects the configuration to still use the actual module name.
@@ -98,7 +100,7 @@
// The stem names are included because sometimes the stem is set to change the effective name of the
// module that is used in the configuration as well,e .g. when a test library is overriding an
// actual boot jar
-func gatherPossibleUpdatableModuleNamesAndStems(ctx android.ModuleContext, contents []string, tag blueprint.DependencyTag) []string {
+func gatherPossibleApexModuleNamesAndStems(ctx android.ModuleContext, contents []string, tag blueprint.DependencyTag) []string {
set := map[string]struct{}{}
for _, name := range contents {
dep := ctx.GetDirectDepWithTag(name, tag)
@@ -127,25 +129,30 @@
return jars
}
-func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.ModuleContext, jars []classpathJar) {
- outputFilename := strings.ToLower(c.classpathType.String()) + ".pb"
- c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath
- c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths")
+func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.ModuleContext, configuredJars android.ConfiguredJarList, jars []classpathJar) {
+ generateProto := proptools.BoolDefault(c.properties.Generate_classpaths_proto, true)
+ if generateProto {
+ outputFilename := strings.ToLower(c.classpathType.String()) + ".pb"
+ c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath
+ c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths")
- generatedJson := android.PathForModuleOut(ctx, outputFilename+".json")
- writeClasspathsJson(ctx, generatedJson, jars)
+ generatedJson := android.PathForModuleOut(ctx, outputFilename+".json")
+ writeClasspathsJson(ctx, generatedJson, jars)
- rule := android.NewRuleBuilder(pctx, ctx)
- rule.Command().
- BuiltTool("conv_classpaths_proto").
- Flag("encode").
- Flag("--format=json").
- FlagWithInput("--input=", generatedJson).
- FlagWithOutput("--output=", c.outputFilepath)
+ rule := android.NewRuleBuilder(pctx, ctx)
+ rule.Command().
+ BuiltTool("conv_classpaths_proto").
+ Flag("encode").
+ Flag("--format=json").
+ FlagWithInput("--input=", generatedJson).
+ FlagWithOutput("--output=", c.outputFilepath)
- rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String())
+ rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String())
+ }
classpathProtoInfo := ClasspathFragmentProtoContentInfo{
+ ClasspathFragmentProtoGenerated: generateProto,
+ ClasspathFragmentProtoContents: configuredJars,
ClasspathFragmentProtoInstallDir: c.installDirPath,
ClasspathFragmentProtoOutput: c.outputFilepath,
}
@@ -191,6 +198,12 @@
var ClasspathFragmentProtoContentInfoProvider = blueprint.NewProvider(ClasspathFragmentProtoContentInfo{})
type ClasspathFragmentProtoContentInfo struct {
+ // Whether the classpaths.proto config is generated for the fragment.
+ ClasspathFragmentProtoGenerated bool
+
+ // ClasspathFragmentProtoContents contains a list of jars that are part of this classpath fragment.
+ ClasspathFragmentProtoContents android.ConfiguredJarList
+
// ClasspathFragmentProtoOutput is an output path for the generated classpaths.proto config of this module.
//
// The file should be copied to a relevant place on device, see ClasspathFragmentProtoInstallDir
diff --git a/java/config/config.go b/java/config/config.go
index 273084c..30c6f91 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -69,8 +69,6 @@
pctx.StaticVariable("JavacHeapSize", "2048M")
pctx.StaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
pctx.StaticVariable("DexFlags", "-JXX:OnError='cat hs_err_pid%p.log' -JXX:CICompilerCount=6 -JXX:+UseDynamicNumberOfGCThreads")
- // TODO(b/181095653): remove duplicated flags.
- pctx.StaticVariable("DexJavaFlags", "-XX:OnError='cat hs_err_pid%p.log' -XX:CICompilerCount=6 -XX:+UseDynamicNumberOfGCThreads -Xmx2G")
pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
`-Xmaxerrs 9999999`,
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
new file mode 100644
index 0000000..51d998a
--- /dev/null
+++ b/java/core-libraries/Android.bp
@@ -0,0 +1,194 @@
+// 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.
+
+//
+// Definitions for building the Android core libraries, i.e. ART, I18n and
+// Conscrypt.
+//
+// These are here as the definitions are used by the build itself and include
+// parts from all three of those modules.
+//
+
+// A stubs target containing the parts of the public SDK API provided by the
+// core libraries.
+//
+// Don't use this directly, use "sdk_version: core_current".
+java_library {
+ name: "core.current.stubs",
+ visibility: ["//visibility:public"],
+ static_libs: [
+ "art.module.public.api.stubs",
+ "conscrypt.module.public.api.stubs",
+ "i18n.module.public.api.stubs",
+ ],
+ sdk_version: "none",
+ system_modules: "none",
+
+ dist: {
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
+ },
+}
+
+// Distributed with the SDK for turning into system modules to compile apps
+// against.
+java_library {
+ name: "core-current-stubs-for-system-modules",
+ visibility: ["//development/sdk"],
+ static_libs: [
+ "core.current.stubs",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs-for-system-modules",
+ // This one is not on device but it's needed when javac compiles code
+ // containing @Generated annotations produced by some code generation
+ // tools.
+ // See http://b/123891440.
+ "core-generated-annotation-stubs",
+ ],
+ sdk_version: "none",
+ system_modules: "none",
+ dist: {
+ dest: "core-for-system-modules.jar",
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
+ },
+}
+
+// Used when compiling higher-level code against core.current.stubs.
+java_system_modules {
+ name: "core-current-stubs-system-modules",
+ visibility: ["//visibility:public"],
+ libs: [
+ "core-current-stubs-for-system-modules",
+ ],
+}
+
+// A stubs target containing the parts of the public SDK & @SystemApi(MODULE_LIBRARIES) API
+// provided by the core libraries.
+//
+// Don't use this directly, use "sdk_version: module_current".
+java_library {
+ name: "core.module_lib.stubs",
+ static_libs: [
+ "art.module.public.api.stubs.module_lib",
+
+ // Replace the following with the module-lib correspondence when Conscrypt or i18N module
+ // provides @SystemApi(MODULE_LIBRARIES). Currently, assume that only ART module provides
+ // @SystemApi(MODULE_LIBRARIES).
+ "conscrypt.module.public.api.stubs",
+ "i18n.module.public.api.stubs",
+ ],
+ sdk_version: "none",
+ system_modules: "none",
+ visibility: ["//visibility:private"],
+}
+
+// Used when compiling higher-level code with sdk_version "module_current"
+java_system_modules {
+ name: "core-module-lib-stubs-system-modules",
+ libs: [
+ "core.module_lib.stubs",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs-for-system-modules",
+ // This one is not on device but it's needed when javac compiles code
+ // containing @Generated annotations produced by some code generation
+ // tools.
+ // See http://b/123891440.
+ "core-generated-annotation-stubs",
+ ],
+ visibility: ["//visibility:public"],
+}
+
+// Ideally this should be a restricted allowlist but there are hundreds of modules that depend on
+// this.
+// TODO(http://b/134561230) - limit the number of dependents on this.
+core_platform_visibility = ["//visibility:public"]
+
+// Libraries containing the core platform API stubs for the core libraries.
+//
+// Although this stubs library is primarily used by the Java compiler / build to indicate
+// the core platform API surface area, compile_dex: true is used so that the Core Platform
+// API annotations are available to the dex tools that enable enforcement of runtime
+// accessibility. b/119068555
+java_library {
+ name: "legacy.core.platform.api.stubs",
+ visibility: core_platform_visibility,
+ hostdex: true,
+ compile_dex: true,
+
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: [
+ "art.module.public.api.stubs.module_lib",
+ "conscrypt.module.platform.api.stubs",
+ "legacy.i18n.module.platform.api.stubs",
+ ],
+ patch_module: "java.base",
+}
+
+java_library {
+ name: "stable.core.platform.api.stubs",
+ visibility: core_platform_visibility,
+ hostdex: true,
+ compile_dex: true,
+
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: [
+ "art.module.public.api.stubs.module_lib",
+ // conscrypt only has a stable version, so it is okay to depend on it here:
+ "conscrypt.module.platform.api.stubs",
+ "stable.i18n.module.platform.api.stubs",
+ ],
+ patch_module: "java.base",
+}
+
+// Used when compiling higher-level code against *.core.platform.api.stubs.
+java_system_modules {
+ name: "legacy-core-platform-api-stubs-system-modules",
+ visibility: core_platform_visibility,
+ libs: [
+ "legacy.core.platform.api.stubs",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs-for-system-modules",
+ // This one is not on device but it's needed when javac compiles code
+ // containing @Generated annotations produced by some code generation
+ // tools.
+ // See http://b/123891440.
+ "core-generated-annotation-stubs",
+ ],
+}
+
+java_system_modules {
+ name: "stable-core-platform-api-stubs-system-modules",
+ visibility: core_platform_visibility,
+ libs: [
+ "stable.core.platform.api.stubs",
+ // This one is not on device but it's needed when javac compiles code
+ // containing lambdas.
+ "core-lambda-stubs-for-system-modules",
+ // This one is not on device but it's needed when javac compiles code
+ // containing @Generated annotations produced by some code generation
+ // tools.
+ // See http://b/123891440.
+ "core-generated-annotation-stubs",
+ ],
+}
diff --git a/java/core-libraries/OWNERS b/java/core-libraries/OWNERS
new file mode 100644
index 0000000..bb3546a
--- /dev/null
+++ b/java/core-libraries/OWNERS
@@ -0,0 +1,3 @@
+include platform/external/icu:/OWNERS
+include platform/external/conscrypt:/OWNERS
+include platform/libcore:/OWNERS
diff --git a/java/dex.go b/java/dex.go
index 6bf0143..667800f 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -84,19 +84,17 @@
return BoolDefault(d.dexProperties.Optimize.Enabled, d.dexProperties.Optimize.EnabledByDefault)
}
-func init() {
- pctx.HostBinToolVariable("runWithTimeoutCmd", "run_with_timeout")
- pctx.SourcePathVariable("jstackCmd", "${config.JavaToolchain}/jstack")
-}
-
var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
- `$d8Template${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
+ `mkdir -p $$(dirname $tmpJar) && ` +
+ `${config.Zip2ZipCmd} -i $in -o $tmpJar -x '**/*.dex' && ` +
+ `$d8Template${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $tmpJar && ` +
`$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
"${config.D8Cmd}",
+ "${config.Zip2ZipCmd}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
@@ -115,17 +113,16 @@
ExecStrategy: "${config.RED8ExecStrategy}",
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
},
- }, []string{"outDir", "d8Flags", "zipFlags"}, nil)
+ }, []string{"outDir", "d8Flags", "zipFlags", "tmpJar"}, nil)
var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`rm -f "$outDict" && rm -rf "${outUsageDir}" && ` +
`mkdir -p $$(dirname ${outUsage}) && ` +
- // TODO(b/181095653): remove R8 timeout and go back to config.R8Cmd.
- `${runWithTimeoutCmd} -timeout 30m -on_timeout '${jstackCmd} $$PID' -- ` +
- `$r8Template${config.JavaCmd} ${config.DexJavaFlags} -cp ${config.R8Jar} ` +
- `com.android.tools.r8.compatproguard.CompatProguard -injars $in --output $outDir ` +
+ `mkdir -p $$(dirname $tmpJar) && ` +
+ `${config.Zip2ZipCmd} -i $in -o $tmpJar -x '**/*.dex' && ` +
+ `$r8Template${config.R8Cmd} ${config.DexFlags} -injars $tmpJar --output $outDir ` +
`--no-data-resources ` +
`-printmapping ${outDict} ` +
`-printusage ${outUsage} ` +
@@ -136,10 +133,10 @@
`$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
- "${config.R8Jar}",
+ "${config.R8Cmd}",
+ "${config.Zip2ZipCmd}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
- "${runWithTimeoutCmd}",
},
}, map[string]*remoteexec.REParams{
"$r8Template": &remoteexec.REParams{
@@ -165,7 +162,7 @@
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
},
}, []string{"outDir", "outDict", "outUsage", "outUsageZip", "outUsageDir",
- "r8Flags", "zipFlags"}, []string{"implicits"})
+ "r8Flags", "zipFlags", "tmpJar"}, []string{"implicits"})
func (d *dexer) dexCommonFlags(ctx android.ModuleContext, minSdkVersion android.SdkSpec) []string {
flags := d.dexProperties.Dxflags
@@ -282,6 +279,7 @@
// Compile classes.jar into classes.dex and then javalib.jar
javalibJar := android.PathForModuleOut(ctx, "dex", jarName).OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
+ tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", jarName)
zipFlags := "--ignore_missing_files"
if proptools.Bool(d.dexProperties.Uncompress_dex) {
@@ -309,6 +307,7 @@
"outUsage": proguardUsage.String(),
"outUsageZip": proguardUsageZip.String(),
"outDir": outDir.String(),
+ "tmpJar": tmpJar.String(),
}
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") {
rule = r8RE
@@ -339,6 +338,7 @@
"d8Flags": strings.Join(append(commonFlags, d8Flags...), " "),
"zipFlags": zipFlags,
"outDir": outDir.String(),
+ "tmpJar": tmpJar.String(),
},
})
}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 2e46d74..0faae36 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -141,10 +141,9 @@
}
}
- // If it is neither app nor test, make config files regardless of its dexpreopt setting.
+ // If it is test, make config files regardless of its dexpreopt setting.
// The config files are required for apps defined in make which depend on the lib.
- // TODO(b/158843648): The config for apps should be generated as well regardless of setting.
- if (d.isApp || d.isTest) && d.dexpreoptDisabled(ctx) {
+ if d.isTest && d.dexpreoptDisabled(ctx) {
return
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 19c65ca..1019b4c 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -154,12 +154,23 @@
// PRODUCT_BOOT_JARS_EXTRA variables. The AOSP makefiles specify some common Framework libraries,
// but more product-specific libraries can be added in the product makefiles.
//
-// Each component of the PRODUCT_BOOT_JARS and PRODUCT_BOOT_JARS_EXTRA variables is either a simple
-// name (if the library is a part of the Platform), or a colon-separated pair <apex, name> (if the
-// library is a part of a non-updatable APEX).
+// Each component of the PRODUCT_BOOT_JARS and PRODUCT_BOOT_JARS_EXTRA variables is a
+// colon-separated pair <apex>:<library>, where <apex> is the variant name of a non-updatable APEX,
+// "platform" if the library is a part of the platform in the system partition, or "system_ext" if
+// it's in the system_ext partition.
//
-// A related variable PRODUCT_UPDATABLE_BOOT_JARS contains bootclasspath libraries that are in
-// updatable APEXes. They are not included in the boot image.
+// In these variables APEXes are identified by their "variant names", i.e. the names they get
+// mounted as in /apex on device. In Soong modules that is the name set in the "apex_name"
+// properties, which default to the "name" values. For example, many APEXes have both
+// com.android.xxx and com.google.android.xxx modules in Soong, but take the same place
+// /apex/com.android.xxx at runtime. In these cases the variant name is always com.android.xxx,
+// regardless which APEX goes into the product. See also android.ApexInfo.ApexVariationName and
+// apex.apexBundleProperties.Apex_name.
+//
+// A related variable PRODUCT_APEX_BOOT_JARS contains bootclasspath libraries that are in APEXes.
+// They are not included in the boot image. The only exception here are ART jars and core-icu4j.jar
+// that have been historically part of the boot image and are now in apexes; they are in boot images
+// and core-icu4j.jar is generally treated as being part of PRODUCT_BOOT_JARS.
//
// One exception to the above rules are "coverage" builds (a special build flavor which requires
// setting environment variable EMMA_INSTRUMENT_FRAMEWORK=true). In coverage builds the Java code in
@@ -512,14 +523,14 @@
}
// buildBootImageVariantsForBuildOs generates rules to build the boot image variants for the
-// android.BuildOs OsType, i.e. the type of OS on which the build is being running.
+// config.BuildOS OsType, i.e. the type of OS on which the build is being running.
//
// The files need to be generated into their predefined location because they are used from there
// both within Soong and outside, e.g. for ART based host side testing and also for use by some
// cloud based tools. However, they are not needed by callers of this function and so the paths do
// not need to be returned from this func, unlike the buildBootImageVariantsForAndroidOs func.
func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) {
- buildBootImageForOsType(ctx, image, profile, android.BuildOs)
+ buildBootImageForOsType(ctx, image, profile, ctx.Config().BuildOS)
}
// buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType
@@ -799,10 +810,10 @@
// generateUpdatableBcpPackagesRule generates the rule to create the updatable-bcp-packages.txt file
// and returns a path to the generated file.
-func generateUpdatableBcpPackagesRule(ctx android.ModuleContext, image *bootImageConfig, updatableModules []android.Module) android.WritablePath {
+func generateUpdatableBcpPackagesRule(ctx android.ModuleContext, image *bootImageConfig, apexModules []android.Module) android.WritablePath {
// Collect `permitted_packages` for updatable boot jars.
var updatablePackages []string
- for _, module := range updatableModules {
+ for _, module := range apexModules {
if j, ok := module.(PermittedPackagesForUpdatableBootJars); ok {
pp := j.PermittedPackagesForUpdatableBootJars()
if len(pp) > 0 {
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index b13955f..415a1d4 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -32,7 +32,7 @@
}
}
// We may also need the images on host in order to run host-based tests.
- for _, target := range ctx.Config().Targets[android.BuildOs] {
+ for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] {
targets = append(targets, target)
}
@@ -142,14 +142,14 @@
return genBootImageConfigs(ctx)[frameworkBootImageName]
}
-// Updatable boot config allows to access build/install paths of updatable boot jars without going
+// Apex boot config allows to access build/install paths of apex boot jars without going
// through the usual trouble of registering dependencies on those modules and extracting build paths
// from those dependencies.
-type updatableBootConfig struct {
- // A list of updatable boot jars.
+type apexBootConfig struct {
+ // A list of apex boot jars.
modules android.ConfiguredJarList
- // A list of predefined build paths to updatable boot jars. They are configured very early,
+ // A list of predefined build paths to apex boot jars. They are configured very early,
// before the modules for these jars are processed and the actual paths are generated, and
// later on a singleton adds commands to copy actual jars to the predefined paths.
dexPaths android.WritablePaths
@@ -161,21 +161,21 @@
dexLocations []string
}
-var updatableBootConfigKey = android.NewOnceKey("updatableBootConfig")
+var updatableBootConfigKey = android.NewOnceKey("apexBootConfig")
-// Returns updatable boot config.
-func GetUpdatableBootConfig(ctx android.PathContext) updatableBootConfig {
+// Returns apex boot config.
+func GetApexBootConfig(ctx android.PathContext) apexBootConfig {
return ctx.Config().Once(updatableBootConfigKey, func() interface{} {
- updatableBootJars := dexpreopt.GetGlobalConfig(ctx).UpdatableBootJars
+ apexBootJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
- dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "updatable_bootjars")
- dexPaths := updatableBootJars.BuildPaths(ctx, dir)
- dexPathsByModuleName := updatableBootJars.BuildPathsByModule(ctx, dir)
+ dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "apex_bootjars")
+ dexPaths := apexBootJars.BuildPaths(ctx, dir)
+ dexPathsByModuleName := apexBootJars.BuildPathsByModule(ctx, dir)
- dexLocations := updatableBootJars.DevicePaths(ctx.Config(), android.Android)
+ dexLocations := apexBootJars.DevicePaths(ctx.Config(), android.Android)
- return updatableBootConfig{updatableBootJars, dexPaths, dexPathsByModuleName, dexLocations}
- }).(updatableBootConfig)
+ return apexBootConfig{apexBootJars, dexPaths, dexPathsByModuleName, dexLocations}
+ }).(apexBootConfig)
}
// Returns a list of paths and a list of locations for the boot jars used in dexpreopt (to be
@@ -188,10 +188,10 @@
dexLocations := bootImage.getAnyAndroidVariant().dexLocationsDeps
if withUpdatable {
- // Updatable boot jars (they are used only in dexpreopt, but not in the boot image).
- updBootConfig := GetUpdatableBootConfig(ctx)
- dexPaths = append(dexPaths, updBootConfig.dexPaths...)
- dexLocations = append(dexLocations, updBootConfig.dexLocations...)
+ // Apex boot jars (they are used only in dexpreopt, but not in the boot image).
+ apexBootConfig := GetApexBootConfig(ctx)
+ dexPaths = append(dexPaths, apexBootConfig.dexPaths...)
+ dexLocations = append(dexLocations, apexBootConfig.dexLocations...)
}
return dexPaths, dexLocations
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index b25dece..8dc7b79 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "runtime"
"testing"
"android/soong/android"
@@ -173,9 +174,9 @@
}
func TestDex2oatToolDeps(t *testing.T) {
- if android.BuildOs != android.Linux {
+ if runtime.GOOS != "linux" {
// The host binary paths checked below are build OS dependent.
- t.Skipf("Unsupported build OS %s", android.BuildOs)
+ t.Skipf("Unsupported build OS %s", runtime.GOOS)
}
preparers := android.GroupFixturePreparers(
diff --git a/java/droidstubs.go b/java/droidstubs.go
index c756815..ec1b04a 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -128,12 +128,15 @@
// whicih can be used for scheduling purposes
High_mem *bool
- // is set to true, Metalava will allow framework SDK to contain API levels annotations.
+ // if set to true, Metalava will allow framework SDK to contain API levels annotations.
Api_levels_annotations_enabled *bool
// 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.
+ Api_levels_sdk_type *string
+
// the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
Api_levels_jar_filename *string
@@ -367,6 +370,7 @@
filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
+ var dirs []string
ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
if t, ok := m.(*ExportedDroiddocDir); ok {
for _, dep := range t.deps {
@@ -383,12 +387,32 @@
cmd.Implicit(dep)
}
}
- cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/"+filename)
+
+ dirs = append(dirs, t.dir.String())
} else {
ctx.PropertyErrorf("api_levels_annotations_dirs",
"module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
}
})
+
+ // Add all relevant --android-jar-pattern patterns for Metalava.
+ // 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 _, 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))
+ }
}
func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
@@ -530,7 +554,8 @@
`\n` +
`If it is not possible to do so, there are workarounds:\n` +
`\n` +
- `1. You can suppress the errors with @SuppressLint("<id>")\n`
+ `1. You can suppress the errors with @SuppressLint("<id>")\n` +
+ ` where the <id> is given in brackets in the error message above.\n`
if baselineFile.Valid() {
cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index db664c1..60d0bea 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -16,6 +16,7 @@
import (
"reflect"
+ "regexp"
"strings"
"testing"
@@ -81,6 +82,46 @@
}
}
+func TestSystemDroidstubs(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ droiddoc_exported_dir {
+ name: "some-exported-dir",
+ path: "somedir",
+ }
+
+ droiddoc_exported_dir {
+ name: "some-other-exported-dir",
+ path: "someotherdir",
+ }
+
+ droidstubs {
+ name: "foo-stubs",
+ srcs: ["foo-doc/a.java"],
+ api_levels_annotations_dirs: [
+ "some-exported-dir",
+ "some-other-exported-dir",
+ ],
+ api_levels_annotations_enabled: true,
+ api_levels_sdk_type: "system",
+ }
+ `,
+ map[string][]byte{
+ "foo-doc/a.java": nil,
+ })
+
+ m := ctx.ModuleForTests("foo-stubs", "android_common")
+ 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)
+ 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)
+}
+
func TestDroidstubsSandbox(t *testing.T) {
ctx, _ := testJavaWithFS(t, `
genrule {
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index f901434..30683da 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -118,11 +118,11 @@
}
func isModuleInBootClassPath(ctx android.BaseModuleContext, module android.Module) bool {
- // Get the configured non-updatable and updatable boot jars.
- nonUpdatableBootJars := ctx.Config().NonUpdatableBootJars()
- updatableBootJars := ctx.Config().UpdatableBootJars()
- active := isModuleInConfiguredList(ctx, module, nonUpdatableBootJars) ||
- isModuleInConfiguredList(ctx, module, updatableBootJars)
+ // Get the configured platform and apex boot jars.
+ nonApexBootJars := ctx.Config().NonApexBootJars()
+ apexBootJars := ctx.Config().ApexBootJars()
+ active := isModuleInConfiguredList(ctx, module, nonApexBootJars) ||
+ isModuleInConfiguredList(ctx, module, apexBootJars)
return active
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 654ebb7..8a06a99 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -297,7 +297,7 @@
//
// The rule is initialized but not built so that the caller can modify it and select an appropriate
// name.
-func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, moduleStubFlagsPaths android.Paths) {
+func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, stubFlagSubsets SignatureCsvSubsets) {
// Singleton rule which applies hiddenapi on all boot class path dex files.
rule := android.NewRuleBuilder(pctx, ctx)
@@ -317,7 +317,7 @@
// If no module stub flags paths are provided then this must be being called for a
// bootclasspath_fragment and not the whole platform_bootclasspath.
- if moduleStubFlagsPaths == nil {
+ if stubFlagSubsets == nil {
// This is being run on a fragment of the bootclasspath.
command.Flag("--fragment")
}
@@ -342,8 +342,8 @@
// If there are stub flag files that have been generated by fragments on which this depends then
// use them to validate the stub flag file generated by the rules created by this method.
- if len(moduleStubFlagsPaths) > 0 {
- validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, moduleStubFlagsPaths)
+ if len(stubFlagSubsets) > 0 {
+ validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, stubFlagSubsets)
// Add the file that indicates that the file generated by this is valid.
//
@@ -510,14 +510,6 @@
}
}
-// dedup removes duplicates in the flag files, while maintaining the order in which they were
-// appended.
-func (s FlagFilesByCategory) dedup() {
- for category, paths := range s {
- s[category] = android.FirstUniquePaths(paths)
- }
-}
-
// HiddenAPIInfo contains information provided by the hidden API processing.
//
// That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API
@@ -554,6 +546,20 @@
}
}
+// 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.
+func (i *HiddenAPIInfo) StubFlagSubset() SignatureCsvSubset {
+ return SignatureCsvSubset{i.StubFlagsPath, i.SignaturePatternsPath}
+}
+
+// FlagSubset returns a SignatureCsvSubset that contains a path to an all-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}
+}
+
var HiddenAPIInfoProvider = blueprint.NewProvider(HiddenAPIInfo{})
// ModuleStubDexJars contains the stub dex jars provided by a single module.
@@ -790,6 +796,10 @@
// 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
}
// bootDexJarByModule is a map from base module name (without prebuilt_ prefix) to the boot dex
@@ -856,7 +866,7 @@
// the annotationFlags.
func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string,
outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlagPaths android.Paths,
- flagFilesByCategory FlagFilesByCategory, allFlagsPaths android.Paths, generatedRemovedDexSignatures android.OptionalPath) {
+ flagFilesByCategory FlagFilesByCategory, flagSubsets SignatureCsvSubsets, generatedRemovedDexSignatures android.OptionalPath) {
// Create the rule that will generate the flag files.
tempPath := tempPathForRestat(ctx, outputPath)
@@ -885,8 +895,8 @@
// If there are flag files that have been generated by fragments on which this depends then use
// them to validate the flag file generated by the rules created by this method.
- if len(allFlagsPaths) > 0 {
- validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, allFlagsPaths)
+ if len(flagSubsets) > 0 {
+ validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, flagSubsets)
// Add the file that indicates that the file generated by this is valid.
//
@@ -898,20 +908,66 @@
rule.Build(name, desc)
}
+// SignatureCsvSubset describes a subset of a monolithic flags file, i.e. either
+// out/soong/hiddenapi/hiddenapi-stub-flags.txt or out/soong/hiddenapi/hiddenapi-flags.csv
+type SignatureCsvSubset struct {
+ // The path to the CSV file containing hidden API flags.
+ //
+ // It has the dex member signature as the first column, with flags, one per column, in the
+ // subsequent columns.
+ CsvFile android.Path
+
+ // The path to the CSV file containing the signature patterns.
+ //
+ // It is a single column CSV file with the column containing a signature pattern.
+ SignaturePatternsFile android.Path
+}
+
+type SignatureCsvSubsets []SignatureCsvSubset
+
+func (s SignatureCsvSubsets) RelativeToTop() []string {
+ result := []string{}
+ for _, subset := range s {
+ result = append(result, fmt.Sprintf("%s:%s", subset.CsvFile.RelativeToTop(), subset.SignaturePatternsFile.RelativeToTop()))
+ }
+ return result
+}
+
+// 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 {
+ 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)
+ rule.Command().
+ BuiltTool("signature_patterns").
+ FlagWithInput("--flags ", flagsPath).
+ FlagWithOutput("--output ", patternsFile)
+ rule.Build("hiddenAPISignaturePatterns", "hidden API signature patterns")
+
+ return patternsFile
+}
+
// buildRuleValidateOverlappingCsvFiles checks that the modular CSV files, i.e. the files generated
// by the individual bootclasspath_fragment modules are subsets of the monolithic CSV file.
-func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, monolithicFilePath android.WritablePath, modularFilePaths android.Paths) android.WritablePath {
+func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, monolithicFilePath android.WritablePath, csvSubsets SignatureCsvSubsets) android.WritablePath {
// The file which is used to record that the flags file is valid.
validFile := pathForValidation(ctx, monolithicFilePath)
// Create a rule to validate the output from the following rule.
rule := android.NewRuleBuilder(pctx, ctx)
- rule.Command().
+ command := rule.Command().
BuiltTool("verify_overlaps").
- Input(monolithicFilePath).
- Inputs(modularFilePaths).
- // If validation passes then update the file that records that.
- Text("&& touch").Output(validFile)
+ Input(monolithicFilePath)
+
+ for _, subset := range csvSubsets {
+ command.
+ Textf("%s:%s", subset.CsvFile, subset.SignaturePatternsFile).
+ Implicit(subset.CsvFile).Implicit(subset.SignaturePatternsFile)
+ }
+
+ // If validation passes then update the file that records that.
+ command.Text("&& touch").Output(validFile)
rule.Build(name+"Validation", desc+" validation")
return validFile
diff --git a/java/hiddenapi_monolithic.go b/java/hiddenapi_monolithic.go
index 52f0770..5956e3c 100644
--- a/java/hiddenapi_monolithic.go
+++ b/java/hiddenapi_monolithic.go
@@ -29,9 +29,6 @@
// that category.
FlagsFilesByCategory FlagFilesByCategory
- // The paths to the generated stub-flags.csv files.
- StubFlagsPaths android.Paths
-
// The paths to the generated annotation-flags.csv files.
AnnotationFlagsPaths android.Paths
@@ -41,8 +38,13 @@
// The paths to the generated index.csv files.
IndexPaths android.Paths
- // The paths to the generated all-flags.csv files.
- AllFlagsPaths android.Paths
+ // The subsets of the monolithic hiddenapi-stubs-flags.txt file that are provided by each
+ // bootclasspath_fragment modules.
+ StubFlagSubsets SignatureCsvSubsets
+
+ // The subsets of the monolithic hiddenapi-flags.csv file that are provided by each
+ // bootclasspath_fragment modules.
+ FlagSubsets SignatureCsvSubsets
// The classes jars from the libraries on the platform bootclasspath.
ClassesJars android.Paths
@@ -58,68 +60,34 @@
// Merge all the information from the classpathElements. The fragments form a DAG so it is possible that
// this will introduce duplicates so they will be resolved after processing all the classpathElements.
for _, element := range classpathElements {
- var classesJars android.Paths
switch e := element.(type) {
case *ClasspathLibraryElement:
- classesJars = retrieveClassesJarsFromModule(e.Module())
+ classesJars := retrieveClassesJarsFromModule(e.Module())
+ monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, classesJars...)
case *ClasspathFragmentElement:
fragment := e.Module()
if ctx.OtherModuleHasProvider(fragment, HiddenAPIInfoProvider) {
info := ctx.OtherModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo)
monolithicInfo.append(&info)
-
- // If the bootclasspath fragment actually perform hidden API processing itself then use the
- // CSV files it provides and do not bother processing the classesJars files. This ensures
- // consistent behavior between source and prebuilt as prebuilt modules do not provide
- // classesJars.
- if info.AllFlagsPath != nil {
- continue
- }
+ } else {
+ ctx.ModuleErrorf("%s does not provide hidden API information", fragment)
}
-
- classesJars = extractClassesJarsFromModules(e.Contents)
}
-
- monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, classesJars...)
}
- // Dedup paths.
- monolithicInfo.dedup()
-
return monolithicInfo
}
// append appends all the files from the supplied info to the corresponding files in this struct.
func (i *MonolithicHiddenAPIInfo) append(other *HiddenAPIInfo) {
i.FlagsFilesByCategory.append(other.FlagFilesByCategory)
+ i.AnnotationFlagsPaths = append(i.AnnotationFlagsPaths, other.AnnotationFlagsPath)
+ i.MetadataPaths = append(i.MetadataPaths, other.MetadataPath)
+ i.IndexPaths = append(i.IndexPaths, other.IndexPath)
- // The output may not be set if the bootclasspath_fragment has not yet been updated to support
- // hidden API processing.
- // TODO(b/179354495): Switch back to append once all bootclasspath_fragment modules have been
- // updated to support hidden API processing properly.
- appendIfNotNil := func(paths android.Paths, path android.Path) android.Paths {
- if path == nil {
- return paths
- }
- return append(paths, path)
- }
- i.StubFlagsPaths = appendIfNotNil(i.StubFlagsPaths, other.StubFlagsPath)
- i.AnnotationFlagsPaths = appendIfNotNil(i.AnnotationFlagsPaths, other.AnnotationFlagsPath)
- i.MetadataPaths = appendIfNotNil(i.MetadataPaths, other.MetadataPath)
- i.IndexPaths = appendIfNotNil(i.IndexPaths, other.IndexPath)
- i.AllFlagsPaths = appendIfNotNil(i.AllFlagsPaths, other.AllFlagsPath)
-}
-
-// dedup removes duplicates in all the paths, while maintaining the order in which they were
-// appended.
-func (i *MonolithicHiddenAPIInfo) dedup() {
- i.FlagsFilesByCategory.dedup()
- i.StubFlagsPaths = android.FirstUniquePaths(i.StubFlagsPaths)
- i.AnnotationFlagsPaths = android.FirstUniquePaths(i.AnnotationFlagsPaths)
- i.MetadataPaths = android.FirstUniquePaths(i.MetadataPaths)
- i.IndexPaths = android.FirstUniquePaths(i.IndexPaths)
- i.AllFlagsPaths = android.FirstUniquePaths(i.AllFlagsPaths)
+ i.StubFlagSubsets = append(i.StubFlagSubsets, other.StubFlagSubset())
+ i.FlagSubsets = append(i.FlagSubsets, other.FlagSubset())
}
var MonolithicHiddenAPIInfoProvider = blueprint.NewProvider(MonolithicHiddenAPIInfo{})
diff --git a/java/jacoco.go b/java/jacoco.go
index 9162161..e11c2ce 100644
--- a/java/jacoco.go
+++ b/java/jacoco.go
@@ -94,7 +94,7 @@
if len(includes) > 0 {
specs += strings.Join(includes, " ")
} else {
- specs += "**/*.class"
+ specs += "'**/*.class'"
}
return specs
}
diff --git a/java/jacoco_test.go b/java/jacoco_test.go
index 91f0553..1882908 100644
--- a/java/jacoco_test.go
+++ b/java/jacoco_test.go
@@ -74,7 +74,7 @@
{
name: "implicit wildcard",
includes: []string{},
- out: "**/*.class",
+ out: "'**/*.class'",
},
{
name: "only include",
diff --git a/java/java.go b/java/java.go
index bbed42d..b6e2a54 100644
--- a/java/java.go
+++ b/java/java.go
@@ -21,7 +21,6 @@
import (
"fmt"
"path/filepath"
- "strings"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -131,11 +130,19 @@
PropertyName: "java_boot_libs",
SupportsSdk: true,
},
- // Temporarily export implementation classes jar for java_boot_libs as it is required for the
- // hiddenapi processing.
- // TODO(b/179354495): Revert once hiddenapi processing has been modularized.
- exportImplementationClassesJar,
- sdkSnapshotFilePathForJar,
+ func(ctx android.SdkMemberContext, j *Library) android.Path {
+ // Java boot libs are only provided in the SDK to provide access to their dex implementation
+ // jar for use by dexpreopting and boot jars package check. 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_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
+ },
onlyCopyJarToSnapshot,
}
@@ -450,7 +457,7 @@
var _ android.ApexModule = (*Library)(nil)
-// Provides access to the list of permitted packages from updatable boot jars.
+// Provides access to the list of permitted packages from apex boot jars.
type PermittedPackagesForUpdatableBootJars interface {
PermittedPackagesForUpdatableBootJars() []string
}
@@ -1180,7 +1187,8 @@
properties ImportProperties
// output file containing classes.dex and resources
- dexJarFile android.Path
+ dexJarFile android.Path
+ dexJarInstallFile android.Path
combinedClasspathFile android.Path
classLoaderContexts dexpreopt.ClassLoaderContextMap
@@ -1303,10 +1311,6 @@
// Save away the `deapexer` module on which this depends, if any.
if tag == android.DeapexerTag {
- if deapexerModule != nil {
- ctx.ModuleErrorf("Ambiguous duplicate deapexer module dependencies %q and %q",
- deapexerModule.Name(), module.Name())
- }
deapexerModule = module
}
})
@@ -1335,6 +1339,7 @@
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil {
j.dexJarFile = dexOutputPath
+ j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName()))
// Initialize the hiddenapi structure.
j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil)
@@ -1375,6 +1380,7 @@
dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile)
j.dexJarFile = dexOutputFile
+ j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName)
}
}
@@ -1416,7 +1422,7 @@
}
func (j *Import) DexJarInstallPath() android.Path {
- return nil
+ return j.dexJarInstallFile
}
func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
@@ -1440,12 +1446,8 @@
if sdkSpec.Kind == android.SdkCore {
return nil
}
- ver, err := sdkSpec.EffectiveVersion(ctx)
- if err != nil {
- return err
- }
- if ver.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", ver)
+ if sdkSpec.ApiLevel.GreaterThan(sdkVersion) {
+ return fmt.Errorf("newer SDK(%v)", sdkSpec.ApiLevel)
}
return nil
}
@@ -1490,11 +1492,7 @@
// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
// solution to get the Import name.
- name := j.Name()
- if strings.HasPrefix(name, removedPrefix) {
- name = strings.TrimPrefix(name, removedPrefix)
- }
- return name
+ return android.RemoveOptionalPrebuiltPrefix(j.Name())
}
var _ android.PrebuiltInterface = (*Import)(nil)
@@ -1796,22 +1794,16 @@
return
}
- // Find out if the dependency is either an SDK library or an ordinary library that is disguised
- // as an SDK library by the means of `provides_uses_lib` property. If yes, the library is itself
- // a <uses-library> and should be added as a node in the CLC tree, and its CLC should be added
- // as subtree of that node. Otherwise the library is not a <uses_library> and should not be
- // added to CLC, but the transitive <uses-library> dependencies from its CLC should be added to
- // the current CLC.
- var implicitSdkLib *string
- comp, isComp := depModule.(SdkLibraryComponentDependency)
- if isComp {
- implicitSdkLib = comp.OptionalImplicitSdkLibrary()
- // OptionalImplicitSdkLibrary() may be nil so need to fall through to ProvidesUsesLib().
- }
- if implicitSdkLib == nil {
- if ulib, ok := depModule.(ProvidesUsesLib); ok {
- implicitSdkLib = ulib.ProvidesUsesLib()
- }
+ depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule))
+
+ var sdkLib *string
+ if lib, ok := depModule.(SdkLibraryDependency); ok && lib.sharedLibrary() {
+ // A shared SDK library. This should be added as a top-level CLC element.
+ sdkLib = &depName
+ } else if ulib, ok := depModule.(ProvidesUsesLib); ok {
+ // A non-SDK library disguised as an SDK library by the means of `provides_uses_lib`
+ // property. This should be handled in the same way as a shared SDK library.
+ sdkLib = ulib.ProvidesUsesLib()
}
depTag := ctx.OtherModuleDependencyTag(depModule)
@@ -1821,7 +1813,7 @@
// Propagate <uses-library> through static library dependencies, unless it is a component
// library (such as stubs). Component libraries have a dependency on their SDK library,
// which should not be pulled just because of a static component library.
- if implicitSdkLib != nil {
+ if sdkLib != nil {
return
}
} else {
@@ -1829,11 +1821,14 @@
return
}
- if implicitSdkLib != nil {
- clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *implicitSdkLib,
+ // If this is an SDK (or SDK-like) library, then it should be added as a node in the CLC tree,
+ // and its CLC should be added as subtree of that node. Otherwise the library is not a
+ // <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies
+ // from its CLC should be added to the current CLC.
+ if sdkLib != nil {
+ clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib,
dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
} else {
- depName := ctx.OtherModuleName(depModule)
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
}
}
diff --git a/java/java_test.go b/java/java_test.go
index bd373c1..b6780c2 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -441,7 +441,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
bar := ctx.ModuleForTests("bar", buildOS+"_common")
barJar := bar.Output("bar.jar").Output.String()
@@ -478,7 +478,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
foo := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
@@ -523,7 +523,7 @@
}
// check that -g is not overridden for host modules
- buildOS := android.BuildOs.String()
+ buildOS := result.Config.BuildOS.String()
hostBinary := result.ModuleForTests("host_binary", buildOS+"_common")
hostJavaFlags := hostBinary.Module().VariablesForTests()["javacFlags"]
if strings.Contains(hostJavaFlags, "-g:source,lines") {
@@ -1371,7 +1371,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
entries := android.AndroidMkEntriesForTest(t, ctx, test)[0]
@@ -1387,8 +1387,100 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
module := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
assertDeepEquals(t, "Default installable value should be true.", proptools.BoolPtr(true),
module.properties.Installable)
}
+
+func TestErrorproneEnabled(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ errorprone: {
+ enabled: true,
+ },
+ }
+ `)
+
+ javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+
+ // Test that the errorprone plugins are passed to javac
+ expectedSubstring := "-Xplugin:ErrorProne"
+ if !strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
+ t.Errorf("expected javacFlags to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
+ }
+
+ // Modules with errorprone { enabled: true } will include errorprone checks
+ // in the main javac build rule. Only when RUN_ERROR_PRONE is true will
+ // the explicit errorprone build rule be created.
+ errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
+ if errorprone.RuleParams.Description != "" {
+ t.Errorf("expected errorprone build rule to not exist, but it did")
+ }
+}
+
+func TestErrorproneDisabled(t *testing.T) {
+ bp := `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ errorprone: {
+ enabled: false,
+ },
+ }
+ `
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureMergeEnv(map[string]string{
+ "RUN_ERROR_PRONE": "true",
+ }),
+ ).RunTestWithBp(t, bp)
+
+ javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+
+ // Test that the errorprone plugins are not passed to javac, like they would
+ // be if enabled was true.
+ expectedSubstring := "-Xplugin:ErrorProne"
+ if strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
+ t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
+ }
+
+ // Check that no errorprone build rule is created, like there would be
+ // if enabled was unset and RUN_ERROR_PRONE was true.
+ errorprone := ctx.ModuleForTests("foo", "android_common").MaybeDescription("errorprone")
+ if errorprone.RuleParams.Description != "" {
+ t.Errorf("expected errorprone build rule to not exist, but it did")
+ }
+}
+
+func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) {
+ bp := `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+ `
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureMergeEnv(map[string]string{
+ "RUN_ERROR_PRONE": "true",
+ }),
+ ).RunTestWithBp(t, bp)
+
+ javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+ errorprone := ctx.ModuleForTests("foo", "android_common").Description("errorprone")
+
+ // Check that the errorprone plugins are not passed to javac, because they
+ // will instead be passed to the separate errorprone compilation
+ expectedSubstring := "-Xplugin:ErrorProne"
+ if strings.Contains(javac.Args["javacFlags"], expectedSubstring) {
+ t.Errorf("expected javacFlags to not contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
+ }
+
+ // Check that the errorprone plugin is enabled
+ if !strings.Contains(errorprone.Args["javacFlags"], expectedSubstring) {
+ t.Errorf("expected errorprone to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"])
+ }
+}
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index 1c146a1..db30696 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -15,10 +15,11 @@
package java
import (
- "android/soong/android"
"strconv"
"strings"
"testing"
+
+ "android/soong/android"
)
func TestKotlin(t *testing.T) {
@@ -114,7 +115,7 @@
t.Run("", func(t *testing.T) {
ctx, _ := testJava(t, bp)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
kapt := ctx.ModuleForTests("foo", "android_common").Rule("kapt")
kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
@@ -182,10 +183,9 @@
android.FixtureMergeEnv(env),
).RunTestWithBp(t, bp)
- buildOS := android.BuildOs.String()
+ buildOS := result.Config.BuildOS.String()
kapt := result.ModuleForTests("foo", "android_common").Rule("kapt")
- //kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
javac := result.ModuleForTests("foo", "android_common").Description("javac")
errorprone := result.ModuleForTests("foo", "android_common").Description("errorprone")
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index 2de05b0..4bc0c5f 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -1,10 +1,37 @@
# Treat LintError as fatal to catch invocation errors
--fatal_check LintError
+# Checks which do not apply to the platform (implementation
+# in lint assumes that it's running on app code)
+
+--disable_check AnimatorKeep
+--disable_check AppBundleLocaleChanges
+--disable_check BlockedPrivateApi
+--disable_check CustomSplashScreen
+--disable_check CustomX509TrustManager
+--disable_check Deprecated
+--disable_check ExifInterface
+--disable_check HardwareIds
+--disable_check InvalidWakeLockTag
+--disable_check LibraryCustomView
+--disable_check MissingPermission
+--disable_check NonConstantResourceId
+--disable_check OldTargetApi
+--disable_check Override
+--disable_check PackageManagerGetSignatures
+--disable_check PrivateApi
+--disable_check ProtectedPermissions
+--disable_check QueryPermissionsNeeded
+--disable_check ScopedStorage
+--disable_check ServiceCast
+--disable_check SoonBlockedPrivateApi
+--disable_check SuspiciousImport
+--disable_check UnusedResources
+--disable_check ViewConstructor
+
# Downgrade existing errors to warnings
--warning_check AppCompatResource # 55 occurences in 10 modules
--warning_check AppLinkUrlError # 111 occurences in 53 modules
---warning_check BlockedPrivateApi # 2 occurences in 2 modules
--warning_check ByteOrderMark # 2 occurences in 2 modules
--warning_check DuplicateActivity # 3 occurences in 3 modules
--warning_check DuplicateDefinition # 3623 occurences in 48 modules
@@ -22,9 +49,7 @@
--warning_check Instantiatable # 145 occurences in 19 modules
--warning_check InvalidPermission # 6 occurences in 4 modules
--warning_check InvalidUsesTagAttribute # 6 occurences in 2 modules
---warning_check InvalidWakeLockTag # 111 occurences in 37 modules
--warning_check JavascriptInterface # 3 occurences in 2 modules
---warning_check LibraryCustomView # 9 occurences in 4 modules
--warning_check LogTagMismatch # 81 occurences in 13 modules
--warning_check LongLogTag # 249 occurences in 12 modules
--warning_check MenuTitle # 5 occurences in 4 modules
@@ -35,7 +60,6 @@
--warning_check MissingLeanbackLauncher # 3 occurences in 3 modules
--warning_check MissingLeanbackSupport # 2 occurences in 2 modules
--warning_check MissingOnPlayFromSearch # 1 occurences in 1 modules
---warning_check MissingPermission # 2071 occurences in 150 modules
--warning_check MissingPrefix # 46 occurences in 41 modules
--warning_check MissingQuantity # 100 occurences in 1 modules
--warning_check MissingSuperCall # 121 occurences in 36 modules
@@ -47,9 +71,7 @@
--warning_check ObjectAnimatorBinding # 14 occurences in 5 modules
--warning_check OnClick # 49 occurences in 21 modules
--warning_check Orientation # 77 occurences in 19 modules
---warning_check Override # 385 occurences in 36 modules
--warning_check ParcelCreator # 23 occurences in 2 modules
---warning_check ProtectedPermissions # 2413 occurences in 381 modules
--warning_check Range # 80 occurences in 28 modules
--warning_check RecyclerView # 1 occurences in 1 modules
--warning_check ReferenceType # 4 occurences in 1 modules
@@ -60,8 +82,6 @@
--warning_check ResourceType # 137 occurences in 36 modules
--warning_check RestrictedApi # 28 occurences in 5 modules
--warning_check RtlCompat # 9 occurences in 6 modules
---warning_check ServiceCast # 3 occurences in 1 modules
---warning_check SoonBlockedPrivateApi # 5 occurences in 3 modules
--warning_check StringFormatInvalid # 148 occurences in 11 modules
--warning_check StringFormatMatches # 4800 occurences in 30 modules
--warning_check UnknownId # 8 occurences in 7 modules
@@ -74,7 +94,9 @@
--warning_check WrongThread # 14 occurences in 6 modules
--warning_check WrongViewCast # 1 occurences in 1 modules
-# TODO(b/158390965): remove this when lint doesn't crash
---disable_check HardcodedDebugMode
-
+--warning_check CoarseFineLocation
+--warning_check IntentFilterExportedReceiver
--warning_check QueryAllPackagesPermission
+--warning_check RemoteViewLayout
+--warning_check SupportAnnotationUsage
+--warning_check UniqueConstants
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 10739b0..36baf7e 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -32,9 +32,9 @@
// The tags used for the dependencies between the platform bootclasspath and any configured boot
// jars.
var (
- platformBootclasspathArtBootJarDepTag = bootclasspathDependencyTag{name: "art-boot-jar"}
- platformBootclasspathNonUpdatableBootJarDepTag = bootclasspathDependencyTag{name: "non-updatable-boot-jar"}
- platformBootclasspathUpdatableBootJarDepTag = bootclasspathDependencyTag{name: "updatable-boot-jar"}
+ platformBootclasspathArtBootJarDepTag = bootclasspathDependencyTag{name: "art-boot-jar"}
+ platformBootclasspathBootJarDepTag = bootclasspathDependencyTag{name: "platform-boot-jar"}
+ platformBootclasspathApexBootJarDepTag = bootclasspathDependencyTag{name: "apex-boot-jar"}
)
type platformBootclasspathModule struct {
@@ -131,11 +131,11 @@
// Add dependencies on all the non-updatable module configured in the "boot" boot image. That does
// not include modules configured in the "art" boot image.
bootImageConfig := b.getImageConfig(ctx)
- addDependenciesOntoBootImageModules(ctx, bootImageConfig.modules, platformBootclasspathNonUpdatableBootJarDepTag)
+ addDependenciesOntoBootImageModules(ctx, bootImageConfig.modules, platformBootclasspathBootJarDepTag)
- // Add dependencies on all the updatable modules.
- updatableModules := dexpreopt.GetGlobalConfig(ctx).UpdatableBootJars
- addDependenciesOntoBootImageModules(ctx, updatableModules, platformBootclasspathUpdatableBootJarDepTag)
+ // Add dependencies on all the apex jars.
+ apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
+ addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag)
// Add dependencies on all the fragments.
b.properties.BootclasspathFragmentsDepsProperties.addDependenciesOntoFragments(ctx)
@@ -163,16 +163,16 @@
}
func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- // Gather all the dependencies from the art, updatable and non-updatable boot jars.
+ // Gather all the dependencies from the art, platform, and apex boot jars.
artModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathArtBootJarDepTag)
- nonUpdatableModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathNonUpdatableBootJarDepTag)
- updatableModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathUpdatableBootJarDepTag)
+ platformModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathBootJarDepTag)
+ apexModules := gatherApexModulePairDepsWithTag(ctx, platformBootclasspathApexBootJarDepTag)
// Concatenate them all, in order as they would appear on the bootclasspath.
var allModules []android.Module
allModules = append(allModules, artModules...)
- allModules = append(allModules, nonUpdatableModules...)
- allModules = append(allModules, updatableModules...)
+ allModules = append(allModules, platformModules...)
+ allModules = append(allModules, apexModules...)
b.configuredModules = allModules
// Gather all the fragments dependencies.
@@ -180,8 +180,8 @@
// Check the configuration of the boot modules.
// ART modules are checked by the art-bootclasspath-fragment.
- b.checkNonUpdatableModules(ctx, nonUpdatableModules)
- b.checkUpdatableModules(ctx, updatableModules)
+ b.checkPlatformModules(ctx, platformModules)
+ b.checkApexModules(ctx, apexModules)
b.generateClasspathProtoBuildActions(ctx)
@@ -193,23 +193,40 @@
return
}
- b.generateBootImageBuildActions(ctx, nonUpdatableModules, updatableModules)
+ b.generateBootImageBuildActions(ctx, platformModules, apexModules)
}
// Generate classpaths.proto config
func (b *platformBootclasspathModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
+ configuredJars := b.configuredJars(ctx)
// ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
- classpathJars := configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
- b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
+ classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
+ b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
}
-func (b *platformBootclasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
- return b.getImageConfig(ctx).modules
+func (b *platformBootclasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
+ // Include all non APEX jars
+ jars := b.getImageConfig(ctx).modules
+
+ // Include jars from APEXes that don't populate their classpath proto config.
+ remainingJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
+ for _, fragment := range b.fragments {
+ info := ctx.OtherModuleProvider(fragment, ClasspathFragmentProtoContentInfoProvider).(ClasspathFragmentProtoContentInfo)
+ if info.ClasspathFragmentProtoGenerated {
+ remainingJars = remainingJars.RemoveList(info.ClasspathFragmentProtoContents)
+ }
+ }
+ for i := 0; i < remainingJars.Len(); i++ {
+ jars = jars.Append(remainingJars.Apex(i), remainingJars.Jar(i))
+ }
+
+ return jars
}
-// checkNonUpdatableModules ensures that the non-updatable modules supplied are not part of an
-// updatable module.
-func (b *platformBootclasspathModule) checkNonUpdatableModules(ctx android.ModuleContext, modules []android.Module) {
+// checkPlatformModules ensures that the non-updatable modules supplied are not part of an
+// apex module.
+func (b *platformBootclasspathModule) checkPlatformModules(ctx android.ModuleContext, modules []android.Module) {
+ // TODO(satayev): change this check to only allow core-icu4j, all apex jars should not be here.
for _, m := range modules {
apexInfo := ctx.OtherModuleProvider(m, android.ApexInfoProvider).(android.ApexInfo)
fromUpdatableApex := apexInfo.Updatable
@@ -222,8 +239,8 @@
}
}
-// checkUpdatableModules ensures that the updatable modules supplied are not from the platform.
-func (b *platformBootclasspathModule) checkUpdatableModules(ctx android.ModuleContext, modules []android.Module) {
+// checkApexModules ensures that the apex modules supplied are not from the platform.
+func (b *platformBootclasspathModule) checkApexModules(ctx android.ModuleContext, modules []android.Module) {
for _, m := range modules {
apexInfo := ctx.OtherModuleProvider(m, android.ApexInfoProvider).(android.ApexInfo)
fromUpdatableApex := apexInfo.Updatable
@@ -239,12 +256,12 @@
// modules is complete.
if !ctx.Config().AlwaysUsePrebuiltSdks() {
// error: this jar is part of the platform
- ctx.ModuleErrorf("module %q from platform is not allowed in the updatable boot jars list", name)
+ ctx.ModuleErrorf("module %q from platform is not allowed in the apex boot jars list", name)
}
} else {
// TODO(b/177892522): Treat this as an error.
// Cannot do that at the moment because framework-wifi and framework-tethering are in the
- // PRODUCT_UPDATABLE_BOOT_JARS but not marked as updatable in AOSP.
+ // PRODUCT_APEX_BOOT_JARS but not marked as updatable in AOSP.
}
}
}
@@ -299,7 +316,7 @@
// Generate the monolithic stub-flags.csv file.
stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
- buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags", stubFlags, bootDexJarByModule.bootDexJars(), input, monolithicInfo.StubFlagsPaths)
+ buildRuleToGenerateHiddenAPIStubFlagsFile(ctx, "platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags", stubFlags, bootDexJarByModule.bootDexJars(), input, monolithicInfo.StubFlagSubsets)
// Generate the annotation-flags.csv file from all the module annotations.
annotationFlags := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "annotation-flags-from-classes.csv")
@@ -312,7 +329,7 @@
allAnnotationFlagFiles := android.Paths{annotationFlags}
allAnnotationFlagFiles = append(allAnnotationFlagFiles, monolithicInfo.AnnotationFlagsPaths...)
allFlags := hiddenAPISingletonPaths(ctx).flags
- buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "monolithic hidden API flags", allFlags, stubFlags, allAnnotationFlagFiles, monolithicInfo.FlagsFilesByCategory, monolithicInfo.AllFlagsPaths, android.OptionalPath{})
+ buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "monolithic hidden API flags", allFlags, stubFlags, allAnnotationFlagFiles, monolithicInfo.FlagsFilesByCategory, monolithicInfo.FlagSubsets, android.OptionalPath{})
// Generate an intermediate monolithic hiddenapi-metadata.csv file directly from the annotations
// in the source code.
@@ -389,7 +406,7 @@
}
// generateBootImageBuildActions generates ninja rules related to the boot image creation.
-func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.ModuleContext, nonUpdatableModules, updatableModules []android.Module) {
+func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.ModuleContext, platformModules, apexModules []android.Module) {
// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
// GenerateSingletonBuildActions method as it cannot create it for itself.
dexpreopt.GetGlobalSoongConfig(ctx)
@@ -407,17 +424,22 @@
// Generate the framework profile rule
bootFrameworkProfileRule(ctx, imageConfig)
- // Generate the updatable bootclasspath packages rule.
- generateUpdatableBcpPackagesRule(ctx, imageConfig, updatableModules)
+ // If always using prebuilt sdks then do not generate the updatable-bcp-packages.txt file as it
+ // will break because the prebuilts do not yet specify a permitted_packages property.
+ // TODO(b/193889859): Remove when the prebuilts have been updated.
+ if !ctx.Config().AlwaysUsePrebuiltSdks() {
+ // Generate the updatable bootclasspath packages rule.
+ generateUpdatableBcpPackagesRule(ctx, imageConfig, apexModules)
+ }
- // Copy non-updatable module dex jars to their predefined locations.
- nonUpdatableBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, nonUpdatableModules)
- copyBootJarsToPredefinedLocations(ctx, nonUpdatableBootDexJarsByModule, imageConfig.dexPathsByModule)
+ // Copy platform module dex jars to their predefined locations.
+ platformBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, platformModules)
+ copyBootJarsToPredefinedLocations(ctx, platformBootDexJarsByModule, imageConfig.dexPathsByModule)
- // Copy updatable module dex jars to their predefined locations.
- config := GetUpdatableBootConfig(ctx)
- updatableBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, updatableModules)
- copyBootJarsToPredefinedLocations(ctx, updatableBootDexJarsByModule, config.dexPathsByModule)
+ // Copy apex module dex jars to their predefined locations.
+ config := GetApexBootConfig(ctx)
+ apexBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, apexModules)
+ copyBootJarsToPredefinedLocations(ctx, apexBootDexJarsByModule, config.dexPathsByModule)
// Build a profile for the image config and then use that to build the boot image.
profile := bootImageProfileRule(ctx, imageConfig)
diff --git a/java/plugin_test.go b/java/plugin_test.go
index c7913d3..dc29b1c 100644
--- a/java/plugin_test.go
+++ b/java/plugin_test.go
@@ -15,7 +15,6 @@
package java
import (
- "android/soong/android"
"testing"
)
@@ -58,7 +57,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
@@ -98,7 +97,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
turbine := ctx.ModuleForTests("foo", "android_common").MaybeRule("turbine")
diff --git a/java/robolectric.go b/java/robolectric.go
index 9fe1f0e..f216425 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -83,6 +83,9 @@
testConfig android.Path
data android.Paths
+
+ forceOSType android.OsType
+ forceArchType android.ArchType
}
func (r *robolectricTest) TestSuites() []string {
@@ -115,6 +118,9 @@
}
func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ r.forceOSType = ctx.Config().BuildOS
+ r.forceArchType = ctx.Config().BuildArch
+
r.testConfig = tradefed.AutoGenRobolectricTestConfig(ctx, r.testProperties.Test_config,
r.testProperties.Test_config_template, r.testProperties.Test_suites,
r.testProperties.Auto_gen_config)
@@ -179,7 +185,7 @@
continue
} else if strings.HasSuffix(s, "/BaseRobolectricTest.java") {
continue
- } else if strings.HasPrefix(s, "src/") {
+ } else {
s = strings.TrimPrefix(s, "src/")
}
r.tests = append(r.tests, s)
@@ -345,7 +351,7 @@
func (r *robolectricTest) InstallBypassMake() bool { return true }
func (r *robolectricTest) InstallInTestcases() bool { return true }
func (r *robolectricTest) InstallForceOS() (*android.OsType, *android.ArchType) {
- return &android.BuildOs, &android.BuildArch
+ return &r.forceOSType, &r.forceArchType
}
func robolectricRuntimesFactory() android.Module {
@@ -366,6 +372,9 @@
props robolectricRuntimesProperties
runtimes []android.InstallPath
+
+ forceOSType android.OsType
+ forceArchType android.ArchType
}
func (r *robolectricRuntimes) TestSuites() []string {
@@ -385,6 +394,9 @@
return
}
+ r.forceOSType = ctx.Config().BuildOS
+ r.forceArchType = ctx.Config().BuildArch
+
files := android.PathsForModuleSrc(ctx, r.props.Jars)
androidAllDir := android.PathForModuleInstall(ctx, "android-all")
@@ -415,5 +427,5 @@
func (r *robolectricRuntimes) InstallBypassMake() bool { return true }
func (r *robolectricRuntimes) InstallInTestcases() bool { return true }
func (r *robolectricRuntimes) InstallForceOS() (*android.OsType, *android.ArchType) {
- return &android.BuildOs, &android.BuildArch
+ return &r.forceOSType, &r.forceArchType
}
diff --git a/java/rro.go b/java/rro.go
index 2e58c04..0b4d091 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -90,6 +90,22 @@
Theme() string
}
+// RRO's partition logic is different from the partition logic of other modules defined in soong/android/paths.go
+// The default partition for RRO is "/product" and not "/system"
+func rroPartition(ctx android.ModuleContext) string {
+ var partition string
+ if ctx.DeviceSpecific() {
+ partition = ctx.DeviceConfig().OdmPath()
+ } else if ctx.SocSpecific() {
+ partition = ctx.DeviceConfig().VendorPath()
+ } else if ctx.SystemExtSpecific() {
+ partition = ctx.DeviceConfig().SystemExtPath()
+ } else {
+ partition = ctx.DeviceConfig().ProductPath()
+ }
+ return partition
+}
+
func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
sdkDep := decodeSdkDep(ctx, android.SdkContext(r))
if sdkDep.hasFrameworkLibs() {
@@ -137,7 +153,8 @@
r.certificate = certificates[0]
r.outputFile = signed
- r.installDir = android.PathForModuleInstall(ctx, "overlay", String(r.properties.Theme))
+ partition := rroPartition(ctx)
+ r.installDir = android.PathForModuleInPartitionInstall(ctx, partition, "overlay", String(r.properties.Theme))
ctx.InstallFile(r.installDir, r.outputFile.Base(), r.outputFile)
}
diff --git a/java/rro_test.go b/java/rro_test.go
index bad60bc..27abbe4 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -177,7 +177,7 @@
// Check device location.
path = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
- expectedPath = []string{shared.JoinPath("out/target/product/test_device/system/overlay")}
+ expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", config, expectedPath, path)
}
@@ -343,3 +343,57 @@
})
}
}
+
+func TestRuntimeResourceOverlayPartition(t *testing.T) {
+ bp := `
+ runtime_resource_overlay {
+ name: "device_specific",
+ device_specific: true,
+ }
+ runtime_resource_overlay {
+ name: "soc_specific",
+ soc_specific: true,
+ }
+ runtime_resource_overlay {
+ name: "system_ext_specific",
+ system_ext_specific: true,
+ }
+ runtime_resource_overlay {
+ name: "product_specific",
+ product_specific: true,
+ }
+ runtime_resource_overlay {
+ name: "default"
+ }
+ `
+ testCases := []struct {
+ name string
+ expectedPath string
+ }{
+ {
+ name: "device_specific",
+ expectedPath: "out/soong/target/product/test_device/odm/overlay",
+ },
+ {
+ name: "soc_specific",
+ expectedPath: "out/soong/target/product/test_device/vendor/overlay",
+ },
+ {
+ name: "system_ext_specific",
+ expectedPath: "out/soong/target/product/test_device/system_ext/overlay",
+ },
+ {
+ name: "product_specific",
+ expectedPath: "out/soong/target/product/test_device/product/overlay",
+ },
+ {
+ name: "default",
+ expectedPath: "out/soong/target/product/test_device/product/overlay",
+ },
+ }
+ for _, testCase := range testCases {
+ ctx, _ := testJava(t, bp)
+ mod := ctx.ModuleForTests(testCase.name, "android_common").Module().(*RuntimeResourceOverlay)
+ android.AssertPathRelativeToTopEquals(t, "Install dir is not correct for "+testCase.name, testCase.expectedPath, mod.installDir)
+ }
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 8c66438..c50e077 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -419,7 +419,7 @@
// local files that are used within user customized droiddoc options.
Droiddoc_option_files []string
- // additional droiddoc options
+ // additional droiddoc options.
// Available variables for substitution:
//
// $(location <label>): the path to the droiddoc_option_files with name <label>
@@ -981,13 +981,15 @@
}
// to satisfy SdkLibraryComponentDependency
-func (e *EmbeddableSdkLibraryComponent) OptionalImplicitSdkLibrary() *string {
- return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack
-}
-
-// to satisfy SdkLibraryComponentDependency
func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *string {
- // Currently implementation library name is the same as the SDK library name.
+ // For shared libraries, this is the same as the SDK library name. If a Java library or app
+ // depends on a component library (e.g. a stub library) it still needs to know the name of the
+ // run-time library and the corresponding module that provides the implementation. This name is
+ // passed to manifest_fixer (to be added to AndroidManifest.xml) and added to CLC (to be used
+ // in dexpreopt).
+ //
+ // For non-shared SDK (component or not) libraries this returns `nil`, as they are not
+ // <uses-library> and should not be added to the manifest or to CLC.
return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack
}
@@ -999,12 +1001,6 @@
// SdkLibraryName returns the name of the java_sdk_library/_import module.
SdkLibraryName() *string
- // The optional name of the sdk library that should be implicitly added to the
- // AndroidManifest of an app that contains code which references the sdk library.
- //
- // Returns the name of the optional implicit SDK library or nil, if there isn't one.
- OptionalImplicitSdkLibrary() *string
-
// The name of the implementation library for the optional SDK library or nil, if there isn't one.
OptionalSdkLibraryImplementation() *string
}
@@ -1700,8 +1696,12 @@
path := path.Join(mctx.ModuleDir(), apiDir, scope.apiFilePrefix+api)
p := android.ExistentPathForSource(mctx, path)
if !p.Valid() {
- mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
- missingCurrentApi = true
+ if mctx.Config().AllowMissingDependencies() {
+ mctx.AddMissingDependencies([]string{path})
+ } else {
+ mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
+ missingCurrentApi = true
+ }
}
}
}
@@ -1923,8 +1923,12 @@
// Is nil if the source module does not exist.
xmlPermissionsFileModule *sdkLibraryXml
- // Path to the dex implementation jar obtained from the prebuilt_apex, if any.
+ // Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
dexJarFile android.Path
+
+ // Expected install file path of the source module(sdk_library)
+ // or dex implementation jar obtained from the prebuilt_apex, if any.
+ installFile android.Path
}
var _ SdkLibraryDependency = (*SdkLibraryImport)(nil)
@@ -2142,6 +2146,9 @@
var deapexerModule android.Module
+ // Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework
+ module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
+
// Record the paths to the prebuilt stubs library and stubs source.
ctx.VisitDirectDeps(func(to android.Module) {
tag := ctx.OtherModuleDependencyTag(to)
@@ -2170,10 +2177,6 @@
// Save away the `deapexer` module on which this depends, if any.
if tag == android.DeapexerTag {
- if deapexerModule != nil {
- ctx.ModuleErrorf("Ambiguous duplicate deapexer module dependencies %q and %q",
- deapexerModule.Name(), to.Name())
- }
deapexerModule = to
}
})
@@ -2205,6 +2208,7 @@
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil {
module.dexJarFile = dexOutputPath
+ module.installFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName()))
module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
} else {
// This should never happen as a variant for a prebuilt_apex is only created if the
@@ -2259,11 +2263,7 @@
// to satisfy UsesLibraryDependency interface
func (module *SdkLibraryImport) DexJarInstallPath() android.Path {
- if module.implLibraryModule == nil {
- return nil
- } else {
- return module.implLibraryModule.DexJarInstallPath()
- }
+ return module.installFile
}
// to satisfy UsesLibraryDependency interface
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 65af953..8e0618e 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -122,7 +122,7 @@
result.ModuleForTests("foo.api.system.28", "")
result.ModuleForTests("foo.api.test.28", "")
- exportedComponentsInfo := result.ModuleProvider(foo.Module(), ExportedComponentsInfoProvider).(ExportedComponentsInfo)
+ exportedComponentsInfo := result.ModuleProvider(foo.Module(), android.ExportedComponentsInfoProvider).(android.ExportedComponentsInfo)
expectedFooExportedComponents := []string{
"foo.stubs",
"foo.stubs.source",
diff --git a/java/sdk_test.go b/java/sdk_test.go
index bb595a5..6d62130 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -255,9 +255,11 @@
` + testcase.properties + `
}`
- variant := "android_common"
- if testcase.host == android.Host {
- variant = android.BuildOs.String() + "_common"
+ variant := func(result *android.TestResult) string {
+ if testcase.host == android.Host {
+ return result.Config.BuildOS.String() + "_common"
+ }
+ return "android_common"
}
convertModulesToPaths := func(cp []string) []string {
@@ -312,7 +314,7 @@
}
checkClasspath := func(t *testing.T, result *android.TestResult, isJava8 bool) {
- foo := result.ModuleForTests("foo", variant)
+ foo := result.ModuleForTests("foo", variant(result))
javac := foo.Rule("javac")
var deps []string
@@ -376,7 +378,7 @@
checkClasspath(t, result, true /* isJava8 */)
if testcase.host != android.Host {
- aidl := result.ModuleForTests("foo", variant).Rule("aidl")
+ aidl := result.ModuleForTests("foo", variant(result)).Rule("aidl")
android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.")
}
@@ -389,7 +391,7 @@
checkClasspath(t, result, false /* isJava8 */)
if testcase.host != android.Host {
- aidl := result.ModuleForTests("foo", variant).Rule("aidl")
+ aidl := result.ModuleForTests("foo", variant(result)).Rule("aidl")
android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.")
}
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index a2006b7..c02dcc1 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -48,13 +48,14 @@
}
func (p *platformSystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- classpathJars := configuredJarListToClasspathJars(ctx, p.ClasspathFragmentToConfiguredJarList(ctx), p.classpathType)
- p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
+ configuredJars := p.configuredJars(ctx)
+ classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, p.classpathType)
+ p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
}
-func (p *platformSystemServerClasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
- global := dexpreopt.GetGlobalConfig(ctx)
- return global.SystemServerJars
+func (p *platformSystemServerClasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
+ // TODO(satayev): include any apex jars that don't populate their classpath proto config.
+ return dexpreopt.GetGlobalConfig(ctx).SystemServerJars
}
type SystemServerClasspathModule struct {
@@ -64,6 +65,9 @@
ClasspathFragmentBase
properties systemServerClasspathFragmentProperties
+
+ // Collect the module directory for IDE info in java/jdeps.go.
+ modulePaths []string
}
func (s *SystemServerClasspathModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
@@ -91,19 +95,19 @@
ctx.PropertyErrorf("contents", "empty contents are not allowed")
}
- classpathJars := configuredJarListToClasspathJars(ctx, s.ClasspathFragmentToConfiguredJarList(ctx), s.classpathType)
- s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
+ configuredJars := s.configuredJars(ctx)
+ classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, s.classpathType)
+ s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
+
+ // Collect the module directory for IDE info in java/jdeps.go.
+ s.modulePaths = append(s.modulePaths, ctx.ModuleDir())
}
-func (s *SystemServerClasspathModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
+func (s *SystemServerClasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
global := dexpreopt.GetGlobalConfig(ctx)
- possibleUpdatableModules := gatherPossibleUpdatableModuleNamesAndStems(ctx, s.properties.Contents, systemServerClasspathFragmentContentDepTag)
-
- // Only create configs for updatable boot jars. Non-updatable system server jars must be part of the
- // platform_systemserverclasspath's classpath proto config to guarantee that they come before any
- // updatable jars at runtime.
- return global.UpdatableSystemServerJars.Filter(possibleUpdatableModules)
+ possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, s.properties.Contents, systemServerClasspathFragmentContentDepTag)
+ return global.ApexSystemServerJars.Filter(possibleUpdatableModules)
}
type systemServerClasspathFragmentContentDependencyTag struct {
@@ -135,3 +139,9 @@
ctx.AddDependency(module, systemServerClasspathFragmentContentDepTag, name)
}
}
+
+// Collect information for opening IDE project files in java/jdeps.go.
+func (s *SystemServerClasspathModule) IDEInfo(dpInfo *android.IdeInfo) {
+ dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents...)
+ dpInfo.Paths = append(dpInfo.Paths, s.modulePaths...)
+}
diff --git a/java/testing.go b/java/testing.go
index 3ef51bd..8860b45 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -214,15 +214,15 @@
)
}
-// FixtureConfigureUpdatableBootJars configures the updatable boot jars in both the
+// FixtureConfigureApexBootJars configures the apex boot jars in both the
// dexpreopt.GlobalConfig and Config.productVariables structs. As a side effect that enables
// dexpreopt.
-func FixtureConfigureUpdatableBootJars(bootJars ...string) android.FixturePreparer {
+func FixtureConfigureApexBootJars(bootJars ...string) android.FixturePreparer {
return android.GroupFixturePreparers(
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.UpdatableBootJars = android.CreateTestConfiguredJarList(bootJars)
+ variables.ApexBootJars = android.CreateTestConfiguredJarList(bootJars)
}),
- dexpreopt.FixtureSetUpdatableBootJars(bootJars...),
+ dexpreopt.FixtureSetApexBootJars(bootJars...),
// Add a fake dex2oatd module.
dexpreopt.PrepareForTestWithFakeDex2oatd,
@@ -364,6 +364,17 @@
android.AssertDeepEquals(t, fmt.Sprintf("%s modules", "platform-bootclasspath"), expected, pairs)
}
+func CheckClasspathFragmentProtoContentInfoProvider(t *testing.T, result *android.TestResult, generated bool, contents, outputFilename, installDir string) {
+ t.Helper()
+ p := result.Module("platform-bootclasspath", "android_common").(*platformBootclasspathModule)
+ info := result.ModuleProvider(p, ClasspathFragmentProtoContentInfoProvider).(ClasspathFragmentProtoContentInfo)
+
+ android.AssertBoolEquals(t, "classpath proto generated", generated, info.ClasspathFragmentProtoGenerated)
+ android.AssertStringEquals(t, "classpath proto contents", contents, info.ClasspathFragmentProtoContents.String())
+ android.AssertStringEquals(t, "output filepath", outputFilename, info.ClasspathFragmentProtoOutput.Base())
+ android.AssertPathRelativeToTopEquals(t, "install filepath", installDir, info.ClasspathFragmentProtoInstallDir)
+}
+
// ApexNamePairsFromModules returns the apex:module pair for the supplied modules.
func ApexNamePairsFromModules(ctx *android.TestContext, modules []android.Module) []string {
pairs := []string{}
diff --git a/mk2rbc/Android.bp b/mk2rbc/Android.bp
new file mode 100644
index 0000000..3ea3f7f
--- /dev/null
+++ b/mk2rbc/Android.bp
@@ -0,0 +1,39 @@
+//
+// 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.
+
+blueprint_go_binary {
+ name: "mk2rbc",
+ srcs: ["cmd/mk2rbc.go"],
+ deps: [
+ "mk2rbc-lib",
+ "androidmk-parser",
+ ],
+}
+
+bootstrap_go_package {
+ name: "mk2rbc-lib",
+ pkgPath: "android/soong/mk2rbc",
+ srcs: [
+ "android_products.go",
+ "config_variables.go",
+ "expr.go",
+ "mk2rbc.go",
+ "node.go",
+ "soong_variables.go",
+ "types.go",
+ "variable.go",
+ ],
+ deps: ["androidmk-parser"],
+}
diff --git a/mk2rbc/TODO b/mk2rbc/TODO
new file mode 100644
index 0000000..731deb6
--- /dev/null
+++ b/mk2rbc/TODO
@@ -0,0 +1,14 @@
+* Checking filter/filter-out results is incorrect if pattern contains '%'
+* Need heuristics to recognize that a variable is local. Propose to use lowercase.
+* Need heuristics for the local variable type. Propose '_list' suffix
+* Internal source tree has variables in the inherit-product macro argument. Handle it
+* Enumerate all environment variables that configuration files use.
+* Break mk2rbc.go into multiple files.
+* If variable's type is not yet known, try to divine it from the value assigned to it
+ (it may be a variable of the known type, or a function result)
+* ifneq (,$(VAR)) should translate to
+ if getattr(<>, "VAR", <default>):
+* Launcher file needs to have same suffix as the rest of the generated files
+* Implement $(shell) function
+* Write execution tests
+* Review all TODOs in mk2rbc.go
\ No newline at end of file
diff --git a/mk2rbc/android_products.go b/mk2rbc/android_products.go
new file mode 100644
index 0000000..de38391
--- /dev/null
+++ b/mk2rbc/android_products.go
@@ -0,0 +1,110 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+// Implements mkparser.Scope, to be used by mkparser.Value.Value()
+type localDirEval struct {
+ localDir string
+ hasErrors bool
+}
+
+func (l *localDirEval) Get(name string) string {
+ if name == "LOCAL_DIR" {
+ return l.localDir
+ }
+ l.hasErrors = true
+ return fmt.Sprintf("$(%s)", name)
+}
+
+func (l *localDirEval) Set(_, _ string) {
+}
+
+func (l *localDirEval) Call(_ string, _ []string) []string {
+ l.hasErrors = true
+ return []string{"$(call ...)"}
+}
+
+func (l *localDirEval) SetFunc(_ string, _ func([]string) []string) {
+}
+
+// UpdateProductConfigMap builds product configuration map.
+// The product configuration map maps a product name (i.e., the value of the
+// TARGET_PRODUCT variable) to the top-level configuration file.
+// In the Android's Make-based build machinery, the equivalent of the
+// product configuration map is $(PRODUCT_MAKEFILES), which is the list
+// of <product>:<configuration makefile> pairs (if <product>: is missing,
+// <product> is the basename of the configuration makefile).
+// UpdateProductConfigMap emulates this build logic by processing the
+// assignments to PRODUCT_MAKEFILES in the file passed to it.
+func UpdateProductConfigMap(configMap map[string]string, configMakefile string) error {
+ contents, err := ioutil.ReadFile(configMakefile)
+ if err != nil {
+ return err
+ }
+ parser := mkparser.NewParser(configMakefile, bytes.NewBuffer(contents))
+ nodes, errs := parser.Parse()
+ if len(errs) > 0 {
+ for _, e := range errs {
+ fmt.Fprintln(os.Stderr, "ERROR:", e)
+ }
+ return fmt.Errorf("cannot parse %s", configMakefile)
+ }
+
+ ldEval := &localDirEval{localDir: filepath.Dir(configMakefile)}
+
+ for _, node := range nodes {
+ // We are interested in assignments to 'PRODUCT_MAKEFILES'
+ asgn, ok := node.(*mkparser.Assignment)
+ if !ok {
+ continue
+ }
+ if !(asgn.Name.Const() && asgn.Name.Strings[0] == "PRODUCT_MAKEFILES") {
+ continue
+ }
+
+ // Resolve the references to $(LOCAL_DIR) in $(PRODUCT_MAKEFILES).
+ ldEval.hasErrors = false
+ value := asgn.Value.Value(ldEval)
+ if ldEval.hasErrors {
+ return fmt.Errorf("cannot evaluate %s", asgn.Value.Dump())
+ }
+ // Each item is either <product>:<configuration makefile>, or
+ // just <configuration makefile>
+ for _, token := range strings.Fields(value) {
+ var product, config_path string
+ if n := strings.Index(token, ":"); n >= 0 {
+ product = token[0:n]
+ config_path = token[n+1:]
+ } else {
+ config_path = token
+ product = filepath.Base(config_path)
+ product = strings.TrimSuffix(product, filepath.Ext(product))
+ }
+ configMap[product] = config_path
+ }
+ }
+ return nil
+}
diff --git a/mk2rbc/android_products_test.go b/mk2rbc/android_products_test.go
new file mode 100644
index 0000000..f8c930a
--- /dev/null
+++ b/mk2rbc/android_products_test.go
@@ -0,0 +1,38 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "path/filepath"
+ "reflect"
+ "testing"
+)
+
+func TestProductsMakefile(t *testing.T) {
+ testDir := getTestDirectory()
+ abspath := func(relPath string) string { return filepath.Join(testDir, relPath) }
+ actualProducts := make(map[string]string)
+ if err := UpdateProductConfigMap(actualProducts, abspath("android_products.mk.test")); err != nil {
+ t.Fatal(err)
+ }
+ expectedProducts := map[string]string{
+ "aosp_cf_x86_tv": abspath("vsoc_x86/tv/device.mk"),
+ "aosp_tv_arm": abspath("aosp_tv_arm.mk"),
+ "aosp_tv_arm64": abspath("aosp_tv_arm64.mk"),
+ }
+ if !reflect.DeepEqual(actualProducts, expectedProducts) {
+ t.Errorf("\nExpected: %v\n Actual: %v", expectedProducts, actualProducts)
+ }
+}
diff --git a/mk2rbc/cmd/mk2rbc.go b/mk2rbc/cmd/mk2rbc.go
new file mode 100644
index 0000000..72525c4
--- /dev/null
+++ b/mk2rbc/cmd/mk2rbc.go
@@ -0,0 +1,547 @@
+// Copyright 2021 Google LLC
+//
+// 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.
+
+// The application to convert product configuration makefiles to Starlark.
+// Converts either given list of files (and optionally the dependent files
+// of the same kind), or all all product configuration makefiles in the
+// given source tree.
+// Previous version of a converted file can be backed up.
+// Optionally prints detailed statistics at the end.
+package main
+
+import (
+ "bufio"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "runtime/debug"
+ "runtime/pprof"
+ "sort"
+ "strings"
+ "time"
+
+ "android/soong/androidmk/parser"
+ "android/soong/mk2rbc"
+)
+
+var (
+ rootDir = flag.String("root", ".", "the value of // for load paths")
+ // TODO(asmundak): remove this option once there is a consensus on suffix
+ suffix = flag.String("suffix", ".rbc", "generated files' suffix")
+ dryRun = flag.Bool("dry_run", false, "dry run")
+ recurse = flag.Bool("convert_dependents", false, "convert all dependent files")
+ mode = flag.String("mode", "", `"backup" to back up existing files, "write" to overwrite them`)
+ warn = flag.Bool("warnings", false, "warn about partially failed conversions")
+ verbose = flag.Bool("v", false, "print summary")
+ errstat = flag.Bool("error_stat", false, "print error statistics")
+ traceVar = flag.String("trace", "", "comma-separated list of variables to trace")
+ // TODO(asmundak): this option is for debugging
+ allInSource = flag.Bool("all", false, "convert all product config makefiles in the tree under //")
+ outputTop = flag.String("outdir", "", "write output files into this directory hierarchy")
+ launcher = flag.String("launcher", "", "generated launcher path. If set, the non-flag argument is _product_name_")
+ printProductConfigMap = flag.Bool("print_product_config_map", false, "print product config map and exit")
+ cpuProfile = flag.String("cpu_profile", "", "write cpu profile to file")
+ traceCalls = flag.Bool("trace_calls", false, "trace function calls")
+)
+
+func init() {
+ // Poor man's flag aliasing: works, but the usage string is ugly and
+ // both flag and its alias can be present on the command line
+ flagAlias := func(target string, alias string) {
+ if f := flag.Lookup(target); f != nil {
+ flag.Var(f.Value, alias, "alias for --"+f.Name)
+ return
+ }
+ quit("cannot alias unknown flag " + target)
+ }
+ flagAlias("suffix", "s")
+ flagAlias("root", "d")
+ flagAlias("dry_run", "n")
+ flagAlias("convert_dependents", "r")
+ flagAlias("warnings", "w")
+ flagAlias("error_stat", "e")
+}
+
+var backupSuffix string
+var tracedVariables []string
+var errorLogger = errorsByType{data: make(map[string]datum)}
+var makefileFinder = &LinuxMakefileFinder{}
+
+func main() {
+ flag.Usage = func() {
+ cmd := filepath.Base(os.Args[0])
+ fmt.Fprintf(flag.CommandLine.Output(),
+ "Usage: %[1]s flags file...\n"+
+ "or: %[1]s flags --launcher=PATH PRODUCT\n", cmd)
+ flag.PrintDefaults()
+ }
+ flag.Parse()
+
+ // Delouse
+ if *suffix == ".mk" {
+ quit("cannot use .mk as generated file suffix")
+ }
+ if *suffix == "" {
+ quit("suffix cannot be empty")
+ }
+ if *outputTop != "" {
+ if err := os.MkdirAll(*outputTop, os.ModeDir+os.ModePerm); err != nil {
+ quit(err)
+ }
+ s, err := filepath.Abs(*outputTop)
+ if err != nil {
+ quit(err)
+ }
+ *outputTop = s
+ }
+ if *allInSource && len(flag.Args()) > 0 {
+ quit("file list cannot be specified when -all is present")
+ }
+ if *allInSource && *launcher != "" {
+ quit("--all and --launcher are mutually exclusive")
+ }
+
+ // Flag-driven adjustments
+ if (*suffix)[0] != '.' {
+ *suffix = "." + *suffix
+ }
+ if *mode == "backup" {
+ backupSuffix = time.Now().Format("20060102150405")
+ }
+ if *traceVar != "" {
+ tracedVariables = strings.Split(*traceVar, ",")
+ }
+
+ if *cpuProfile != "" {
+ f, err := os.Create(*cpuProfile)
+ if err != nil {
+ quit(err)
+ }
+ pprof.StartCPUProfile(f)
+ defer pprof.StopCPUProfile()
+ }
+ // Find out global variables
+ getConfigVariables()
+ getSoongVariables()
+
+ if *printProductConfigMap {
+ productConfigMap := buildProductConfigMap()
+ var products []string
+ for p := range productConfigMap {
+ products = append(products, p)
+ }
+ sort.Strings(products)
+ for _, p := range products {
+ fmt.Println(p, productConfigMap[p])
+ }
+ os.Exit(0)
+ }
+
+ // 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]
+ productConfigMap := buildProductConfigMap()
+ path, found := productConfigMap[product]
+ if !found {
+ quit(fmt.Errorf("cannot generate configuration launcher for %s, it is not a known product",
+ product))
+ }
+ ok = convertOne(path) && ok
+ err := writeGenerated(*launcher, mk2rbc.Launcher(outputFilePath(path), mk2rbc.MakePath2ModuleName(path)))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s:%s", path, 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()
+ if *errstat {
+ errorLogger.printStatistics()
+ }
+ if !ok {
+ os.Exit(1)
+ }
+}
+
+func quit(s interface{}) {
+ fmt.Fprintln(os.Stderr, s)
+ os.Exit(2)
+}
+
+func buildProductConfigMap() map[string]string {
+ const androidProductsMk = "AndroidProducts.mk"
+ // Build the list of AndroidProducts.mk files: it's
+ // build/make/target/product/AndroidProducts.mk plus
+ // device/**/AndroidProducts.mk
+ targetAndroidProductsFile := filepath.Join(*rootDir, "build", "make", "target", "product", androidProductsMk)
+ if _, err := os.Stat(targetAndroidProductsFile); err != nil {
+ fmt.Fprintf(os.Stderr, "%s: %s\n(hint: %s is not a source tree root)\n",
+ targetAndroidProductsFile, err, *rootDir)
+ }
+ productConfigMap := make(map[string]string)
+ if err := mk2rbc.UpdateProductConfigMap(productConfigMap, targetAndroidProductsFile); err != nil {
+ fmt.Fprintf(os.Stderr, "%s: %s\n", targetAndroidProductsFile, err)
+ }
+ _ = filepath.Walk(filepath.Join(*rootDir, "device"),
+ func(path string, info os.FileInfo, err error) error {
+ if info.IsDir() || filepath.Base(path) != androidProductsMk {
+ return nil
+ }
+ if err2 := mk2rbc.UpdateProductConfigMap(productConfigMap, path); err2 != nil {
+ fmt.Fprintf(os.Stderr, "%s: %s\n", path, err)
+ // Keep going, we want to find all such errors in a single run
+ }
+ return nil
+ })
+ return productConfigMap
+}
+
+func getConfigVariables() {
+ path := filepath.Join(*rootDir, "build", "make", "core", "product.mk")
+ if err := mk2rbc.FindConfigVariables(path, mk2rbc.KnownVariables); err != nil {
+ quit(fmt.Errorf("%s\n(check --root[=%s], it should point to the source root)",
+ err, *rootDir))
+ }
+}
+
+// Implements mkparser.Scope, to be used by mkparser.Value.Value()
+type fileNameScope struct {
+ mk2rbc.ScopeBase
+}
+
+func (s fileNameScope) Get(name string) string {
+ if name != "BUILD_SYSTEM" {
+ return fmt.Sprintf("$(%s)", name)
+ }
+ return filepath.Join(*rootDir, "build", "make", "core")
+}
+
+func getSoongVariables() {
+ path := filepath.Join(*rootDir, "build", "make", "core", "soong_config.mk")
+ err := mk2rbc.FindSoongVariables(path, fileNameScope{}, mk2rbc.KnownVariables)
+ if err != nil {
+ quit(err)
+ }
+}
+
+var converted = make(map[string]*mk2rbc.StarlarkScript)
+
+//goland:noinspection RegExpRepeatedSpace
+var cpNormalizer = regexp.MustCompile(
+ "# Copyright \\(C\\) 20.. The Android Open Source Project")
+
+const cpNormalizedCopyright = "# Copyright (C) 20xx The Android Open Source Project"
+const copyright = `#
+# Copyright (C) 20xx 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.
+#
+`
+
+// Convert a single file.
+// Write the result either to the same directory, to the same place in
+// the output hierarchy, or to the stdout.
+// Optionally, recursively convert the files this one includes by
+// $(call inherit-product) or an include statement.
+func convertOne(mkFile string) (ok bool) {
+ if v, ok := converted[mkFile]; ok {
+ return v != nil
+ }
+ converted[mkFile] = nil
+ defer func() {
+ if r := recover(); r != nil {
+ ok = false
+ fmt.Fprintf(os.Stderr, "%s: panic while converting: %s\n%s\n", mkFile, r, debug.Stack())
+ }
+ }()
+
+ mk2starRequest := mk2rbc.Request{
+ MkFile: mkFile,
+ Reader: nil,
+ RootDir: *rootDir,
+ OutputDir: *outputTop,
+ OutputSuffix: *suffix,
+ TracedVariables: tracedVariables,
+ TraceCalls: *traceCalls,
+ WarnPartialSuccess: *warn,
+ SourceFS: os.DirFS(*rootDir),
+ MakefileFinder: makefileFinder,
+ }
+ if *errstat {
+ mk2starRequest.ErrorLogger = errorLogger
+ }
+ ss, err := mk2rbc.Convert(mk2starRequest)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, mkFile, ": ", err)
+ return false
+ }
+ script := ss.String()
+ outputPath := outputFilePath(mkFile)
+
+ if *dryRun {
+ fmt.Printf("==== %s ====\n", outputPath)
+ // Print generated script after removing the copyright header
+ outText := cpNormalizer.ReplaceAllString(script, cpNormalizedCopyright)
+ fmt.Println(strings.TrimPrefix(outText, copyright))
+ } else {
+ if err := maybeBackup(outputPath); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ return false
+ }
+ if err := writeGenerated(outputPath, script); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ return false
+ }
+ }
+ ok = true
+ if *recurse {
+ for _, sub := range ss.SubConfigFiles() {
+ // File may be absent if it is a conditional load
+ if _, err := os.Stat(sub); os.IsNotExist(err) {
+ continue
+ }
+ ok = convertOne(sub) && ok
+ }
+ }
+ converted[mkFile] = ss
+ return ok
+}
+
+// Optionally saves the previous version of the generated file
+func maybeBackup(filename string) error {
+ stat, err := os.Stat(filename)
+ if os.IsNotExist(err) {
+ return nil
+ }
+ if !stat.Mode().IsRegular() {
+ return fmt.Errorf("%s exists and is not a regular file", filename)
+ }
+ switch *mode {
+ case "backup":
+ return os.Rename(filename, filename+backupSuffix)
+ case "write":
+ return os.Remove(filename)
+ default:
+ return fmt.Errorf("%s already exists, use --mode option", filename)
+ }
+}
+
+func outputFilePath(mkFile string) string {
+ path := strings.TrimSuffix(mkFile, filepath.Ext(mkFile)) + *suffix
+ if *outputTop != "" {
+ path = filepath.Join(*outputTop, path)
+ }
+ return path
+}
+
+func writeGenerated(path string, contents string) error {
+ if err := os.MkdirAll(filepath.Dir(path), os.ModeDir|os.ModePerm); err != nil {
+ return err
+ }
+ if err := ioutil.WriteFile(path, []byte(contents), 0644); err != nil {
+ return err
+ }
+ return nil
+}
+
+func printStats() {
+ var sortedFiles []string
+ if !*warn && !*verbose {
+ return
+ }
+ for p := range converted {
+ sortedFiles = append(sortedFiles, p)
+ }
+ sort.Strings(sortedFiles)
+
+ nOk, nPartial, nFailed := 0, 0, 0
+ for _, f := range sortedFiles {
+ if converted[f] == nil {
+ nFailed++
+ } else if converted[f].HasErrors() {
+ nPartial++
+ } else {
+ nOk++
+ }
+ }
+ if *warn {
+ if nPartial > 0 {
+ fmt.Fprintf(os.Stderr, "Conversion was partially successful for:\n")
+ for _, f := range sortedFiles {
+ if ss := converted[f]; ss != nil && ss.HasErrors() {
+ fmt.Fprintln(os.Stderr, " ", f)
+ }
+ }
+ }
+
+ if nFailed > 0 {
+ fmt.Fprintf(os.Stderr, "Conversion failed for files:\n")
+ for _, f := range sortedFiles {
+ if converted[f] == nil {
+ fmt.Fprintln(os.Stderr, " ", f)
+ }
+ }
+ }
+ }
+ if *verbose {
+ fmt.Fprintf(os.Stderr, "%-16s%5d\n", "Succeeded:", nOk)
+ fmt.Fprintf(os.Stderr, "%-16s%5d\n", "Partial:", nPartial)
+ fmt.Fprintf(os.Stderr, "%-16s%5d\n", "Failed:", nFailed)
+ }
+}
+
+type datum struct {
+ count int
+ formattingArgs []string
+}
+
+type errorsByType struct {
+ data map[string]datum
+}
+
+func (ebt errorsByType) NewError(message string, node parser.Node, args ...interface{}) {
+ v, exists := ebt.data[message]
+ if exists {
+ v.count++
+ } else {
+ v = datum{1, nil}
+ }
+ if strings.Contains(message, "%s") {
+ var newArg1 string
+ if len(args) == 0 {
+ panic(fmt.Errorf(`%s has %%s but args are missing`, message))
+ }
+ newArg1 = fmt.Sprint(args[0])
+ if message == "unsupported line" {
+ newArg1 = node.Dump()
+ } else if message == "unsupported directive %s" {
+ if newArg1 == "include" || newArg1 == "-include" {
+ newArg1 = node.Dump()
+ }
+ }
+ v.formattingArgs = append(v.formattingArgs, newArg1)
+ }
+ ebt.data[message] = v
+}
+
+func (ebt errorsByType) printStatistics() {
+ if len(ebt.data) > 0 {
+ fmt.Fprintln(os.Stderr, "Error counts:")
+ }
+ for message, data := range ebt.data {
+ if len(data.formattingArgs) == 0 {
+ fmt.Fprintf(os.Stderr, "%4d %s\n", data.count, message)
+ continue
+ }
+ itemsByFreq, count := stringsWithFreq(data.formattingArgs, 30)
+ fmt.Fprintf(os.Stderr, "%4d %s [%d unique items]:\n", data.count, message, count)
+ fmt.Fprintln(os.Stderr, " ", itemsByFreq)
+ }
+}
+
+func stringsWithFreq(items []string, topN int) (string, int) {
+ freq := make(map[string]int)
+ for _, item := range items {
+ freq[strings.TrimPrefix(strings.TrimSuffix(item, "]"), "[")]++
+ }
+ var sorted []string
+ for item := range freq {
+ sorted = append(sorted, item)
+ }
+ sort.Slice(sorted, func(i int, j int) bool {
+ return freq[sorted[i]] > freq[sorted[j]]
+ })
+ sep := ""
+ res := ""
+ for i, item := range sorted {
+ if i >= topN {
+ res += " ..."
+ break
+ }
+ count := freq[item]
+ if count > 1 {
+ res += fmt.Sprintf("%s%s(%d)", sep, item, count)
+ } else {
+ res += fmt.Sprintf("%s%s", sep, item)
+ }
+ sep = ", "
+ }
+ return res, len(sorted)
+}
+
+type LinuxMakefileFinder struct {
+ cachedRoot string
+ cachedMakefiles []string
+}
+
+func (l *LinuxMakefileFinder) Find(root string) []string {
+ if l.cachedMakefiles != nil && l.cachedRoot == root {
+ return l.cachedMakefiles
+ }
+ l.cachedRoot = root
+ l.cachedMakefiles = make([]string, 0)
+
+ // Return all *.mk files but not in hidden directories.
+
+ // NOTE(asmundak): as it turns out, even the WalkDir (which is an _optimized_ directory tree walker)
+ // is about twice slower than running `find` command (14s vs 6s on the internal Android source tree).
+ common_args := []string{"!", "-type", "d", "-name", "*.mk", "!", "-path", "*/.*/*"}
+ if root != "" {
+ common_args = append([]string{root}, common_args...)
+ }
+ cmd := exec.Command("/usr/bin/find", common_args...)
+ stdout, err := cmd.StdoutPipe()
+ if err == nil {
+ err = cmd.Start()
+ }
+ if err != nil {
+ panic(fmt.Errorf("cannot get the output from %s: %s", cmd, err))
+ }
+ scanner := bufio.NewScanner(stdout)
+ for scanner.Scan() {
+ l.cachedMakefiles = append(l.cachedMakefiles, strings.TrimPrefix(scanner.Text(), "./"))
+ }
+ stdout.Close()
+ return l.cachedMakefiles
+}
diff --git a/mk2rbc/config_variables.go b/mk2rbc/config_variables.go
new file mode 100644
index 0000000..dac509c
--- /dev/null
+++ b/mk2rbc/config_variables.go
@@ -0,0 +1,67 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+// Extracts the list of product config variables from a file, calling
+// given registrar for each variable.
+func FindConfigVariables(mkFile string, vr variableRegistrar) error {
+ mkContents, err := ioutil.ReadFile(mkFile)
+ if err != nil {
+ return err
+ }
+ parser := mkparser.NewParser(mkFile, bytes.NewBuffer(mkContents))
+ nodes, errs := parser.Parse()
+ if len(errs) > 0 {
+ for _, e := range errs {
+ fmt.Fprintln(os.Stderr, "ERROR:", e)
+ }
+ return fmt.Errorf("cannot parse %s", mkFile)
+ }
+ for _, node := range nodes {
+ asgn, ok := node.(*mkparser.Assignment)
+ if !ok {
+ continue
+ }
+ // We are looking for a variable called '_product_list_vars'
+ // or '_product_single_value_vars'.
+ if !asgn.Name.Const() {
+ continue
+ }
+ varName := asgn.Name.Strings[0]
+ var starType starlarkType
+ if varName == "_product_list_vars" {
+ starType = starlarkTypeList
+ } else if varName == "_product_single_value_vars" {
+ starType = starlarkTypeUnknown
+ } else {
+ continue
+ }
+ for _, name := range strings.Fields(asgn.Value.Dump()) {
+ vr.NewVariable(name, VarClassConfig, starType)
+ }
+
+ }
+ return nil
+}
diff --git a/mk2rbc/config_variables_test.go b/mk2rbc/config_variables_test.go
new file mode 100644
index 0000000..f5a5180
--- /dev/null
+++ b/mk2rbc/config_variables_test.go
@@ -0,0 +1,60 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "testing"
+)
+
+type testVar struct {
+ name string
+ cl varClass
+ ty starlarkType
+}
+
+type testVariables struct {
+ v []testVar
+}
+
+func (v *testVariables) NewVariable(name string, varClass varClass, valueType starlarkType) {
+ v.v = append(v.v, testVar{name, varClass, valueType})
+}
+
+// getTestDirectory returns the test directory, which should be the test/ subdirectory
+func getTestDirectory() string {
+ _, myFile, _, _ := runtime.Caller(1)
+ return filepath.Join(filepath.Dir(myFile), "test")
+}
+
+func TestConfigVariables(t *testing.T) {
+ testFile := filepath.Join(getTestDirectory(), "config_variables.mk.test")
+ var actual testVariables
+ if err := FindConfigVariables(testFile, &actual); err != nil {
+ t.Fatal(err)
+ }
+ expected := testVariables{[]testVar{
+ {"PRODUCT_NAME", VarClassConfig, starlarkTypeUnknown},
+ {"PRODUCT_MODEL", VarClassConfig, starlarkTypeUnknown},
+ {"PRODUCT_LOCALES", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_AAPT_CONFIG", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_AAPT_PREF_CONFIG", VarClassConfig, starlarkTypeUnknown},
+ }}
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("\nExpected: %v\n Actual: %v", expected, actual)
+ }
+}
diff --git a/mk2rbc/expr.go b/mk2rbc/expr.go
new file mode 100644
index 0000000..0bb8b95
--- /dev/null
+++ b/mk2rbc/expr.go
@@ -0,0 +1,591 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+// Represents an expression in the Starlark code. An expression has
+// a type, and it can be evaluated.
+type starlarkExpr interface {
+ starlarkNode
+ typ() starlarkType
+ // Try to substitute variable values. Return substitution result
+ // and whether it is the same as the original expression.
+ eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool)
+ // Emit the code to copy the expression, otherwise we will end up
+ // with source and target pointing to the same list.
+ emitListVarCopy(gctx *generationContext)
+}
+
+func maybeString(expr starlarkExpr) (string, bool) {
+ if x, ok := expr.(*stringLiteralExpr); ok {
+ return x.literal, true
+ }
+ return "", false
+}
+
+type stringLiteralExpr struct {
+ literal string
+}
+
+func (s *stringLiteralExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ res = s
+ same = true
+ return
+}
+
+func (s *stringLiteralExpr) emit(gctx *generationContext) {
+ gctx.writef("%q", s.literal)
+}
+
+func (_ *stringLiteralExpr) typ() starlarkType {
+ return starlarkTypeString
+}
+
+func (s *stringLiteralExpr) emitListVarCopy(gctx *generationContext) {
+ s.emit(gctx)
+}
+
+// Integer literal
+type intLiteralExpr struct {
+ literal int
+}
+
+func (s *intLiteralExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ res = s
+ same = true
+ return
+}
+
+func (s *intLiteralExpr) emit(gctx *generationContext) {
+ gctx.writef("%d", s.literal)
+}
+
+func (_ *intLiteralExpr) typ() starlarkType {
+ return starlarkTypeInt
+}
+
+func (s *intLiteralExpr) emitListVarCopy(gctx *generationContext) {
+ s.emit(gctx)
+}
+
+// interpolateExpr represents Starlark's interpolation operator <string> % list
+// we break <string> into a list of chunks, i.e., "first%second%third" % (X, Y)
+// will have chunks = ["first", "second", "third"] and args = [X, Y]
+type interpolateExpr struct {
+ chunks []string // string chunks, separated by '%'
+ args []starlarkExpr
+}
+
+func (xi *interpolateExpr) emit(gctx *generationContext) {
+ if len(xi.chunks) != len(xi.args)+1 {
+ panic(fmt.Errorf("malformed interpolateExpr: #chunks(%d) != #args(%d)+1",
+ len(xi.chunks), len(xi.args)))
+ }
+ // Generate format as join of chunks, but first escape '%' in them
+ format := strings.ReplaceAll(xi.chunks[0], "%", "%%")
+ for _, chunk := range xi.chunks[1:] {
+ format += "%s" + strings.ReplaceAll(chunk, "%", "%%")
+ }
+ gctx.writef("%q %% ", format)
+ emitarg := func(arg starlarkExpr) {
+ if arg.typ() == starlarkTypeList {
+ gctx.write(`" ".join(`)
+ arg.emit(gctx)
+ gctx.write(`)`)
+ } else {
+ arg.emit(gctx)
+ }
+ }
+ if len(xi.args) == 1 {
+ emitarg(xi.args[0])
+ } else {
+ sep := "("
+ for _, arg := range xi.args {
+ gctx.write(sep)
+ emitarg(arg)
+ sep = ", "
+ }
+ gctx.write(")")
+ }
+}
+
+func (xi *interpolateExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ same = true
+ newChunks := []string{xi.chunks[0]}
+ var newArgs []starlarkExpr
+ for i, arg := range xi.args {
+ newArg, sameArg := arg.eval(valueMap)
+ same = same && sameArg
+ switch x := newArg.(type) {
+ case *stringLiteralExpr:
+ newChunks[len(newChunks)-1] += x.literal + xi.chunks[i+1]
+ same = false
+ continue
+ case *intLiteralExpr:
+ newChunks[len(newChunks)-1] += strconv.Itoa(x.literal) + xi.chunks[i+1]
+ same = false
+ continue
+ default:
+ newChunks = append(newChunks, xi.chunks[i+1])
+ newArgs = append(newArgs, newArg)
+ }
+ }
+ if same {
+ res = xi
+ } else if len(newChunks) == 1 {
+ res = &stringLiteralExpr{newChunks[0]}
+ } else {
+ res = &interpolateExpr{chunks: newChunks, args: newArgs}
+ }
+ return
+}
+
+func (_ *interpolateExpr) typ() starlarkType {
+ return starlarkTypeString
+}
+
+func (xi *interpolateExpr) emitListVarCopy(gctx *generationContext) {
+ xi.emit(gctx)
+}
+
+type variableRefExpr struct {
+ ref variable
+ isDefined bool
+}
+
+func (v *variableRefExpr) eval(map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ predefined, ok := v.ref.(*predefinedVariable)
+ if same = !ok; same {
+ res = v
+ } else {
+ res = predefined.value
+ }
+ return
+}
+
+func (v *variableRefExpr) emit(gctx *generationContext) {
+ v.ref.emitGet(gctx, v.isDefined)
+}
+
+func (v *variableRefExpr) typ() starlarkType {
+ return v.ref.valueType()
+}
+
+func (v *variableRefExpr) emitListVarCopy(gctx *generationContext) {
+ v.emit(gctx)
+ if v.typ() == starlarkTypeList {
+ gctx.write("[:]") // this will copy the list
+ }
+}
+
+type notExpr struct {
+ expr starlarkExpr
+}
+
+func (n *notExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ if x, same := n.expr.eval(valueMap); same {
+ res = n
+ } else {
+ res = ¬Expr{expr: x}
+ }
+ return
+}
+
+func (n *notExpr) emit(ctx *generationContext) {
+ ctx.write("not ")
+ n.expr.emit(ctx)
+}
+
+func (_ *notExpr) typ() starlarkType {
+ return starlarkTypeBool
+}
+
+func (n *notExpr) emitListVarCopy(gctx *generationContext) {
+ n.emit(gctx)
+}
+
+type eqExpr struct {
+ left, right starlarkExpr
+ isEq bool // if false, it's !=
+}
+
+func (eq *eqExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ xLeft, sameLeft := eq.left.eval(valueMap)
+ xRight, sameRight := eq.right.eval(valueMap)
+ if same = sameLeft && sameRight; same {
+ res = eq
+ } else {
+ res = &eqExpr{left: xLeft, right: xRight, isEq: eq.isEq}
+ }
+ return
+}
+
+func (eq *eqExpr) emit(gctx *generationContext) {
+ emitSimple := func(expr starlarkExpr) {
+ if eq.isEq {
+ gctx.write("not ")
+ }
+ expr.emit(gctx)
+ }
+ // Are we checking that a variable is empty?
+ if isEmptyString(eq.left) {
+ emitSimple(eq.right)
+ return
+ } else if isEmptyString(eq.right) {
+ emitSimple(eq.left)
+ return
+
+ }
+ // General case
+ eq.left.emit(gctx)
+ if eq.isEq {
+ gctx.write(" == ")
+ } else {
+ gctx.write(" != ")
+ }
+ eq.right.emit(gctx)
+}
+
+func (_ *eqExpr) typ() starlarkType {
+ return starlarkTypeBool
+}
+
+func (eq *eqExpr) emitListVarCopy(gctx *generationContext) {
+ eq.emit(gctx)
+}
+
+// variableDefinedExpr corresponds to Make's ifdef VAR
+type variableDefinedExpr struct {
+ v variable
+}
+
+func (v *variableDefinedExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ res = v
+ same = true
+ return
+
+}
+
+func (v *variableDefinedExpr) emit(gctx *generationContext) {
+ if v.v != nil {
+ v.v.emitDefined(gctx)
+ return
+ }
+ gctx.writef("%s(%q)", cfnWarning, "TODO(VAR)")
+}
+
+func (_ *variableDefinedExpr) typ() starlarkType {
+ return starlarkTypeBool
+}
+
+func (v *variableDefinedExpr) emitListVarCopy(gctx *generationContext) {
+ v.emit(gctx)
+}
+
+type listExpr struct {
+ items []starlarkExpr
+}
+
+func (l *listExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ newItems := make([]starlarkExpr, len(l.items))
+ same = true
+ for i, item := range l.items {
+ var sameItem bool
+ newItems[i], sameItem = item.eval(valueMap)
+ same = same && sameItem
+ }
+ if same {
+ res = l
+ } else {
+ res = &listExpr{newItems}
+ }
+ return
+}
+
+func (l *listExpr) emit(gctx *generationContext) {
+ if !gctx.inAssignment || len(l.items) < 2 {
+ gctx.write("[")
+ sep := ""
+ for _, item := range l.items {
+ gctx.write(sep)
+ item.emit(gctx)
+ sep = ", "
+ }
+ gctx.write("]")
+ return
+ }
+
+ gctx.write("[")
+ gctx.indentLevel += 2
+
+ for _, item := range l.items {
+ gctx.newLine()
+ item.emit(gctx)
+ gctx.write(",")
+ }
+ gctx.indentLevel -= 2
+ gctx.newLine()
+ gctx.write("]")
+}
+
+func (_ *listExpr) typ() starlarkType {
+ return starlarkTypeList
+}
+
+func (l *listExpr) emitListVarCopy(gctx *generationContext) {
+ l.emit(gctx)
+}
+
+func newStringListExpr(items []string) *listExpr {
+ v := listExpr{}
+ for _, item := range items {
+ v.items = append(v.items, &stringLiteralExpr{item})
+ }
+ return &v
+}
+
+// concatExpr generates epxr1 + expr2 + ... + exprN in Starlark.
+type concatExpr struct {
+ items []starlarkExpr
+}
+
+func (c *concatExpr) emit(gctx *generationContext) {
+ if len(c.items) == 1 {
+ c.items[0].emit(gctx)
+ return
+ }
+
+ if !gctx.inAssignment {
+ c.items[0].emit(gctx)
+ for _, item := range c.items[1:] {
+ gctx.write(" + ")
+ item.emit(gctx)
+ }
+ return
+ }
+ gctx.write("(")
+ c.items[0].emit(gctx)
+ gctx.indentLevel += 2
+ for _, item := range c.items[1:] {
+ gctx.write(" +")
+ gctx.newLine()
+ item.emit(gctx)
+ }
+ gctx.write(")")
+ gctx.indentLevel -= 2
+}
+
+func (c *concatExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ same = true
+ xConcat := &concatExpr{items: make([]starlarkExpr, len(c.items))}
+ for i, item := range c.items {
+ var sameItem bool
+ xConcat.items[i], sameItem = item.eval(valueMap)
+ same = same && sameItem
+ }
+ if same {
+ res = c
+ } else {
+ res = xConcat
+ }
+ return
+}
+
+func (_ *concatExpr) typ() starlarkType {
+ return starlarkTypeList
+}
+
+func (c *concatExpr) emitListVarCopy(gctx *generationContext) {
+ c.emit(gctx)
+}
+
+// inExpr generates <expr> [not] in <list>
+type inExpr struct {
+ expr starlarkExpr
+ list starlarkExpr
+ isNot bool
+}
+
+func (i *inExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ x := &inExpr{isNot: i.isNot}
+ var sameExpr, sameList bool
+ x.expr, sameExpr = i.expr.eval(valueMap)
+ x.list, sameList = i.list.eval(valueMap)
+ if same = sameExpr && sameList; same {
+ res = i
+ } else {
+ res = x
+ }
+ return
+}
+
+func (i *inExpr) emit(gctx *generationContext) {
+ i.expr.emit(gctx)
+ if i.isNot {
+ gctx.write(" not in ")
+ } else {
+ gctx.write(" in ")
+ }
+ i.list.emit(gctx)
+}
+
+func (_ *inExpr) typ() starlarkType {
+ return starlarkTypeBool
+}
+
+func (i *inExpr) emitListVarCopy(gctx *generationContext) {
+ i.emit(gctx)
+}
+
+type indexExpr struct {
+ array starlarkExpr
+ index starlarkExpr
+}
+
+func (ix indexExpr) emit(gctx *generationContext) {
+ ix.array.emit(gctx)
+ gctx.write("[")
+ ix.index.emit(gctx)
+ gctx.write("]")
+}
+
+func (ix indexExpr) typ() starlarkType {
+ return starlarkTypeString
+}
+
+func (ix indexExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ newArray, isSameArray := ix.array.eval(valueMap)
+ newIndex, isSameIndex := ix.index.eval(valueMap)
+ if same = isSameArray && isSameIndex; same {
+ res = ix
+ } else {
+ res = &indexExpr{newArray, newIndex}
+ }
+ return
+}
+
+func (ix indexExpr) emitListVarCopy(gctx *generationContext) {
+ ix.emit(gctx)
+}
+
+type callExpr struct {
+ object starlarkExpr // nil if static call
+ name string
+ args []starlarkExpr
+ returnType starlarkType
+}
+
+func (cx *callExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ newCallExpr := &callExpr{name: cx.name, args: make([]starlarkExpr, len(cx.args)),
+ returnType: cx.returnType}
+ if cx.object != nil {
+ newCallExpr.object, same = cx.object.eval(valueMap)
+ } else {
+ same = true
+ }
+ for i, args := range cx.args {
+ var s bool
+ newCallExpr.args[i], s = args.eval(valueMap)
+ same = same && s
+ }
+ if same {
+ res = cx
+ } else {
+ res = newCallExpr
+ }
+ return
+}
+
+func (cx *callExpr) emit(gctx *generationContext) {
+ sep := ""
+ if cx.object != nil {
+ gctx.write("(")
+ cx.object.emit(gctx)
+ gctx.write(")")
+ gctx.write(".", cx.name, "(")
+ } else {
+ kf, found := knownFunctions[cx.name]
+ if !found {
+ panic(fmt.Errorf("callExpr with unknown function %q", cx.name))
+ }
+ if kf.runtimeName[0] == '!' {
+ panic(fmt.Errorf("callExpr for %q should not be there", cx.name))
+ }
+ gctx.write(kf.runtimeName, "(")
+ if kf.hiddenArg == hiddenArgGlobal {
+ gctx.write("g")
+ sep = ", "
+ } else if kf.hiddenArg == hiddenArgConfig {
+ gctx.write("cfg")
+ sep = ", "
+ }
+ }
+ for _, arg := range cx.args {
+ gctx.write(sep)
+ arg.emit(gctx)
+ sep = ", "
+ }
+ gctx.write(")")
+}
+
+func (cx *callExpr) typ() starlarkType {
+ return cx.returnType
+}
+
+func (cx *callExpr) emitListVarCopy(gctx *generationContext) {
+ cx.emit(gctx)
+}
+
+type badExpr struct {
+ node mkparser.Node
+ message string
+}
+
+func (b *badExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
+ res = b
+ same = true
+ return
+}
+
+func (b *badExpr) emit(_ *generationContext) {
+ panic("implement me")
+}
+
+func (_ *badExpr) typ() starlarkType {
+ return starlarkTypeUnknown
+}
+
+func (b *badExpr) emitListVarCopy(gctx *generationContext) {
+ panic("implement me")
+}
+
+func maybeConvertToStringList(expr starlarkExpr) starlarkExpr {
+ if xString, ok := expr.(*stringLiteralExpr); ok {
+ return newStringListExpr(strings.Fields(xString.literal))
+ }
+ return expr
+}
+
+func isEmptyString(expr starlarkExpr) bool {
+ x, ok := expr.(*stringLiteralExpr)
+ return ok && x.literal == ""
+}
diff --git a/mk2rbc/find_mockfs.go b/mk2rbc/find_mockfs.go
new file mode 100644
index 0000000..73eff07
--- /dev/null
+++ b/mk2rbc/find_mockfs.go
@@ -0,0 +1,121 @@
+package mk2rbc
+
+import (
+ "io/fs"
+ "os"
+ "path/filepath"
+ "time"
+)
+
+// Mock FS. Maps a directory name to an array of entries.
+// An entry implements fs.DirEntry, fs.FIleInfo and fs.File interface
+type FindMockFS struct {
+ dirs map[string][]myFileInfo
+}
+
+func (m FindMockFS) locate(name string) (myFileInfo, bool) {
+ if name == "." {
+ return myFileInfo{".", true}, true
+ }
+ dir := filepath.Dir(name)
+ base := filepath.Base(name)
+ if entries, ok := m.dirs[dir]; ok {
+ for _, e := range entries {
+ if e.name == base {
+ return e, true
+ }
+ }
+ }
+ return myFileInfo{}, false
+}
+
+func (m FindMockFS) create(name string, isDir bool) {
+ dir := filepath.Dir(name)
+ m.dirs[dir] = append(m.dirs[dir], myFileInfo{filepath.Base(name), isDir})
+}
+
+func (m FindMockFS) Stat(name string) (fs.FileInfo, error) {
+ if fi, ok := m.locate(name); ok {
+ return fi, nil
+ }
+ return nil, os.ErrNotExist
+}
+
+type myFileInfo struct {
+ name string
+ isDir bool
+}
+
+func (m myFileInfo) Info() (fs.FileInfo, error) {
+ panic("implement me")
+}
+
+func (m myFileInfo) Size() int64 {
+ panic("implement me")
+}
+
+func (m myFileInfo) Mode() fs.FileMode {
+ panic("implement me")
+}
+
+func (m myFileInfo) ModTime() time.Time {
+ panic("implement me")
+}
+
+func (m myFileInfo) Sys() interface{} {
+ return nil
+}
+
+func (m myFileInfo) Stat() (fs.FileInfo, error) {
+ return m, nil
+}
+
+func (m myFileInfo) Read(bytes []byte) (int, error) {
+ panic("implement me")
+}
+
+func (m myFileInfo) Close() error {
+ panic("implement me")
+}
+
+func (m myFileInfo) Name() string {
+ return m.name
+}
+
+func (m myFileInfo) IsDir() bool {
+ return m.isDir
+}
+
+func (m myFileInfo) Type() fs.FileMode {
+ return m.Mode()
+}
+
+func (m FindMockFS) Open(name string) (fs.File, error) {
+ panic("implement me")
+}
+
+func (m FindMockFS) ReadDir(name string) ([]fs.DirEntry, error) {
+ if d, ok := m.dirs[name]; ok {
+ var res []fs.DirEntry
+ for _, e := range d {
+ res = append(res, e)
+ }
+ return res, nil
+ }
+ return nil, os.ErrNotExist
+}
+
+func NewFindMockFS(files []string) FindMockFS {
+ myfs := FindMockFS{make(map[string][]myFileInfo)}
+ for _, f := range files {
+ isDir := false
+ for f != "." {
+ if _, ok := myfs.locate(f); !ok {
+ myfs.create(f, isDir)
+ }
+ isDir = true
+ f = filepath.Dir(f)
+ }
+ }
+ return myfs
+}
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
new file mode 100644
index 0000000..7ceac41
--- /dev/null
+++ b/mk2rbc/mk2rbc.go
@@ -0,0 +1,1639 @@
+// Copyright 2021 Google LLC
+//
+// 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.
+
+// Convert makefile containing device configuration to Starlark file
+// The conversion can handle the following constructs in a makefile:
+// * comments
+// * simple variable assignments
+// * $(call init-product,<file>)
+// * $(call inherit-product-if-exists
+// * if directives
+// All other constructs are carried over to the output starlark file as comments.
+//
+package mk2rbc
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/fs"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strconv"
+ "strings"
+ "text/scanner"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+const (
+ 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"
+
+ // And here are the functions and variables:
+ cfnGetCfg = baseName + ".cfg"
+ cfnMain = baseName + ".product_configuration"
+ cfnPrintVars = baseName + ".printvars"
+ cfnWarning = baseName + ".warning"
+ cfnLocalAppend = baseName + ".local_append"
+ cfnLocalSetDefault = baseName + ".local_set_default"
+ cfnInherit = baseName + ".inherit"
+ cfnSetListDefault = baseName + ".setdefault"
+)
+
+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"
+)
+
+const (
+ callLoadAlways = "inherit-product"
+ callLoadIf = "inherit-product-if-exists"
+)
+
+var knownFunctions = map[string]struct {
+ // The name of the runtime function this function call in makefiles maps to.
+ // If it starts with !, then this makefile function call is rewritten to
+ // something else.
+ runtimeName string
+ returnType starlarkType
+ hiddenArg hiddenArgType
+}{
+ "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},
+ "add-to-product-copy-files-if-exists": {baseName + ".copy_if_exists", starlarkTypeList, hiddenArgNone},
+ "addprefix": {baseName + ".addprefix", starlarkTypeList, hiddenArgNone},
+ "addsuffix": {baseName + ".addsuffix", starlarkTypeList, hiddenArgNone},
+ "copy-files": {baseName + ".copy_files", starlarkTypeList, hiddenArgNone},
+ "dir": {baseName + ".dir", starlarkTypeList, hiddenArgNone},
+ "enforce-product-packages-exist": {baseName + ".enforce_product_packages_exist", starlarkTypeVoid, hiddenArgNone},
+ "error": {baseName + ".mkerror", starlarkTypeVoid, hiddenArgNone},
+ "findstring": {"!findstring", starlarkTypeInt, hiddenArgNone},
+ "find-copy-subdir-files": {baseName + ".find_and_copy", starlarkTypeList, hiddenArgNone},
+ "find-word-in-list": {"!find-word-in-list", starlarkTypeUnknown, hiddenArgNone}, // internal macro
+ "filter": {baseName + ".filter", starlarkTypeList, hiddenArgNone},
+ "filter-out": {baseName + ".filter_out", starlarkTypeList, hiddenArgNone},
+ "firstword": {"!firstword", starlarkTypeString, hiddenArgNone},
+ "get-vendor-board-platforms": {"!get-vendor-board-platforms", starlarkTypeList, hiddenArgNone}, // internal macro, used by is-board-platform, etc.
+ "info": {baseName + ".mkinfo", starlarkTypeVoid, hiddenArgNone},
+ "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-platform-in-list": {"!is-board-platform-in-list", starlarkTypeBool, hiddenArgNone},
+ "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},
+ callLoadAlways: {"!inherit-product", starlarkTypeVoid, hiddenArgNone},
+ callLoadIf: {"!inherit-product-if-exists", starlarkTypeVoid, hiddenArgNone},
+ "lastword": {"!lastword", starlarkTypeString, hiddenArgNone},
+ "match-prefix": {"!match-prefix", starlarkTypeUnknown, hiddenArgNone}, // internal macro
+ "match-word": {"!match-word", starlarkTypeUnknown, hiddenArgNone}, // internal macro
+ "match-word-in-list": {"!match-word-in-list", starlarkTypeUnknown, hiddenArgNone}, // internal macro
+ "notdir": {baseName + ".notdir", starlarkTypeString, hiddenArgNone},
+ "my-dir": {"!my-dir", starlarkTypeString, hiddenArgNone},
+ "patsubst": {baseName + ".mkpatsubst", starlarkTypeString, hiddenArgNone},
+ "produce_copy_files": {baseName + ".produce_copy_files", starlarkTypeList, hiddenArgNone},
+ "require-artifacts-in-path": {baseName + ".require_artifacts_in_path", starlarkTypeVoid, hiddenArgNone},
+ "require-artifacts-in-path-relaxed": {baseName + ".require_artifacts_in_path_relaxed", starlarkTypeVoid, hiddenArgNone},
+ // TODO(asmundak): remove it once all calls are removed from configuration makefiles. see b/183161002
+ "shell": {baseName + ".shell", starlarkTypeString, hiddenArgNone},
+ "strip": {baseName + ".mkstrip", starlarkTypeString, hiddenArgNone},
+ "tb-modules": {"!tb-modules", starlarkTypeUnknown, hiddenArgNone}, // defined in hardware/amlogic/tb_modules/tb_detect.mk, unused
+ "subst": {baseName + ".mksubst", starlarkTypeString, hiddenArgNone},
+ "warning": {baseName + ".mkwarning", starlarkTypeVoid, hiddenArgNone},
+ "word": {baseName + "!word", starlarkTypeString, hiddenArgNone},
+ "wildcard": {baseName + ".expand_wildcard", starlarkTypeList, hiddenArgNone},
+}
+
+var builtinFuncRex = regexp.MustCompile(
+ "^(addprefix|addsuffix|abspath|and|basename|call|dir|error|eval" +
+ "|flavor|foreach|file|filter|filter-out|findstring|firstword|guile" +
+ "|if|info|join|lastword|notdir|or|origin|patsubst|realpath" +
+ "|shell|sort|strip|subst|suffix|value|warning|word|wordlist|words" +
+ "|wildcard)")
+
+// Conversion request parameters
+type Request struct {
+ MkFile string // file to convert
+ Reader io.Reader // if set, read input from this stream instead
+ RootDir string // root directory path used to resolve included files
+ OutputSuffix string // generated Starlark files suffix
+ OutputDir string // if set, root of the output hierarchy
+ ErrorLogger ErrorMonitorCB
+ TracedVariables []string // trace assignment to these variables
+ TraceCalls bool
+ WarnPartialSuccess bool
+ SourceFS fs.FS
+ MakefileFinder MakefileFinder
+}
+
+// An error sink allowing to gather error statistics.
+// NewError is called on every error encountered during processing.
+type ErrorMonitorCB interface {
+ NewError(s string, node mkparser.Node, args ...interface{})
+}
+
+// Derives module name for a given file. It is base name
+// (file name without suffix), with some characters replaced to make it a Starlark identifier
+func moduleNameForFile(mkFile string) string {
+ base := strings.TrimSuffix(filepath.Base(mkFile), filepath.Ext(mkFile))
+ // TODO(asmundak): what else can be in the product file names?
+ return strings.NewReplacer("-", "_", ".", "_").Replace(base)
+
+}
+
+func cloneMakeString(mkString *mkparser.MakeString) *mkparser.MakeString {
+ r := &mkparser.MakeString{StringPos: mkString.StringPos}
+ r.Strings = append(r.Strings, mkString.Strings...)
+ r.Variables = append(r.Variables, mkString.Variables...)
+ return r
+}
+
+func isMakeControlFunc(s string) bool {
+ return s == "error" || s == "warning" || s == "info"
+}
+
+// Starlark output generation context
+type generationContext struct {
+ buf strings.Builder
+ starScript *StarlarkScript
+ indentLevel int
+ inAssignment bool
+ tracedCount int
+}
+
+func NewGenerateContext(ss *StarlarkScript) *generationContext {
+ return &generationContext{starScript: ss}
+}
+
+// emit returns generated script
+func (gctx *generationContext) emit() string {
+ ss := gctx.starScript
+
+ // The emitted code has the following layout:
+ // <initial comments>
+ // preamble, i.e.,
+ // load statement for the runtime support
+ // load statement for each unique submodule pulled in by this one
+ // def init(g, handle):
+ // cfg = rblf.cfg(handle)
+ // <statements>
+ // <warning if conversion was not clean>
+
+ iNode := len(ss.nodes)
+ for i, node := range ss.nodes {
+ if _, ok := node.(*commentNode); !ok {
+ iNode = i
+ break
+ }
+ node.emit(gctx)
+ }
+
+ gctx.emitPreamble()
+
+ gctx.newLine()
+ // The arguments passed to the init function are the global dictionary
+ // ('g') and the product configuration dictionary ('cfg')
+ gctx.write("def init(g, handle):")
+ gctx.indentLevel++
+ if gctx.starScript.traceCalls {
+ gctx.newLine()
+ gctx.writef(`print(">%s")`, gctx.starScript.mkFile)
+ }
+ gctx.newLine()
+ gctx.writef("cfg = %s(handle)", cfnGetCfg)
+ for _, node := range ss.nodes[iNode:] {
+ node.emit(gctx)
+ }
+
+ if ss.hasErrors && ss.warnPartialSuccess {
+ gctx.newLine()
+ gctx.writef("%s(%q, %q)", cfnWarning, filepath.Base(ss.mkFile), "partially successful conversion")
+ }
+ if gctx.starScript.traceCalls {
+ gctx.newLine()
+ gctx.writef(`print("<%s")`, gctx.starScript.mkFile)
+ }
+ gctx.indentLevel--
+ gctx.write("\n")
+ return gctx.buf.String()
+}
+
+func (gctx *generationContext) emitPreamble() {
+ gctx.newLine()
+ gctx.writef("load(%q, %q)", baseUri, baseName)
+ // Emit exactly one load statement for each URI.
+ loadedSubConfigs := make(map[string]string)
+ for _, sc := range gctx.starScript.inherited {
+ uri := sc.path
+ if m, ok := loadedSubConfigs[uri]; ok {
+ // No need to emit load statement, but fix module name.
+ sc.moduleLocalName = m
+ continue
+ }
+ if sc.optional {
+ uri += "|init"
+ }
+ gctx.newLine()
+ gctx.writef("load(%q, %s = \"init\")", uri, sc.entryName())
+ loadedSubConfigs[uri] = sc.moduleLocalName
+ }
+ gctx.write("\n")
+}
+
+func (gctx *generationContext) emitPass() {
+ gctx.newLine()
+ gctx.write("pass")
+}
+
+func (gctx *generationContext) write(ss ...string) {
+ for _, s := range ss {
+ gctx.buf.WriteString(s)
+ }
+}
+
+func (gctx *generationContext) writef(format string, args ...interface{}) {
+ gctx.write(fmt.Sprintf(format, args...))
+}
+
+func (gctx *generationContext) newLine() {
+ if gctx.buf.Len() == 0 {
+ return
+ }
+ gctx.write("\n")
+ gctx.writef("%*s", 2*gctx.indentLevel, "")
+}
+
+type knownVariable struct {
+ name string
+ class varClass
+ valueType starlarkType
+}
+
+type knownVariables map[string]knownVariable
+
+func (pcv knownVariables) NewVariable(name string, varClass varClass, valueType starlarkType) {
+ v, exists := pcv[name]
+ if !exists {
+ pcv[name] = knownVariable{name, varClass, valueType}
+ return
+ }
+ // Conflict resolution:
+ // * config class trumps everything
+ // * any type trumps unknown type
+ match := varClass == v.class
+ if !match {
+ if varClass == VarClassConfig {
+ v.class = VarClassConfig
+ match = true
+ } else if v.class == VarClassConfig {
+ match = true
+ }
+ }
+ if valueType != v.valueType {
+ if valueType != starlarkTypeUnknown {
+ if v.valueType == starlarkTypeUnknown {
+ v.valueType = valueType
+ } else {
+ match = false
+ }
+ }
+ }
+ if !match {
+ fmt.Fprintf(os.Stderr, "cannot redefine %s as %v/%v (already defined as %v/%v)\n",
+ name, varClass, valueType, v.class, v.valueType)
+ }
+}
+
+// All known product variables.
+var KnownVariables = make(knownVariables)
+
+func init() {
+ for _, kv := range []string{
+ // Kernel-related variables that we know are lists.
+ "BOARD_VENDOR_KERNEL_MODULES",
+ "BOARD_VENDOR_RAMDISK_KERNEL_MODULES",
+ "BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD",
+ "BOARD_RECOVERY_KERNEL_MODULES",
+ // Other variables we knwo are lists
+ "ART_APEX_JARS",
+ } {
+ KnownVariables.NewVariable(kv, VarClassSoong, starlarkTypeList)
+ }
+}
+
+type nodeReceiver interface {
+ newNode(node starlarkNode)
+}
+
+// Information about the generated Starlark script.
+type StarlarkScript struct {
+ mkFile string
+ moduleName string
+ mkPos scanner.Position
+ nodes []starlarkNode
+ inherited []*moduleInfo
+ hasErrors bool
+ topDir string
+ traceCalls bool // print enter/exit each init function
+ warnPartialSuccess bool
+ sourceFS fs.FS
+ makefileFinder MakefileFinder
+}
+
+func (ss *StarlarkScript) newNode(node starlarkNode) {
+ ss.nodes = append(ss.nodes, node)
+}
+
+// varAssignmentScope points to the last assignment for each variable
+// in the current block. It is used during the parsing to chain
+// the assignments to a variable together.
+type varAssignmentScope struct {
+ outer *varAssignmentScope
+ vars map[string]*assignmentNode
+}
+
+// parseContext holds the script we are generating and all the ephemeral data
+// needed during the parsing.
+type parseContext struct {
+ script *StarlarkScript
+ nodes []mkparser.Node // Makefile as parsed by mkparser
+ currentNodeIndex int // Node in it we are processing
+ ifNestLevel int
+ moduleNameCount map[string]int // count of imported modules with given basename
+ fatalError error
+ builtinMakeVars map[string]starlarkExpr
+ outputSuffix string
+ errorLogger ErrorMonitorCB
+ tracedVariables map[string]bool // variables to be traced in the generated script
+ variables map[string]variable
+ varAssignments *varAssignmentScope
+ receiver nodeReceiver // receptacle for the generated starlarkNode's
+ receiverStack []nodeReceiver
+ outputDir string
+ dependentModules map[string]*moduleInfo
+ soongNamespaces map[string]map[string]bool
+}
+
+func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
+ topdir, _ := filepath.Split(filepath.Join(ss.topDir, "foo"))
+ predefined := []struct{ name, value string }{
+ {"SRC_TARGET_DIR", filepath.Join("build", "make", "target")},
+ {"LOCAL_PATH", filepath.Dir(ss.mkFile)},
+ {"TOPDIR", topdir},
+ // TODO(asmundak): maybe read it from build/make/core/envsetup.mk?
+ {"TARGET_COPY_OUT_SYSTEM", "system"},
+ {"TARGET_COPY_OUT_SYSTEM_OTHER", "system_other"},
+ {"TARGET_COPY_OUT_DATA", "data"},
+ {"TARGET_COPY_OUT_ASAN", filepath.Join("data", "asan")},
+ {"TARGET_COPY_OUT_OEM", "oem"},
+ {"TARGET_COPY_OUT_RAMDISK", "ramdisk"},
+ {"TARGET_COPY_OUT_DEBUG_RAMDISK", "debug_ramdisk"},
+ {"TARGET_COPY_OUT_VENDOR_DEBUG_RAMDISK", "vendor_debug_ramdisk"},
+ {"TARGET_COPY_OUT_TEST_HARNESS_RAMDISK", "test_harness_ramdisk"},
+ {"TARGET_COPY_OUT_ROOT", "root"},
+ {"TARGET_COPY_OUT_RECOVERY", "recovery"},
+ {"TARGET_COPY_OUT_VENDOR", "||VENDOR-PATH-PH||"},
+ {"TARGET_COPY_OUT_VENDOR_RAMDISK", "vendor_ramdisk"},
+ {"TARGET_COPY_OUT_PRODUCT", "||PRODUCT-PATH-PH||"},
+ {"TARGET_COPY_OUT_PRODUCT_SERVICES", "||PRODUCT-PATH-PH||"},
+ {"TARGET_COPY_OUT_SYSTEM_EXT", "||SYSTEM_EXT-PATH-PH||"},
+ {"TARGET_COPY_OUT_ODM", "||ODM-PATH-PH||"},
+ {"TARGET_COPY_OUT_VENDOR_DLKM", "||VENDOR_DLKM-PATH-PH||"},
+ {"TARGET_COPY_OUT_ODM_DLKM", "||ODM_DLKM-PATH-PH||"},
+ // TODO(asmundak): to process internal config files, we need the following variables:
+ // BOARD_CONFIG_VENDOR_PATH
+ // TARGET_VENDOR
+ // target_base_product
+ //
+
+ // the following utility variables are set in build/make/common/core.mk:
+ {"empty", ""},
+ {"space", " "},
+ {"comma", ","},
+ {"newline", "\n"},
+ {"pound", "#"},
+ {"backslash", "\\"},
+ }
+ ctx := &parseContext{
+ script: ss,
+ nodes: nodes,
+ currentNodeIndex: 0,
+ ifNestLevel: 0,
+ moduleNameCount: make(map[string]int),
+ builtinMakeVars: map[string]starlarkExpr{},
+ variables: make(map[string]variable),
+ dependentModules: make(map[string]*moduleInfo),
+ soongNamespaces: make(map[string]map[string]bool),
+ }
+ ctx.pushVarAssignments()
+ for _, item := range predefined {
+ ctx.variables[item.name] = &predefinedVariable{
+ baseVariable: baseVariable{nam: item.name, typ: starlarkTypeString},
+ value: &stringLiteralExpr{item.value},
+ }
+ }
+
+ return ctx
+}
+
+func (ctx *parseContext) lastAssignment(name string) *assignmentNode {
+ for va := ctx.varAssignments; va != nil; va = va.outer {
+ if v, ok := va.vars[name]; ok {
+ return v
+ }
+ }
+ return nil
+}
+
+func (ctx *parseContext) setLastAssignment(name string, asgn *assignmentNode) {
+ ctx.varAssignments.vars[name] = asgn
+}
+
+func (ctx *parseContext) pushVarAssignments() {
+ va := &varAssignmentScope{
+ outer: ctx.varAssignments,
+ vars: make(map[string]*assignmentNode),
+ }
+ ctx.varAssignments = va
+}
+
+func (ctx *parseContext) popVarAssignments() {
+ ctx.varAssignments = ctx.varAssignments.outer
+}
+
+func (ctx *parseContext) pushReceiver(rcv nodeReceiver) {
+ ctx.receiverStack = append(ctx.receiverStack, ctx.receiver)
+ ctx.receiver = rcv
+}
+
+func (ctx *parseContext) popReceiver() {
+ last := len(ctx.receiverStack) - 1
+ if last < 0 {
+ panic(fmt.Errorf("popReceiver: receiver stack empty"))
+ }
+ ctx.receiver = ctx.receiverStack[last]
+ ctx.receiverStack = ctx.receiverStack[0:last]
+}
+
+func (ctx *parseContext) hasNodes() bool {
+ return ctx.currentNodeIndex < len(ctx.nodes)
+}
+
+func (ctx *parseContext) getNode() mkparser.Node {
+ if !ctx.hasNodes() {
+ return nil
+ }
+ node := ctx.nodes[ctx.currentNodeIndex]
+ ctx.currentNodeIndex++
+ return node
+}
+
+func (ctx *parseContext) backNode() {
+ if ctx.currentNodeIndex <= 0 {
+ panic("Cannot back off")
+ }
+ ctx.currentNodeIndex--
+}
+
+func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) {
+ // Handle only simple variables
+ if !a.Name.Const() {
+ ctx.errorf(a, "Only simple variables are handled")
+ return
+ }
+ name := a.Name.Strings[0]
+ const soongNsPrefix = "SOONG_CONFIG_"
+ // Soong confuguration
+ if strings.HasPrefix(name, soongNsPrefix) {
+ ctx.handleSoongNsAssignment(strings.TrimPrefix(name, soongNsPrefix), a)
+ return
+ }
+ lhs := ctx.addVariable(name)
+ if lhs == nil {
+ ctx.errorf(a, "unknown variable %s", name)
+ return
+ }
+ _, isTraced := ctx.tracedVariables[name]
+ asgn := &assignmentNode{lhs: lhs, mkValue: a.Value, isTraced: isTraced}
+ if lhs.valueType() == starlarkTypeUnknown {
+ // Try to divine variable type from the RHS
+ asgn.value = ctx.parseMakeString(a, a.Value)
+ if xBad, ok := asgn.value.(*badExpr); ok {
+ ctx.wrapBadExpr(xBad)
+ return
+ }
+ inferred_type := asgn.value.typ()
+ if inferred_type != starlarkTypeUnknown {
+ lhs.setValueType(inferred_type)
+ }
+ }
+ if lhs.valueType() == starlarkTypeList {
+ xConcat := ctx.buildConcatExpr(a)
+ if xConcat == nil {
+ return
+ }
+ switch len(xConcat.items) {
+ case 0:
+ asgn.value = &listExpr{}
+ case 1:
+ asgn.value = xConcat.items[0]
+ default:
+ asgn.value = xConcat
+ }
+ } else {
+ asgn.value = ctx.parseMakeString(a, a.Value)
+ if xBad, ok := asgn.value.(*badExpr); ok {
+ ctx.wrapBadExpr(xBad)
+ return
+ }
+ }
+
+ // TODO(asmundak): move evaluation to a separate pass
+ asgn.value, _ = asgn.value.eval(ctx.builtinMakeVars)
+
+ asgn.previous = ctx.lastAssignment(name)
+ ctx.setLastAssignment(name, asgn)
+ switch a.Type {
+ case "=", ":=":
+ asgn.flavor = asgnSet
+ case "+=":
+ if asgn.previous == nil && !asgn.lhs.isPreset() {
+ asgn.flavor = asgnMaybeAppend
+ } else {
+ asgn.flavor = asgnAppend
+ }
+ case "?=":
+ asgn.flavor = asgnMaybeSet
+ default:
+ panic(fmt.Errorf("unexpected assignment type %s", a.Type))
+ }
+
+ ctx.receiver.newNode(asgn)
+}
+
+func (ctx *parseContext) handleSoongNsAssignment(name string, asgn *mkparser.Assignment) {
+ val := ctx.parseMakeString(asgn, asgn.Value)
+ if xBad, ok := val.(*badExpr); ok {
+ ctx.wrapBadExpr(xBad)
+ return
+ }
+ val, _ = val.eval(ctx.builtinMakeVars)
+
+ // Unfortunately, Soong namespaces can be set up by directly setting corresponding Make
+ // variables instead of via add_soong_config_namespace + add_soong_config_var_value.
+ // Try to divine the call from the assignment as follows:
+ if name == "NAMESPACES" {
+ // Upon seeng
+ // SOONG_CONFIG_NAMESPACES += foo
+ // remember that there is a namespace `foo` and act as we saw
+ // $(call add_soong_config_namespace,foo)
+ s, ok := maybeString(val)
+ if !ok {
+ ctx.errorf(asgn, "cannot handle variables in SOONG_CONFIG_NAMESPACES assignment, please use add_soong_config_namespace instead")
+ return
+ }
+ for _, ns := range strings.Fields(s) {
+ ctx.addSoongNamespace(ns)
+ ctx.receiver.newNode(&exprNode{&callExpr{
+ name: addSoongNamespace,
+ args: []starlarkExpr{&stringLiteralExpr{ns}},
+ returnType: starlarkTypeVoid,
+ }})
+ }
+ } else {
+ // Upon seeing
+ // SOONG_CONFIG_x_y = v
+ // find a namespace called `x` and act as if we encountered
+ // $(call add_config_var_value(x,y,v)
+ // or check that `x_y` is a namespace, and then add the RHS of this assignment as variables in
+ // it.
+ // Emit an error in the ambiguous situation (namespaces `foo_bar` with a variable `baz`
+ // and `foo` with a variable `bar_baz`.
+ namespaceName := ""
+ if ctx.hasSoongNamespace(name) {
+ namespaceName = name
+ }
+ var varName string
+ for pos, ch := range name {
+ if !(ch == '_' && ctx.hasSoongNamespace(name[0:pos])) {
+ continue
+ }
+ if namespaceName != "" {
+ ctx.errorf(asgn, "ambiguous soong namespace (may be either `%s` or `%s`)", namespaceName, name[0:pos])
+ return
+ }
+ namespaceName = name[0:pos]
+ varName = name[pos+1:]
+ }
+ if namespaceName == "" {
+ ctx.errorf(asgn, "cannot figure out Soong namespace, please use add_soong_config_var_value macro instead")
+ return
+ }
+ if varName == "" {
+ // Remember variables in this namespace
+ s, ok := maybeString(val)
+ if !ok {
+ ctx.errorf(asgn, "cannot handle variables in SOONG_CONFIG_ assignment, please use add_soong_config_var_value instead")
+ return
+ }
+ ctx.updateSoongNamespace(asgn.Type != "+=", namespaceName, strings.Fields(s))
+ return
+ }
+
+ // Finally, handle assignment to a namespace variable
+ if !ctx.hasNamespaceVar(namespaceName, varName) {
+ ctx.errorf(asgn, "no %s variable in %s namespace, please use add_soong_config_var_value instead", varName, namespaceName)
+ return
+ }
+ ctx.receiver.newNode(&exprNode{&callExpr{
+ name: addSoongConfigVarValue,
+ args: []starlarkExpr{&stringLiteralExpr{namespaceName}, &stringLiteralExpr{varName}, val},
+ returnType: starlarkTypeVoid,
+ }})
+ }
+}
+
+func (ctx *parseContext) buildConcatExpr(a *mkparser.Assignment) *concatExpr {
+ xConcat := &concatExpr{}
+ var xItemList *listExpr
+ addToItemList := func(x ...starlarkExpr) {
+ if xItemList == nil {
+ xItemList = &listExpr{[]starlarkExpr{}}
+ }
+ xItemList.items = append(xItemList.items, x...)
+ }
+ finishItemList := func() {
+ if xItemList != nil {
+ xConcat.items = append(xConcat.items, xItemList)
+ xItemList = nil
+ }
+ }
+
+ items := a.Value.Words()
+ for _, item := range items {
+ // A function call in RHS is supposed to return a list, all other item
+ // expressions return individual elements.
+ switch x := ctx.parseMakeString(a, item).(type) {
+ case *badExpr:
+ ctx.wrapBadExpr(x)
+ return nil
+ case *stringLiteralExpr:
+ addToItemList(maybeConvertToStringList(x).(*listExpr).items...)
+ default:
+ switch x.typ() {
+ case starlarkTypeList:
+ finishItemList()
+ xConcat.items = append(xConcat.items, x)
+ case starlarkTypeString:
+ finishItemList()
+ xConcat.items = append(xConcat.items, &callExpr{
+ object: x,
+ name: "split",
+ args: nil,
+ returnType: starlarkTypeList,
+ })
+ default:
+ addToItemList(x)
+ }
+ }
+ }
+ if xItemList != nil {
+ xConcat.items = append(xConcat.items, xItemList)
+ }
+ return xConcat
+}
+
+func (ctx *parseContext) newDependentModule(path string, optional bool) *moduleInfo {
+ modulePath := ctx.loadedModulePath(path)
+ if mi, ok := ctx.dependentModules[modulePath]; ok {
+ mi.optional = mi.optional || optional
+ return mi
+ }
+ moduleName := moduleNameForFile(path)
+ moduleLocalName := "_" + moduleName
+ n, found := ctx.moduleNameCount[moduleName]
+ if found {
+ moduleLocalName += fmt.Sprintf("%d", n)
+ }
+ ctx.moduleNameCount[moduleName] = n + 1
+ mi := &moduleInfo{
+ path: modulePath,
+ originalPath: path,
+ moduleLocalName: moduleLocalName,
+ optional: optional,
+ }
+ ctx.dependentModules[modulePath] = mi
+ ctx.script.inherited = append(ctx.script.inherited, mi)
+ return mi
+}
+
+func (ctx *parseContext) handleSubConfig(
+ v mkparser.Node, pathExpr starlarkExpr, loadAlways bool, processModule func(inheritedModule)) {
+ pathExpr, _ = pathExpr.eval(ctx.builtinMakeVars)
+
+ // In a simple case, the name of a module to inherit/include is known statically.
+ if path, ok := maybeString(pathExpr); ok {
+ if strings.Contains(path, "*") {
+ if paths, err := fs.Glob(ctx.script.sourceFS, path); err == nil {
+ for _, p := range paths {
+ processModule(inheritedStaticModule{ctx.newDependentModule(p, !loadAlways), loadAlways})
+ }
+ } else {
+ ctx.errorf(v, "cannot glob wildcard argument")
+ }
+ } else {
+ processModule(inheritedStaticModule{ctx.newDependentModule(path, !loadAlways), loadAlways})
+ }
+ return
+ }
+
+ // If module path references variables (e.g., $(v1)/foo/$(v2)/device-config.mk), find all the paths in the
+ // source tree that may be a match and the corresponding variable values. For instance, if the source tree
+ // contains vendor1/foo/abc/dev.mk and vendor2/foo/def/dev.mk, the first one will be inherited when
+ // (v1, v2) == ('vendor1', 'abc'), and the second one when (v1, v2) == ('vendor2', 'def').
+ // We then emit the code that loads all of them, e.g.:
+ // load("//vendor1/foo/abc:dev.rbc", _dev1_init="init")
+ // load("//vendor2/foo/def/dev.rbc", _dev2_init="init")
+ // And then inherit it as follows:
+ // _e = {
+ // "vendor1/foo/abc/dev.mk": ("vendor1/foo/abc/dev", _dev1_init),
+ // "vendor2/foo/def/dev.mk": ("vendor2/foo/def/dev", _dev_init2) }.get("%s/foo/%s/dev.mk" % (v1, v2))
+ // if _e:
+ // rblf.inherit(handle, _e[0], _e[1])
+ //
+ var matchingPaths []string
+ varPath, ok := pathExpr.(*interpolateExpr)
+ if !ok {
+ ctx.errorf(v, "inherit-product/include argument is too complex")
+ return
+ }
+
+ pathPattern := []string{varPath.chunks[0]}
+ for _, chunk := range varPath.chunks[1:] {
+ if chunk != "" {
+ 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)...)
+ }
+ }
+ }
+ // Safeguard against $(call inherit-product,$(PRODUCT_PATH))
+ const maxMatchingFiles = 150
+ if len(matchingPaths) > maxMatchingFiles {
+ ctx.errorf(v, "there are >%d files matching the pattern, please rewrite it", maxMatchingFiles)
+ return
+ }
+ res := inheritedDynamicModule{*varPath, []*moduleInfo{}, loadAlways}
+ for _, p := range matchingPaths {
+ // A product configuration files discovered dynamically may attempt to inherit
+ // from another one which does not exist in this source tree. Prevent load errors
+ // by always loading the dynamic files as optional.
+ res.candidateModules = append(res.candidateModules, ctx.newDependentModule(p, true))
+ }
+ processModule(res)
+}
+
+func (ctx *parseContext) findMatchingPaths(pattern []string) []string {
+ files := ctx.script.makefileFinder.Find(ctx.script.topDir)
+ if len(pattern) == 0 {
+ return files
+ }
+
+ // Create regular expression from the pattern
+ s_regexp := "^" + regexp.QuoteMeta(pattern[0])
+ for _, s := range pattern[1:] {
+ s_regexp += ".*" + regexp.QuoteMeta(s)
+ }
+ s_regexp += "$"
+ rex := regexp.MustCompile(s_regexp)
+
+ // Now match
+ var res []string
+ for _, p := range files {
+ if rex.MatchString(p) {
+ res = append(res, p)
+ }
+ }
+ return res
+}
+
+func (ctx *parseContext) handleInheritModule(v mkparser.Node, pathExpr starlarkExpr, loadAlways bool) {
+ ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) {
+ ctx.receiver.newNode(&inheritNode{im})
+ })
+}
+
+func (ctx *parseContext) handleInclude(v mkparser.Node, pathExpr starlarkExpr, loadAlways bool) {
+ ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) {
+ ctx.receiver.newNode(&includeNode{im})
+ })
+}
+
+func (ctx *parseContext) handleVariable(v *mkparser.Variable) {
+ // Handle:
+ // $(call inherit-product,...)
+ // $(call inherit-product-if-exists,...)
+ // $(info xxx)
+ // $(warning xxx)
+ // $(error xxx)
+ expr := ctx.parseReference(v, v.Name)
+ switch x := expr.(type) {
+ case *callExpr:
+ if x.name == callLoadAlways || x.name == callLoadIf {
+ ctx.handleInheritModule(v, x.args[0], x.name == callLoadAlways)
+ } else if isMakeControlFunc(x.name) {
+ // File name is the first argument
+ args := []starlarkExpr{
+ &stringLiteralExpr{ctx.script.mkFile},
+ x.args[0],
+ }
+ ctx.receiver.newNode(&exprNode{
+ &callExpr{name: x.name, args: args, returnType: starlarkTypeUnknown},
+ })
+ } else {
+ ctx.receiver.newNode(&exprNode{expr})
+ }
+ case *badExpr:
+ ctx.wrapBadExpr(x)
+ return
+ default:
+ ctx.errorf(v, "cannot handle %s", v.Dump())
+ return
+ }
+}
+
+func (ctx *parseContext) handleDefine(directive *mkparser.Directive) {
+ macro_name := strings.Fields(directive.Args.Strings[0])[0]
+ // Ignore the macros that we handle
+ if _, ok := knownFunctions[macro_name]; !ok {
+ ctx.errorf(directive, "define is not supported: %s", macro_name)
+ }
+}
+
+func (ctx *parseContext) handleIfBlock(ifDirective *mkparser.Directive) {
+ ssSwitch := &switchNode{}
+ ctx.pushReceiver(ssSwitch)
+ for ctx.processBranch(ifDirective); ctx.hasNodes() && ctx.fatalError == nil; {
+ node := ctx.getNode()
+ switch x := node.(type) {
+ case *mkparser.Directive:
+ switch x.Name {
+ case "else", "elifdef", "elifndef", "elifeq", "elifneq":
+ ctx.processBranch(x)
+ case "endif":
+ ctx.popReceiver()
+ ctx.receiver.newNode(ssSwitch)
+ return
+ default:
+ ctx.errorf(node, "unexpected directive %s", x.Name)
+ }
+ default:
+ ctx.errorf(ifDirective, "unexpected statement")
+ }
+ }
+ if ctx.fatalError == nil {
+ ctx.fatalError = fmt.Errorf("no matching endif for %s", ifDirective.Dump())
+ }
+ ctx.popReceiver()
+}
+
+// processBranch processes a single branch (if/elseif/else) until the next directive
+// on the same level.
+func (ctx *parseContext) processBranch(check *mkparser.Directive) {
+ block := switchCase{gate: ctx.parseCondition(check)}
+ defer func() {
+ ctx.popVarAssignments()
+ ctx.ifNestLevel--
+
+ }()
+ ctx.pushVarAssignments()
+ ctx.ifNestLevel++
+
+ ctx.pushReceiver(&block)
+ for ctx.hasNodes() {
+ node := ctx.getNode()
+ if ctx.handleSimpleStatement(node) {
+ continue
+ }
+ switch d := node.(type) {
+ case *mkparser.Directive:
+ switch d.Name {
+ case "else", "elifdef", "elifndef", "elifeq", "elifneq", "endif":
+ ctx.popReceiver()
+ ctx.receiver.newNode(&block)
+ ctx.backNode()
+ return
+ case "ifdef", "ifndef", "ifeq", "ifneq":
+ ctx.handleIfBlock(d)
+ default:
+ ctx.errorf(d, "unexpected directive %s", d.Name)
+ }
+ default:
+ ctx.errorf(node, "unexpected statement")
+ }
+ }
+ ctx.fatalError = fmt.Errorf("no matching endif for %s", check.Dump())
+ ctx.popReceiver()
+}
+
+func (ctx *parseContext) newIfDefinedNode(check *mkparser.Directive) (starlarkExpr, bool) {
+ if !check.Args.Const() {
+ return ctx.newBadExpr(check, "ifdef variable ref too complex: %s", check.Args.Dump()), false
+ }
+ v := ctx.addVariable(check.Args.Strings[0])
+ return &variableDefinedExpr{v}, true
+}
+
+func (ctx *parseContext) parseCondition(check *mkparser.Directive) starlarkNode {
+ switch check.Name {
+ case "ifdef", "ifndef", "elifdef", "elifndef":
+ v, ok := ctx.newIfDefinedNode(check)
+ if ok && strings.HasSuffix(check.Name, "ndef") {
+ v = ¬Expr{v}
+ }
+ return &ifNode{
+ isElif: strings.HasPrefix(check.Name, "elif"),
+ expr: v,
+ }
+ case "ifeq", "ifneq", "elifeq", "elifneq":
+ return &ifNode{
+ isElif: strings.HasPrefix(check.Name, "elif"),
+ expr: ctx.parseCompare(check),
+ }
+ case "else":
+ return &elseNode{}
+ default:
+ panic(fmt.Errorf("%s: unknown directive: %s", ctx.script.mkFile, check.Dump()))
+ }
+}
+
+func (ctx *parseContext) newBadExpr(node mkparser.Node, text string, args ...interface{}) starlarkExpr {
+ message := fmt.Sprintf(text, args...)
+ if ctx.errorLogger != nil {
+ ctx.errorLogger.NewError(text, node, args)
+ }
+ ctx.script.hasErrors = true
+ return &badExpr{node, message}
+}
+
+func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr {
+ // Strip outer parentheses
+ mkArg := cloneMakeString(cond.Args)
+ mkArg.Strings[0] = strings.TrimLeft(mkArg.Strings[0], "( ")
+ n := len(mkArg.Strings)
+ mkArg.Strings[n-1] = strings.TrimRight(mkArg.Strings[n-1], ") ")
+ args := mkArg.Split(",")
+ // TODO(asmundak): handle the case where the arguments are in quotes and space-separated
+ if len(args) != 2 {
+ return ctx.newBadExpr(cond, "ifeq/ifneq len(args) != 2 %s", cond.Dump())
+ }
+ args[0].TrimRightSpaces()
+ args[1].TrimLeftSpaces()
+
+ isEq := !strings.HasSuffix(cond.Name, "neq")
+ switch xLeft := ctx.parseMakeString(cond, args[0]).(type) {
+ case *stringLiteralExpr, *variableRefExpr:
+ switch xRight := ctx.parseMakeString(cond, args[1]).(type) {
+ case *stringLiteralExpr, *variableRefExpr:
+ return &eqExpr{left: xLeft, right: xRight, isEq: isEq}
+ case *badExpr:
+ return xRight
+ default:
+ expr, ok := ctx.parseCheckFunctionCallResult(cond, xLeft, args[1])
+ if ok {
+ return expr
+ }
+ return ctx.newBadExpr(cond, "right operand is too complex: %s", args[1].Dump())
+ }
+ case *badExpr:
+ return xLeft
+ default:
+ switch xRight := ctx.parseMakeString(cond, args[1]).(type) {
+ case *stringLiteralExpr, *variableRefExpr:
+ expr, ok := ctx.parseCheckFunctionCallResult(cond, xRight, args[0])
+ if ok {
+ return expr
+ }
+ return ctx.newBadExpr(cond, "left operand is too complex: %s", args[0].Dump())
+ case *badExpr:
+ return xRight
+ default:
+ return ctx.newBadExpr(cond, "operands are too complex: (%s,%s)", args[0].Dump(), args[1].Dump())
+ }
+ }
+}
+
+func (ctx *parseContext) parseCheckFunctionCallResult(directive *mkparser.Directive, xValue starlarkExpr,
+ varArg *mkparser.MakeString) (starlarkExpr, bool) {
+ mkSingleVar, ok := varArg.SingleVariable()
+ if !ok {
+ return nil, false
+ }
+ expr := ctx.parseReference(directive, mkSingleVar)
+ negate := strings.HasSuffix(directive.Name, "neq")
+ checkIsSomethingFunction := func(xCall *callExpr) starlarkExpr {
+ s, ok := maybeString(xValue)
+ if !ok || s != "true" {
+ return ctx.newBadExpr(directive,
+ fmt.Sprintf("the result of %s can be compared only to 'true'", xCall.name))
+ }
+ if len(xCall.args) < 1 {
+ return ctx.newBadExpr(directive, "%s requires an argument", xCall.name)
+ }
+ return nil
+ }
+ switch x := expr.(type) {
+ case *callExpr:
+ switch x.name {
+ case "filter":
+ return ctx.parseCompareFilterFuncResult(directive, x, xValue, !negate), true
+ case "filter-out":
+ return ctx.parseCompareFilterFuncResult(directive, x, xValue, negate), true
+ case "wildcard":
+ return ctx.parseCompareWildcardFuncResult(directive, x, xValue, negate), true
+ case "findstring":
+ return ctx.parseCheckFindstringFuncResult(directive, x, xValue, negate), true
+ case "strip":
+ return ctx.parseCompareStripFuncResult(directive, x, xValue, negate), true
+ case "is-board-platform":
+ if xBad := checkIsSomethingFunction(x); xBad != nil {
+ return xBad, true
+ }
+ return &eqExpr{
+ left: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
+ right: x.args[0],
+ isEq: !negate,
+ }, true
+ case "is-board-platform-in-list":
+ if xBad := checkIsSomethingFunction(x); xBad != nil {
+ return xBad, true
+ }
+ return &inExpr{
+ expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
+ list: maybeConvertToStringList(x.args[0]),
+ isNot: negate,
+ }, true
+ case "is-product-in-list":
+ if xBad := checkIsSomethingFunction(x); xBad != nil {
+ return xBad, true
+ }
+ return &inExpr{
+ expr: &variableRefExpr{ctx.addVariable("TARGET_PRODUCT"), true},
+ list: maybeConvertToStringList(x.args[0]),
+ isNot: negate,
+ }, true
+ case "is-vendor-board-platform":
+ if xBad := checkIsSomethingFunction(x); xBad != nil {
+ return xBad, true
+ }
+ s, ok := maybeString(x.args[0])
+ if !ok {
+ return ctx.newBadExpr(directive, "cannot handle non-constant argument to is-vendor-board-platform"), true
+ }
+ return &inExpr{
+ expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
+ list: &variableRefExpr{ctx.addVariable(s + "_BOARD_PLATFORMS"), true},
+ isNot: negate,
+ }, true
+ default:
+ return ctx.newBadExpr(directive, "Unknown function in ifeq: %s", x.name), true
+ }
+ case *badExpr:
+ return x, true
+ default:
+ return nil, false
+ }
+}
+
+func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive,
+ filterFuncCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr {
+ // We handle:
+ // * ifeq/ifneq (,$(filter v1 v2 ..., EXPR) becomes if EXPR not in/in ["v1", "v2", ...]
+ // * ifeq/ifneq (,$(filter EXPR, v1 v2 ...) becomes if EXPR not in/in ["v1", "v2", ...]
+ // * ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...) becomes if VAR in/not in ["v1", "v2"]
+ // TODO(Asmundak): check the last case works for filter-out, too.
+ xPattern := filterFuncCall.args[0]
+ xText := filterFuncCall.args[1]
+ var xInList *stringLiteralExpr
+ var expr starlarkExpr
+ var ok bool
+ switch x := xValue.(type) {
+ case *stringLiteralExpr:
+ if x.literal != "" {
+ return ctx.newBadExpr(cond, "filter comparison to non-empty value: %s", xValue)
+ }
+ // Either pattern or text should be const, and the
+ // non-const one should be varRefExpr
+ if xInList, ok = xPattern.(*stringLiteralExpr); ok {
+ expr = xText
+ } else if xInList, ok = xText.(*stringLiteralExpr); ok {
+ expr = xPattern
+ } else {
+ return &callExpr{
+ object: nil,
+ name: filterFuncCall.name,
+ args: filterFuncCall.args,
+ returnType: starlarkTypeBool,
+ }
+ }
+ case *variableRefExpr:
+ if v, ok := xPattern.(*variableRefExpr); ok {
+ if xInList, ok = xText.(*stringLiteralExpr); ok && v.ref.name() == x.ref.name() {
+ // ifeq/ifneq ($(VAR),$(filter $(VAR), v1 v2 ...), flip negate,
+ // it's the opposite to what is done when comparing to empty.
+ expr = xPattern
+ negate = !negate
+ }
+ }
+ }
+ if expr != nil && xInList != nil {
+ slExpr := newStringListExpr(strings.Fields(xInList.literal))
+ // Generate simpler code for the common cases:
+ if expr.typ() == starlarkTypeList {
+ if len(slExpr.items) == 1 {
+ // Checking that a string belongs to list
+ return &inExpr{isNot: negate, list: expr, expr: slExpr.items[0]}
+ } else {
+ // TODO(asmundak):
+ panic("TBD")
+ }
+ } else if len(slExpr.items) == 1 {
+ return &eqExpr{left: expr, right: slExpr.items[0], isEq: !negate}
+ } else {
+ return &inExpr{isNot: negate, list: newStringListExpr(strings.Fields(xInList.literal)), expr: expr}
+ }
+ }
+ return ctx.newBadExpr(cond, "filter arguments are too complex: %s", cond.Dump())
+}
+
+func (ctx *parseContext) parseCompareWildcardFuncResult(directive *mkparser.Directive,
+ xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr {
+ if !isEmptyString(xValue) {
+ return ctx.newBadExpr(directive, "wildcard result can be compared only to empty: %s", xValue)
+ }
+ callFunc := wildcardExistsPhony
+ if s, ok := xCall.args[0].(*stringLiteralExpr); ok && !strings.ContainsAny(s.literal, "*?{[") {
+ callFunc = fileExistsPhony
+ }
+ var cc starlarkExpr = &callExpr{name: callFunc, args: xCall.args, returnType: starlarkTypeBool}
+ if !negate {
+ cc = ¬Expr{cc}
+ }
+ return cc
+}
+
+func (ctx *parseContext) parseCheckFindstringFuncResult(directive *mkparser.Directive,
+ xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr {
+ if isEmptyString(xValue) {
+ return &eqExpr{
+ left: &callExpr{
+ object: xCall.args[1],
+ name: "find",
+ args: []starlarkExpr{xCall.args[0]},
+ returnType: starlarkTypeInt,
+ },
+ right: &intLiteralExpr{-1},
+ isEq: !negate,
+ }
+ }
+ return ctx.newBadExpr(directive, "findstring result can be compared only to empty: %s", xValue)
+}
+
+func (ctx *parseContext) parseCompareStripFuncResult(directive *mkparser.Directive,
+ xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr {
+ if _, ok := xValue.(*stringLiteralExpr); !ok {
+ return ctx.newBadExpr(directive, "strip result can be compared only to string: %s", xValue)
+ }
+ return &eqExpr{
+ left: &callExpr{
+ name: "strip",
+ args: xCall.args,
+ returnType: starlarkTypeString,
+ },
+ right: xValue, isEq: !negate}
+}
+
+// parses $(...), returning an expression
+func (ctx *parseContext) parseReference(node mkparser.Node, ref *mkparser.MakeString) starlarkExpr {
+ ref.TrimLeftSpaces()
+ ref.TrimRightSpaces()
+ refDump := ref.Dump()
+
+ // Handle only the case where the first (or only) word is constant
+ words := ref.SplitN(" ", 2)
+ if !words[0].Const() {
+ return ctx.newBadExpr(node, "reference is too complex: %s", refDump)
+ }
+
+ // If it is a single word, it can be a simple variable
+ // reference or a function call
+ if len(words) == 1 {
+ if isMakeControlFunc(refDump) || refDump == "shell" {
+ return &callExpr{
+ name: refDump,
+ args: []starlarkExpr{&stringLiteralExpr{""}},
+ returnType: starlarkTypeUnknown,
+ }
+ }
+ if v := ctx.addVariable(refDump); v != nil {
+ return &variableRefExpr{v, ctx.lastAssignment(v.name()) != nil}
+ }
+ return ctx.newBadExpr(node, "unknown variable %s", refDump)
+ }
+
+ expr := &callExpr{name: words[0].Dump(), returnType: starlarkTypeUnknown}
+ args := words[1]
+ args.TrimLeftSpaces()
+ // Make control functions and shell need special treatment as everything
+ // after the name is a single text argument
+ if isMakeControlFunc(expr.name) || expr.name == "shell" {
+ x := ctx.parseMakeString(node, args)
+ if xBad, ok := x.(*badExpr); ok {
+ return xBad
+ }
+ expr.args = []starlarkExpr{x}
+ return expr
+ }
+ if expr.name == "call" {
+ words = args.SplitN(",", 2)
+ if words[0].Empty() || !words[0].Const() {
+ return ctx.newBadExpr(node, "cannot handle %s", refDump)
+ }
+ expr.name = words[0].Dump()
+ if len(words) < 2 {
+ args = &mkparser.MakeString{}
+ } else {
+ args = words[1]
+ }
+ }
+ if kf, found := knownFunctions[expr.name]; found {
+ expr.returnType = kf.returnType
+ } else {
+ return ctx.newBadExpr(node, "cannot handle invoking %s", expr.name)
+ }
+ switch expr.name {
+ case "word":
+ return ctx.parseWordFunc(node, args)
+ case "firstword", "lastword":
+ return ctx.parseFirstOrLastwordFunc(node, expr.name, args)
+ case "my-dir":
+ return &variableRefExpr{ctx.addVariable("LOCAL_PATH"), true}
+ case "subst", "patsubst":
+ return ctx.parseSubstFunc(node, expr.name, args)
+ default:
+ for _, arg := range args.Split(",") {
+ arg.TrimLeftSpaces()
+ arg.TrimRightSpaces()
+ x := ctx.parseMakeString(node, arg)
+ if xBad, ok := x.(*badExpr); ok {
+ return xBad
+ }
+ expr.args = append(expr.args, x)
+ }
+ }
+ return expr
+}
+
+func (ctx *parseContext) parseSubstFunc(node mkparser.Node, fname string, args *mkparser.MakeString) starlarkExpr {
+ words := args.Split(",")
+ if len(words) != 3 {
+ return ctx.newBadExpr(node, "%s function should have 3 arguments", fname)
+ }
+ if !words[0].Const() || !words[1].Const() {
+ return ctx.newBadExpr(node, "%s function's from and to arguments should be constant", fname)
+ }
+ from := words[0].Strings[0]
+ to := words[1].Strings[0]
+ words[2].TrimLeftSpaces()
+ words[2].TrimRightSpaces()
+ obj := ctx.parseMakeString(node, words[2])
+ typ := obj.typ()
+ if typ == starlarkTypeString && fname == "subst" {
+ // Optimization: if it's $(subst from, to, string), emit string.replace(from, to)
+ return &callExpr{
+ object: obj,
+ name: "replace",
+ args: []starlarkExpr{&stringLiteralExpr{from}, &stringLiteralExpr{to}},
+ returnType: typ,
+ }
+ }
+ return &callExpr{
+ name: fname,
+ args: []starlarkExpr{&stringLiteralExpr{from}, &stringLiteralExpr{to}, obj},
+ returnType: obj.typ(),
+ }
+}
+
+func (ctx *parseContext) parseWordFunc(node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
+ words := args.Split(",")
+ if len(words) != 2 {
+ return ctx.newBadExpr(node, "word function should have 2 arguments")
+ }
+ var index uint64 = 0
+ if words[0].Const() {
+ index, _ = strconv.ParseUint(strings.TrimSpace(words[0].Strings[0]), 10, 64)
+ }
+ if index < 1 {
+ return ctx.newBadExpr(node, "word index should be constant positive integer")
+ }
+ words[1].TrimLeftSpaces()
+ words[1].TrimRightSpaces()
+ array := ctx.parseMakeString(node, words[1])
+ if xBad, ok := array.(*badExpr); ok {
+ return xBad
+ }
+ if array.typ() != starlarkTypeList {
+ array = &callExpr{object: array, name: "split", returnType: starlarkTypeList}
+ }
+ return indexExpr{array, &intLiteralExpr{int(index - 1)}}
+}
+
+func (ctx *parseContext) parseFirstOrLastwordFunc(node mkparser.Node, name string, args *mkparser.MakeString) starlarkExpr {
+ arg := ctx.parseMakeString(node, args)
+ if bad, ok := arg.(*badExpr); ok {
+ return bad
+ }
+ index := &intLiteralExpr{0}
+ if name == "lastword" {
+ if v, ok := arg.(*variableRefExpr); ok && v.ref.name() == "MAKEFILE_LIST" {
+ return &stringLiteralExpr{ctx.script.mkFile}
+ }
+ index.literal = -1
+ }
+ if arg.typ() == starlarkTypeList {
+ return &indexExpr{arg, index}
+ }
+ return &indexExpr{&callExpr{object: arg, name: "split", returnType: starlarkTypeList}, index}
+}
+
+func (ctx *parseContext) parseMakeString(node mkparser.Node, mk *mkparser.MakeString) starlarkExpr {
+ if mk.Const() {
+ return &stringLiteralExpr{mk.Dump()}
+ }
+ if mkRef, ok := mk.SingleVariable(); ok {
+ return ctx.parseReference(node, mkRef)
+ }
+ // If we reached here, it's neither string literal nor a simple variable,
+ // we need a full-blown interpolation node that will generate
+ // "a%b%c" % (X, Y) for a$(X)b$(Y)c
+ xInterp := &interpolateExpr{args: make([]starlarkExpr, len(mk.Variables))}
+ for i, ref := range mk.Variables {
+ arg := ctx.parseReference(node, ref.Name)
+ if x, ok := arg.(*badExpr); ok {
+ return x
+ }
+ xInterp.args[i] = arg
+ }
+ xInterp.chunks = append(xInterp.chunks, mk.Strings...)
+ return xInterp
+}
+
+// Handles the statements whose treatment is the same in all contexts: comment,
+// assignment, variable (which is a macro call in reality) and all constructs that
+// do not handle in any context ('define directive and any unrecognized stuff).
+// Return true if we handled it.
+func (ctx *parseContext) handleSimpleStatement(node mkparser.Node) bool {
+ handled := true
+ switch x := node.(type) {
+ case *mkparser.Comment:
+ ctx.insertComment("#" + x.Comment)
+ case *mkparser.Assignment:
+ ctx.handleAssignment(x)
+ case *mkparser.Variable:
+ ctx.handleVariable(x)
+ case *mkparser.Directive:
+ switch x.Name {
+ case "define":
+ ctx.handleDefine(x)
+ case "include", "-include":
+ ctx.handleInclude(node, ctx.parseMakeString(node, x.Args), x.Name[0] != '-')
+ default:
+ handled = false
+ }
+ default:
+ ctx.errorf(x, "unsupported line %s", x.Dump())
+ }
+ return handled
+}
+
+func (ctx *parseContext) insertComment(s string) {
+ ctx.receiver.newNode(&commentNode{strings.TrimSpace(s)})
+}
+
+func (ctx *parseContext) carryAsComment(failedNode mkparser.Node) {
+ for _, line := range strings.Split(failedNode.Dump(), "\n") {
+ ctx.insertComment("# " + line)
+ }
+}
+
+// records that the given node failed to be converted and includes an explanatory message
+func (ctx *parseContext) errorf(failedNode mkparser.Node, message string, args ...interface{}) {
+ if ctx.errorLogger != nil {
+ ctx.errorLogger.NewError(message, failedNode, args...)
+ }
+ message = fmt.Sprintf(message, args...)
+ ctx.insertComment(fmt.Sprintf("# MK2RBC TRANSLATION ERROR: %s", message))
+ ctx.carryAsComment(failedNode)
+ ctx.script.hasErrors = true
+}
+
+func (ctx *parseContext) wrapBadExpr(xBad *badExpr) {
+ ctx.insertComment(fmt.Sprintf("# MK2RBC TRANSLATION ERROR: %s", xBad.message))
+ ctx.carryAsComment(xBad.node)
+}
+
+func (ctx *parseContext) loadedModulePath(path string) string {
+ // During the transition to Roboleaf some of the product configuration files
+ // will be converted and checked in while the others will be generated on the fly
+ // and run. The runner (rbcrun application) accommodates this by allowing three
+ // different ways to specify the loaded file location:
+ // 1) load(":<file>",...) loads <file> from the same directory
+ // 2) load("//path/relative/to/source/root:<file>", ...) loads <file> source tree
+ // 3) load("/absolute/path/to/<file> absolute path
+ // If the file being generated and the file it wants to load are in the same directory,
+ // generate option 1.
+ // Otherwise, if output directory is not specified, generate 2)
+ // Finally, if output directory has been specified and the file being generated and
+ // the file it wants to load from are in the different directories, generate 2) or 3):
+ // * if the file being loaded exists in the source tree, generate 2)
+ // * otherwise, generate 3)
+ // Finally, figure out the loaded module path and name and create a node for it
+ loadedModuleDir := filepath.Dir(path)
+ base := filepath.Base(path)
+ loadedModuleName := strings.TrimSuffix(base, filepath.Ext(base)) + ctx.outputSuffix
+ if loadedModuleDir == filepath.Dir(ctx.script.mkFile) {
+ return ":" + loadedModuleName
+ }
+ if ctx.outputDir == "" {
+ return fmt.Sprintf("//%s:%s", loadedModuleDir, loadedModuleName)
+ }
+ if _, err := os.Stat(filepath.Join(loadedModuleDir, loadedModuleName)); err == nil {
+ return fmt.Sprintf("//%s:%s", loadedModuleDir, loadedModuleName)
+ }
+ return filepath.Join(ctx.outputDir, loadedModuleDir, loadedModuleName)
+}
+
+func (ctx *parseContext) addSoongNamespace(ns string) {
+ if _, ok := ctx.soongNamespaces[ns]; ok {
+ return
+ }
+ ctx.soongNamespaces[ns] = make(map[string]bool)
+}
+
+func (ctx *parseContext) hasSoongNamespace(name string) bool {
+ _, ok := ctx.soongNamespaces[name]
+ return ok
+}
+
+func (ctx *parseContext) updateSoongNamespace(replace bool, namespaceName string, varNames []string) {
+ ctx.addSoongNamespace(namespaceName)
+ vars := ctx.soongNamespaces[namespaceName]
+ if replace {
+ vars = make(map[string]bool)
+ ctx.soongNamespaces[namespaceName] = vars
+ }
+ for _, v := range varNames {
+ vars[v] = true
+ }
+}
+
+func (ctx *parseContext) hasNamespaceVar(namespaceName string, varName string) bool {
+ vars, ok := ctx.soongNamespaces[namespaceName]
+ if ok {
+ _, ok = vars[varName]
+ }
+ return ok
+}
+
+func (ss *StarlarkScript) String() string {
+ return NewGenerateContext(ss).emit()
+}
+
+func (ss *StarlarkScript) SubConfigFiles() []string {
+
+ var subs []string
+ for _, src := range ss.inherited {
+ subs = append(subs, src.originalPath)
+ }
+ return subs
+}
+
+func (ss *StarlarkScript) HasErrors() bool {
+ return ss.hasErrors
+}
+
+// Convert reads and parses a makefile. If successful, parsed tree
+// is returned and then can be passed to String() to get the generated
+// Starlark file.
+func Convert(req Request) (*StarlarkScript, error) {
+ reader := req.Reader
+ if reader == nil {
+ mkContents, err := ioutil.ReadFile(req.MkFile)
+ if err != nil {
+ return nil, err
+ }
+ reader = bytes.NewBuffer(mkContents)
+ }
+ parser := mkparser.NewParser(req.MkFile, reader)
+ nodes, errs := parser.Parse()
+ if len(errs) > 0 {
+ for _, e := range errs {
+ fmt.Fprintln(os.Stderr, "ERROR:", e)
+ }
+ return nil, fmt.Errorf("bad makefile %s", req.MkFile)
+ }
+ starScript := &StarlarkScript{
+ moduleName: moduleNameForFile(req.MkFile),
+ mkFile: req.MkFile,
+ topDir: req.RootDir,
+ traceCalls: req.TraceCalls,
+ warnPartialSuccess: req.WarnPartialSuccess,
+ sourceFS: req.SourceFS,
+ makefileFinder: req.MakefileFinder,
+ }
+ ctx := newParseContext(starScript, nodes)
+ ctx.outputSuffix = req.OutputSuffix
+ ctx.outputDir = req.OutputDir
+ ctx.errorLogger = req.ErrorLogger
+ if len(req.TracedVariables) > 0 {
+ ctx.tracedVariables = make(map[string]bool)
+ for _, v := range req.TracedVariables {
+ ctx.tracedVariables[v] = true
+ }
+ }
+ ctx.pushReceiver(starScript)
+ for ctx.hasNodes() && ctx.fatalError == nil {
+ node := ctx.getNode()
+ if ctx.handleSimpleStatement(node) {
+ continue
+ }
+ switch x := node.(type) {
+ case *mkparser.Directive:
+ switch x.Name {
+ case "ifeq", "ifneq", "ifdef", "ifndef":
+ ctx.handleIfBlock(x)
+ default:
+ ctx.errorf(x, "unexpected directive %s", x.Name)
+ }
+ default:
+ ctx.errorf(x, "unsupported line")
+ }
+ }
+ if ctx.fatalError != nil {
+ return nil, ctx.fatalError
+ }
+ return starScript, nil
+}
+
+func Launcher(path, name string) string {
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "load(%q, %q)\n", baseUri, baseName)
+ fmt.Fprintf(&buf, "load(%q, \"init\")\n", path)
+ fmt.Fprintf(&buf, "g, config = %s(%q, init)\n", cfnMain, name)
+ fmt.Fprintf(&buf, "%s(g, config)\n", cfnPrintVars)
+ return buf.String()
+}
+
+func MakePath2ModuleName(mkPath string) string {
+ return strings.TrimSuffix(mkPath, filepath.Ext(mkPath))
+}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
new file mode 100644
index 0000000..a14c7a4
--- /dev/null
+++ b/mk2rbc/mk2rbc_test.go
@@ -0,0 +1,1007 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "bytes"
+ "io/fs"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+var testCases = []struct {
+ desc string
+ mkname string
+ in string
+ expected string
+}{
+ {
+ desc: "Comment",
+ mkname: "product.mk",
+ in: `
+# Comment
+# FOO= a\
+ b
+`,
+ expected: `# Comment
+# FOO= a
+# b
+load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+`,
+ },
+ {
+ desc: "Name conversion",
+ mkname: "path/bar-baz.mk",
+ in: `
+# Comment
+`,
+ expected: `# Comment
+load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+`,
+ },
+ {
+ desc: "Item variable",
+ mkname: "pixel3.mk",
+ in: `
+PRODUCT_NAME := Pixel 3
+PRODUCT_MODEL :=
+local_var = foo
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_NAME"] = "Pixel 3"
+ cfg["PRODUCT_MODEL"] = ""
+ _local_var = "foo"
+`,
+ },
+ {
+ desc: "List variable",
+ mkname: "pixel4.mk",
+ in: `
+PRODUCT_PACKAGES = package1 package2
+PRODUCT_COPY_FILES += file2:target
+PRODUCT_PACKAGES += package3
+PRODUCT_COPY_FILES =
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_PACKAGES"] = [
+ "package1",
+ "package2",
+ ]
+ rblf.setdefault(handle, "PRODUCT_COPY_FILES")
+ cfg["PRODUCT_COPY_FILES"] += ["file2:target"]
+ cfg["PRODUCT_PACKAGES"] += ["package3"]
+ cfg["PRODUCT_COPY_FILES"] = []
+`,
+ },
+ {
+ desc: "Unknown function",
+ mkname: "product.mk",
+ in: `
+PRODUCT_NAME := $(call foo1, bar)
+PRODUCT_NAME := $(call foo0)
+`,
+ expected: `# MK2RBC TRANSLATION ERROR: cannot handle invoking foo1
+# PRODUCT_NAME := $(call foo1, bar)
+# MK2RBC TRANSLATION ERROR: cannot handle invoking foo0
+# PRODUCT_NAME := $(call foo0)
+load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ rblf.warning("product.mk", "partially successful conversion")
+`,
+ },
+ {
+ desc: "Inherit configuration always",
+ mkname: "product.mk",
+ in: `
+ifdef PRODUCT_NAME
+$(call inherit-product, part.mk)
+else # Comment
+$(call inherit-product, $(LOCAL_PATH)/part.mk)
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+load(":part.star", _part_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g.get("PRODUCT_NAME") != None:
+ rblf.inherit(handle, "part", _part_init)
+ else:
+ # Comment
+ rblf.inherit(handle, "part", _part_init)
+`,
+ },
+ {
+ desc: "Inherit configuration if it exists",
+ mkname: "product.mk",
+ in: `
+$(call inherit-product-if-exists, part.mk)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+load(":part.star|init", _part_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if _part_init:
+ rblf.inherit(handle, "part", _part_init)
+`,
+ },
+
+ {
+ desc: "Include configuration",
+ mkname: "product.mk",
+ in: `
+ifdef PRODUCT_NAME
+include part.mk
+else
+-include $(LOCAL_PATH)/part.mk)
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+load(":part.star|init", _part_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g.get("PRODUCT_NAME") != None:
+ _part_init(g, handle)
+ else:
+ if _part_init != None:
+ _part_init(g, handle)
+`,
+ },
+
+ {
+ desc: "Synonymous inherited configurations",
+ mkname: "path/product.mk",
+ in: `
+$(call inherit-product, */font.mk)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+load("//foo:font.star", _font_init = "init")
+load("//bar:font.star", _font1_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ rblf.inherit(handle, "foo/font", _font_init)
+ rblf.inherit(handle, "bar/font", _font1_init)
+`,
+ },
+ {
+ desc: "Directive define",
+ mkname: "product.mk",
+ in: `
+define some-macro
+ $(info foo)
+endef
+`,
+ expected: `# MK2RBC TRANSLATION ERROR: define is not supported: some-macro
+# define some-macro
+# $(info foo)
+# endef
+load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ rblf.warning("product.mk", "partially successful conversion")
+`,
+ },
+ {
+ desc: "Ifdef",
+ mkname: "product.mk",
+ in: `
+ifdef PRODUCT_NAME
+ PRODUCT_NAME = gizmo
+else
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g.get("PRODUCT_NAME") != None:
+ cfg["PRODUCT_NAME"] = "gizmo"
+ else:
+ pass
+`,
+ },
+ {
+ desc: "Simple functions",
+ mkname: "product.mk",
+ in: `
+$(warning this is the warning)
+$(warning)
+$(info this is the info)
+$(error this is the error)
+PRODUCT_NAME:=$(shell echo *)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ rblf.mkwarning("product.mk", "this is the warning")
+ rblf.mkwarning("product.mk", "")
+ rblf.mkinfo("product.mk", "this is the info")
+ rblf.mkerror("product.mk", "this is the error")
+ cfg["PRODUCT_NAME"] = rblf.shell("echo *")
+`,
+ },
+ {
+ desc: "Empty if",
+ mkname: "product.mk",
+ in: `
+ifdef PRODUCT_NAME
+# Comment
+else
+ TARGET_COPY_OUT_VENDOR := foo
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g.get("PRODUCT_NAME") != None:
+ # Comment
+ pass
+ else:
+ # MK2RBC TRANSLATION ERROR: cannot set predefined variable TARGET_COPY_OUT_VENDOR to "foo", its value should be "||VENDOR-PATH-PH||"
+ pass
+ rblf.warning("product.mk", "partially successful conversion")
+`,
+ },
+ {
+ desc: "if/else/endif",
+ mkname: "product.mk",
+ in: `
+ifndef PRODUCT_NAME
+ PRODUCT_NAME=gizmo1
+else
+ PRODUCT_NAME=gizmo2
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if not g.get("PRODUCT_NAME") != None:
+ cfg["PRODUCT_NAME"] = "gizmo1"
+ else:
+ cfg["PRODUCT_NAME"] = "gizmo2"
+`,
+ },
+ {
+ desc: "else if",
+ mkname: "product.mk",
+ in: `
+ifdef PRODUCT_NAME
+ PRODUCT_NAME = gizmo
+else ifndef PRODUCT_PACKAGES # Comment
+endif
+ `,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g.get("PRODUCT_NAME") != None:
+ cfg["PRODUCT_NAME"] = "gizmo"
+ elif not g.get("PRODUCT_PACKAGES") != None:
+ # Comment
+ pass
+`,
+ },
+ {
+ desc: "ifeq / ifneq",
+ mkname: "product.mk",
+ in: `
+ifeq (aosp_arm, $(TARGET_PRODUCT))
+ PRODUCT_MODEL = pix2
+else
+ PRODUCT_MODEL = pix21
+endif
+ifneq (aosp_x86, $(TARGET_PRODUCT))
+ PRODUCT_MODEL = pix3
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if "aosp_arm" == g["TARGET_PRODUCT"]:
+ cfg["PRODUCT_MODEL"] = "pix2"
+ else:
+ cfg["PRODUCT_MODEL"] = "pix21"
+ if "aosp_x86" != g["TARGET_PRODUCT"]:
+ cfg["PRODUCT_MODEL"] = "pix3"
+`,
+ },
+ {
+ desc: "Check filter result",
+ mkname: "product.mk",
+ in: `
+ifeq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
+endif
+ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT))
+endif
+ifneq (,$(filter plaf,$(PLATFORM_LIST)))
+endif
+ifeq ($(TARGET_BUILD_VARIANT), $(filter $(TARGET_BUILD_VARIANT), userdebug eng))
+endif
+ifneq (,$(filter true, $(v1)$(v2)))
+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"]:
+ pass
+ if g["TARGET_BUILD_VARIANT"] == "userdebug":
+ pass
+ if "plaf" in g.get("PLATFORM_LIST", []):
+ pass
+ if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]:
+ pass
+ if "%s%s" % (_v1, _v2) == "true":
+ pass
+`,
+ },
+ {
+ desc: "Get filter result",
+ mkname: "product.mk",
+ in: `
+PRODUCT_LIST2=$(filter-out %/foo.ko,$(wildcard path/*.ko))
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_LIST2"] = rblf.filter_out("%/foo.ko", rblf.expand_wildcard("path/*.ko"))
+`,
+ },
+ {
+ desc: "filter $(VAR), values",
+ mkname: "product.mk",
+ in: `
+ifeq (,$(filter $(TARGET_PRODUCT), yukawa_gms yukawa_sei510_gms)
+ ifneq (,$(filter $(TARGET_PRODUCT), yukawa_gms)
+ endif
+endif
+
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g["TARGET_PRODUCT"] not in ["yukawa_gms", "yukawa_sei510_gms"]:
+ if g["TARGET_PRODUCT"] == "yukawa_gms":
+ pass
+`,
+ },
+ {
+ desc: "filter $(V1), $(V2)",
+ mkname: "product.mk",
+ in: `
+ifneq (, $(filter $(PRODUCT_LIST), $(TARGET_PRODUCT)))
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if rblf.filter(g.get("PRODUCT_LIST", ""), g["TARGET_PRODUCT"]):
+ pass
+`,
+ },
+ {
+ desc: "ifeq",
+ mkname: "product.mk",
+ in: `
+ifeq (aosp, $(TARGET_PRODUCT)) # Comment
+else ifneq (, $(TARGET_PRODUCT))
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if "aosp" == g["TARGET_PRODUCT"]:
+ # Comment
+ pass
+ elif g["TARGET_PRODUCT"]:
+ pass
+`,
+ },
+ {
+ desc: "Nested if",
+ mkname: "product.mk",
+ in: `
+ifdef PRODUCT_NAME
+ PRODUCT_PACKAGES = pack-if0
+ ifdef PRODUCT_MODEL
+ PRODUCT_PACKAGES = pack-if-if
+ else ifdef PRODUCT_NAME
+ PRODUCT_PACKAGES = pack-if-elif
+ else
+ PRODUCT_PACKAGES = pack-if-else
+ endif
+ PRODUCT_PACKAGES = pack-if
+else ifneq (,$(TARGET_PRODUCT))
+ PRODUCT_PACKAGES = pack-elif
+else
+ PRODUCT_PACKAGES = pack-else
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g.get("PRODUCT_NAME") != None:
+ cfg["PRODUCT_PACKAGES"] = ["pack-if0"]
+ if g.get("PRODUCT_MODEL") != None:
+ cfg["PRODUCT_PACKAGES"] = ["pack-if-if"]
+ elif g.get("PRODUCT_NAME") != None:
+ cfg["PRODUCT_PACKAGES"] = ["pack-if-elif"]
+ else:
+ cfg["PRODUCT_PACKAGES"] = ["pack-if-else"]
+ cfg["PRODUCT_PACKAGES"] = ["pack-if"]
+ elif g["TARGET_PRODUCT"]:
+ cfg["PRODUCT_PACKAGES"] = ["pack-elif"]
+ else:
+ cfg["PRODUCT_PACKAGES"] = ["pack-else"]
+`,
+ },
+ {
+ desc: "Wildcard",
+ mkname: "product.mk",
+ in: `
+ifeq (,$(wildcard foo.mk))
+endif
+ifneq (,$(wildcard foo*.mk))
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if not rblf.file_exists("foo.mk"):
+ pass
+ if rblf.file_wildcard_exists("foo*.mk"):
+ pass
+`,
+ },
+ {
+ desc: "ifneq $(X),true",
+ mkname: "product.mk",
+ in: `
+ifneq ($(VARIABLE),true)
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g.get("VARIABLE", "") != "true":
+ pass
+`,
+ },
+ {
+ desc: "Const neq",
+ mkname: "product.mk",
+ in: `
+ifneq (1,0)
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if "1" != "0":
+ pass
+`,
+ },
+ {
+ desc: "is-board calls",
+ mkname: "product.mk",
+ in: `
+ifeq ($(call is-board-platform-in-list,msm8998), true)
+else ifneq ($(call is-board-platform,copper),true)
+else ifneq ($(call is-vendor-board-platform,QCOM),true)
+else ifeq ($(call is-product-in-list, $(PLATFORM_LIST)), true)
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if g.get("TARGET_BOARD_PLATFORM", "") in ["msm8998"]:
+ pass
+ elif g.get("TARGET_BOARD_PLATFORM", "") != "copper":
+ pass
+ elif g.get("TARGET_BOARD_PLATFORM", "") not in g["QCOM_BOARD_PLATFORMS"]:
+ pass
+ elif g["TARGET_PRODUCT"] in g.get("PLATFORM_LIST", []):
+ pass
+`,
+ },
+ {
+ desc: "findstring call",
+ mkname: "product.mk",
+ in: `
+ifneq ($(findstring foo,$(PRODUCT_PACKAGES)),)
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") != -1:
+ pass
+`,
+ },
+ {
+ desc: "rhs call",
+ mkname: "product.mk",
+ in: `
+PRODUCT_COPY_FILES = $(call add-to-product-copy-files-if-exists, path:distpath) \
+ $(call find-copy-subdir-files, *, fromdir, todir) $(wildcard foo.*)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_COPY_FILES"] = (rblf.copy_if_exists("path:distpath") +
+ rblf.find_and_copy("*", "fromdir", "todir") +
+ rblf.expand_wildcard("foo.*"))
+`,
+ },
+ {
+ desc: "inferred type",
+ mkname: "product.mk",
+ in: `
+HIKEY_MODS := $(wildcard foo/*.ko)
+BOARD_VENDOR_KERNEL_MODULES += $(HIKEY_MODS)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["HIKEY_MODS"] = rblf.expand_wildcard("foo/*.ko")
+ g.setdefault("BOARD_VENDOR_KERNEL_MODULES", [])
+ g["BOARD_VENDOR_KERNEL_MODULES"] += g["HIKEY_MODS"]
+`,
+ },
+ {
+ desc: "list with vars",
+ mkname: "product.mk",
+ in: `
+PRODUCT_COPY_FILES += path1:$(TARGET_PRODUCT)/path1 $(PRODUCT_MODEL)/path2:$(TARGET_PRODUCT)/path2
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ rblf.setdefault(handle, "PRODUCT_COPY_FILES")
+ cfg["PRODUCT_COPY_FILES"] += (("path1:%s/path1" % g["TARGET_PRODUCT"]).split() +
+ ("%s/path2:%s/path2" % (cfg.get("PRODUCT_MODEL", ""), g["TARGET_PRODUCT"])).split())
+`,
+ },
+ {
+ desc: "misc calls",
+ mkname: "product.mk",
+ in: `
+$(call enforce-product-packages-exist,)
+$(call enforce-product-packages-exist, foo)
+$(call require-artifacts-in-path, foo, bar)
+$(call require-artifacts-in-path-relaxed, foo, bar)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ rblf.enforce_product_packages_exist("")
+ rblf.enforce_product_packages_exist("foo")
+ rblf.require_artifacts_in_path("foo", "bar")
+ rblf.require_artifacts_in_path_relaxed("foo", "bar")
+`,
+ },
+ {
+ desc: "list with functions",
+ mkname: "product.mk",
+ in: `
+PRODUCT_COPY_FILES := $(call find-copy-subdir-files,*.kl,from1,to1) \
+ $(call find-copy-subdir-files,*.kc,from2,to2) \
+ foo bar
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_COPY_FILES"] = (rblf.find_and_copy("*.kl", "from1", "to1") +
+ rblf.find_and_copy("*.kc", "from2", "to2") +
+ [
+ "foo",
+ "bar",
+ ])
+`,
+ },
+ {
+ desc: "Text functions",
+ mkname: "product.mk",
+ in: `
+PRODUCT_COPY_FILES := $(addprefix pfx-,a b c)
+PRODUCT_COPY_FILES := $(addsuffix .sff, a b c)
+PRODUCT_NAME := $(word 1, $(subst ., ,$(TARGET_BOARD_PLATFORM)))
+$(info $(patsubst %.pub,%,$(PRODUCT_ADB_KEYS)))
+$(info $(dir foo/bar))
+$(info $(firstword $(PRODUCT_COPY_FILES)))
+$(info $(lastword $(PRODUCT_COPY_FILES)))
+$(info $(dir $(lastword $(MAKEFILE_LIST))))
+$(info $(dir $(lastword $(PRODUCT_COPY_FILES))))
+$(info $(dir $(lastword $(foobar))))
+$(info $(abspath foo/bar))
+$(info $(notdir foo/bar))
+$(call add_soong_config_namespace,snsconfig)
+$(call add_soong_config_var_value,snsconfig,imagetype,odm_image)
+PRODUCT_COPY_FILES := $(call copy-files,$(wildcard foo*.mk),etc)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_COPY_FILES"] = rblf.addprefix("pfx-", "a b c")
+ cfg["PRODUCT_COPY_FILES"] = rblf.addsuffix(".sff", "a b c")
+ cfg["PRODUCT_NAME"] = ((g.get("TARGET_BOARD_PLATFORM", "")).replace(".", " ")).split()[0]
+ rblf.mkinfo("product.mk", rblf.mkpatsubst("%.pub", "%", g.get("PRODUCT_ADB_KEYS", "")))
+ rblf.mkinfo("product.mk", rblf.dir("foo/bar"))
+ rblf.mkinfo("product.mk", cfg["PRODUCT_COPY_FILES"][0])
+ rblf.mkinfo("product.mk", cfg["PRODUCT_COPY_FILES"][-1])
+ rblf.mkinfo("product.mk", rblf.dir("product.mk"))
+ rblf.mkinfo("product.mk", rblf.dir(cfg["PRODUCT_COPY_FILES"][-1]))
+ 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")
+ cfg["PRODUCT_COPY_FILES"] = rblf.copy_files(rblf.expand_wildcard("foo*.mk"), "etc")
+`,
+ },
+ {
+ desc: "subst in list",
+ mkname: "product.mk",
+ in: `
+files = $(call find-copy-subdir-files,*,from,to)
+PRODUCT_COPY_FILES += $(subst foo,bar,$(files))
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ _files = rblf.find_and_copy("*", "from", "to")
+ rblf.setdefault(handle, "PRODUCT_COPY_FILES")
+ cfg["PRODUCT_COPY_FILES"] += rblf.mksubst("foo", "bar", _files)
+`,
+ },
+ {
+ desc: "assignment flavors",
+ mkname: "product.mk",
+ in: `
+PRODUCT_LIST1 := a
+PRODUCT_LIST2 += a
+PRODUCT_LIST1 += b
+PRODUCT_LIST2 += b
+PRODUCT_LIST3 ?= a
+PRODUCT_LIST1 = c
+PLATFORM_LIST += x
+PRODUCT_PACKAGES := $(PLATFORM_LIST)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_LIST1"] = ["a"]
+ rblf.setdefault(handle, "PRODUCT_LIST2")
+ cfg["PRODUCT_LIST2"] += ["a"]
+ cfg["PRODUCT_LIST1"] += ["b"]
+ cfg["PRODUCT_LIST2"] += ["b"]
+ if cfg.get("PRODUCT_LIST3") == None:
+ cfg["PRODUCT_LIST3"] = ["a"]
+ cfg["PRODUCT_LIST1"] = ["c"]
+ g.setdefault("PLATFORM_LIST", [])
+ g["PLATFORM_LIST"] += ["x"]
+ cfg["PRODUCT_PACKAGES"] = g["PLATFORM_LIST"][:]
+`,
+ },
+ {
+ desc: "assigment flavors2",
+ mkname: "product.mk",
+ in: `
+PRODUCT_LIST1 = a
+ifeq (0,1)
+ PRODUCT_LIST1 += b
+ PRODUCT_LIST2 += b
+endif
+PRODUCT_LIST1 += c
+PRODUCT_LIST2 += c
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_LIST1"] = ["a"]
+ if "0" == "1":
+ cfg["PRODUCT_LIST1"] += ["b"]
+ rblf.setdefault(handle, "PRODUCT_LIST2")
+ cfg["PRODUCT_LIST2"] += ["b"]
+ cfg["PRODUCT_LIST1"] += ["c"]
+ rblf.setdefault(handle, "PRODUCT_LIST2")
+ cfg["PRODUCT_LIST2"] += ["c"]
+`,
+ },
+ {
+ desc: "soong namespace assignments",
+ mkname: "product.mk",
+ in: `
+SOONG_CONFIG_NAMESPACES += cvd
+SOONG_CONFIG_cvd += launch_configs
+SOONG_CONFIG_cvd_launch_configs += cvd_config_auto.json
+SOONG_CONFIG_cvd += grub_config
+SOONG_CONFIG_cvd_grub_config += grub.cfg
+`,
+ 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")
+`,
+ },
+ {
+ desc: "string split",
+ mkname: "product.mk",
+ in: `
+PRODUCT_LIST1 = a
+local = b
+local += c
+FOO = d
+FOO += e
+PRODUCT_LIST1 += $(local)
+PRODUCT_LIST1 += $(FOO)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_LIST1"] = ["a"]
+ _local = "b"
+ _local += " " + "c"
+ g["FOO"] = "d"
+ g["FOO"] += " " + "e"
+ cfg["PRODUCT_LIST1"] += (_local).split()
+ cfg["PRODUCT_LIST1"] += (g["FOO"]).split()
+`,
+ },
+ {
+ desc: "apex_jars",
+ mkname: "product.mk",
+ in: `
+PRODUCT_BOOT_JARS := $(ART_APEX_JARS) framework-minus-apex
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ cfg["PRODUCT_BOOT_JARS"] = (g.get("ART_APEX_JARS", []) +
+ ["framework-minus-apex"])
+`,
+ },
+ {
+ desc: "strip function",
+ mkname: "product.mk",
+ in: `
+ifeq ($(filter hwaddress,$(PRODUCT_PACKAGES)),)
+ PRODUCT_PACKAGES := $(strip $(PRODUCT_PACKAGES) hwaddress)
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if "hwaddress" not in cfg.get("PRODUCT_PACKAGES", []):
+ cfg["PRODUCT_PACKAGES"] = (rblf.mkstrip("%s hwaddress" % " ".join(cfg.get("PRODUCT_PACKAGES", [])))).split()
+`,
+ },
+ {
+ desc: "strip func in condition",
+ mkname: "product.mk",
+ in: `
+ifneq ($(strip $(TARGET_VENDOR)),)
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if rblf.mkstrip(g.get("TARGET_VENDOR", "")):
+ pass
+`,
+ },
+ {
+ desc: "ref after set",
+ mkname: "product.mk",
+ in: `
+PRODUCT_ADB_KEYS:=value
+FOO := $(PRODUCT_ADB_KEYS)
+ifneq (,$(PRODUCT_ADB_KEYS))
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["PRODUCT_ADB_KEYS"] = "value"
+ g["FOO"] = g["PRODUCT_ADB_KEYS"]
+ if g["PRODUCT_ADB_KEYS"]:
+ pass
+`,
+ },
+ {
+ desc: "ref before set",
+ mkname: "product.mk",
+ in: `
+V1 := $(PRODUCT_ADB_KEYS)
+ifeq (,$(PRODUCT_ADB_KEYS))
+ V2 := $(PRODUCT_ADB_KEYS)
+ PRODUCT_ADB_KEYS:=foo
+ V3 := $(PRODUCT_ADB_KEYS)
+endif`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["V1"] = g.get("PRODUCT_ADB_KEYS", "")
+ if not g.get("PRODUCT_ADB_KEYS", ""):
+ g["V2"] = g.get("PRODUCT_ADB_KEYS", "")
+ g["PRODUCT_ADB_KEYS"] = "foo"
+ g["V3"] = g["PRODUCT_ADB_KEYS"]
+`,
+ },
+ {
+ desc: "Dynamic inherit path",
+ mkname: "product.mk",
+ in: `
+MY_PATH=foo
+$(call inherit-product,vendor/$(MY_PATH)/cfg.mk)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
+load("//vendor/bar/baz:cfg.star|init", _cfg1_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["MY_PATH"] = "foo"
+ _entry = {
+ "vendor/foo1/cfg.mk": ("_cfg", _cfg_init),
+ "vendor/bar/baz/cfg.mk": ("_cfg1", _cfg1_init),
+ }.get("vendor/%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)
+`,
+ },
+}
+
+var known_variables = []struct {
+ name string
+ class varClass
+ starlarkType
+}{
+ {"PRODUCT_NAME", VarClassConfig, starlarkTypeString},
+ {"PRODUCT_MODEL", VarClassConfig, starlarkTypeString},
+ {"PRODUCT_PACKAGES", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_BOOT_JARS", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_COPY_FILES", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_IS_64BIT", VarClassConfig, starlarkTypeString},
+ {"PRODUCT_LIST1", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_LIST2", VarClassConfig, starlarkTypeList},
+ {"PRODUCT_LIST3", VarClassConfig, starlarkTypeList},
+ {"TARGET_PRODUCT", VarClassSoong, starlarkTypeString},
+ {"TARGET_BUILD_VARIANT", VarClassSoong, starlarkTypeString},
+ {"TARGET_BOARD_PLATFORM", VarClassSoong, starlarkTypeString},
+ {"QCOM_BOARD_PLATFORMS", VarClassSoong, starlarkTypeString},
+ {"PLATFORM_LIST", VarClassSoong, starlarkTypeList}, // TODO(asmundak): make it local instead of soong
+}
+
+type testMakefileFinder struct {
+ fs fs.FS
+ root string
+ files []string
+}
+
+func (t *testMakefileFinder) Find(root string) []string {
+ if t.files != nil || root == t.root {
+ return t.files
+ }
+ t.files = make([]string, 0)
+ fs.WalkDir(t.fs, root, func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if d.IsDir() {
+ base := filepath.Base(path)
+ if base[0] == '.' && len(base) > 1 {
+ return fs.SkipDir
+ }
+ return nil
+ }
+ if strings.HasSuffix(path, ".mk") {
+ t.files = append(t.files, path)
+ }
+ return nil
+ })
+ return t.files
+}
+
+func TestGood(t *testing.T) {
+ for _, v := range known_variables {
+ KnownVariables.NewVariable(v.name, v.class, v.starlarkType)
+ }
+ fs := NewFindMockFS([]string{
+ "vendor/foo1/cfg.mk",
+ "vendor/bar/baz/cfg.mk",
+ "part.mk",
+ "foo/font.mk",
+ "bar/font.mk",
+ })
+ for _, test := range testCases {
+ t.Run(test.desc,
+ func(t *testing.T) {
+ ss, err := Convert(Request{
+ MkFile: test.mkname,
+ Reader: bytes.NewBufferString(test.in),
+ RootDir: ".",
+ OutputSuffix: ".star",
+ WarnPartialSuccess: true,
+ SourceFS: fs,
+ MakefileFinder: &testMakefileFinder{fs: fs},
+ })
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ got := ss.String()
+ if got != test.expected {
+ t.Errorf("%q failed\nExpected:\n%s\nActual:\n%s\n", test.desc,
+ strings.ReplaceAll(test.expected, "\n", "\n"),
+ strings.ReplaceAll(got, "\n", "\n"))
+ }
+ })
+ }
+}
diff --git a/mk2rbc/node.go b/mk2rbc/node.go
new file mode 100644
index 0000000..8efe207
--- /dev/null
+++ b/mk2rbc/node.go
@@ -0,0 +1,306 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "fmt"
+ "strings"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+// A parsed node for which starlark code will be generated
+// by calling emit().
+type starlarkNode interface {
+ emit(ctx *generationContext)
+}
+
+// Types used to keep processed makefile data:
+type commentNode struct {
+ text string
+}
+
+func (c *commentNode) emit(gctx *generationContext) {
+ chunks := strings.Split(c.text, "\\\n")
+ gctx.newLine()
+ gctx.write(chunks[0]) // It has '#' at the beginning already.
+ for _, chunk := range chunks[1:] {
+ gctx.newLine()
+ gctx.write("#", chunk)
+ }
+}
+
+type moduleInfo struct {
+ path string // Converted Starlark file path
+ originalPath string // Makefile file path
+ moduleLocalName string
+ optional bool
+}
+
+func (im moduleInfo) entryName() string {
+ return im.moduleLocalName + "_init"
+}
+
+type inheritedModule interface {
+ name() string
+ entryName() string
+ emitSelect(gctx *generationContext)
+ isLoadAlways() bool
+}
+
+type inheritedStaticModule struct {
+ *moduleInfo
+ loadAlways bool
+}
+
+func (im inheritedStaticModule) name() string {
+ return fmt.Sprintf("%q", MakePath2ModuleName(im.originalPath))
+}
+
+func (im inheritedStaticModule) emitSelect(_ *generationContext) {
+}
+
+func (im inheritedStaticModule) isLoadAlways() bool {
+ return im.loadAlways
+}
+
+type inheritedDynamicModule struct {
+ path interpolateExpr
+ candidateModules []*moduleInfo
+ loadAlways bool
+}
+
+func (i inheritedDynamicModule) name() string {
+ return "_varmod"
+}
+
+func (i inheritedDynamicModule) entryName() string {
+ return i.name() + "_init"
+}
+
+func (i inheritedDynamicModule) emitSelect(gctx *generationContext) {
+ gctx.newLine()
+ gctx.writef("_entry = {")
+ gctx.indentLevel++
+ for _, mi := range i.candidateModules {
+ gctx.newLine()
+ gctx.writef(`"%s": (%q, %s),`, mi.originalPath, mi.moduleLocalName, mi.entryName())
+ }
+ gctx.indentLevel--
+ gctx.newLine()
+ gctx.write("}.get(")
+ i.path.emit(gctx)
+ gctx.write(")")
+ gctx.newLine()
+ gctx.writef("(%s, %s) = _entry if _entry else (None, None)", i.name(), i.entryName())
+ if i.loadAlways {
+ gctx.newLine()
+ gctx.writef("if not %s:", i.entryName())
+ gctx.indentLevel++
+ gctx.newLine()
+ gctx.write(`rblf.mkerror("cannot")`)
+ gctx.indentLevel--
+ }
+}
+
+func (i inheritedDynamicModule) isLoadAlways() bool {
+ return i.loadAlways
+}
+
+type inheritNode struct {
+ module inheritedModule
+}
+
+func (inn *inheritNode) emit(gctx *generationContext) {
+ // Unconditional case:
+ // rblf.inherit(handle, <module>, module_init)
+ // Conditional case:
+ // if <module>_init != None:
+ // same as above
+ inn.module.emitSelect(gctx)
+
+ name := inn.module.name()
+ entry := inn.module.entryName()
+ gctx.newLine()
+ if inn.module.isLoadAlways() {
+ gctx.writef("%s(handle, %s, %s)", cfnInherit, name, entry)
+ return
+ }
+
+ gctx.writef("if %s:", entry)
+ gctx.indentLevel++
+ gctx.newLine()
+ gctx.writef("%s(handle, %s, %s)", cfnInherit, name, entry)
+ gctx.indentLevel--
+}
+
+type includeNode struct {
+ module inheritedModule
+}
+
+func (inn *includeNode) emit(gctx *generationContext) {
+ inn.module.emitSelect(gctx)
+ entry := inn.module.entryName()
+ gctx.newLine()
+ if inn.module.isLoadAlways() {
+ gctx.writef("%s(g, handle)", entry)
+ return
+ }
+
+ gctx.writef("if %s != None:", entry)
+ gctx.indentLevel++
+ gctx.newLine()
+ gctx.writef("%s(g, handle)", entry)
+ gctx.indentLevel--
+}
+
+type assignmentFlavor int
+
+const (
+ // Assignment flavors
+ asgnSet assignmentFlavor = iota // := or =
+ asgnMaybeSet assignmentFlavor = iota // ?= and variable may be unset
+ asgnAppend assignmentFlavor = iota // += and variable has been set before
+ asgnMaybeAppend assignmentFlavor = iota // += and variable may be unset
+)
+
+type assignmentNode struct {
+ lhs variable
+ value starlarkExpr
+ mkValue *mkparser.MakeString
+ flavor assignmentFlavor
+ isTraced bool
+ previous *assignmentNode
+}
+
+func (asgn *assignmentNode) emit(gctx *generationContext) {
+ gctx.newLine()
+ gctx.inAssignment = true
+ asgn.lhs.emitSet(gctx, asgn)
+ gctx.inAssignment = false
+
+ if asgn.isTraced {
+ gctx.newLine()
+ gctx.tracedCount++
+ gctx.writef(`print("%s.%d: %s := ", `, gctx.starScript.mkFile, gctx.tracedCount, asgn.lhs.name())
+ asgn.lhs.emitGet(gctx, true)
+ gctx.writef(")")
+ }
+}
+
+type exprNode struct {
+ expr starlarkExpr
+}
+
+func (exn *exprNode) emit(gctx *generationContext) {
+ gctx.newLine()
+ exn.expr.emit(gctx)
+}
+
+type ifNode struct {
+ isElif bool // true if this is 'elif' statement
+ expr starlarkExpr
+}
+
+func (in *ifNode) emit(gctx *generationContext) {
+ ifElif := "if "
+ if in.isElif {
+ ifElif = "elif "
+ }
+
+ gctx.newLine()
+ if bad, ok := in.expr.(*badExpr); ok {
+ gctx.write("# MK2STAR ERROR converting:")
+ gctx.newLine()
+ gctx.writef("# %s", bad.node.Dump())
+ gctx.newLine()
+ gctx.writef("# %s", bad.message)
+ gctx.newLine()
+ // The init function emits a warning if the conversion was not
+ // fullly successful, so here we (arbitrarily) take the false path.
+ gctx.writef("%sFalse:", ifElif)
+ return
+ }
+ gctx.write(ifElif)
+ in.expr.emit(gctx)
+ gctx.write(":")
+}
+
+type elseNode struct{}
+
+func (br *elseNode) emit(gctx *generationContext) {
+ gctx.newLine()
+ gctx.write("else:")
+}
+
+// switchCase represents as single if/elseif/else branch. All the necessary
+// info about flavor (if/elseif/else) is supposed to be kept in `gate`.
+type switchCase struct {
+ gate starlarkNode
+ nodes []starlarkNode
+}
+
+func (cb *switchCase) newNode(node starlarkNode) {
+ cb.nodes = append(cb.nodes, node)
+}
+
+func (cb *switchCase) emit(gctx *generationContext) {
+ cb.gate.emit(gctx)
+ gctx.indentLevel++
+ hasStatements := false
+ emitNode := func(node starlarkNode) {
+ if _, ok := node.(*commentNode); !ok {
+ hasStatements = true
+ }
+ node.emit(gctx)
+ }
+ if len(cb.nodes) > 0 {
+ emitNode(cb.nodes[0])
+ for _, node := range cb.nodes[1:] {
+ emitNode(node)
+ }
+ if !hasStatements {
+ gctx.emitPass()
+ }
+ } else {
+ gctx.emitPass()
+ }
+ gctx.indentLevel--
+}
+
+// A single complete if ... elseif ... else ... endif sequences
+type switchNode struct {
+ ssCases []*switchCase
+}
+
+func (ssw *switchNode) newNode(node starlarkNode) {
+ switch br := node.(type) {
+ case *switchCase:
+ ssw.ssCases = append(ssw.ssCases, br)
+ default:
+ panic(fmt.Errorf("expected switchCase node, got %t", br))
+ }
+}
+
+func (ssw *switchNode) emit(gctx *generationContext) {
+ if len(ssw.ssCases) == 0 {
+ gctx.emitPass()
+ } else {
+ ssw.ssCases[0].emit(gctx)
+ for _, ssCase := range ssw.ssCases[1:] {
+ ssCase.emit(gctx)
+ }
+ }
+}
diff --git a/mk2rbc/soong_variables.go b/mk2rbc/soong_variables.go
new file mode 100644
index 0000000..de46925
--- /dev/null
+++ b/mk2rbc/soong_variables.go
@@ -0,0 +1,151 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "regexp"
+ "strings"
+
+ mkparser "android/soong/androidmk/parser"
+)
+
+type context struct {
+ includeFileScope mkparser.Scope
+ registrar variableRegistrar
+}
+
+// Scans the makefile Soong uses to generate soong.variables file,
+// collecting variable names and types from the lines that look like this:
+// $(call add_json_XXX, <...>, $(VAR))
+//
+func FindSoongVariables(mkFile string, includeFileScope mkparser.Scope, registrar variableRegistrar) error {
+ ctx := context{includeFileScope, registrar}
+ return ctx.doFind(mkFile)
+}
+
+func (ctx *context) doFind(mkFile string) error {
+ mkContents, err := ioutil.ReadFile(mkFile)
+ if err != nil {
+ return err
+ }
+ parser := mkparser.NewParser(mkFile, bytes.NewBuffer(mkContents))
+ nodes, errs := parser.Parse()
+ if len(errs) > 0 {
+ for _, e := range errs {
+ fmt.Fprintln(os.Stderr, "ERROR:", e)
+ }
+ return fmt.Errorf("cannot parse %s", mkFile)
+ }
+ for _, node := range nodes {
+ switch t := node.(type) {
+ case *mkparser.Variable:
+ ctx.handleVariable(t)
+ case *mkparser.Directive:
+ ctx.handleInclude(t)
+ }
+ }
+ return nil
+}
+
+func (ctx context) NewSoongVariable(name, typeString string) {
+ var valueType starlarkType
+ switch typeString {
+ case "bool":
+ valueType = starlarkTypeBool
+ case "csv":
+ // Only PLATFORM_VERSION_ALL_CODENAMES, and it's a list
+ valueType = starlarkTypeList
+ case "list":
+ valueType = starlarkTypeList
+ case "str":
+ valueType = starlarkTypeString
+ case "val":
+ // Only PLATFORM_SDK_VERSION uses this, and it's integer
+ valueType = starlarkTypeInt
+ default:
+ panic(fmt.Errorf("unknown Soong variable type %s", typeString))
+ }
+
+ ctx.registrar.NewVariable(name, VarClassSoong, valueType)
+}
+
+func (ctx context) handleInclude(t *mkparser.Directive) {
+ if t.Name != "include" && t.Name != "-include" {
+ return
+ }
+ includedPath := t.Args.Value(ctx.includeFileScope)
+ err := ctx.doFind(includedPath)
+ if err != nil && t.Name == "include" {
+ fmt.Fprintf(os.Stderr, "cannot include %s: %s", includedPath, err)
+ }
+}
+
+var callFuncRex = regexp.MustCompile("^call +add_json_(str|val|bool|csv|list) *,")
+
+func (ctx context) handleVariable(t *mkparser.Variable) {
+ // From the variable reference looking as follows:
+ // $(call json_add_TYPE,arg1,$(VAR))
+ // we infer that the type of $(VAR) is TYPE
+ // VAR can be a simple variable name, or another call
+ // (e.g., $(call invert_bool, $(X)), from which we can infer
+ // that the type of X is bool
+ if prefix, v, ok := prefixedVariable(t.Name); ok && strings.HasPrefix(prefix, "call add_json") {
+ if match := callFuncRex.FindStringSubmatch(prefix); match != nil {
+ ctx.inferSoongVariableType(match[1], v)
+ // NOTE(asmundak): sometimes arg1 (the name of the Soong variable defined
+ // in this statement) may indicate that there is a Make counterpart. E.g, from
+ // $(call add_json_bool, DisablePreopt, $(call invert_bool,$(ENABLE_PREOPT)))
+ // it may be inferred that there is a Make boolean variable DISABLE_PREOPT.
+ // Unfortunately, Soong variable names have no 1:1 correspondence to Make variables,
+ // for instance,
+ // $(call add_json_list, PatternsOnSystemOther, $(SYSTEM_OTHER_ODEX_FILTER))
+ // does not mean that there is PATTERNS_ON_SYSTEM_OTHER
+ // Our main interest lies in finding the variables whose values are lists, and
+ // so far there are none that can be found this way, so it is not important.
+ } else {
+ panic(fmt.Errorf("cannot match the call: %s", prefix))
+ }
+ }
+}
+
+var (
+ callInvertBoolRex = regexp.MustCompile("^call +invert_bool *, *$")
+ callFilterBoolRex = regexp.MustCompile("^(filter|filter-out) +(true|false), *$")
+)
+
+func (ctx context) inferSoongVariableType(vType string, n *mkparser.MakeString) {
+ if n.Const() {
+ ctx.NewSoongVariable(n.Strings[0], vType)
+ return
+ }
+ if prefix, v, ok := prefixedVariable(n); ok {
+ if callInvertBoolRex.MatchString(prefix) || callFilterBoolRex.MatchString(prefix) {
+ // It is $(call invert_bool, $(VAR)) or $(filter[-out] [false|true],$(VAR))
+ ctx.inferSoongVariableType("bool", v)
+ }
+ }
+}
+
+// If MakeString is foo$(BAR), returns 'foo', BAR(as *MakeString) and true
+func prefixedVariable(s *mkparser.MakeString) (string, *mkparser.MakeString, bool) {
+ if len(s.Strings) != 2 || s.Strings[1] != "" {
+ return "", nil, false
+ }
+ return s.Strings[0], s.Variables[0].Name, true
+}
diff --git a/mk2rbc/soong_variables_test.go b/mk2rbc/soong_variables_test.go
new file mode 100644
index 0000000..c883882
--- /dev/null
+++ b/mk2rbc/soong_variables_test.go
@@ -0,0 +1,51 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "fmt"
+ "path/filepath"
+ "reflect"
+ "testing"
+)
+
+type dirResolverForTest struct {
+ ScopeBase
+}
+
+func (t dirResolverForTest) Get(name string) string {
+ if name != "BUILD_SYSTEM" {
+ return fmt.Sprintf("$(%s)", name)
+ }
+ return getTestDirectory()
+}
+
+func TestSoongVariables(t *testing.T) {
+ testFile := filepath.Join(getTestDirectory(), "soong_variables.mk.test")
+ var actual testVariables
+ if err := FindSoongVariables(testFile, dirResolverForTest{}, &actual); err != nil {
+ t.Fatal(err)
+ }
+ expected := testVariables{[]testVar{
+ {"BUILD_ID", VarClassSoong, starlarkTypeString},
+ {"PLATFORM_SDK_VERSION", VarClassSoong, starlarkTypeInt},
+ {"DEVICE_PACKAGE_OVERLAYS", VarClassSoong, starlarkTypeList},
+ {"ENABLE_CFI", VarClassSoong, starlarkTypeBool},
+ {"ENABLE_PREOPT", VarClassSoong, starlarkTypeBool},
+ }}
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("\nExpected: %v\n Actual: %v", expected, actual)
+ }
+}
diff --git a/mk2rbc/test/android_products.mk.test b/mk2rbc/test/android_products.mk.test
new file mode 100644
index 0000000..a2220ed
--- /dev/null
+++ b/mk2rbc/test/android_products.mk.test
@@ -0,0 +1,4 @@
+PRODUCT_MAKEFILES := \
+ $(LOCAL_DIR)/aosp_tv_arm.mk \
+ $(LOCAL_DIR)/aosp_tv_arm64.mk \
+ aosp_cf_x86_tv:$(LOCAL_DIR)/vsoc_x86/tv/device.mk
\ No newline at end of file
diff --git a/mk2rbc/test/config_variables.mk.test b/mk2rbc/test/config_variables.mk.test
new file mode 100644
index 0000000..e5cd0e9
--- /dev/null
+++ b/mk2rbc/test/config_variables.mk.test
@@ -0,0 +1,12 @@
+_product_single_value_vars :=
+
+# Variables that are lists of values.
+_product_list_vars :=
+
+_product_single_value_vars += PRODUCT_NAME
+_product_single_value_vars += PRODUCT_MODEL
+
+# The resoure configuration options to use for this product.
+_product_list_vars += PRODUCT_LOCALES
+_product_list_vars += PRODUCT_AAPT_CONFIG
+_product_single_value_vars += PRODUCT_AAPT_PREF_CONFIG
diff --git a/mk2rbc/test/soong_included.mk.test b/mk2rbc/test/soong_included.mk.test
new file mode 100644
index 0000000..255ecc5
--- /dev/null
+++ b/mk2rbc/test/soong_included.mk.test
@@ -0,0 +1 @@
+ $(call add_json_bool, DisablePreopt, $(call invert_bool,$(ENABLE_PREOPT)))
diff --git a/mk2rbc/test/soong_variables.mk.test b/mk2rbc/test/soong_variables.mk.test
new file mode 100644
index 0000000..ca60c9c
--- /dev/null
+++ b/mk2rbc/test/soong_variables.mk.test
@@ -0,0 +1,5 @@
+$(call add_json_str, BuildId, $(BUILD_ID))
+$(call add_json_val, Platform_sdk_version, $(PLATFORM_SDK_VERSION))
+$(call add_json_list, DeviceResourceOverlays, $(DEVICE_PACKAGE_OVERLAYS))
+$(call add_json_bool, EnableCFI, $(call invert_bool,$(filter false,$(ENABLE_CFI))))
+include $(BUILD_SYSTEM)/soong_included.mk.test
diff --git a/mk2rbc/types.go b/mk2rbc/types.go
new file mode 100644
index 0000000..ebd52d8
--- /dev/null
+++ b/mk2rbc/types.go
@@ -0,0 +1,75 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+// Starlark expression types we use
+type starlarkType int
+
+const (
+ // Variable types. Initially we only know the types of the product
+ // configuration variables that are lists, and the types of some
+ // hardwired variables. The remaining variables are first entered as
+ // having an unknown type and treated as strings, but sometimes we
+ // can infer variable's type from the value assigned to it.
+ starlarkTypeUnknown starlarkType = iota
+ starlarkTypeList starlarkType = iota
+ starlarkTypeString starlarkType = iota
+ starlarkTypeInt starlarkType = iota
+ starlarkTypeBool starlarkType = iota
+ starlarkTypeVoid starlarkType = iota
+)
+
+type hiddenArgType int
+
+const (
+ // Some functions have an implicitly emitted first argument, which may be
+ // a global ('g') or configuration ('cfg') variable.
+ hiddenArgNone hiddenArgType = iota
+ hiddenArgGlobal hiddenArgType = iota
+ hiddenArgConfig hiddenArgType = iota
+)
+
+type varClass int
+
+const (
+ VarClassConfig varClass = iota
+ VarClassSoong varClass = iota
+ VarClassLocal varClass = iota
+)
+
+type variableRegistrar interface {
+ NewVariable(name string, varClass varClass, valueType starlarkType)
+}
+
+// ScopeBase is a dummy implementation of the mkparser.Scope.
+// All our scopes are read-only and resolve only simple variables.
+type ScopeBase struct{}
+
+func (s ScopeBase) Set(_, _ string) {
+ panic("implement me")
+}
+
+func (s ScopeBase) Call(_ string, _ []string) []string {
+ panic("implement me")
+}
+
+func (s ScopeBase) SetFunc(_ string, _ func([]string) []string) {
+ panic("implement me")
+}
+
+// Used to find all makefiles in the source tree
+type MakefileFinder interface {
+ Find(root string) []string
+}
diff --git a/mk2rbc/variable.go b/mk2rbc/variable.go
new file mode 100644
index 0000000..88d63c9
--- /dev/null
+++ b/mk2rbc/variable.go
@@ -0,0 +1,307 @@
+// Copyright 2021 Google LLC
+//
+// 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 mk2rbc
+
+import (
+ "fmt"
+ "strings"
+)
+
+type variable interface {
+ name() string
+ emitGet(gctx *generationContext, isDefined bool)
+ emitSet(gctx *generationContext, asgn *assignmentNode)
+ emitDefined(gctx *generationContext)
+ valueType() starlarkType
+ setValueType(t starlarkType)
+ defaultValueString() string
+ isPreset() bool
+}
+
+type baseVariable struct {
+ nam string
+ typ starlarkType
+ preset bool // true if it has been initialized at startup
+}
+
+func (v baseVariable) name() string {
+ return v.nam
+}
+
+func (v baseVariable) valueType() starlarkType {
+ return v.typ
+}
+
+func (v *baseVariable) setValueType(t starlarkType) {
+ v.typ = t
+}
+
+func (v baseVariable) isPreset() bool {
+ return v.preset
+}
+
+var defaultValuesByType = map[starlarkType]string{
+ starlarkTypeUnknown: `""`,
+ starlarkTypeList: "[]",
+ starlarkTypeString: `""`,
+ starlarkTypeInt: "0",
+ starlarkTypeBool: "False",
+ starlarkTypeVoid: "None",
+}
+
+func (v baseVariable) defaultValueString() string {
+ if v, ok := defaultValuesByType[v.valueType()]; ok {
+ return v
+ }
+ panic(fmt.Errorf("%s has unknown type %q", v.name(), v.valueType()))
+}
+
+type productConfigVariable struct {
+ baseVariable
+}
+
+func (pcv productConfigVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
+ emitAssignment := func() {
+ pcv.emitGet(gctx, true)
+ gctx.write(" = ")
+ asgn.value.emitListVarCopy(gctx)
+ }
+ emitAppend := func() {
+ pcv.emitGet(gctx, true)
+ gctx.write(" += ")
+ if pcv.valueType() == starlarkTypeString {
+ gctx.writef(`" " + `)
+ }
+ asgn.value.emit(gctx)
+ }
+
+ switch asgn.flavor {
+ case asgnSet:
+ emitAssignment()
+ case asgnAppend:
+ emitAppend()
+ case asgnMaybeAppend:
+ // If we are not sure variable has been assigned before, emit setdefault
+ if pcv.typ == starlarkTypeList {
+ gctx.writef("%s(handle, %q)", cfnSetListDefault, pcv.name())
+ } else {
+ gctx.writef("cfg.setdefault(%q, %s)", pcv.name(), pcv.defaultValueString())
+ }
+ gctx.newLine()
+ emitAppend()
+ case asgnMaybeSet:
+ gctx.writef("if cfg.get(%q) == None:", pcv.nam)
+ gctx.indentLevel++
+ gctx.newLine()
+ emitAssignment()
+ gctx.indentLevel--
+ }
+}
+
+func (pcv productConfigVariable) emitGet(gctx *generationContext, isDefined bool) {
+ if isDefined || pcv.isPreset() {
+ gctx.writef("cfg[%q]", pcv.nam)
+ } else {
+ gctx.writef("cfg.get(%q, %s)", pcv.nam, pcv.defaultValueString())
+ }
+}
+
+func (pcv productConfigVariable) emitDefined(gctx *generationContext) {
+ gctx.writef("g.get(%q) != None", pcv.name())
+}
+
+type otherGlobalVariable struct {
+ baseVariable
+}
+
+func (scv otherGlobalVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
+ emitAssignment := func() {
+ scv.emitGet(gctx, true)
+ gctx.write(" = ")
+ asgn.value.emitListVarCopy(gctx)
+ }
+
+ emitAppend := func() {
+ scv.emitGet(gctx, true)
+ gctx.write(" += ")
+ if scv.valueType() == starlarkTypeString {
+ gctx.writef(`" " + `)
+ }
+ asgn.value.emit(gctx)
+ }
+
+ switch asgn.flavor {
+ case asgnSet:
+ emitAssignment()
+ case asgnAppend:
+ emitAppend()
+ case asgnMaybeAppend:
+ // If we are not sure variable has been assigned before, emit setdefault
+ gctx.writef("g.setdefault(%q, %s)", scv.name(), scv.defaultValueString())
+ gctx.newLine()
+ emitAppend()
+ case asgnMaybeSet:
+ gctx.writef("if g.get(%q) == None:", scv.nam)
+ gctx.indentLevel++
+ gctx.newLine()
+ emitAssignment()
+ gctx.indentLevel--
+ }
+}
+
+func (scv otherGlobalVariable) emitGet(gctx *generationContext, isDefined bool) {
+ if isDefined || scv.isPreset() {
+ gctx.writef("g[%q]", scv.nam)
+ } else {
+ gctx.writef("g.get(%q, %s)", scv.nam, scv.defaultValueString())
+ }
+}
+
+func (scv otherGlobalVariable) emitDefined(gctx *generationContext) {
+ gctx.writef("g.get(%q) != None", scv.name())
+}
+
+type localVariable struct {
+ baseVariable
+}
+
+func (lv localVariable) emitDefined(_ *generationContext) {
+ panic("implement me")
+}
+
+func (lv localVariable) String() string {
+ return "_" + lv.nam
+}
+
+func (lv localVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
+ switch asgn.flavor {
+ case asgnSet:
+ gctx.writef("%s = ", lv)
+ asgn.value.emitListVarCopy(gctx)
+ case asgnAppend:
+ lv.emitGet(gctx, false)
+ gctx.write(" += ")
+ if lv.valueType() == starlarkTypeString {
+ gctx.writef(`" " + `)
+ }
+ asgn.value.emit(gctx)
+ case asgnMaybeAppend:
+ gctx.writef("%s(%q, ", cfnLocalAppend, lv)
+ asgn.value.emit(gctx)
+ gctx.write(")")
+ case asgnMaybeSet:
+ gctx.writef("%s(%q, ", cfnLocalSetDefault, lv)
+ asgn.value.emit(gctx)
+ gctx.write(")")
+ }
+}
+
+func (lv localVariable) emitGet(gctx *generationContext, _ bool) {
+ gctx.writef("%s", lv)
+}
+
+type predefinedVariable struct {
+ baseVariable
+ value starlarkExpr
+}
+
+func (pv predefinedVariable) emitGet(gctx *generationContext, _ bool) {
+ pv.value.emit(gctx)
+}
+
+func (pv predefinedVariable) emitSet(gctx *generationContext, asgn *assignmentNode) {
+ if expectedValue, ok1 := maybeString(pv.value); ok1 {
+ actualValue, ok2 := maybeString(asgn.value)
+ if ok2 {
+ if actualValue == expectedValue {
+ return
+ }
+ gctx.writef("# MK2RBC TRANSLATION ERROR: cannot set predefined variable %s to %q, its value should be %q",
+ pv.name(), actualValue, expectedValue)
+ gctx.newLine()
+ gctx.write("pass")
+ gctx.starScript.hasErrors = true
+ return
+ }
+ }
+ panic(fmt.Errorf("cannot set predefined variable %s to %q", pv.name(), asgn.mkValue.Dump()))
+}
+
+func (pv predefinedVariable) emitDefined(gctx *generationContext) {
+ gctx.write("True")
+}
+
+var localProductConfigVariables = map[string]string{
+ "LOCAL_AUDIO_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
+ "LOCAL_AUDIO_PRODUCT_COPY_FILES": "PRODUCT_COPY_FILES",
+ "LOCAL_AUDIO_DEVICE_PACKAGE_OVERLAYS": "DEVICE_PACKAGE_OVERLAYS",
+ "LOCAL_DUMPSTATE_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
+ "LOCAL_GATEKEEPER_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
+ "LOCAL_HEALTH_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
+ "LOCAL_SENSOR_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
+ "LOCAL_KEYMASTER_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
+ "LOCAL_KEYMINT_PRODUCT_PACKAGE": "PRODUCT_PACKAGES",
+}
+
+var presetVariables = map[string]bool{
+ "BUILD_ID": true,
+ "HOST_ARCH": true,
+ "HOST_OS": true,
+ "HOST_BUILD_TYPE": true,
+ "OUT_DIR": true,
+ "PLATFORM_VERSION_CODENAME": true,
+ "PLATFORM_VERSION": true,
+ "TARGET_ARCH": true,
+ "TARGET_ARCH_VARIANT": true,
+ "TARGET_BUILD_TYPE": true,
+ "TARGET_BUILD_VARIANT": true,
+ "TARGET_PRODUCT": true,
+}
+
+// addVariable returns a variable with a given name. A variable is
+// added if it does not exist yet.
+func (ctx *parseContext) addVariable(name string) variable {
+ v, found := ctx.variables[name]
+ if !found {
+ _, preset := presetVariables[name]
+ if vi, found := KnownVariables[name]; found {
+ switch vi.class {
+ case VarClassConfig:
+ v = &productConfigVariable{baseVariable{nam: name, typ: vi.valueType, preset: preset}}
+ case VarClassSoong:
+ v = &otherGlobalVariable{baseVariable{nam: name, typ: vi.valueType, preset: preset}}
+ }
+ } else if name == strings.ToLower(name) {
+ // Heuristics: if variable's name is all lowercase, consider it local
+ // string variable.
+ v = &localVariable{baseVariable{nam: name, typ: starlarkTypeUnknown}}
+ } else {
+ vt := starlarkTypeUnknown
+ if strings.HasPrefix(name, "LOCAL_") {
+ // Heuristics: local variables that contribute to corresponding config variables
+ if cfgVarName, found := localProductConfigVariables[name]; found {
+ vi, found2 := KnownVariables[cfgVarName]
+ if !found2 {
+ panic(fmt.Errorf("unknown config variable %s for %s", cfgVarName, name))
+ }
+ vt = vi.valueType
+ }
+ }
+ v = &otherGlobalVariable{baseVariable{nam: name, typ: vt}}
+ }
+ ctx.variables[name] = v
+ }
+ return v
+}
diff --git a/python/test.go b/python/test.go
index 6713189..7413782 100644
--- a/python/test.go
+++ b/python/test.go
@@ -15,6 +15,8 @@
package python
import (
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/tradefed"
)
@@ -102,6 +104,9 @@
binary.pythonInstaller = NewPythonInstaller("nativetest", "nativetest64")
test := &testDecorator{binaryDecorator: binary}
+ if hod == android.HostSupportedNoCross && test.testProperties.Test_options.Unit_test == nil {
+ test.testProperties.Test_options.Unit_test = proptools.BoolPtr(true)
+ }
module.bootstrapper = test
module.installer = test
diff --git a/rust/Android.bp b/rust/Android.bp
index b611672..221014e 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -11,6 +11,7 @@
"soong-bloaty",
"soong-cc",
"soong-rust-config",
+ "soong-snapshot",
],
srcs: [
"androidmk.go",
@@ -32,6 +33,7 @@
"rust.go",
"sanitize.go",
"source_provider.go",
+ "snapshot_prebuilt.go",
"snapshot_utils.go",
"strip.go",
"test.go",
@@ -53,6 +55,7 @@
"rust_test.go",
"source_provider_test.go",
"test_test.go",
+ "vendor_snapshot_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/rust/androidmk.go b/rust/androidmk.go
index ea45ebd..630805a 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -205,24 +205,24 @@
ctx.SubAndroidMk(entries, fuzz.binaryDecorator)
var fuzzFiles []string
- for _, d := range fuzz.corpus {
+ for _, d := range fuzz.fuzzPackagedModule.Corpus {
fuzzFiles = append(fuzzFiles,
- filepath.Dir(fuzz.corpusIntermediateDir.String())+":corpus/"+d.Base())
+ filepath.Dir(fuzz.fuzzPackagedModule.CorpusIntermediateDir.String())+":corpus/"+d.Base())
}
- for _, d := range fuzz.data {
+ for _, d := range fuzz.fuzzPackagedModule.Data {
fuzzFiles = append(fuzzFiles,
- filepath.Dir(fuzz.dataIntermediateDir.String())+":data/"+d.Rel())
+ filepath.Dir(fuzz.fuzzPackagedModule.DataIntermediateDir.String())+":data/"+d.Rel())
}
- if fuzz.dictionary != nil {
+ if fuzz.fuzzPackagedModule.Dictionary != nil {
fuzzFiles = append(fuzzFiles,
- filepath.Dir(fuzz.dictionary.String())+":"+fuzz.dictionary.Base())
+ filepath.Dir(fuzz.fuzzPackagedModule.Dictionary.String())+":"+fuzz.fuzzPackagedModule.Dictionary.Base())
}
- if fuzz.config != nil {
+ if fuzz.fuzzPackagedModule.Config != nil {
fuzzFiles = append(fuzzFiles,
- filepath.Dir(fuzz.config.String())+":config.json")
+ filepath.Dir(fuzz.fuzzPackagedModule.Config.String())+":config.json")
}
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext,
diff --git a/rust/benchmark.go b/rust/benchmark.go
index b89f5cd..0e84243 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -101,6 +101,7 @@
func (benchmark *benchmarkDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
deps = benchmark.binaryDecorator.compilerDeps(ctx, deps)
+ deps.Rustlibs = append(deps.Rustlibs, "libtest")
deps.Rustlibs = append(deps.Rustlibs, "libcriterion")
return deps
diff --git a/rust/binary.go b/rust/binary.go
index ffc0413..2c3f548 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -137,6 +137,9 @@
// Binaries default to dylib dependencies for device, rlib for host.
if binary.preferRlib() {
return rlibAutoDep
+ } else if mod, ok := ctx.Module().(*Module); ok && mod.InVendor() {
+ // Vendor Rust binaries should prefer rlibs.
+ return rlibAutoDep
} else if ctx.Device() {
return dylibAutoDep
} else {
@@ -147,10 +150,8 @@
func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
if binary.preferRlib() {
return RlibLinkage
+ } else if ctx.RustModule().InVendor() {
+ return RlibLinkage
}
return binary.baseCompiler.stdLinkage(ctx)
}
-
-func (binary *binaryDecorator) isDependencyRoot() bool {
- return true
-}
diff --git a/rust/binary_test.go b/rust/binary_test.go
index 86f50d3..968c0c1 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -114,6 +114,23 @@
}
}
+// Test that the bootstrap property sets the appropriate linker
+func TestBootstrap(t *testing.T) {
+ ctx := testRust(t, `
+ rust_binary {
+ name: "foo",
+ srcs: ["foo.rs"],
+ bootstrap: true,
+ }`)
+
+ foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+
+ flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64"
+ if !strings.Contains(foo.Args["linkFlags"], flag) {
+ t.Errorf("missing link flag to use bootstrap linker, expecting %#v, linkFlags: %#v", flag, foo.Args["linkFlags"])
+ }
+}
+
func TestStaticBinaryFlags(t *testing.T) {
ctx := testRust(t, `
rust_binary {
diff --git a/rust/bindgen.go b/rust/bindgen.go
index f9e6cd0..3470e51 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -137,15 +137,15 @@
implicits = append(implicits, deps.depGeneratedHeaders...)
// Default clang flags
- cflags = append(cflags, "${cc_config.CommonClangGlobalCflags}")
+ cflags = append(cflags, "${cc_config.CommonGlobalCflags}")
if ctx.Device() {
- cflags = append(cflags, "${cc_config.DeviceClangGlobalCflags}")
+ cflags = append(cflags, "${cc_config.DeviceGlobalCflags}")
}
// Toolchain clang flags
cflags = append(cflags, "-target "+ccToolchain.ClangTriple())
- cflags = append(cflags, strings.ReplaceAll(ccToolchain.ClangCflags(), "${config.", "${cc_config."))
- cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainClangCflags(), "${config.", "${cc_config."))
+ cflags = append(cflags, strings.ReplaceAll(ccToolchain.Cflags(), "${config.", "${cc_config."))
+ cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainCflags(), "${config.", "${cc_config."))
// Dependency clang flags and include paths
cflags = append(cflags, deps.depClangFlags...)
diff --git a/rust/builder.go b/rust/builder.go
index 6db508d..a5b3ab9 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -220,6 +220,15 @@
linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
linkFlags = append(linkFlags, flags.LinkFlags...)
+ // Check if this module needs to use the bootstrap linker
+ if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
+ dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
+ if ctx.toolchain().Is64Bit() {
+ dynamicLinker += "64"
+ }
+ linkFlags = append(linkFlags, dynamicLinker)
+ }
+
libFlags := makeLibFlags(deps)
// Collect dependencies
@@ -323,6 +332,12 @@
rustdocFlags = append(rustdocFlags, makeLibFlags(deps)...)
docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
+ // Silence warnings about renamed lints for third-party crates
+ modulePath := android.PathForModuleSrc(ctx).String()
+ if android.IsThirdPartyPath(modulePath) {
+ rustdocFlags = append(rustdocFlags, " -A renamed_and_removed_lints")
+ }
+
// Yes, the same out directory is used simultaneously by all rustdoc builds.
// This is what cargo does. The docs for individual crates get generated to
// a subdirectory named for the crate, and rustdoc synchronizes writes to
diff --git a/rust/compiler.go b/rust/compiler.go
index 1598ebf..de59f39 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -17,6 +17,7 @@
import (
"fmt"
"path/filepath"
+ "strings"
"github.com/google/blueprint/proptools"
@@ -235,6 +236,25 @@
if err != nil {
ctx.PropertyErrorf("lints", err.Error())
}
+
+ // linkage-related flags are disallowed.
+ for _, s := range compiler.Properties.Ld_flags {
+ if strings.HasPrefix(s, "-Wl,-l") || strings.HasPrefix(s, "-Wl,-L") {
+ ctx.PropertyErrorf("ld_flags", "'-Wl,-l' and '-Wl,-L' flags cannot be manually specified")
+ }
+ }
+ for _, s := range compiler.Properties.Flags {
+ if strings.HasPrefix(s, "-l") || strings.HasPrefix(s, "-L") {
+ ctx.PropertyErrorf("flags", "'-l' and '-L' flags cannot be manually specified")
+ }
+ if strings.HasPrefix(s, "--extern") {
+ ctx.PropertyErrorf("flags", "'--extern' flag cannot be manually specified")
+ }
+ if strings.HasPrefix(s, "-Clink-args=") || strings.HasPrefix(s, "-C link-args=") {
+ ctx.PropertyErrorf("flags", "'-C link-args' flag cannot be manually specified")
+ }
+ }
+
flags.RustFlags = append(flags.RustFlags, lintFlags)
flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
flags.RustFlags = append(flags.RustFlags, compiler.cfgsToFlags()...)
@@ -289,10 +309,6 @@
return android.OptionalPathForPath(compiler.cargoOutDir)
}
-func (compiler *baseCompiler) isDependencyRoot() bool {
- return false
-}
-
func (compiler *baseCompiler) strippedOutputFilePath() android.OptionalPath {
return compiler.strippedOutputFile
}
@@ -309,7 +325,7 @@
if !Bool(compiler.Properties.No_stdlibs) {
for _, stdlib := range config.Stdlibs {
// If we're building for the primary arch of the build host, use the compiler's stdlibs
- if ctx.Target().Os == android.BuildOs {
+ if ctx.Target().Os == ctx.Config().BuildOS {
stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
}
deps.Stdlibs = append(deps.Stdlibs, stdlib)
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index 5ca9e7f..c331b4c 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -208,3 +208,73 @@
t.Errorf("libstd is not linked dynamically for dylibs")
}
}
+
+// Ensure that manual link flags are disallowed.
+func TestManualLinkageRejection(t *testing.T) {
+ // rustc flags
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["-lbar"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["--extern=foo"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["-Clink-args=foo"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["-C link-args=foo"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["-L foo/"],
+ }
+ `)
+
+ // lld flags
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ ld_flags: ["-Wl,-L bar/"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ ld_flags: ["-Wl,-lbar"],
+ }
+ `)
+}
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 394fcc5..e527aea 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -23,12 +23,23 @@
"system/extras/profcollectd",
"system/extras/simpleperf",
"system/hardware/interfaces/keystore2",
+ "system/librustutils",
"system/logging/rust",
"system/security",
"system/tools/aidl",
+ "tools/security/fuzzing/example_rust_fuzzer",
+ "vendor/",
+ }
+
+ DownstreamRustAllowedPaths = []string{
+ // Add downstream allowed Rust paths here.
}
RustModuleTypes = []string{
+ // Don't add rust_bindgen or rust_protobuf as these are code generation modules
+ // and can be expected to be in paths without Rust code.
+ "rust_benchmark",
+ "rust_benchmark_host",
"rust_binary",
"rust_binary_host",
"rust_library",
@@ -37,6 +48,7 @@
"rust_ffi",
"rust_ffi_shared",
"rust_ffi_static",
+ "rust_fuzz",
"rust_library_host",
"rust_library_host_dylib",
"rust_library_host_rlib",
diff --git a/rust/config/global.go b/rust/config/global.go
index 43b49d1..e5b334d 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,12 +24,11 @@
var pctx = android.NewPackageContext("android/soong/rust/config")
var (
- RustDefaultVersion = "1.51.0"
+ RustDefaultVersion = "1.54.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2018"
Stdlibs = []string{
"libstd",
- "libtest",
}
// Mapping between Soong internal arch types and std::env constants.
diff --git a/rust/config/x86_darwin_host.go b/rust/config/x86_darwin_host.go
index ddd93e8..8ff0dd4 100644
--- a/rust/config/x86_darwin_host.go
+++ b/rust/config/x86_darwin_host.go
@@ -78,7 +78,7 @@
func (t *toolchainDarwinX8664) ToolchainLinkFlags() string {
// Prepend the lld flags from cc_config so we stay in sync with cc
- return "${cc_config.DarwinClangLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}"
+ return "${cc_config.DarwinLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}"
}
func (t *toolchainDarwinX8664) ToolchainRustFlags() string {
diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go
index aae1125..5ae30e7 100644
--- a/rust/config/x86_device.go
+++ b/rust/config/x86_device.go
@@ -65,7 +65,7 @@
func (t *toolchainX86) ToolchainLinkFlags() string {
// Prepend the lld flags from cc_config so we stay in sync with cc
- return "${config.DeviceGlobalLinkFlags} ${cc_config.X86ClangLldflags} ${config.X86ToolchainLinkFlags}"
+ return "${config.DeviceGlobalLinkFlags} ${cc_config.X86Lldflags} ${config.X86ToolchainLinkFlags}"
}
func (t *toolchainX86) ToolchainRustFlags() string {
diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go
index b63e14d..0aa534f 100644
--- a/rust/config/x86_linux_host.go
+++ b/rust/config/x86_linux_host.go
@@ -37,6 +37,10 @@
registerToolchainFactory(android.Linux, android.X86_64, linuxX8664ToolchainFactory)
registerToolchainFactory(android.Linux, android.X86, linuxX86ToolchainFactory)
+ // TODO: musl rust support
+ registerToolchainFactory(android.LinuxMusl, android.X86_64, linuxX8664ToolchainFactory)
+ registerToolchainFactory(android.LinuxMusl, android.X86, linuxX86ToolchainFactory)
+
pctx.StaticVariable("LinuxToolchainRustFlags", strings.Join(LinuxRustFlags, " "))
pctx.StaticVariable("LinuxToolchainLinkFlags", strings.Join(LinuxRustLinkFlags, " "))
pctx.StaticVariable("LinuxToolchainX86RustFlags", strings.Join(linuxX86Rustflags, " "))
@@ -79,7 +83,7 @@
func (t *toolchainLinuxX8664) ToolchainLinkFlags() string {
// Prepend the lld flags from cc_config so we stay in sync with cc
- return "${cc_config.LinuxClangLldflags} ${cc_config.LinuxX8664ClangLldflags} " +
+ return "${cc_config.LinuxLldflags} ${cc_config.LinuxX8664Lldflags} " +
"${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainX8664LinkFlags}"
}
@@ -117,7 +121,7 @@
func (t *toolchainLinuxX86) ToolchainLinkFlags() string {
// Prepend the lld flags from cc_config so we stay in sync with cc
- return "${cc_config.LinuxClangLldflags} ${cc_config.LinuxX86ClangLldflags} " +
+ return "${cc_config.LinuxLldflags} ${cc_config.LinuxX86Lldflags} " +
"${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainX86LinkFlags}"
}
diff --git a/rust/coverage.go b/rust/coverage.go
index dac526a..050b811 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -55,7 +55,7 @@
flags.Coverage = true
coverage := ctx.GetDirectDepWithTag(CovLibraryName, cc.CoverageDepTag).(cc.LinkableInterface)
flags.RustFlags = append(flags.RustFlags,
- "-Z instrument-coverage", "-g", "-C link-dead-code")
+ "-Z instrument-coverage", "-g")
flags.LinkFlags = append(flags.LinkFlags,
profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index 4b6c9d4..f3cd375 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -56,7 +56,7 @@
fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
- rustcCoverageFlags := []string{"-Z instrument-coverage", " -g ", "-C link-dead-code"}
+ rustcCoverageFlags := []string{"-Z instrument-coverage", " -g "}
for _, flag := range rustcCoverageFlags {
missingErrorStr := "missing rustc flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
containsErrorStr := "contains rustc flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
diff --git a/rust/fuzz.go b/rust/fuzz.go
index 7e1c55a..18b2513 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -32,13 +32,7 @@
type fuzzDecorator struct {
*binaryDecorator
- Properties cc.FuzzProperties
- dictionary android.Path
- corpus android.Paths
- corpusIntermediateDir android.Path
- config android.Path
- data android.Paths
- dataIntermediateDir android.Path
+ fuzzPackagedModule cc.FuzzPackagedModule
}
var _ compiler = (*binaryDecorator)(nil)
@@ -88,7 +82,7 @@
func (fuzzer *fuzzDecorator) compilerProps() []interface{} {
return append(fuzzer.binaryDecorator.compilerProps(),
- &fuzzer.Properties)
+ &fuzzer.fuzzPackagedModule.FuzzProperties)
}
func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage {
@@ -102,32 +96,19 @@
// Responsible for generating GNU Make rules that package fuzz targets into
// their architecture & target/host specific zip file.
type rustFuzzPackager struct {
- packages android.Paths
- fuzzTargets map[string]bool
+ cc.FuzzPackager
}
func rustFuzzPackagingFactory() android.Singleton {
return &rustFuzzPackager{}
}
-type fileToZip struct {
- SourceFilePath android.Path
- DestinationPathPrefix string
-}
-
-type archOs struct {
- hostOrTarget string
- arch string
- dir string
-}
-
func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
-
// Map between each architecture + host/device combination.
- archDirs := make(map[archOs][]fileToZip)
+ archDirs := make(map[cc.ArchOs][]cc.FileToZip)
// List of individual fuzz targets.
- s.fuzzTargets = make(map[string]bool)
+ s.FuzzTargets = make(map[string]bool)
ctx.VisitAllModules(func(module android.Module) {
// Discard non-fuzz targets.
@@ -136,23 +117,15 @@
return
}
+ if ok := cc.IsValid(rustModule.FuzzModule); !ok || rustModule.Properties.PreventInstall {
+ return
+ }
+
fuzzModule, ok := rustModule.compiler.(*fuzzDecorator)
if !ok {
return
}
- // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
- // fuzz targets we're going to package anyway.
- if !rustModule.Enabled() || rustModule.Properties.PreventInstall ||
- rustModule.InRamdisk() || rustModule.InVendorRamdisk() || rustModule.InRecovery() {
- return
- }
-
- // Discard modules that are in an unavailable namespace.
- if !rustModule.ExportedToMake() {
- return
- }
-
hostOrTargetString := "target"
if rustModule.Host() {
hostOrTargetString = "host"
@@ -160,126 +133,34 @@
archString := rustModule.Arch().ArchType.String()
archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
- archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()}
+ archOs := cc.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
- var files []fileToZip
+ var files []cc.FileToZip
builder := android.NewRuleBuilder(pctx, ctx)
- // Package the corpora into a zipfile.
- if fuzzModule.corpus != nil {
- corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip")
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", corpusZip)
- rspFile := corpusZip.ReplaceExtension(ctx, "rsp")
- command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.corpus)
- files = append(files, fileToZip{corpusZip, ""})
- }
-
- // Package the data into a zipfile.
- if fuzzModule.data != nil {
- dataZip := archDir.Join(ctx, module.Name()+"_data.zip")
- command := builder.Command().BuiltTool("soong_zip").
- FlagWithOutput("-o ", dataZip)
- for _, f := range fuzzModule.data {
- intermediateDir := strings.TrimSuffix(f.String(), f.Rel())
- command.FlagWithArg("-C ", intermediateDir)
- command.FlagWithInput("-f ", f)
- }
- files = append(files, fileToZip{dataZip, ""})
- }
+ // Package the artifacts (data, corpus, config and dictionary into a zipfile.
+ files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder)
// The executable.
- files = append(files, fileToZip{rustModule.unstrippedOutputFile.Path(), ""})
+ files = append(files, cc.FileToZip{rustModule.unstrippedOutputFile.Path(), ""})
- // The dictionary.
- if fuzzModule.dictionary != nil {
- files = append(files, fileToZip{fuzzModule.dictionary, ""})
+ archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
+ if !ok {
+ return
}
- // Additional fuzz config.
- if fuzzModule.config != nil {
- files = append(files, fileToZip{fuzzModule.config, ""})
- }
-
- fuzzZip := archDir.Join(ctx, module.Name()+".zip")
-
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", fuzzZip)
-
- for _, file := range files {
- if file.DestinationPathPrefix != "" {
- command.FlagWithArg("-P ", file.DestinationPathPrefix)
- } else {
- command.Flag("-P ''")
- }
- command.FlagWithInput("-f ", file.SourceFilePath)
- }
-
- builder.Build("create-"+fuzzZip.String(),
- "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
-
- // Don't add modules to 'make haiku-rust' that are set to not be
- // exported to the fuzzing infrastructure.
- if config := fuzzModule.Properties.Fuzz_config; config != nil {
- if rustModule.Host() && !BoolDefault(config.Fuzz_on_haiku_host, true) {
- return
- } else if !BoolDefault(config.Fuzz_on_haiku_device, true) {
- return
- }
- }
-
- s.fuzzTargets[module.Name()] = true
- archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""})
})
-
- var archOsList []archOs
- for archOs := range archDirs {
- archOsList = append(archOsList, archOs)
- }
- sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].dir < archOsList[j].dir })
-
- for _, archOs := range archOsList {
- filesToZip := archDirs[archOs]
- arch := archOs.arch
- hostOrTarget := archOs.hostOrTarget
- builder := android.NewRuleBuilder(pctx, ctx)
- outputFile := android.PathForOutput(ctx, "fuzz-rust-"+hostOrTarget+"-"+arch+".zip")
- s.packages = append(s.packages, outputFile)
-
- command := builder.Command().BuiltTool("soong_zip").
- Flag("-j").
- FlagWithOutput("-o ", outputFile).
- Flag("-L 0") // No need to try and re-compress the zipfiles.
-
- for _, fileToZip := range filesToZip {
- if fileToZip.DestinationPathPrefix != "" {
- command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
- } else {
- command.Flag("-P ''")
- }
- command.FlagWithInput("-f ", fileToZip.SourceFilePath)
- }
- builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget,
- "Create fuzz target packages for "+arch+"-"+hostOrTarget)
- }
-
+ s.CreateFuzzPackage(ctx, archDirs, cc.Rust)
}
func (s *rustFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
- packages := s.packages.Strings()
+ packages := s.Packages.Strings()
sort.Strings(packages)
ctx.Strict("SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
- // Preallocate the slice of fuzz targets to minimise memory allocations.
- fuzzTargets := make([]string, 0, len(s.fuzzTargets))
- for target, _ := range s.fuzzTargets {
- fuzzTargets = append(fuzzTargets, target)
- }
- sort.Strings(fuzzTargets)
- ctx.Strict("ALL_RUST_FUZZ_TARGETS", strings.Join(fuzzTargets, " "))
+ // Preallocate the slice of fuzz targets to minimize memory allocations.
+ s.PreallocateSlice(ctx, "ALL_RUST_FUZZ_TARGETS")
}
func (fuzz *fuzzDecorator) install(ctx ModuleContext) {
@@ -289,13 +170,13 @@
"fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
fuzz.binaryDecorator.baseCompiler.install(ctx)
- if fuzz.Properties.Corpus != nil {
- fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus)
+ if fuzz.fuzzPackagedModule.FuzzProperties.Corpus != nil {
+ fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus)
}
- if fuzz.Properties.Data != nil {
- fuzz.data = android.PathsForModuleSrc(ctx, fuzz.Properties.Data)
+ if fuzz.fuzzPackagedModule.FuzzProperties.Data != nil {
+ fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data)
}
- if fuzz.Properties.Dictionary != nil {
- fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary)
+ if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
+ fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary)
}
}
diff --git a/rust/image.go b/rust/image.go
index 1b2df1d..3b54f12 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -82,7 +82,12 @@
}
func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
- panic("Rust modules do not support snapshotting: " + mod.BaseModuleName())
+ if snapshot, ok := mod.compiler.(cc.SnapshotInterface); ok {
+ return snapshot.Version()
+ } else {
+ mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
+ return ""
+ }
}
func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
@@ -110,7 +115,9 @@
}
func (mod *Module) IsSnapshotPrebuilt() bool {
- // Rust does not support prebuilts in its snapshots
+ if p, ok := mod.compiler.(cc.SnapshotInterface); ok {
+ return p.IsSnapshotPrebuilt()
+ }
return false
}
@@ -202,6 +209,8 @@
func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
// Rust does not support installing to the product image yet.
+ vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
+
if Bool(mod.VendorProperties.Product_available) {
mctx.PropertyErrorf("product_available",
"Rust modules do not yet support being available to the product image")
@@ -217,11 +226,10 @@
mctx.PropertyErrorf("vendor_ramdisk_available", "cannot be set for rust_ffi or rust_ffi_shared modules.")
}
}
- vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
if vendorSpecific {
- mctx.PropertyErrorf("vendor or soc_specific",
- "Rust modules do not yet support soc-specific modules")
-
+ if lib, ok := mod.compiler.(libraryInterface); ok && lib.buildDylib() {
+ mctx.PropertyErrorf("vendor", "Vendor-only dylibs are not yet supported, use rust_library_rlib.")
+ }
}
cc.MutateImage(mctx, mod)
diff --git a/rust/library.go b/rust/library.go
index 1bdf83a..8c10e29 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -21,6 +21,7 @@
"android/soong/android"
"android/soong/cc"
+ "android/soong/snapshot"
)
var (
@@ -99,6 +100,8 @@
MutatedProperties LibraryMutatedProperties
includeDirs android.Paths
sourceProvider SourceProvider
+
+ collectedSnapshotHeaders android.Paths
}
type libraryInterface interface {
@@ -122,7 +125,8 @@
setStatic()
setSource()
- // Set libstd linkage
+ // libstd linkage functions
+ rlibStd() bool
setRlibStd()
setDylibStd()
@@ -193,6 +197,10 @@
library.MutatedProperties.VariantIsShared = false
}
+func (library *libraryDecorator) rlibStd() bool {
+ return library.MutatedProperties.VariantIsStaticStd
+}
+
func (library *libraryDecorator) setRlibStd() {
library.MutatedProperties.VariantIsStaticStd = true
}
@@ -220,7 +228,10 @@
}
func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
- if library.preferRlib() {
+ if ctx.Module().(*Module).InVendor() {
+ // Vendor modules should statically link libstd.
+ return rlibAutoDep
+ } else if library.preferRlib() {
return rlibAutoDep
} else if library.rlib() || library.static() {
return rlibAutoDep
@@ -236,7 +247,10 @@
}
func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
- if library.static() || library.MutatedProperties.VariantIsStaticStd {
+ if ctx.RustModule().InVendor() {
+ // Vendor modules should statically link libstd.
+ return RlibLinkage
+ } else if library.static() || library.MutatedProperties.VariantIsStaticStd {
return RlibLinkage
} else if library.baseCompiler.preferRlib() {
return RlibLinkage
@@ -418,6 +432,12 @@
func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
+ if library.dylib() {
+ // We need to add a dependency on std in order to link crates as dylibs.
+ // The hack to add this dependency is guarded by the following cfg so
+ // that we don't force a dependency when it isn't needed.
+ library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib")
+ }
flags = library.baseCompiler.compilerFlags(ctx, flags)
if library.shared() || library.static() {
library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
@@ -490,9 +510,8 @@
if library.shared() {
ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
- SharedLibrary: outputFile,
- UnstrippedSharedLibrary: outputFile,
- Target: ctx.Target(),
+ SharedLibrary: outputFile,
+ Target: ctx.Target(),
})
}
@@ -623,6 +642,19 @@
// Disable dylib Vendor Ramdisk variations until we support these.
v.(*Module).Disable()
}
+
+ variation := v.(*Module).ModuleBase.ImageVariation().Variation
+ if strings.HasPrefix(variation, cc.VendorVariationPrefix) &&
+ m.HasVendorVariant() &&
+ !snapshot.IsVendorProprietaryModule(mctx) &&
+ strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() {
+
+ // cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are
+ // produced for Dylibs; however, dylibs should not be enabled for boardVndkVersion for
+ // non-vendor proprietary modules.
+ v.(*Module).Disable()
+ }
+
case "source":
v.(*Module).compiler.(libraryInterface).setSource()
// The source variant does not produce any library.
@@ -659,9 +691,10 @@
dylib := modules[1].(*Module)
rlib.compiler.(libraryInterface).setRlibStd()
dylib.compiler.(libraryInterface).setDylibStd()
- if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
+ if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation ||
+ strings.HasPrefix(dylib.ModuleBase.ImageVariation().Variation, cc.VendorVariationPrefix) {
// TODO(b/165791368)
- // Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
+ // Disable rlibs that link against dylib-std on vendor and vendor ramdisk variations until those dylib
// variants are properly supported.
dylib.Disable()
}
@@ -671,3 +704,54 @@
}
}
}
+
+func (l *libraryDecorator) snapshotHeaders() android.Paths {
+ if l.collectedSnapshotHeaders == nil {
+ panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
+ }
+ return l.collectedSnapshotHeaders
+}
+
+// collectHeadersForSnapshot collects all exported headers from library.
+// It globs header files in the source tree for exported include directories,
+// and tracks generated header files separately.
+//
+// This is to be called from GenerateAndroidBuildActions, and then collected
+// header files can be retrieved by snapshotHeaders().
+func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) {
+ ret := android.Paths{}
+
+ // Glob together the headers from the modules include_dirs property
+ for _, path := range android.CopyOfPaths(l.includeDirs) {
+ dir := path.String()
+ glob, err := ctx.GlobWithDeps(dir+"/**/*", nil)
+ if err != nil {
+ ctx.ModuleErrorf("glob failed: %#v", err)
+ return
+ }
+
+ for _, header := range glob {
+ // Filter out only the files with extensions that are headers.
+ found := false
+ for _, ext := range cc.HeaderExts {
+ if strings.HasSuffix(header, ext) {
+ found = true
+ break
+ }
+ }
+ if !found {
+ continue
+ }
+ ret = append(ret, android.PathForSource(ctx, header))
+ }
+ }
+
+ // Glob together the headers from C dependencies as well, starting with non-generated headers.
+ ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...)
+
+ // Collect generated headers from C dependencies.
+ ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...)
+
+ // TODO(185577950): If support for generated headers is added, they need to be collected here as well.
+ l.collectedSnapshotHeaders = ret
+}
diff --git a/rust/library_test.go b/rust/library_test.go
index 54cd2a5..cb4ef7e 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -85,6 +85,22 @@
}
}
+// Check that we are passing the android_dylib config flag
+func TestAndroidDylib(t *testing.T) {
+ ctx := testRust(t, `
+ rust_library_host_dylib {
+ name: "libfoo",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ }`)
+
+ libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.dylib.so")
+
+ if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") {
+ t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
+ }
+}
+
func TestValidateLibraryStem(t *testing.T) {
testRustError(t, "crate_name must be defined.", `
rust_library_host {
diff --git a/rust/project_json_test.go b/rust/project_json_test.go
index 09d30db..bdd54c5 100644
--- a/rust/project_json_test.go
+++ b/rust/project_json_test.go
@@ -176,6 +176,8 @@
}
func TestProjectJsonBindGen(t *testing.T) {
+ buildOS := android.TestConfig(t.TempDir(), nil, "", nil).BuildOS
+
bp := `
rust_library {
name: "libd",
@@ -214,9 +216,9 @@
if strings.Contains(rootModule, "libbindings1") && !strings.Contains(rootModule, "android_arm64") {
t.Errorf("The source path for libbindings1 does not contain android_arm64, got %v", rootModule)
}
- if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, android.BuildOs.String()) {
+ if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, buildOS.String()) {
t.Errorf("The source path for libbindings2 does not contain the BuildOs, got %v; want %v",
- rootModule, android.BuildOs.String())
+ rootModule, buildOS.String())
}
// Check that libbindings1 does not depend on itself.
if strings.Contains(rootModule, "libbindings1") {
diff --git a/rust/rust.go b/rust/rust.go
index f068b3d..80be496 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -35,7 +35,7 @@
android.AddNeverAllowRules(
android.NeverAllow().
- NotIn(config.RustAllowedPaths...).
+ NotIn(append(config.RustAllowedPaths, config.DownstreamRustAllowedPaths...)...).
ModuleType(config.RustModuleTypes...))
android.RegisterModuleType("rust_defaults", defaultsFactory)
@@ -85,6 +85,14 @@
VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
ExtraVariants []string `blueprint:"mutated"`
+ // Allows this module to use non-APEX version of libraries. Useful
+ // for building binaries that are started before APEXes are activated.
+ Bootstrap *bool
+
+ // Used by vendor snapshot to record dependencies from snapshot modules.
+ SnapshotSharedLibs []string `blueprint:"mutated"`
+ SnapshotStaticLibs []string `blueprint:"mutated"`
+
// Make this module available when building for vendor ramdisk.
// On device without a dedicated recovery partition, the module is only
// available after switching root into
@@ -92,6 +100,20 @@
// the recovery variant instead (TODO(b/165791368) recovery not yet supported)
Vendor_ramdisk_available *bool
+ // Normally Soong uses the directory structure to decide which modules
+ // should be included (framework) or excluded (non-framework) from the
+ // different snapshots (vendor, recovery, etc.), but this property
+ // allows a partner to exclude a module normally thought of as a
+ // framework module from the vendor snapshot.
+ Exclude_from_vendor_snapshot *bool
+
+ // Normally Soong uses the directory structure to decide which modules
+ // should be included (framework) or excluded (non-framework) from the
+ // different snapshots (vendor, recovery, etc.), but this property
+ // allows a partner to exclude a module normally thought of as a
+ // framework module from the recovery snapshot.
+ Exclude_from_recovery_snapshot *bool
+
// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
Min_sdk_version *string
@@ -101,9 +123,7 @@
}
type Module struct {
- android.ModuleBase
- android.DefaultableModuleBase
- android.ApexModuleBase
+ cc.FuzzModule
VendorProperties cc.VendorProperties
@@ -154,13 +174,6 @@
return mod.sanitize != nil && mod.compiler != nil
}
-func (mod *Module) IsDependencyRoot() bool {
- if mod.compiler != nil {
- return mod.compiler.isDependencyRoot()
- }
- panic("IsDependencyRoot called on a non-compiler Rust module")
-}
-
func (mod *Module) IsPrebuilt() bool {
if _, ok := mod.compiler.(*prebuiltLibraryDecorator); ok {
return true
@@ -242,6 +255,13 @@
return false
}
+func (mod *Module) StaticExecutable() bool {
+ if !mod.Binary() {
+ return false
+ }
+ return Bool(mod.compiler.(*binaryDecorator).Properties.Static_executable)
+}
+
func (mod *Module) Object() bool {
// Rust has no modules which produce only object files.
return false
@@ -271,6 +291,10 @@
return mod.Properties.VndkVersion != ""
}
+func (mod *Module) Bootstrap() bool {
+ return Bool(mod.Properties.Bootstrap)
+}
+
func (mod *Module) MustUseVendorVariant() bool {
return true
}
@@ -420,7 +444,6 @@
SetDisabled()
stdLinkage(ctx *depsContext) RustLinkage
- isDependencyRoot() bool
strippedOutputFilePath() android.OptionalPath
}
@@ -619,6 +642,10 @@
}
func (mod *Module) installable(apexInfo android.ApexInfo) bool {
+ if !mod.EverInstallable() {
+ return false
+ }
+
// The apex variant is not installable because it is included in the APEX and won't appear
// in the system partition as a standalone file.
if !apexInfo.IsForPlatform() {
@@ -822,10 +849,20 @@
mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps)
+ // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
+ // RECOVERY_SNAPSHOT_VERSION is current.
+ if lib, ok := mod.compiler.(snapshotLibraryInterface); ok {
+ if cc.ShouldCollectHeadersForSnapshot(ctx, mod, apexInfo) {
+ lib.collectHeadersForSnapshot(ctx, deps)
+ }
+ }
+
apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if mod.installable(apexInfo) {
mod.compiler.install(ctx)
}
+
+ ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
}
}
@@ -923,7 +960,7 @@
directRlibDeps := []*Module{}
directDylibDeps := []*Module{}
directProcMacroDeps := []*Module{}
- directSharedLibDeps := [](cc.LinkableInterface){}
+ directSharedLibDeps := []cc.SharedLibraryInfo{}
directStaticLibDeps := [](cc.LinkableInterface){}
directSrcProvidersDeps := []*Module{}
directSrcDeps := [](android.SourceFileProducer){}
@@ -957,7 +994,9 @@
case procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, rustDep)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
- case android.SourceDepTag:
+ }
+
+ if android.IsSourceDepTagWithOutputTag(depTag, "") {
// Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
// OS/Arch variant is used.
var helper string
@@ -1044,14 +1083,28 @@
directStaticLibDeps = append(directStaticLibDeps, ccDep)
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, makeLibName)
case cc.IsSharedDepTag(depTag):
+ // For the shared lib dependencies, we may link to the stub variant
+ // of the dependency depending on the context (e.g. if this
+ // dependency crosses the APEX boundaries).
+ sharedLibraryInfo, exportedInfo := cc.ChooseStubOrImpl(ctx, dep)
+
+ // Re-get linkObject as ChooseStubOrImpl actually tells us which
+ // object (either from stub or non-stub) to use.
+ linkObject = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary)
+ linkPath = linkPathFromFilePath(linkObject.Path())
+
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
- exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
- directSharedLibDeps = append(directSharedLibDeps, ccDep)
+ directSharedLibDeps = append(directSharedLibDeps, sharedLibraryInfo)
+
+ // Record baseLibName for snapshots.
+ mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName))
+ mod.Properties.SnapshotStaticLibs = append(mod.Properties.SnapshotStaticLibs, cc.BaseLibName(depName))
+
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName)
exportDep = true
case cc.IsHeaderDepTag(depTag):
@@ -1073,8 +1126,7 @@
}
if srcDep, ok := dep.(android.SourceFileProducer); ok {
- switch depTag {
- case android.SourceDepTag:
+ if android.IsSourceDepTagWithOutputTag(depTag, "") {
// These are usually genrules which don't have per-target variants.
directSrcDeps = append(directSrcDeps, srcDep)
}
@@ -1102,11 +1154,11 @@
var sharedLibFiles android.Paths
var sharedLibDepFiles android.Paths
for _, dep := range directSharedLibDeps {
- sharedLibFiles = append(sharedLibFiles, dep.OutputFile().Path())
- if dep.Toc().Valid() {
- sharedLibDepFiles = append(sharedLibDepFiles, dep.Toc().Path())
+ sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary)
+ if dep.TableOfContents.Valid() {
+ sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path())
} else {
- sharedLibDepFiles = append(sharedLibDepFiles, dep.OutputFile().Path())
+ sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary)
}
}
@@ -1157,6 +1209,11 @@
deps := mod.deps(ctx)
var commonDepVariations []blueprint.Variation
+ var snapshotInfo *cc.SnapshotInfo
+
+ if ctx.Os() == android.Android {
+ deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs)
+ }
stdLinkage := "dylib-std"
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
@@ -1164,61 +1221,101 @@
}
rlibDepVariations := commonDepVariations
+
if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
rlibDepVariations = append(rlibDepVariations,
blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
}
- actx.AddVariationDependencies(
- append(rlibDepVariations, []blueprint.Variation{
- {Mutator: "rust_libraries", Variation: rlibVariation}}...),
- rlibDepTag, deps.Rlibs...)
+ // rlibs
+ for _, lib := range deps.Rlibs {
+ depTag := rlibDepTag
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+
+ actx.AddVariationDependencies(append(rlibDepVariations, []blueprint.Variation{
+ {Mutator: "rust_libraries", Variation: rlibVariation},
+ }...), depTag, lib)
+ }
+
+ // dylibs
actx.AddVariationDependencies(
append(commonDepVariations, []blueprint.Variation{
{Mutator: "rust_libraries", Variation: dylibVariation}}...),
dylibDepTag, deps.Dylibs...)
+ // rustlibs
if deps.Rustlibs != nil && !mod.compiler.Disabled() {
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
if autoDep.depTag == rlibDepTag {
- actx.AddVariationDependencies(
- append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}),
- autoDep.depTag, deps.Rustlibs...)
+ for _, lib := range deps.Rustlibs {
+ depTag := autoDep.depTag
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+ actx.AddVariationDependencies(append(rlibDepVariations, []blueprint.Variation{
+ {Mutator: "rust_libraries", Variation: autoDep.variation},
+ }...), depTag, lib)
+ }
} else {
actx.AddVariationDependencies(
append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}),
autoDep.depTag, deps.Rustlibs...)
}
}
+
+ // stdlibs
if deps.Stdlibs != nil {
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
- actx.AddVariationDependencies(
- append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "rlib"}),
- rlibDepTag, deps.Stdlibs...)
+ for _, lib := range deps.Stdlibs {
+ depTag := rlibDepTag
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+
+ actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
+ depTag, lib)
+ }
} else {
actx.AddVariationDependencies(
append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"}),
dylibDepTag, deps.Stdlibs...)
}
}
- actx.AddVariationDependencies(append(commonDepVariations,
- blueprint.Variation{Mutator: "link", Variation: "shared"}),
- cc.SharedDepTag(), deps.SharedLibs...)
- actx.AddVariationDependencies(append(commonDepVariations,
- blueprint.Variation{Mutator: "link", Variation: "static"}),
- cc.StaticDepTag(false), deps.StaticLibs...)
- actx.AddVariationDependencies(append(commonDepVariations,
- blueprint.Variation{Mutator: "link", Variation: "static"}),
- cc.StaticDepTag(true), deps.WholeStaticLibs...)
+
+ for _, lib := range deps.SharedLibs {
+ depTag := cc.SharedDepTag()
+ name, version := cc.StubsLibNameAndVersion(lib)
+
+ variations := []blueprint.Variation{
+ {Mutator: "link", Variation: "shared"},
+ }
+ cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
+ }
+
+ for _, lib := range deps.WholeStaticLibs {
+ depTag := cc.StaticDepTag(true)
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
+
+ actx.AddVariationDependencies([]blueprint.Variation{
+ {Mutator: "link", Variation: "static"},
+ }, depTag, lib)
+ }
+
+ for _, lib := range deps.StaticLibs {
+ depTag := cc.StaticDepTag(false)
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
+
+ actx.AddVariationDependencies([]blueprint.Variation{
+ {Mutator: "link", Variation: "static"},
+ }, depTag, lib)
+ }
actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...)
crtVariations := cc.GetCrtVariations(ctx, mod)
if deps.CrtBegin != "" {
- actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, deps.CrtBegin)
+ actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag,
+ cc.RewriteSnapshotLib(deps.CrtBegin, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
}
if deps.CrtEnd != "" {
- actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, deps.CrtEnd)
+ actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag,
+ cc.RewriteSnapshotLib(deps.CrtEnd, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
}
if mod.sourceProvider != nil {
@@ -1228,6 +1325,7 @@
bindgen.Properties.Custom_bindgen)
}
}
+
// proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy.
actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...)
}
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 6ae05d9..80f693e 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -37,21 +37,29 @@
genrule.PrepareForTestWithGenRuleBuildComponents,
- PrepareForIntegrationTestWithRust,
+ PrepareForTestWithRustIncludeVndk,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.DeviceVndkVersion = StringPtr("current")
+ variables.ProductVndkVersion = StringPtr("current")
+ variables.Platform_vndk_version = StringPtr("29")
+ }),
)
var rustMockedFiles = android.MockFS{
- "foo.rs": nil,
- "foo.c": nil,
- "src/bar.rs": nil,
- "src/any.h": nil,
- "proto.proto": nil,
- "proto/buf.proto": nil,
- "buf.proto": nil,
- "foo.proto": nil,
- "liby.so": nil,
- "libz.so": nil,
- "data.txt": nil,
+ "foo.rs": nil,
+ "foo.c": nil,
+ "src/bar.rs": nil,
+ "src/any.h": nil,
+ "c_includes/c_header.h": nil,
+ "rust_includes/rust_headers.h": nil,
+ "proto.proto": nil,
+ "proto/buf.proto": nil,
+ "buf.proto": nil,
+ "foo.proto": nil,
+ "liby.so": nil,
+ "libz.so": nil,
+ "data.txt": nil,
+ "liblog.map.txt": nil,
}
// testRust returns a TestContext in which a basic environment has been setup.
@@ -67,19 +75,33 @@
}
func testRustVndk(t *testing.T, bp string) *android.TestContext {
+ return testRustVndkFs(t, bp, rustMockedFiles)
+}
+
+const (
+ sharedVendorVariant = "android_vendor.29_arm64_armv8-a_shared"
+ rlibVendorVariant = "android_vendor.29_arm64_armv8-a_rlib_rlib-std"
+)
+
+func testRustVndkFs(t *testing.T, bp string, fs android.MockFS) *android.TestContext {
+ return testRustVndkFsVersions(t, bp, fs, "current", "current", "29")
+}
+
+func testRustVndkFsVersions(t *testing.T, bp string, fs android.MockFS, device_version, product_version, vndk_version string) *android.TestContext {
skipTestIfOsNotSupported(t)
result := android.GroupFixturePreparers(
prepareForRustTest,
- rustMockedFiles.AddToFixture(),
+ fs.AddToFixture(),
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = StringPtr("current")
- variables.ProductVndkVersion = StringPtr("current")
- variables.Platform_vndk_version = StringPtr("29")
+ variables.DeviceVndkVersion = StringPtr(device_version)
+ variables.ProductVndkVersion = StringPtr(product_version)
+ variables.Platform_vndk_version = StringPtr(vndk_version)
},
),
).RunTestWithBp(t, bp)
return result.TestContext
+
}
// testRustCov returns a TestContext in which a basic environment has been
@@ -115,10 +137,14 @@
// testRustVndkError is similar to testRustError, but can be used to test VNDK-related errors.
func testRustVndkError(t *testing.T, pattern string, bp string) {
+ testRustVndkFsError(t, pattern, bp, rustMockedFiles)
+}
+
+func testRustVndkFsError(t *testing.T, pattern string, bp string, fs android.MockFS) {
skipTestIfOsNotSupported(t)
android.GroupFixturePreparers(
prepareForRustTest,
- rustMockedFiles.AddToFixture(),
+ fs.AddToFixture(),
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
diff --git a/rust/sanitize.go b/rust/sanitize.go
index 3d14d51..a4ba4bd 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -47,6 +47,9 @@
"-C llvm-args=-sanitizer-coverage-trace-geps",
"-C llvm-args=-sanitizer-coverage-prune-blocks=0",
+ // See https://github.com/rust-fuzz/cargo-fuzz/pull/193
+ "-C link-dead-code",
+
// Sancov breaks with lto
// TODO: Remove when https://bugs.llvm.org/show_bug.cgi?id=41734 is resolved and sancov works with LTO
"-C lto=no",
diff --git a/rust/snapshot_prebuilt.go b/rust/snapshot_prebuilt.go
new file mode 100644
index 0000000..79eaab3
--- /dev/null
+++ b/rust/snapshot_prebuilt.go
@@ -0,0 +1,122 @@
+// Copyright 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 rust
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+
+ "github.com/google/blueprint/proptools"
+)
+
+const (
+ snapshotRlibSuffix = "_rlib."
+)
+
+type snapshotLibraryDecorator struct {
+ cc.BaseSnapshotDecorator
+ *libraryDecorator
+ properties cc.SnapshotLibraryProperties
+ sanitizerProperties struct {
+ CfiEnabled bool `blueprint:"mutated"`
+
+ // Library flags for cfi variant.
+ Cfi cc.SnapshotLibraryProperties `android:"arch_variant"`
+ }
+}
+
+func init() {
+ registerRustSnapshotModules(android.InitRegistrationContext)
+}
+
+func registerRustSnapshotModules(ctx android.RegistrationContext) {
+ cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx,
+ "vendor_snapshot_rlib", VendorSnapshotRlibFactory)
+}
+
+func snapshotLibraryFactory(image cc.SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
+ module, library := NewRustLibrary(android.DeviceSupported)
+
+ module.sanitize = nil
+ library.stripper.StripProperties.Strip.None = proptools.BoolPtr(true)
+
+ prebuilt := &snapshotLibraryDecorator{
+ libraryDecorator: library,
+ }
+
+ module.compiler = prebuilt
+
+ prebuilt.Init(module, image, moduleSuffix)
+ module.AddProperties(
+ &prebuilt.properties,
+ &prebuilt.sanitizerProperties,
+ )
+
+ return module, prebuilt
+}
+
+func (library *snapshotLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
+ var variant string
+ if library.static() {
+ variant = cc.SnapshotStaticSuffix
+ } else if library.shared() {
+ variant = cc.SnapshotSharedSuffix
+ } else if library.rlib() {
+ variant = cc.SnapshotRlibSuffix
+ }
+
+ if !library.dylib() {
+ // TODO(184042776): Remove this check when dylibs are supported in snapshots.
+ library.SetSnapshotAndroidMkSuffix(ctx, variant)
+ }
+
+ if !library.MatchesWithDevice(ctx.DeviceConfig()) {
+ return nil
+ }
+
+ return android.PathForModuleSrc(ctx, *library.properties.Src)
+}
+
+func (library *snapshotLibraryDecorator) rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath {
+ return android.OptionalPath{}
+}
+
+// vendor_snapshot_rlib is a special prebuilt rlib library which is auto-generated by
+// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_rlib
+// overrides the vendor variant of the rust rlib library with the same name, if BOARD_VNDK_VERSION
+// is set.
+func VendorSnapshotRlibFactory() android.Module {
+ module, prebuilt := snapshotLibraryFactory(cc.VendorSnapshotImageSingleton, cc.SnapshotRlibSuffix)
+ prebuilt.libraryDecorator.BuildOnlyRlib()
+ prebuilt.libraryDecorator.setNoStdlibs()
+ return module.Init()
+}
+
+func (library *snapshotLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
+ arches := config.Arches()
+ if len(arches) == 0 || arches[0].ArchType.String() != library.Arch() {
+ return false
+ }
+ if library.properties.Src == nil {
+ return false
+ }
+ return true
+}
+
+func (library *snapshotLibraryDecorator) IsSnapshotPrebuilt() bool {
+ return true
+}
+
+var _ cc.SnapshotInterface = (*snapshotLibraryDecorator)(nil)
diff --git a/rust/snapshot_utils.go b/rust/snapshot_utils.go
index 943c790..8dabd9b 100644
--- a/rust/snapshot_utils.go
+++ b/rust/snapshot_utils.go
@@ -18,18 +18,33 @@
"android/soong/android"
)
+// snapshotLibraryInterface is an interface for libraries captured to VNDK / vendor snapshots.
+type snapshotLibraryInterface interface {
+ libraryInterface
+
+ // collectHeadersForSnapshot is called in GenerateAndroidBuildActions for snapshot aware
+ // modules (See isSnapshotAware below).
+ // This function should gather all headers needed for snapshot.
+ collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps)
+
+ // snapshotHeaders should return collected headers by collectHeadersForSnapshot.
+ // Calling snapshotHeaders before collectHeadersForSnapshot is an error.
+ snapshotHeaders() android.Paths
+}
+
func (mod *Module) ExcludeFromVendorSnapshot() bool {
- // TODO Rust does not yet support snapshotting
- return false
+ return Bool(mod.Properties.Exclude_from_vendor_snapshot)
}
func (mod *Module) ExcludeFromRecoverySnapshot() bool {
- // TODO Rust does not yet support snapshotting
- return false
+ return Bool(mod.Properties.Exclude_from_recovery_snapshot)
}
func (mod *Module) IsSnapshotLibrary() bool {
- // TODO Rust does not yet support snapshotting
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ // Rust-native dylibs are not snapshot supported yet. Only snapshot the rlib-std variants of rlibs.
+ return lib.shared() || lib.static() || (lib.rlib() && lib.rlibStd())
+ }
return false
}
@@ -39,8 +54,11 @@
}
func (mod *Module) SnapshotSharedLibs() []string {
- // TODO Rust does not yet support snapshotting
- return []string{}
+ return mod.Properties.SnapshotSharedLibs
+}
+
+func (mod *Module) SnapshotStaticLibs() []string {
+ return mod.Properties.SnapshotStaticLibs
}
func (mod *Module) Symlinks() []string {
@@ -49,6 +67,8 @@
}
func (m *Module) SnapshotHeaders() android.Paths {
- // TODO Rust does not yet support snapshotting
+ if l, ok := m.compiler.(snapshotLibraryInterface); ok {
+ return l.snapshotHeaders()
+ }
return android.Paths{}
}
diff --git a/rust/test.go b/rust/test.go
index 6caa7b1..e95b47c 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -169,3 +169,11 @@
func (test *testDecorator) stdLinkage(ctx *depsContext) RustLinkage {
return RlibLinkage
}
+
+func (test *testDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
+ deps = test.binaryDecorator.compilerDeps(ctx, deps)
+
+ deps.Rustlibs = append(deps.Rustlibs, "libtest")
+
+ return deps
+}
diff --git a/rust/testing.go b/rust/testing.go
index a0f86b2..94cdd9d 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -45,6 +45,11 @@
PrepareForTestWithRustDefaultModules,
)
+var PrepareForTestWithRustIncludeVndk = android.GroupFixturePreparers(
+ PrepareForIntegrationTestWithRust,
+ cc.PrepareForTestWithCcIncludeVndk,
+)
+
func GatherRequiredDepsForTest() string {
bp := `
rust_prebuilt_library {
@@ -130,6 +135,9 @@
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
vendor_available: true,
+ llndk: {
+ symbol_file: "liblog.map.txt",
+ },
}
cc_library {
name: "libprotobuf-cpp-full",
@@ -162,12 +170,10 @@
name: "libtest",
crate_name: "test",
srcs: ["foo.rs"],
- no_stdlibs: true,
host_supported: true,
vendor_available: true,
vendor_ramdisk_available: true,
native_coverage: false,
- sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
}
@@ -240,4 +246,5 @@
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
ctx.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
+ registerRustSnapshotModules(ctx)
}
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
new file mode 100644
index 0000000..60ddb65
--- /dev/null
+++ b/rust/vendor_snapshot_test.go
@@ -0,0 +1,996 @@
+// Copyright 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 rust
+
+import (
+ "fmt"
+ "path/filepath"
+ "reflect"
+ "strings"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/cc"
+)
+
+func TestVendorSnapshotCapture(t *testing.T) {
+ bp := `
+ rust_ffi {
+ name: "libffivendor_available",
+ crate_name: "ffivendor_available",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ include_dirs: ["rust_headers/"],
+ }
+
+ rust_ffi {
+ name: "libffivendor",
+ crate_name: "ffivendor",
+ srcs: ["lib.rs"],
+ vendor: true,
+ include_dirs: ["rust_headers/"],
+ }
+
+ rust_library {
+ name: "librustvendor_available",
+ crate_name: "rustvendor_available",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ include_dirs: ["rust_headers/"],
+ }
+
+ rust_library_rlib {
+ name: "librustvendor",
+ crate_name: "rustvendor",
+ srcs: ["lib.rs"],
+ vendor: true,
+ include_dirs: ["rust_headers/"],
+ }
+
+ rust_binary {
+ name: "vendor_available_bin",
+ vendor_available: true,
+ srcs: ["srcs/lib.rs"],
+ }
+
+ rust_binary {
+ name: "vendor_bin",
+ vendor: true,
+ srcs: ["srcs/lib.rs"],
+ }
+ `
+ skipTestIfOsNotSupported(t)
+ result := android.GroupFixturePreparers(
+ prepareForRustTest,
+ rustMockedFiles.AddToFixture(),
+ android.FixtureModifyProductVariables(
+ func(variables android.FixtureProductVariables) {
+ variables.DeviceVndkVersion = StringPtr("current")
+ variables.Platform_vndk_version = StringPtr("29")
+ },
+ ),
+ ).RunTestWithBp(t, bp)
+ ctx := result.TestContext
+
+ // Check Vendor snapshot output.
+
+ snapshotDir := "vendor-snapshot"
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
+ snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
+ var jsonFiles []string
+ for _, arch := range [][]string{
+ []string{"arm64", "armv8-a"},
+ []string{"arm", "armv7-a-neon"},
+ } {
+ archType := arch[0]
+ archVariant := arch[1]
+ archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
+
+ // For shared libraries, only non-VNDK vendor_available modules are captured
+ sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
+ sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.so", sharedDir, sharedVariant)
+ jsonFiles = append(jsonFiles,
+ filepath.Join(sharedDir, "libffivendor_available.so.json"))
+
+ // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
+ staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant)
+ staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.a", staticDir, staticVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor", "libffivendor.a", staticDir, staticVariant)
+ jsonFiles = append(jsonFiles,
+ filepath.Join(staticDir, "libffivendor_available.a.json"))
+ jsonFiles = append(jsonFiles,
+ filepath.Join(staticDir, "libffivendor.a.json"))
+
+ // For rlib libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
+ rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
+ rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib", rlibDir, rlibVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor", "librustvendor.rlib", rlibDir, rlibVariant)
+ jsonFiles = append(jsonFiles,
+ filepath.Join(rlibDir, "librustvendor_available.rlib.json"))
+ jsonFiles = append(jsonFiles,
+ filepath.Join(rlibDir, "librustvendor.rlib.json"))
+
+ // For binary executables, all vendor:true and vendor_available modules are captured.
+ if archType == "arm64" {
+ binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
+ binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
+ jsonFiles = append(jsonFiles,
+ filepath.Join(binaryDir, "vendor_available_bin.json"))
+ jsonFiles = append(jsonFiles,
+ filepath.Join(binaryDir, "vendor_bin.json"))
+ }
+ }
+
+ for _, jsonFile := range jsonFiles {
+ // verify all json files exist
+ if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
+ t.Errorf("%q expected but not found; #%v", jsonFile, jsonFiles)
+ }
+ }
+
+ // fake snapshot should have all outputs in the normal snapshot.
+ fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
+
+ for _, output := range snapshotSingleton.AllOutputs() {
+ fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
+ if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
+ t.Errorf("%q expected but not found", fakeOutput)
+ }
+ }
+}
+
+func TestVendorSnapshotDirected(t *testing.T) {
+ bp := `
+ rust_ffi_shared {
+ name: "libffivendor_available",
+ crate_name: "ffivendor_available",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ }
+
+ rust_library {
+ name: "librustvendor_available",
+ crate_name: "rustvendor_available",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ }
+
+ rust_ffi_shared {
+ name: "libffivendor_exclude",
+ crate_name: "ffivendor_exclude",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ }
+
+ rust_library {
+ name: "librustvendor_exclude",
+ crate_name: "rustvendor_exclude",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ }
+`
+ ctx := testRustVndk(t, bp)
+ ctx.Config().TestProductVariables.VendorSnapshotModules = make(map[string]bool)
+ ctx.Config().TestProductVariables.VendorSnapshotModules["librustvendor_available"] = true
+ ctx.Config().TestProductVariables.VendorSnapshotModules["libffivendor_available"] = true
+ ctx.Config().TestProductVariables.DirectedVendorSnapshot = true
+
+ // Check Vendor snapshot output.
+
+ snapshotDir := "vendor-snapshot"
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
+ snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
+
+ var includeJsonFiles []string
+
+ for _, arch := range [][]string{
+ []string{"arm64", "armv8-a"},
+ []string{"arm", "armv7-a-neon"},
+ } {
+ archType := arch[0]
+ archVariant := arch[1]
+ archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
+
+ sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
+ rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
+ sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
+ rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
+
+ // Included modules
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib", rlibDir, rlibVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.so", sharedDir, sharedVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_available.rlib.json"))
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libffivendor_available.so.json"))
+
+ // Excluded modules. Modules not included in the directed vendor snapshot
+ // are still include as fake modules.
+ cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.rlib", rlibDir, rlibVariant)
+ cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "libffivendor_exclude", "libffivendor_exclude.so", sharedDir, sharedVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_exclude.rlib.json"))
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libffivendor_exclude.so.json"))
+ }
+
+ // Verify that each json file for an included module has a rule.
+ for _, jsonFile := range includeJsonFiles {
+ if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
+ t.Errorf("include json file %q not found", jsonFile)
+ }
+ }
+}
+
+func TestVendorSnapshotExclude(t *testing.T) {
+
+ // This test verifies that the exclude_from_vendor_snapshot property
+ // makes its way from the Android.bp source file into the module data
+ // structure. It also verifies that modules are correctly included or
+ // excluded in the vendor snapshot based on their path (framework or
+ // vendor) and the exclude_from_vendor_snapshot property.
+
+ frameworkBp := `
+ rust_ffi_shared {
+ name: "libinclude",
+ crate_name: "include",
+ srcs: ["include.rs"],
+ vendor_available: true,
+ }
+
+ rust_ffi_shared {
+ name: "libexclude",
+ crate_name: "exclude",
+ srcs: ["exclude.rs"],
+ vendor: true,
+ exclude_from_vendor_snapshot: true,
+ }
+
+ rust_ffi_shared {
+ name: "libavailable_exclude",
+ crate_name: "available_exclude",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ exclude_from_vendor_snapshot: true,
+ }
+
+ rust_library {
+ name: "librust_include",
+ crate_name: "rust_include",
+ srcs: ["include.rs"],
+ vendor_available: true,
+ }
+
+ rust_library_rlib {
+ name: "librust_exclude",
+ crate_name: "rust_exclude",
+ srcs: ["exclude.rs"],
+ vendor: true,
+ exclude_from_vendor_snapshot: true,
+ }
+
+ rust_library {
+ name: "librust_available_exclude",
+ crate_name: "rust_available_exclude",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ exclude_from_vendor_snapshot: true,
+ }
+ `
+
+ mockFS := map[string][]byte{
+ "framework/Android.bp": []byte(frameworkBp),
+ "framework/include.rs": nil,
+ "framework/exclude.rs": nil,
+ }
+
+ ctx := testRustVndkFs(t, "", mockFS)
+
+ // Test an include and exclude framework module.
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, sharedVendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, sharedVendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, sharedVendorVariant)
+
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_include", false, rlibVendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_exclude", true, rlibVendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_available_exclude", true, rlibVendorVariant)
+
+ // Verify the content of the vendor snapshot.
+
+ snapshotDir := "vendor-snapshot"
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
+ snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
+
+ var includeJsonFiles []string
+ var excludeJsonFiles []string
+
+ for _, arch := range [][]string{
+ []string{"arm64", "armv8-a"},
+ []string{"arm", "armv7-a-neon"},
+ } {
+ archType := arch[0]
+ archVariant := arch[1]
+ archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
+
+ sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
+ sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
+ rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
+ rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
+
+ // Included modules
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "librust_include", "librust_include.rlib", rlibDir, rlibVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librust_include.rlib.json"))
+
+ // Excluded modules
+ cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
+ excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
+ cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
+ excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
+ cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_exclude", "librust_exclude.rlib", rlibDir, rlibVariant)
+ excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_exclude.rlib.json"))
+ cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_available_exclude", "librust_available_exclude.rlib", rlibDir, rlibVariant)
+ excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_available_exclude.rlib.json"))
+ }
+
+ // Verify that each json file for an included module has a rule.
+ for _, jsonFile := range includeJsonFiles {
+ if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
+ t.Errorf("include json file %q not found", jsonFile)
+ }
+ }
+
+ // Verify that each json file for an excluded module has no rule.
+ for _, jsonFile := range excludeJsonFiles {
+ if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
+ t.Errorf("exclude json file %q found", jsonFile)
+ }
+ }
+}
+
+func TestVendorSnapshotUse(t *testing.T) {
+ frameworkBp := `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ }
+
+ cc_library {
+ name: "libvendor_available",
+ vendor_available: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ }
+
+ cc_library {
+ name: "lib32",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ compile_multilib: "32",
+ }
+
+ cc_library {
+ name: "lib64",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ compile_multilib: "64",
+ }
+
+ rust_binary {
+ name: "bin",
+ vendor: true,
+ srcs: ["bin.rs"],
+ }
+
+ rust_binary {
+ name: "bin32",
+ vendor: true,
+ compile_multilib: "32",
+ srcs: ["bin.rs"],
+ }
+`
+
+ vndkBp := `
+ vndk_prebuilt_shared {
+ name: "libvndk",
+ version: "30",
+ target_arch: "arm64",
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ arch: {
+ arm64: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ arm: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ },
+ }
+
+ // old snapshot module which has to be ignored
+ vndk_prebuilt_shared {
+ name: "libvndk",
+ version: "26",
+ target_arch: "arm64",
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ arch: {
+ arm64: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ arm: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ },
+ }
+
+ // different arch snapshot which has to be ignored
+ vndk_prebuilt_shared {
+ name: "libvndk",
+ version: "30",
+ target_arch: "arm",
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ arch: {
+ arm: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ },
+ }
+`
+
+ vendorProprietaryBp := `
+ cc_library {
+ name: "libvendor_without_snapshot",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ }
+
+ rust_library {
+ name: "librust_vendor_available",
+ crate_name: "rust_vendor",
+ vendor_available: true,
+ srcs: ["client.rs"],
+ }
+
+ rust_ffi_shared {
+ name: "libclient",
+ crate_name: "client",
+ vendor: true,
+ shared_libs: ["libvndk", "libvendor_available"],
+ static_libs: ["libvendor", "libvendor_without_snapshot"],
+ rustlibs: ["librust_vendor_available"],
+ arch: {
+ arm64: {
+ shared_libs: ["lib64"],
+ },
+ arm: {
+ shared_libs: ["lib32"],
+ },
+ },
+ srcs: ["client.rs"],
+ }
+
+ rust_library_rlib {
+ name: "libclient_rust",
+ crate_name: "client_rust",
+ vendor: true,
+ shared_libs: ["libvndk", "libvendor_available"],
+ static_libs: ["libvendor", "libvendor_without_snapshot"],
+ rustlibs: ["librust_vendor_available"],
+ arch: {
+ arm64: {
+ shared_libs: ["lib64"],
+ },
+ arm: {
+ shared_libs: ["lib32"],
+ },
+ },
+ srcs: ["client.rs"],
+ }
+
+ rust_binary {
+ name: "bin_without_snapshot",
+ vendor: true,
+ static_libs: ["libvndk"],
+ srcs: ["bin.rs"],
+ rustlibs: ["librust_vendor_available"],
+ }
+
+ vendor_snapshot {
+ name: "vendor_snapshot",
+ version: "30",
+ arch: {
+ arm64: {
+ vndk_libs: [
+ "libvndk",
+ ],
+ static_libs: [
+ "libvendor",
+ "libvndk",
+ "libclang_rt.builtins-aarch64-android",
+ ],
+ shared_libs: [
+ "libvendor_available",
+ "lib64",
+ ],
+ rlibs: [
+ "libstd",
+ "librust_vendor_available",
+ ],
+ binaries: [
+ "bin",
+ ],
+ objects: [
+ "crtend_so",
+ "crtbegin_so",
+ "crtbegin_dynamic",
+ "crtend_android"
+ ],
+ },
+ arm: {
+ vndk_libs: [
+ "libvndk",
+ ],
+ static_libs: [
+ "libvendor",
+ "libvndk",
+ "libclang_rt.builtins-arm-android",
+ ],
+ shared_libs: [
+ "libvendor_available",
+ "lib32",
+ ],
+ rlibs: [
+ "libstd",
+ "librust_vendor_available",
+ ],
+ binaries: [
+ "bin32",
+ ],
+ objects: [
+ "crtend_so",
+ "crtbegin_so",
+ "crtbegin_dynamic",
+ "crtend_android"
+ ],
+
+ },
+ }
+ }
+
+ vendor_snapshot_object {
+ name: "crtend_so",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ stl: "none",
+ crt: true,
+ arch: {
+ arm64: {
+ src: "crtend_so.o",
+ },
+ arm: {
+ src: "crtend_so.o",
+ },
+ },
+ }
+
+ vendor_snapshot_object {
+ name: "crtbegin_so",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ stl: "none",
+ crt: true,
+ arch: {
+ arm64: {
+ src: "crtbegin_so.o",
+ },
+ arm: {
+ src: "crtbegin_so.o",
+ },
+ },
+ }
+
+ vendor_snapshot_rlib {
+ name: "libstd",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ sysroot: true,
+ arch: {
+ arm64: {
+ src: "libstd.rlib",
+ },
+ arm: {
+ src: "libstd.rlib",
+ },
+ },
+ }
+
+ vendor_snapshot_rlib {
+ name: "librust_vendor_available",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "librust_vendor_available.rlib",
+ },
+ arm: {
+ src: "librust_vendor_available.rlib",
+ },
+ },
+ }
+
+ vendor_snapshot_object {
+ name: "crtend_android",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ stl: "none",
+ crt: true,
+ arch: {
+ arm64: {
+ src: "crtend_so.o",
+ },
+ arm: {
+ src: "crtend_so.o",
+ },
+ },
+ }
+
+ vendor_snapshot_object {
+ name: "crtbegin_dynamic",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ stl: "none",
+ crt: true,
+ arch: {
+ arm64: {
+ src: "crtbegin_so.o",
+ },
+ arm: {
+ src: "crtbegin_so.o",
+ },
+ },
+ }
+
+ vendor_snapshot_static {
+ name: "libvndk",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "both",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "libvndk.a",
+ },
+ arm: {
+ src: "libvndk.a",
+ },
+ },
+ shared_libs: ["libvndk"],
+ export_shared_lib_headers: ["libvndk"],
+ }
+
+ vendor_snapshot_static {
+ name: "libclang_rt.builtins-aarch64-android",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "libclang_rt.builtins-aarch64-android.a",
+ },
+ },
+ }
+
+ vendor_snapshot_static {
+ name: "libclang_rt.builtins-arm-android",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ arch: {
+ arm: {
+ src: "libclang_rt.builtins-arm-android.a",
+ },
+ },
+ }
+
+ vendor_snapshot_shared {
+ name: "lib32",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "32",
+ vendor: true,
+ arch: {
+ arm: {
+ src: "lib32.so",
+ },
+ },
+ }
+
+ vendor_snapshot_shared {
+ name: "lib64",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "lib64.so",
+ },
+ },
+ }
+ vendor_snapshot_shared {
+ name: "liblog",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "liblog.so",
+ },
+ },
+ }
+
+ vendor_snapshot_static {
+ name: "libvendor",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "both",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "libvendor.a",
+ export_include_dirs: ["include/libvendor"],
+ },
+ arm: {
+ src: "libvendor.a",
+ export_include_dirs: ["include/libvendor"],
+ },
+ },
+ }
+
+ vendor_snapshot_shared {
+ name: "libvendor_available",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "both",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "libvendor_available.so",
+ export_include_dirs: ["include/libvendor"],
+ },
+ arm: {
+ src: "libvendor_available.so",
+ export_include_dirs: ["include/libvendor"],
+ },
+ },
+ }
+
+ vendor_snapshot_binary {
+ name: "bin",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "bin",
+ },
+ },
+ }
+
+ vendor_snapshot_binary {
+ name: "bin32",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "32",
+ vendor: true,
+ arch: {
+ arm: {
+ src: "bin32",
+ },
+ },
+ }
+
+ // old snapshot module which has to be ignored
+ vendor_snapshot_binary {
+ name: "bin",
+ version: "26",
+ target_arch: "arm64",
+ compile_multilib: "first",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "bin",
+ },
+ },
+ }
+
+ // different arch snapshot which has to be ignored
+ vendor_snapshot_binary {
+ name: "bin",
+ version: "30",
+ target_arch: "arm",
+ compile_multilib: "first",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "bin",
+ },
+ },
+ }
+`
+
+ mockFS := android.MockFS{
+ "framework/Android.bp": []byte(frameworkBp),
+ "framework/bin.rs": nil,
+ "vendor/Android.bp": []byte(vendorProprietaryBp),
+ "vendor/bin": nil,
+ "vendor/bin32": nil,
+ "vendor/bin.rs": nil,
+ "vendor/client.rs": nil,
+ "vendor/include/libvndk/a.h": nil,
+ "vendor/include/libvendor/b.h": nil,
+ "vendor/libvndk.a": nil,
+ "vendor/libvendor.a": nil,
+ "vendor/libvendor.so": nil,
+ "vendor/lib32.so": nil,
+ "vendor/lib64.so": nil,
+ "vendor/liblog.so": nil,
+ "vendor/libstd.rlib": nil,
+ "vendor/librust_vendor_available.rlib": nil,
+ "vendor/crtbegin_so.o": nil,
+ "vendor/crtend_so.o": nil,
+ "vendor/libclang_rt.builtins-aarch64-android.a": nil,
+ "vendor/libclang_rt.builtins-arm-android.a": nil,
+ "vndk/Android.bp": []byte(vndkBp),
+ "vndk/include/libvndk/a.h": nil,
+ "vndk/libvndk.so": nil,
+ }
+
+ sharedVariant := "android_vendor.30_arm64_armv8-a_shared"
+ rlibVariant := "android_vendor.30_arm64_armv8-a_rlib_rlib-std"
+ staticVariant := "android_vendor.30_arm64_armv8-a_static"
+ binaryVariant := "android_vendor.30_arm64_armv8-a"
+
+ shared32Variant := "android_vendor.30_arm_armv7-a-neon_shared"
+ binary32Variant := "android_vendor.30_arm_armv7-a-neon"
+
+ ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31")
+
+ // libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot
+ libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustc").Args["linkFlags"]
+ for _, input := range [][]string{
+ []string{sharedVariant, "libvndk.vndk.30.arm64"},
+ []string{staticVariant, "libvendor.vendor_static.30.arm64"},
+ []string{staticVariant, "libvendor_without_snapshot"},
+ } {
+ outputPaths := cc.GetOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
+ if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
+ t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
+ }
+ }
+
+ libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
+ if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib64", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
+ }
+
+ libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs
+ if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot", "libclang_rt.builtins-aarch64-android.vendor"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g)
+ }
+
+ libclientAndroidMkRlibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkRlibs
+ if g, w := libclientAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g)
+ }
+
+ libclientAndroidMkDylibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkDylibs
+ if len(libclientAndroidMkDylibs) > 0 {
+ t.Errorf("wanted libclient libclientAndroidMkDylibs [], got %q", libclientAndroidMkDylibs)
+ }
+
+ libclient32AndroidMkSharedLibs := ctx.ModuleForTests("libclient", shared32Variant).Module().(*Module).Properties.AndroidMkSharedLibs
+ if g, w := libclient32AndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib32", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g)
+ }
+
+ libclientRustAndroidMkRlibs := ctx.ModuleForTests("libclient_rust", rlibVariant).Module().(*Module).Properties.AndroidMkRlibs
+ if g, w := libclientRustAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g)
+ }
+
+ binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").Args["linkFlags"]
+ libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"})
+ if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
+ t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
+ libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
+ }
+
+ // bin is installed by bin.vendor_binary.30.arm64
+ ctx.ModuleForTests("bin.vendor_binary.30.arm64", binaryVariant).Output("bin")
+
+ // bin32 is installed by bin32.vendor_binary.30.arm64
+ ctx.ModuleForTests("bin32.vendor_binary.30.arm64", binary32Variant).Output("bin32")
+
+ // bin_without_snapshot is installed by bin_without_snapshot
+ ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
+
+ // libvendor, libvendor_available and bin don't have vendor.30 variant
+ libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
+ if android.InList(sharedVariant, libvendorVariants) {
+ t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
+ }
+
+ libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available")
+ if android.InList(sharedVariant, libvendorAvailableVariants) {
+ t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant)
+ }
+
+ binVariants := ctx.ModuleVariantsForTests("bin")
+ if android.InList(binaryVariant, binVariants) {
+ t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
+ }
+}
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 1c02bd0..635be10 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -265,3 +265,19 @@
"linker_config_proto",
],
}
+
+python_binary_host {
+ name: "get_clang_version",
+ main: "get_clang_version.py",
+ srcs: [
+ "get_clang_version.py",
+ ],
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ },
+ },
+}
diff --git a/scripts/OWNERS b/scripts/OWNERS
index 2b9c2de..1830a18 100644
--- a/scripts/OWNERS
+++ b/scripts/OWNERS
@@ -1,6 +1,6 @@
per-file system-clang-format,system-clang-format-2 = enh@google.com,smoreland@google.com
per-file build-mainline-modules.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
per-file build-aml-prebuilts.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
-per-file construct_context.py = ngeoffray@google.com,calin@google.com,mathieuc@google.com,skvadrik@google.com
+per-file construct_context.py = ngeoffray@google.com,calin@google.com,skvadrik@google.com
per-file conv_linker_config.py = kiyoungkim@google.com, jiyong@google.com, jooyung@google.com
per-file gen_ndk*.sh = sophiez@google.com, allenhair@google.com
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index 7d49492..b05861b 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -28,7 +28,6 @@
runtime-module-host-exports
runtime-module-sdk
statsd-module-sdk
- statsd-module-sdk-for-art
tzdata-module-test-exports
)
diff --git a/scripts/build-rustdocs.sh b/scripts/build-rustdocs.sh
new file mode 100755
index 0000000..ad8ba16
--- /dev/null
+++ b/scripts/build-rustdocs.sh
@@ -0,0 +1,31 @@
+#!/bin/bash -ex
+
+# 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.
+
+# Builds the platform rustdocs and copies them to the dist directory to provide
+# online docs for each build.
+
+if [ -z "${OUT_DIR}" ]; then
+ echo Must set OUT_DIR
+ exit 1
+fi
+
+source build/envsetup.sh
+m rustdoc
+
+if [ -n "${DIST_DIR}" ]; then
+ mkdir -p ${DIST_DIR}
+ cp -r ${OUT_DIR}/soong/rustdoc $DIST_DIR/rustdoc
+fi
diff --git a/scripts/gen_sorted_bss_symbols.sh b/scripts/gen_sorted_bss_symbols.sh
deleted file mode 100755
index a9b61a1..0000000
--- a/scripts/gen_sorted_bss_symbols.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash -e
-
-# Copyright 2019 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.
-
-# Script to generate a symbol ordering file that sorts bss section symbols by
-# their sizes.
-# Inputs:
-# Environment:
-# CLANG_BIN: path to the clang bin directory
-# Arguments:
-# $1: Input ELF file
-# $2: Output symbol ordering file
-
-set -o pipefail
-
-${CLANG_BIN}/llvm-nm --size-sort $1 | awk '{if ($2 == "b" || $2 == "B") print $3}' > $2
diff --git a/scripts/get_clang_version.py b/scripts/get_clang_version.py
new file mode 100755
index 0000000..622fca1
--- /dev/null
+++ b/scripts/get_clang_version.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+#
+# 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.
+"""A tool to report the current clang version used during build"""
+
+import os
+import re
+import sys
+
+
+ANDROID_BUILD_TOP = os.environ.get("ANDROID_BUILD_TOP", ".")
+
+def get_clang_prebuilts_version(global_go):
+ # TODO(b/187231324): Get clang version from the json file once it is no longer
+ # hard-coded in global.go
+ if global_go is None:
+ global_go = ANDROID_BUILD_TOP + '/build/soong/cc/config/global.go'
+ with open(global_go) as infile:
+ contents = infile.read()
+
+ regex_rev = r'\tClangDefaultVersion\s+= "clang-(?P<rev>r\d+[a-z]?\d?)"'
+ match_rev = re.search(regex_rev, contents)
+ if match_rev is None:
+ raise RuntimeError('Parsing clang info failed')
+ return match_rev.group('rev')
+
+
+def main():
+ global_go = sys.argv[1] if len(sys.argv) > 1 else None
+ print(get_clang_prebuilts_version(global_go));
+
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/get_clang_version_test.py b/scripts/get_clang_version_test.py
new file mode 100644
index 0000000..e57df6c
--- /dev/null
+++ b/scripts/get_clang_version_test.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+"""Unit tests for get_clang_version.py."""
+
+import unittest
+
+import get_clang_version
+
+class GetClangVersionTest(unittest.TestCase):
+ """Unit tests for get_clang_version."""
+
+ def test_get_clang_version(self):
+ """Test parsing of clang prebuilts version."""
+ self.assertIsNotNone(get_clang_version.get_clang_prebuilts_version())
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/scripts/hiddenapi/Android.bp b/scripts/hiddenapi/Android.bp
index 7472f52..7ffda62 100644
--- a/scripts/hiddenapi/Android.bp
+++ b/scripts/hiddenapi/Android.bp
@@ -48,6 +48,27 @@
},
}
+python_test_host {
+ name: "generate_hiddenapi_lists_test",
+ main: "generate_hiddenapi_lists_test.py",
+ srcs: [
+ "generate_hiddenapi_lists.py",
+ "generate_hiddenapi_lists_test.py",
+ ],
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ },
+ test_options: {
+ unit_test: true,
+ },
+}
+
python_binary_host {
name: "verify_overlaps",
main: "verify_overlaps.py",
@@ -62,3 +83,60 @@
},
},
}
+
+python_test_host {
+ name: "verify_overlaps_test",
+ main: "verify_overlaps_test.py",
+ srcs: [
+ "verify_overlaps.py",
+ "verify_overlaps_test.py",
+ ],
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ },
+ test_options: {
+ unit_test: true,
+ },
+}
+
+python_binary_host {
+ name: "signature_patterns",
+ main: "signature_patterns.py",
+ srcs: ["signature_patterns.py"],
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ },
+}
+
+python_test_host {
+ name: "signature_patterns_test",
+ main: "signature_patterns_test.py",
+ srcs: [
+ "signature_patterns.py",
+ "signature_patterns_test.py",
+ ],
+ version: {
+ py2: {
+ enabled: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: true,
+ },
+ },
+ test_options: {
+ unit_test: true,
+ },
+}
diff --git a/scripts/hiddenapi/generate_hiddenapi_lists_test.py b/scripts/hiddenapi/generate_hiddenapi_lists_test.py
index ff3d708..b81424b 100755
--- a/scripts/hiddenapi/generate_hiddenapi_lists_test.py
+++ b/scripts/hiddenapi/generate_hiddenapi_lists_test.py
@@ -101,4 +101,4 @@
self.assertEqual(extract_package(signature), expected_package)
if __name__ == '__main__':
- unittest.main()
+ unittest.main(verbosity=2)
diff --git a/scripts/hiddenapi/signature_patterns.py b/scripts/hiddenapi/signature_patterns.py
new file mode 100755
index 0000000..91328e6
--- /dev/null
+++ b/scripts/hiddenapi/signature_patterns.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+#
+# 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.
+"""
+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
+against which the modular flags can be compared.
+"""
+
+import argparse
+import csv
+
+def dict_reader(input):
+ return csv.DictReader(input, delimiter=',', quotechar='|', fieldnames=['signature'])
+
+def produce_patterns_from_file(file):
+ with open(file, 'r') as f:
+ return produce_patterns_from_stream(f)
+
+def produce_patterns_from_stream(stream):
+ patterns = []
+ allFlagsReader = dict_reader(stream)
+ for row in allFlagsReader:
+ signature = row['signature']
+ patterns.append(signature)
+ return patterns
+
+def main(args):
+ args_parser = argparse.ArgumentParser(description='Generate a set of signature patterns 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('--output', help='Generated signature prefixes')
+ args = args_parser.parse_args(args)
+
+ # Read in all the patterns into a list.
+ patterns = produce_patterns_from_file(args.flags)
+
+ # Write out all the patterns.
+ with open(args.output, 'w') as outputFile:
+ for pattern in patterns:
+ outputFile.write(pattern)
+ outputFile.write("\n")
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/scripts/hiddenapi/signature_patterns_test.py b/scripts/hiddenapi/signature_patterns_test.py
new file mode 100755
index 0000000..83c9db2
--- /dev/null
+++ b/scripts/hiddenapi/signature_patterns_test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit tests for signature_patterns.py."""
+import io
+import unittest
+
+from signature_patterns import *
+
+class TestGeneratedPatterns(unittest.TestCase):
+
+ def produce_patterns_from_string(self, csv):
+ with io.StringIO(csv) as f:
+ return produce_patterns_from_stream(f)
+
+ def test_generate(self):
+ patterns = self.produce_patterns_from_string('''
+Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
+Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
+''')
+ expected = [
+ "Ljava/lang/Object;->hashCode()I",
+ "Ljava/lang/Object;->toString()Ljava/lang/String;",
+ ]
+ self.assertEqual(expected, patterns)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/scripts/hiddenapi/verify_overlaps.py b/scripts/hiddenapi/verify_overlaps.py
index bb0917e..8579321 100755
--- a/scripts/hiddenapi/verify_overlaps.py
+++ b/scripts/hiddenapi/verify_overlaps.py
@@ -19,51 +19,123 @@
import argparse
import csv
-
-args_parser = argparse.ArgumentParser(description='Verify that one set of hidden API flags is a subset of another.')
-args_parser.add_argument('all', help='All the flags')
-args_parser.add_argument('subsets', nargs=argparse.REMAINDER, help='Subsets of the flags')
-args = args_parser.parse_args()
-
+from itertools import chain
def dict_reader(input):
return csv.DictReader(input, delimiter=',', quotechar='|', fieldnames=['signature'])
-# Read in all the flags into a dict indexed by signature
-allFlagsBySignature = {}
-with open(args.all, 'r') as allFlagsFile:
- allFlagsReader = dict_reader(allFlagsFile)
- for row in allFlagsReader:
+def extract_subset_from_monolithic_flags_as_dict_from_file(monolithicFlagsDict, patternsFile):
+ """
+ Extract a subset of flags from the dict containing all the monolithic flags.
+
+ :param monolithicFlagsDict: the dict containing all the monolithic flags.
+ :param patternsFile: a file containing a list of signature patterns that
+ define the subset.
+ :return: the dict from signature to row.
+ """
+ with open(patternsFile, 'r') as stream:
+ return extract_subset_from_monolithic_flags_as_dict_from_stream(monolithicFlagsDict, stream)
+
+def extract_subset_from_monolithic_flags_as_dict_from_stream(monolithicFlagsDict, stream):
+ """
+ Extract a subset of flags from the dict containing all the monolithic flags.
+
+ :param monolithicFlagsDict: the dict containing all the monolithic flags.
+ :param stream: a stream containing a list of signature patterns that define
+ the subset.
+ :return: the dict from signature to row.
+ """
+ dict = {}
+ for signature in stream:
+ signature = signature.rstrip()
+ dict[signature] = monolithicFlagsDict.get(signature, {})
+ return dict
+
+def read_signature_csv_from_stream_as_dict(stream):
+ """
+ Read the csv contents from the stream into a dict. The first column is assumed to be the
+ signature and used as the key. The whole row is stored as the value.
+
+ :param stream: the csv contents to read
+ :return: the dict from signature to row.
+ """
+ dict = {}
+ reader = dict_reader(stream)
+ for row in reader:
signature = row['signature']
- allFlagsBySignature[signature]=row
+ dict[signature] = row
+ return dict
-failed = False
-for subsetPath in args.subsets:
+def read_signature_csv_from_file_as_dict(csvFile):
+ """
+ Read the csvFile into a dict. The first column is assumed to be the
+ signature and used as the key. The whole row is stored as the value.
+
+ :param csvFile: the csv file to read
+ :return: the dict from signature to row.
+ """
+ with open(csvFile, 'r') as f:
+ return read_signature_csv_from_stream_as_dict(f)
+
+def compare_signature_flags(monolithicFlagsDict, modularFlagsDict):
+ """
+ Compare the signature flags between the two dicts.
+
+ :param monolithicFlagsDict: the dict containing the subset of the monolithic
+ flags that should be equal to the modular flags.
+ :param modularFlagsDict:the dict containing the flags produced by a single
+ bootclasspath_fragment module.
+ :return: list of mismatches., each mismatch is a tuple where the first item
+ is the signature, and the second and third items are lists of the flags from
+ modular dict, and monolithic dict respectively.
+ """
mismatchingSignatures = []
- with open(subsetPath, 'r') as subsetFlagsFile:
- subsetReader = dict_reader(subsetFlagsFile)
- for row in subsetReader:
- signature = row['signature']
- if signature in allFlagsBySignature:
- allFlags = allFlagsBySignature.get(signature)
- if allFlags != row:
- mismatchingSignatures.append((signature, row.get(None, []), allFlags.get(None, [])))
- else:
- mismatchingSignatures.append((signature, row.get(None, []), []))
+ # Create a sorted set of all the signatures from both the monolithic and
+ # modular dicts.
+ allSignatures = sorted(set(chain(monolithicFlagsDict.keys(), modularFlagsDict.keys())))
+ for signature in allSignatures:
+ monolithicRow = monolithicFlagsDict.get(signature, {})
+ monolithicFlags = monolithicRow.get(None, [])
+ modularRow = modularFlagsDict.get(signature, {})
+ modularFlags = modularRow.get(None, [])
+ if monolithicFlags != modularFlags:
+ mismatchingSignatures.append((signature, modularFlags, monolithicFlags))
+ return mismatchingSignatures
+def main(argv):
+ args_parser = argparse.ArgumentParser(description='Verify that sets of hidden API flags are each a subset of the monolithic flag file.')
+ args_parser.add_argument('monolithicFlags', help='The monolithic flag file')
+ args_parser.add_argument('modularFlags', nargs=argparse.REMAINDER, help='Flags produced by individual bootclasspath_fragment modules')
+ args = args_parser.parse_args(argv[1:])
- if mismatchingSignatures:
- failed = True
- print("ERROR: Hidden API flags are inconsistent:")
- print("< " + subsetPath)
- print("> " + args.all)
- for mismatch in mismatchingSignatures:
- print()
- print("< " + mismatch[0] + "," + ",".join(mismatch[1]))
- if mismatch[2] != []:
- print("> " + mismatch[0] + "," + ",".join(mismatch[2]))
- else:
- print("> " + mismatch[0] + " - missing")
+ # Read in the monolithic flags into a dict indexed by signature
+ monolithicFlagsPath = args.monolithicFlags
+ monolithicFlagsDict = read_signature_csv_from_file_as_dict(monolithicFlagsPath)
-if failed:
- sys.exit(1)
+ # For each subset specified on the command line, create dicts for the flags
+ # provided by the subset and the corresponding flags from the complete set of
+ # flags and compare them.
+ failed = False
+ for modularPair in args.modularFlags:
+ parts = modularPair.split(":")
+ modularFlagsPath = parts[0]
+ modularPatternsPath = parts[1]
+ modularFlagsDict = read_signature_csv_from_file_as_dict(modularFlagsPath)
+ monolithicFlagsSubsetDict = extract_subset_from_monolithic_flags_as_dict_from_file(monolithicFlagsDict, modularPatternsPath)
+ mismatchingSignatures = compare_signature_flags(monolithicFlagsSubsetDict, modularFlagsDict)
+ if mismatchingSignatures:
+ failed = True
+ print("ERROR: Hidden API flags are inconsistent:")
+ print("< " + modularFlagsPath)
+ print("> " + monolithicFlagsPath)
+ for mismatch in mismatchingSignatures:
+ signature = mismatch[0]
+ print()
+ print("< " + ",".join([signature]+ mismatch[1]))
+ print("> " + ",".join([signature]+ mismatch[2]))
+
+ if failed:
+ sys.exit(1)
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/scripts/hiddenapi/verify_overlaps_test.py b/scripts/hiddenapi/verify_overlaps_test.py
new file mode 100755
index 0000000..b6d5fa3
--- /dev/null
+++ b/scripts/hiddenapi/verify_overlaps_test.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit tests for verify_overlaps_test.py."""
+import io
+import unittest
+
+from verify_overlaps import *
+
+class TestDetectOverlaps(unittest.TestCase):
+
+ def read_signature_csv_from_string_as_dict(self, csv):
+ with io.StringIO(csv) as f:
+ return read_signature_csv_from_stream_as_dict(f)
+
+ def extract_subset_from_monolithic_flags_as_dict_from_string(self, monolithic, patterns):
+ with io.StringIO(patterns) as f:
+ return extract_subset_from_monolithic_flags_as_dict_from_stream(monolithic, f)
+
+ extractInput = '''
+Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
+Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
+'''
+
+ def test_extract_subset(self):
+ monolithic = self.read_signature_csv_from_string_as_dict(TestDetectOverlaps.extractInput)
+ modular = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
+''')
+
+ patterns = 'Ljava/lang/Object;->hashCode()I'
+
+ subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(monolithic, patterns)
+ expected = {
+ 'Ljava/lang/Object;->hashCode()I': {
+ None: ['public-api', 'system-api', 'test-api'],
+ 'signature': 'Ljava/lang/Object;->hashCode()I',
+ },
+ }
+ self.assertEqual(expected, subset)
+
+ def test_match(self):
+ monolithic = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
+''')
+ modular = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
+''')
+ mismatches = compare_signature_flags(monolithic, modular)
+ expected = []
+ self.assertEqual(expected, mismatches)
+
+ def test_mismatch_overlapping_flags(self):
+ monolithic = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->toString()Ljava/lang/String;,public-api
+''')
+ modular = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->toString()Ljava/lang/String;,public-api,system-api,test-api
+''')
+ mismatches = compare_signature_flags(monolithic, modular)
+ expected = [
+ (
+ 'Ljava/lang/Object;->toString()Ljava/lang/String;',
+ ['public-api', 'system-api', 'test-api'],
+ ['public-api'],
+ ),
+ ]
+ self.assertEqual(expected, mismatches)
+
+
+ def test_mismatch_monolithic_blocked(self):
+ monolithic = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
+''')
+ modular = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->toString()Ljava/lang/String;,public-api,system-api,test-api
+''')
+ mismatches = compare_signature_flags(monolithic, modular)
+ expected = [
+ (
+ 'Ljava/lang/Object;->toString()Ljava/lang/String;',
+ ['public-api', 'system-api', 'test-api'],
+ ['blocked'],
+ ),
+ ]
+ self.assertEqual(expected, mismatches)
+
+ def test_mismatch_modular_blocked(self):
+ monolithic = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->toString()Ljava/lang/String;,public-api,system-api,test-api
+''')
+ modular = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
+''')
+ mismatches = compare_signature_flags(monolithic, modular)
+ expected = [
+ (
+ 'Ljava/lang/Object;->toString()Ljava/lang/String;',
+ ['blocked'],
+ ['public-api', 'system-api', 'test-api'],
+ ),
+ ]
+ self.assertEqual(expected, mismatches)
+
+ def test_missing_from_monolithic(self):
+ monolithic = self.read_signature_csv_from_string_as_dict('')
+ modular = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->toString()Ljava/lang/String;,public-api,system-api,test-api
+''')
+ mismatches = compare_signature_flags(monolithic, modular)
+ expected = [
+ (
+ 'Ljava/lang/Object;->toString()Ljava/lang/String;',
+ ['public-api', 'system-api', 'test-api'],
+ [],
+ ),
+ ]
+ self.assertEqual(expected, mismatches)
+
+ def test_missing_from_modular(self):
+ monolithic = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
+''')
+ modular = {}
+ mismatches = compare_signature_flags(monolithic, modular)
+ expected = [
+ (
+ 'Ljava/lang/Object;->hashCode()I',
+ [],
+ ['public-api', 'system-api', 'test-api'],
+ ),
+ ]
+ self.assertEqual(expected, mismatches)
+
+ def test_blocked_missing_from_modular(self):
+ monolithic = self.read_signature_csv_from_string_as_dict('''
+Ljava/lang/Object;->hashCode()I,blocked
+''')
+ modular = {}
+ mismatches = compare_signature_flags(monolithic, modular)
+ expected = [
+ (
+ 'Ljava/lang/Object;->hashCode()I',
+ [],
+ ['blocked'],
+ ),
+ ]
+ self.assertEqual(expected, mismatches)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index 8168fbf..4ef4399 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -90,6 +90,15 @@
else:
manifest_required, manifest_optional, tags = extract_uses_libs_xml(manifest)
+ # Trim namespace component. Normally Soong does that automatically when it
+ # handles module names specified in Android.bp properties. However not all
+ # <uses-library> entries in the manifest correspond to real modules: some of
+ # the optional libraries may be missing at build time. Therefor this script
+ # accepts raw module names as spelled in Android.bp/Amdroid.mk and trims the
+ # optional namespace part manually.
+ required = trim_namespace_parts(required)
+ optional = trim_namespace_parts(optional)
+
if manifest_required == required and manifest_optional == optional:
return None
@@ -118,6 +127,17 @@
return errmsg
+MODULE_NAMESPACE = re.compile("^//[^:]+:")
+
+def trim_namespace_parts(modules):
+ """Trim the namespace part of each module, if present. Leave only the name."""
+
+ trimmed = []
+ for module in modules:
+ trimmed.append(MODULE_NAMESPACE.sub('', module))
+ return trimmed
+
+
def extract_uses_libs_apk(badging):
"""Extract <uses-library> tags from the manifest of an APK."""
diff --git a/scripts/manifest_check_test.py b/scripts/manifest_check_test.py
index 7159bdd..e3e8ac4 100755
--- a/scripts/manifest_check_test.py
+++ b/scripts/manifest_check_test.py
@@ -183,6 +183,15 @@
optional_uses_libraries=['bar'])
self.assertTrue(matches)
+ def test_mixed_with_namespace(self):
+ xml = self.xml_tmpl % ('\n'.join([uses_library_xml('foo'),
+ uses_library_xml('bar', required_xml(False))]))
+ apk = self.apk_tmpl % ('\n'.join([uses_library_apk('foo'),
+ uses_library_apk('bar', required_apk(False))]))
+ matches = self.run_test(xml, apk, uses_libraries=['//x/y/z:foo'],
+ optional_uses_libraries=['//x/y/z:bar'])
+ self.assertTrue(matches)
+
class ExtractTargetSdkVersionTest(unittest.TestCase):
def run_test(self, xml, apk, version):
diff --git a/scripts/microfactory.bash b/scripts/microfactory.bash
index 4bb6058..5e702e0 100644
--- a/scripts/microfactory.bash
+++ b/scripts/microfactory.bash
@@ -59,7 +59,7 @@
BUILDDIR=$(getoutdir) \
SRCDIR=${TOP} \
BLUEPRINTDIR=${TOP}/build/blueprint \
- EXTRA_ARGS="-pkg-path android/soong=${TOP}/build/soong -pkg-path github.com/golang/protobuf=${TOP}/external/golang-protobuf" \
+ EXTRA_ARGS="-pkg-path android/soong=${TOP}/build/soong -pkg-path google.golang.org/protobuf=${TOP}/external/golang-protobuf" \
build_go $@
}
diff --git a/scripts/rbc-run b/scripts/rbc-run
new file mode 100755
index 0000000..e2fa6d1
--- /dev/null
+++ b/scripts/rbc-run
@@ -0,0 +1,16 @@
+#! /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}"
+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
+
diff --git a/scripts/setup_go_workspace_for_soong.sh b/scripts/setup_go_workspace_for_soong.sh
index 479d09c..434d2fb 100755
--- a/scripts/setup_go_workspace_for_soong.sh
+++ b/scripts/setup_go_workspace_for_soong.sh
@@ -346,7 +346,7 @@
"${ANDROID_PATH}/build/blueprint|${OUTPUT_PATH}/src/github.com/google/blueprint"
"${ANDROID_PATH}/build/soong|${OUTPUT_PATH}/src/android/soong"
"${ANDROID_PATH}/art/build|${OUTPUT_PATH}/src/android/soong/art"
- "${ANDROID_PATH}/external/golang-protobuf|${OUTPUT_PATH}/src/github.com/golang/protobuf"
+ "${ANDROID_PATH}/external/golang-protobuf|${OUTPUT_PATH}/src/google.golang.org/protobuf"
"${ANDROID_PATH}/external/llvm/soong|${OUTPUT_PATH}/src/android/soong/llvm"
"${ANDROID_PATH}/external/clang/soong|${OUTPUT_PATH}/src/android/soong/clang"
"${ANDROID_PATH}/external/robolectric-shadows/soong|${OUTPUT_PATH}/src/android/soong/robolectric"
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 412e806..9166109 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -134,10 +134,11 @@
image_name: "art",
contents: ["mybootlib"],
hidden_api: {
- stub_flags: "hiddenapi/stub-flags.csv",
annotation_flags: "hiddenapi/annotation-flags.csv",
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
+ signature_patterns: "hiddenapi/signature-patterns.csv",
+ stub_flags: "hiddenapi/stub-flags.csv",
all_flags: "hiddenapi/all-flags.csv",
},
}
@@ -147,7 +148,7 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["com.android.art"],
- jars: ["java/mybootlib.jar"],
+ jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
}
`),
checkVersionedAndroidBpContents(`
@@ -161,10 +162,11 @@
image_name: "art",
contents: ["mysdk_mybootlib@current"],
hidden_api: {
- stub_flags: "hiddenapi/stub-flags.csv",
annotation_flags: "hiddenapi/annotation-flags.csv",
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
+ signature_patterns: "hiddenapi/signature-patterns.csv",
+ stub_flags: "hiddenapi/stub-flags.csv",
all_flags: "hiddenapi/all-flags.csv",
},
}
@@ -174,7 +176,7 @@
sdk_member_name: "mybootlib",
visibility: ["//visibility:public"],
apex_available: ["com.android.art"],
- jars: ["java/mybootlib.jar"],
+ jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
}
sdk_snapshot {
@@ -185,12 +187,13 @@
}
`),
checkAllCopyRules(`
-.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv
.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/signature-patterns.csv -> hiddenapi/signature-patterns.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/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
`),
snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot),
@@ -224,7 +227,7 @@
java.PrepareForTestWithJavaDefaultModules,
java.PrepareForTestWithJavaSdkLibraryFiles,
java.FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary", "mycoreplatform"),
- java.FixtureConfigureUpdatableBootJars("myapex:mybootlib", "myapex:myothersdklibrary"),
+ java.FixtureConfigureApexBootJars("myapex:mybootlib", "myapex:myothersdklibrary"),
prepareForSdkTestWithApex,
// Add a platform_bootclasspath that depends on the fragment.
@@ -332,10 +335,11 @@
stub_libs: ["mycoreplatform"],
},
hidden_api: {
- stub_flags: "hiddenapi/stub-flags.csv",
annotation_flags: "hiddenapi/annotation-flags.csv",
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
+ signature_patterns: "hiddenapi/signature-patterns.csv",
+ stub_flags: "hiddenapi/stub-flags.csv",
all_flags: "hiddenapi/all-flags.csv",
},
}
@@ -345,7 +349,7 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- jars: ["java/mybootlib.jar"],
+ jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
permitted_packages: ["mybootlib"],
}
@@ -416,10 +420,11 @@
stub_libs: ["mysdk_mycoreplatform@current"],
},
hidden_api: {
- stub_flags: "hiddenapi/stub-flags.csv",
annotation_flags: "hiddenapi/annotation-flags.csv",
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
+ signature_patterns: "hiddenapi/signature-patterns.csv",
+ stub_flags: "hiddenapi/stub-flags.csv",
all_flags: "hiddenapi/all-flags.csv",
},
}
@@ -429,7 +434,7 @@
sdk_member_name: "mybootlib",
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- jars: ["java/mybootlib.jar"],
+ jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
permitted_packages: ["mybootlib"],
}
@@ -494,12 +499,13 @@
}
`),
checkAllCopyRules(`
-.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv
.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/signature-patterns.csv -> hiddenapi/signature-patterns.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/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
.intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar
.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt
.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt
@@ -538,8 +544,138 @@
rule = module.Output("updatable-bcp-packages.txt")
expectedContents := `'mybootlib\nmyothersdklibrary\n'`
android.AssertStringEquals(t, "updatable-bcp-packages.txt", expectedContents, rule.Args["content"])
+
+ rule = module.Output("out/soong/hiddenapi/hiddenapi-flags.csv.valid")
+ android.AssertStringDoesContain(t, "verify-overlaps", rule.RuleParams.Command, " snapshot/hiddenapi/all-flags.csv:snapshot/hiddenapi/signature-patterns.csv ")
}),
snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot),
+ snapshotTestChecker(checkSnapshotWithSourcePreferred, func(t *testing.T, result *android.TestResult) {
+ module := result.ModuleForTests("platform-bootclasspath", "android_common")
+ rule := module.Output("out/soong/hiddenapi/hiddenapi-flags.csv.valid")
+ android.AssertStringDoesContain(t, "verify-overlaps", rule.RuleParams.Command, " out/soong/.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/all-flags.csv:out/soong/.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv ")
+ }),
+ snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot),
+ )
+}
+
+// TestSnapshotWithBootClasspathFragment_Fragments makes sure that the fragments property of a
+// bootclasspath_fragment is correctly output to the sdk snapshot.
+func TestSnapshotWithBootClasspathFragment_Fragments(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ java.PrepareForTestWithJavaDefaultModules,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("mysdklibrary", "myothersdklibrary"),
+ prepareForSdkTestWithApex,
+
+ // Some additional files needed for the myotherapex.
+ android.FixtureMergeMockFs(android.MockFS{
+ "system/sepolicy/apex/myotherapex-file_contexts": nil,
+ "myotherapex/apex_manifest.json": nil,
+ "myotherapex/Test.java": nil,
+ }),
+
+ android.FixtureAddTextFile("myotherapex/Android.bp", `
+ apex {
+ name: "myotherapex",
+ key: "myapex.key",
+ min_sdk_version: "2",
+ bootclasspath_fragments: ["myotherbootclasspathfragment"],
+ }
+
+ bootclasspath_fragment {
+ name: "myotherbootclasspathfragment",
+ apex_available: ["myotherapex"],
+ contents: [
+ "myotherlib",
+ ],
+ }
+
+ java_library {
+ name: "myotherlib",
+ apex_available: ["myotherapex"],
+ srcs: ["Test.java"],
+ min_sdk_version: "2",
+ permitted_packages: ["myothersdklibrary"],
+ compile_dex: true,
+ }
+ `),
+
+ android.FixtureWithRootAndroidBp(`
+ sdk {
+ name: "mysdk",
+ bootclasspath_fragments: ["mybootclasspathfragment"],
+ }
+
+ bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ contents: [
+ "mysdklibrary",
+ ],
+ fragments: [
+ {
+ apex: "myotherapex",
+ module: "myotherbootclasspathfragment"
+ },
+ ],
+ }
+
+ java_sdk_library {
+ name: "mysdklibrary",
+ srcs: ["Test.java"],
+ shared_library: false,
+ public: {enabled: true},
+ min_sdk_version: "2",
+ }
+ `),
+ ).RunTest(t)
+
+ // A preparer to update the test fixture used when processing an unpackage snapshot.
+ preparerForSnapshot := fixtureAddPrebuiltApexForBootclasspathFragment("myapex", "mybootclasspathfragment")
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_bootclasspath_fragment {
+ name: "mybootclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ contents: ["mysdklibrary"],
+ fragments: [
+ {
+ apex: "myotherapex",
+ module: "myotherbootclasspathfragment",
+ },
+ ],
+ hidden_api: {
+ annotation_flags: "hiddenapi/annotation-flags.csv",
+ metadata: "hiddenapi/metadata.csv",
+ index: "hiddenapi/index.csv",
+ signature_patterns: "hiddenapi/signature-patterns.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: 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",
+ },
+}
+ `),
+ snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot),
+ snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot),
snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot),
)
}
@@ -607,7 +743,7 @@
java.PrepareForTestWithJavaDefaultModules,
java.PrepareForTestWithJavaSdkLibraryFiles,
java.FixtureWithLastReleaseApis("mysdklibrary"),
- java.FixtureConfigureUpdatableBootJars("myapex:mybootlib"),
+ java.FixtureConfigureApexBootJars("myapex:mybootlib"),
prepareForSdkTestWithApex,
// Add a platform_bootclasspath that depends on the fragment.
@@ -717,10 +853,11 @@
max_target_o_low_priority: ["hiddenapi/my-max-target-o-low-priority.txt"],
blocked: ["hiddenapi/my-blocked.txt"],
unsupported_packages: ["hiddenapi/my-unsupported-packages.txt"],
- stub_flags: "hiddenapi/stub-flags.csv",
annotation_flags: "hiddenapi/annotation-flags.csv",
metadata: "hiddenapi/metadata.csv",
index: "hiddenapi/index.csv",
+ signature_patterns: "hiddenapi/signature-patterns.csv",
+ stub_flags: "hiddenapi/stub-flags.csv",
all_flags: "hiddenapi/all-flags.csv",
},
}
@@ -730,7 +867,7 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["myapex"],
- jars: ["java/mybootlib.jar"],
+ jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
permitted_packages: ["mybootlib"],
}
@@ -760,12 +897,13 @@
my-max-target-o-low-priority.txt -> hiddenapi/my-max-target-o-low-priority.txt
my-blocked.txt -> hiddenapi/my-blocked.txt
my-unsupported-packages.txt -> hiddenapi/my-unsupported-packages.txt
-.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv
.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/signature-patterns.csv -> hiddenapi/signature-patterns.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/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
.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/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 31555c0..25e35fc 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -347,6 +347,7 @@
cc_object {
name: "crtobj",
stl: "none",
+ system_shared_libs: [],
sanitize: {
never: true,
},
@@ -364,6 +365,7 @@
apex_available: ["//apex_available:platform"],
stl: "none",
compile_multilib: "both",
+ system_shared_libs: [],
sanitize: {
never: true,
},
@@ -388,6 +390,7 @@
apex_available: ["//apex_available:platform"],
stl: "none",
compile_multilib: "both",
+ system_shared_libs: [],
sanitize: {
never: true,
},
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 813dcfd..9efb3a4 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -453,7 +453,7 @@
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["//apex_available:platform"],
- jars: ["java/myjavalib.jar"],
+ jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"],
permitted_packages: ["pkg.myjavalib"],
}
`),
@@ -465,7 +465,7 @@
sdk_member_name: "myjavalib",
visibility: ["//visibility:public"],
apex_available: ["//apex_available:platform"],
- jars: ["java/myjavalib.jar"],
+ jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"],
permitted_packages: ["pkg.myjavalib"],
}
@@ -474,9 +474,10 @@
visibility: ["//visibility:public"],
java_boot_libs: ["myexports_myjavalib@current"],
}
+
`),
checkAllCopyRules(`
-.intermediates/myjavalib/android_common/withres/myjavalib.jar -> java/myjavalib.jar
+.intermediates/myexports/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar
`),
)
}
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index a13b0d7..85e3d87 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -15,19 +15,21 @@
package sdk
import (
- "android/soong/android"
"log"
"os"
+ "runtime"
"testing"
+ "android/soong/android"
+
"github.com/google/blueprint/proptools"
)
// Needed in an _test.go file in this package to ensure tests run correctly, particularly in IDE.
func TestMain(m *testing.M) {
- if android.BuildOs != android.Linux {
+ if runtime.GOOS != "linux" {
// b/145598135 - Generating host snapshots for anything other than linux is not supported.
- log.Printf("Skipping as sdk snapshot generation is only supported on %s not %s", android.Linux, android.BuildOs)
+ log.Printf("Skipping as sdk snapshot generation is only supported on linux not %s", runtime.GOOS)
os.Exit(0)
}
@@ -565,6 +567,49 @@
)
})
+ t.Run("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=module:build_from_source", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ preparer,
+ android.FixtureMergeEnv(map[string]string{
+ "SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR": "module:build_from_source",
+ }),
+ ).RunTest(t)
+
+ checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "mysdk_myjavalib@current",
+ sdk_member_name: "myjavalib",
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ jars: ["java/myjavalib.jar"],
+}
+
+java_import {
+ name: "myjavalib",
+ prefer: false,
+ use_source_config_var: {
+ config_namespace: "module",
+ var_name: "build_from_source",
+ },
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ jars: ["java/myjavalib.jar"],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ visibility: ["//visibility:public"],
+ java_header_libs: ["mysdk_myjavalib@current"],
+}
+ `),
+ )
+ })
+
t.Run("SOONG_SDK_SNAPSHOT_VERSION=unversioned", func(t *testing.T) {
result := android.GroupFixturePreparers(
preparer,
diff --git a/sdk/update.go b/sdk/update.go
index 84f0e4e..1cd8f13 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -22,6 +22,7 @@
"android/soong/apex"
"android/soong/cc"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -35,6 +36,37 @@
// By default every unversioned module in the generated snapshot has prefer: false. Building it
// with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true.
//
+// SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR
+// If set this specifies the Soong config var that can be used to control whether the prebuilt
+// modules from the generated snapshot or the original source modules. Values must be a colon
+// separated pair of strings, the first of which is the Soong config namespace, and the second
+// is the name of the variable within that namespace.
+//
+// The config namespace and var name are used to set the `use_source_config_var` property. That
+// in turn will cause the generated prebuilts to use the soong config variable to select whether
+// source or the prebuilt is used.
+// e.g. If an sdk snapshot is built using:
+// m SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=acme:build_from_source sdkextensions-sdk
+// Then the resulting snapshot will include:
+// use_source_config_var: {
+// config_namespace: "acme",
+// var_name: "build_from_source",
+// }
+//
+// Assuming that the config variable is defined in .mk using something like:
+// $(call add_soong_config_namespace,acme)
+// $(call add_soong_config_var_value,acme,build_from_source,true)
+//
+// Then when the snapshot is unpacked in the repository it will have the following behavior:
+// m droid - will use the sdkextensions-sdk prebuilts if present. Otherwise, it will use the
+// sources.
+// m SOONG_CONFIG_acme_build_from_source=true droid - will use the sdkextensions-sdk
+// sources, if present. Otherwise, it will use the prebuilts.
+//
+// This is a temporary mechanism to control the prefer flags and will be removed once a more
+// maintainable solution has been implemented.
+// TODO(b/174997203): Remove when no longer necessary.
+//
// SOONG_SDK_SNAPSHOT_VERSION
// This provides control over the version of the generated snapshot.
//
@@ -113,8 +145,16 @@
gc.indentLevel--
}
-func (gc *generatedContents) Printfln(format string, args ...interface{}) {
- fmt.Fprintf(&(gc.content), strings.Repeat(" ", gc.indentLevel)+format+"\n", args...)
+// IndentedPrintf will add spaces to indent the line to the appropriate level before printing the
+// arguments.
+func (gc *generatedContents) IndentedPrintf(format string, args ...interface{}) {
+ fmt.Fprintf(&(gc.content), strings.Repeat(" ", gc.indentLevel)+format, args...)
+}
+
+// UnindentedPrintf does not add spaces to indent the line to the appropriate level before printing
+// the arguments.
+func (gc *generatedContents) UnindentedPrintf(format string, args ...interface{}) {
+ fmt.Fprintf(&(gc.content), format, args...)
}
func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderContext, implicits android.Paths) {
@@ -752,6 +792,8 @@
module.insertAfter("name", "sdk_member_name", name)
// Remove the prefer property if present as versioned modules never need marking with prefer.
module.removeProperty("prefer")
+ // Ditto for use_source_config_var
+ module.removeProperty("use_source_config_var")
return module
}
@@ -809,13 +851,13 @@
}
func generateFilteredBpContents(contents *generatedContents, bpFile *bpFile, moduleFilter func(module *bpModule) bool) {
- contents.Printfln("// This is auto-generated. DO NOT EDIT.")
+ contents.IndentedPrintf("// This is auto-generated. DO NOT EDIT.\n")
for _, bpModule := range bpFile.order {
if moduleFilter(bpModule) {
- contents.Printfln("")
- contents.Printfln("%s {", bpModule.moduleType)
+ contents.IndentedPrintf("\n")
+ contents.IndentedPrintf("%s {\n", bpModule.moduleType)
outputPropertySet(contents, bpModule.bpPropertySet)
- contents.Printfln("}")
+ contents.IndentedPrintf("}\n")
}
}
}
@@ -826,7 +868,7 @@
addComment := func(name string) {
if text, ok := set.comments[name]; ok {
for _, line := range strings.Split(text, "\n") {
- contents.Printfln("// %s", line)
+ contents.IndentedPrintf("// %s\n", line)
}
}
}
@@ -843,29 +885,8 @@
}
addComment(name)
- switch v := value.(type) {
- case []string:
- length := len(v)
- if length > 1 {
- contents.Printfln("%s: [", name)
- contents.Indent()
- for i := 0; i < length; i = i + 1 {
- contents.Printfln("%q,", v[i])
- }
- contents.Dedent()
- contents.Printfln("],")
- } else if length == 0 {
- contents.Printfln("%s: [],", name)
- } else {
- contents.Printfln("%s: [%q],", name, v[0])
- }
-
- case bool:
- contents.Printfln("%s: %t,", name, v)
-
- default:
- contents.Printfln("%s: %q,", name, value)
- }
+ reflectValue := reflect.ValueOf(value)
+ outputNamedValue(contents, name, reflectValue)
}
for _, name := range set.order {
@@ -875,15 +896,94 @@
switch v := value.(type) {
case *bpPropertySet:
addComment(name)
- contents.Printfln("%s: {", name)
+ contents.IndentedPrintf("%s: {\n", name)
outputPropertySet(contents, v)
- contents.Printfln("},")
+ contents.IndentedPrintf("},\n")
}
}
contents.Dedent()
}
+// outputNamedValue outputs a value that has an associated name. The name will be indented, followed
+// by the value and then followed by a , and a newline.
+func outputNamedValue(contents *generatedContents, name string, value reflect.Value) {
+ contents.IndentedPrintf("%s: ", name)
+ outputUnnamedValue(contents, value)
+ contents.UnindentedPrintf(",\n")
+}
+
+// outputUnnamedValue outputs a single value. The value is not indented and is not followed by
+// either a , or a newline. With multi-line values, e.g. slices, all but the first line will be
+// indented and all but the last line will end with a newline.
+func outputUnnamedValue(contents *generatedContents, value reflect.Value) {
+ valueType := value.Type()
+ switch valueType.Kind() {
+ case reflect.Bool:
+ contents.UnindentedPrintf("%t", value.Bool())
+
+ case reflect.String:
+ contents.UnindentedPrintf("%q", value)
+
+ case reflect.Ptr:
+ outputUnnamedValue(contents, value.Elem())
+
+ case reflect.Slice:
+ length := value.Len()
+ if length == 0 {
+ contents.UnindentedPrintf("[]")
+ } else {
+ firstValue := value.Index(0)
+ if length == 1 && !multiLineValue(firstValue) {
+ contents.UnindentedPrintf("[")
+ outputUnnamedValue(contents, firstValue)
+ contents.UnindentedPrintf("]")
+ } else {
+ contents.UnindentedPrintf("[\n")
+ contents.Indent()
+ for i := 0; i < length; i++ {
+ itemValue := value.Index(i)
+ contents.IndentedPrintf("")
+ outputUnnamedValue(contents, itemValue)
+ contents.UnindentedPrintf(",\n")
+ }
+ contents.Dedent()
+ contents.IndentedPrintf("]")
+ }
+ }
+
+ case reflect.Struct:
+ // Avoid unlimited recursion by requiring every structure to implement android.BpPrintable.
+ v := value.Interface()
+ if _, ok := v.(android.BpPrintable); !ok {
+ panic(fmt.Errorf("property value %#v of type %T does not implement android.BpPrintable", v, v))
+ }
+ contents.UnindentedPrintf("{\n")
+ contents.Indent()
+ for f := 0; f < valueType.NumField(); f++ {
+ fieldType := valueType.Field(f)
+ if fieldType.Anonymous {
+ continue
+ }
+ fieldValue := value.Field(f)
+ fieldName := fieldType.Name
+ propertyName := proptools.PropertyNameForField(fieldName)
+ outputNamedValue(contents, propertyName, fieldValue)
+ }
+ contents.Dedent()
+ contents.IndentedPrintf("}")
+
+ default:
+ panic(fmt.Errorf("Unknown type: %T of value %#v", value, value))
+ }
+}
+
+// multiLineValue returns true if the supplied value may require multiple lines in the output.
+func multiLineValue(value reflect.Value) bool {
+ kind := value.Kind()
+ return kind == reflect.Slice || kind == reflect.Struct
+}
+
func (s *sdk) GetAndroidBpContentsForTests() string {
contents := &generatedContents{}
generateBpContents(contents, s.builderForTests.bpFile)
@@ -930,6 +1030,9 @@
filesToZip android.Paths
zipsToMerge android.Paths
+ // The path to an empty file.
+ emptyFile android.WritablePath
+
prebuiltModules map[string]*bpModule
prebuiltOrder []*bpModule
@@ -980,6 +1083,19 @@
s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
}
+func (s *snapshotBuilder) EmptyFile() android.Path {
+ if s.emptyFile == nil {
+ ctx := s.ctx
+ s.emptyFile = android.PathForModuleOut(ctx, "empty")
+ s.ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: s.emptyFile,
+ })
+ }
+
+ return s.emptyFile
+}
+
func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType string) android.BpModule {
name := member.Name()
if s.prebuiltModules[name] != nil {
@@ -1561,13 +1677,24 @@
// 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.
- prefer := ctx.sdkMemberContext.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
+ 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
// provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to
// check the behavior when a prebuilt is preferred. It also makes it explicit what the default
// behavior is for the module.
bpModule.insertAfter("name", "prefer", prefer)
+
+ configVar := config.Getenv("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR")
+ if configVar != "" {
+ parts := strings.Split(configVar, ":")
+ cfp := android.ConfigVarProperties{
+ Config_namespace: proptools.StringPtr(parts[0]),
+ Var_name: proptools.StringPtr(parts[1]),
+ }
+ bpModule.insertAfter("prefer", "use_source_config_var", cfp)
+ }
}
// Group the variants by os type.
@@ -1648,7 +1775,7 @@
var osTypes []android.OsType
for _, osType := range android.OsTypeList() {
if s.DeviceSupported() {
- if osType.Class == android.Device && osType != android.Fuchsia {
+ if osType.Class == android.Device {
osTypes = append(osTypes, osType)
}
}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 42d5680..1647428 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -104,6 +104,12 @@
Recovery_available *bool
}
+// Test option struct.
+type TestOptions struct {
+ // If the test is a hostside(no device required) unittest that shall be run during presubmit check.
+ Unit_test *bool
+}
+
type TestProperties struct {
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
@@ -143,6 +149,9 @@
// list of device library modules that should be installed alongside the test.
// Only available for host sh_test modules.
Data_device_libs []string `android:"path,arch_variant"`
+
+ // Test options.
+ Test_options TestOptions
}
type ShBinary struct {
@@ -440,6 +449,9 @@
dir := strings.TrimSuffix(s.dataModules[relPath].String(), relPath)
entries.AddStrings("LOCAL_TEST_DATA", dir+":"+relPath)
}
+ if Bool(s.testProperties.Test_options.Unit_test) {
+ entries.SetBool("LOCAL_IS_UNIT_TEST", true)
+ }
},
},
}}
@@ -483,6 +495,10 @@
module := &ShTest{}
InitShBinaryModule(&module.ShBinary)
module.AddProperties(&module.testProperties)
+ // Default sh_test_host to unit_tests = true
+ if module.testProperties.Test_options.Unit_test == nil {
+ module.testProperties.Test_options.Unit_test = proptools.BoolPtr(true)
+ }
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
return module
diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go
index 9e7e594..865d5f3 100644
--- a/sh/sh_binary_test.go
+++ b/sh/sh_binary_test.go
@@ -3,6 +3,7 @@
import (
"os"
"path/filepath"
+ "strconv"
"testing"
"android/soong/android"
@@ -114,7 +115,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := config.BuildOS.String()
arches := []string{"android_arm64_armv8-a", buildOS + "_x86_64"}
for _, arch := range arches {
variant := ctx.ModuleForTests("foo", arch)
@@ -148,14 +149,20 @@
"testdata/data1",
"testdata/sub/data2",
],
+ test_options: {
+ unit_test: true,
+ },
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := ctx.Config().BuildOS.String()
mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest)
if !mod.Host() {
t.Errorf("host bit is not set for a sh_test_host module.")
}
+ entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
+ actualData, _ := strconv.ParseBool(entries.EntryMap["LOCAL_IS_UNIT_TEST"][0])
+ android.AssertBoolEquals(t, "LOCAL_IS_UNIT_TEST", true, actualData)
}
func TestShTestHost_dataDeviceModules(t *testing.T) {
@@ -185,7 +192,7 @@
}
`)
- buildOS := android.BuildOs.String()
+ buildOS := config.BuildOS.String()
variant := ctx.ModuleForTests("foo", buildOS+"_x86_64")
relocated := variant.Output("relocated/lib64/libbar.so")
diff --git a/snapshot/Android.bp b/snapshot/Android.bp
new file mode 100644
index 0000000..f17ac53
--- /dev/null
+++ b/snapshot/Android.bp
@@ -0,0 +1,22 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-snapshot",
+ pkgPath: "android/soong/snapshot",
+ deps: [
+ "blueprint",
+ "blueprint-pathtools",
+ "soong",
+ "soong-android",
+ ],
+ srcs: [
+ "recovery_snapshot.go",
+ "snapshot.go",
+ "snapshot_base.go",
+ "util.go",
+ "vendor_snapshot.go",
+ ],
+ pluginFor: ["soong_build"],
+}
diff --git a/snapshot/recovery_snapshot.go b/snapshot/recovery_snapshot.go
new file mode 100644
index 0000000..9b3919c
--- /dev/null
+++ b/snapshot/recovery_snapshot.go
@@ -0,0 +1,130 @@
+// Copyright 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 snapshot
+
+import "android/soong/android"
+
+// Interface for modules which can be captured in the recovery snapshot.
+type RecoverySnapshotModuleInterface interface {
+ SnapshotModuleInterfaceBase
+ InRecovery() bool
+ ExcludeFromRecoverySnapshot() bool
+}
+
+var recoverySnapshotSingleton = SnapshotSingleton{
+ "recovery", // name
+ "SOONG_RECOVERY_SNAPSHOT_ZIP", // makeVar
+ android.OptionalPath{}, // snapshotZipFile
+ RecoverySnapshotImageSingleton, // Image
+ false, // Fake
+}
+
+func RecoverySnapshotSingleton() android.Singleton {
+ return &recoverySnapshotSingleton
+}
+
+// Determine if a dir under source tree is an SoC-owned proprietary directory based
+// on recovery snapshot configuration
+// Examples: device/, vendor/
+func isRecoveryProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
+ return RecoverySnapshotSingleton().(*SnapshotSingleton).Image.IsProprietaryPath(dir, deviceConfig)
+}
+
+func IsRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
+
+ // Any module in a recovery proprietary path is a recovery proprietary
+ // module.
+ if isRecoveryProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) {
+ return true
+ }
+
+ // However if the module is not in a recovery proprietary path, it may
+ // still be a recovery proprietary module. This happens for cc modules
+ // that are excluded from the recovery snapshot, and it means that the
+ // vendor has assumed control of the framework-provided module.
+
+ if c, ok := ctx.Module().(RecoverySnapshotModuleInterface); ok {
+ if c.ExcludeFromRecoverySnapshot() {
+ return true
+ }
+ }
+
+ return false
+}
+
+var RecoverySnapshotImageName = "recovery"
+
+type RecoverySnapshotImage struct{}
+
+func (RecoverySnapshotImage) Init(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton)
+}
+
+func (RecoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
+ // RECOVERY_SNAPSHOT_VERSION must be set to 'current' in order to generate a
+ // snapshot.
+ return ctx.DeviceConfig().RecoverySnapshotVersion() == "current"
+}
+
+func (RecoverySnapshotImage) InImage(m SnapshotModuleInterfaceBase) func() bool {
+ r, ok := m.(RecoverySnapshotModuleInterface)
+
+ if !ok {
+ // This module does not support recovery snapshot
+ return func() bool { return false }
+ }
+ return r.InRecovery
+}
+
+func (RecoverySnapshotImage) IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
+ return isDirectoryExcluded(dir, deviceConfig.RecoverySnapshotDirsExcludedMap(), deviceConfig.RecoverySnapshotDirsIncludedMap())
+}
+
+func (RecoverySnapshotImage) ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool {
+ r, ok := m.(RecoverySnapshotModuleInterface)
+
+ if !ok {
+ // This module does not support recovery snapshot
+ return true
+ }
+ return r.ExcludeFromRecoverySnapshot()
+}
+
+func (RecoverySnapshotImage) IsUsingSnapshot(cfg android.DeviceConfig) bool {
+ recoverySnapshotVersion := cfg.RecoverySnapshotVersion()
+ return recoverySnapshotVersion != "current" && recoverySnapshotVersion != ""
+}
+
+func (RecoverySnapshotImage) TargetSnapshotVersion(cfg android.DeviceConfig) string {
+ return cfg.RecoverySnapshotVersion()
+}
+
+func (RecoverySnapshotImage) ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
+ // If we're using full snapshot, not directed snapshot, capture every module
+ if !cfg.DirectedRecoverySnapshot() {
+ return false
+ }
+ // Else, checks if name is in RECOVERY_SNAPSHOT_MODULES.
+ return !cfg.RecoverySnapshotModules()[name]
+}
+
+func (RecoverySnapshotImage) ImageName() string {
+ return RecoverySnapshotImageName
+}
+
+var RecoverySnapshotImageSingleton RecoverySnapshotImage
+
+func init() {
+ RecoverySnapshotImageSingleton.Init(android.InitRegistrationContext)
+}
diff --git a/snapshot/snapshot.go b/snapshot/snapshot.go
new file mode 100644
index 0000000..294f8b6
--- /dev/null
+++ b/snapshot/snapshot.go
@@ -0,0 +1,122 @@
+// Copyright 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 snapshot
+
+import (
+ "path/filepath"
+ "sort"
+
+ "android/soong/android"
+)
+
+// This file contains singletons to capture snapshots. This singleton will generate snapshot of each target
+// image, and capturing snapshot module will be delegated to each module which implements GenerateSnapshotAction
+// function and register with RegisterSnapshotAction.
+
+var pctx = android.NewPackageContext("android/soong/snapshot")
+
+type SnapshotSingleton struct {
+ // Name, e.g., "vendor", "recovery", "ramdisk".
+ name string
+
+ // Make variable that points to the snapshot file, e.g.,
+ // "SOONG_RECOVERY_SNAPSHOT_ZIP".
+ makeVar string
+
+ // Path to the snapshot zip file.
+ snapshotZipFile android.OptionalPath
+
+ // Implementation of the image interface specific to the image
+ // associated with this snapshot (e.g., specific to the vendor image,
+ // recovery image, etc.).
+ Image SnapshotImage
+
+ // Whether this singleton is for fake snapshot or not.
+ // Fake snapshot is a snapshot whose prebuilt binaries and headers are empty.
+ // It is much faster to generate, and can be used to inspect dependencies.
+ Fake bool
+}
+
+// Interface of function to capture snapshot from each module
+type GenerateSnapshotAction func(snapshot SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) android.Paths
+
+var snapshotActionList []GenerateSnapshotAction
+
+// Register GenerateSnapshotAction function so it can be called while generating snapshot
+func RegisterSnapshotAction(x GenerateSnapshotAction) {
+ snapshotActionList = append(snapshotActionList, x)
+}
+
+func (c *SnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ if !c.Image.shouldGenerateSnapshot(ctx) {
+ return
+ }
+
+ var snapshotOutputs android.Paths
+
+ // Snapshot zipped artifacts will be captured under {SNAPSHOT_ARCH} directory
+
+ snapshotDir := c.name + "-snapshot"
+ if c.Fake {
+ // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
+ // collision with real snapshot files
+ snapshotDir = filepath.Join("fake", snapshotDir)
+ }
+ snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
+
+ for _, f := range snapshotActionList {
+ snapshotOutputs = append(snapshotOutputs, f(*c, ctx, snapshotArchDir)...)
+ }
+
+ // All artifacts are ready. Sort them to normalize ninja and then zip.
+ sort.Slice(snapshotOutputs, func(i, j int) bool {
+ return snapshotOutputs[i].String() < snapshotOutputs[j].String()
+ })
+
+ zipPath := android.PathForOutput(
+ ctx,
+ snapshotDir,
+ c.name+"-"+ctx.Config().DeviceName()+".zip")
+ zipRule := android.NewRuleBuilder(pctx, ctx)
+
+ // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
+ snapshotOutputList := android.PathForOutput(
+ ctx,
+ snapshotDir,
+ c.name+"-"+ctx.Config().DeviceName()+"_list")
+ rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
+ zipRule.Command().
+ Text("tr").
+ FlagWithArg("-d ", "\\'").
+ FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
+ FlagWithOutput("> ", snapshotOutputList)
+
+ zipRule.Temporary(snapshotOutputList)
+
+ zipRule.Command().
+ BuiltTool("soong_zip").
+ FlagWithOutput("-o ", zipPath).
+ FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
+ FlagWithInput("-l ", snapshotOutputList)
+
+ zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
+ zipRule.DeleteTemporaryFiles()
+ c.snapshotZipFile = android.OptionalPathForPath(zipPath)
+}
+
+func (c *SnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
+ ctx.Strict(
+ c.makeVar,
+ c.snapshotZipFile.String())
+}
diff --git a/snapshot/snapshot_base.go b/snapshot/snapshot_base.go
new file mode 100644
index 0000000..de93f3e
--- /dev/null
+++ b/snapshot/snapshot_base.go
@@ -0,0 +1,104 @@
+// Copyright 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 snapshot
+
+import (
+ "android/soong/android"
+ "path/filepath"
+)
+
+// Interface for modules which can be captured in the snapshot.
+type SnapshotModuleInterfaceBase interface{}
+
+// Defines the specifics of different images to which the snapshot process is applicable, e.g.,
+// vendor, recovery, ramdisk.
+type SnapshotImage interface {
+ // Returns true if a snapshot should be generated for this image.
+ shouldGenerateSnapshot(ctx android.SingletonContext) bool
+
+ // Function that returns true if the module is included in this image.
+ // Using a function return instead of a value to prevent early
+ // evalution of a function that may be not be defined.
+ InImage(m SnapshotModuleInterfaceBase) func() bool
+
+ // Returns true if a dir under source tree is an SoC-owned proprietary
+ // directory, such as device/, vendor/, etc.
+ //
+ // For a given snapshot (e.g., vendor, recovery, etc.) if
+ // isProprietaryPath(dir, deviceConfig) returns true, then the module in dir
+ // will be built from sources.
+ IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool
+
+ // Whether a given module has been explicitly excluded from the
+ // snapshot, e.g., using the exclude_from_vendor_snapshot or
+ // exclude_from_recovery_snapshot properties.
+ ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool
+
+ // Returns true if the build is using a snapshot for this image.
+ IsUsingSnapshot(cfg android.DeviceConfig) bool
+
+ // Returns a version of which the snapshot should be used in this target.
+ // This will only be meaningful when isUsingSnapshot is true.
+ TargetSnapshotVersion(cfg android.DeviceConfig) string
+
+ // Whether to exclude a given module from the directed snapshot or not.
+ // If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on,
+ // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured.
+ ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool
+
+ // Returns target image name
+ ImageName() string
+}
+
+type directoryMap map[string]bool
+
+var (
+ // Modules under following directories are ignored. They are OEM's and vendor's
+ // proprietary modules(device/, kernel/, vendor/, and hardware/).
+ defaultDirectoryExcludedMap = directoryMap{
+ "device": true,
+ "hardware": true,
+ "kernel": true,
+ "vendor": true,
+ }
+
+ // Modules under following directories are included as they are in AOSP,
+ // although hardware/ and kernel/ are normally for vendor's own.
+ defaultDirectoryIncludedMap = directoryMap{
+ "kernel/configs": true,
+ "kernel/prebuilts": true,
+ "kernel/tests": true,
+ "hardware/interfaces": true,
+ "hardware/libhardware": true,
+ "hardware/libhardware_legacy": true,
+ "hardware/ril": true,
+ }
+)
+
+func isDirectoryExcluded(dir string, excludedMap directoryMap, includedMap directoryMap) bool {
+ if dir == "." || dir == "/" {
+ return false
+ }
+ if includedMap[dir] {
+ return false
+ } else if excludedMap[dir] {
+ return true
+ } else if defaultDirectoryIncludedMap[dir] {
+ return false
+ } else if defaultDirectoryExcludedMap[dir] {
+ return true
+ } else {
+ return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap)
+ }
+}
diff --git a/snapshot/util.go b/snapshot/util.go
new file mode 100644
index 0000000..2297dfc
--- /dev/null
+++ b/snapshot/util.go
@@ -0,0 +1,36 @@
+// Copyright 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 snapshot
+
+import "android/soong/android"
+
+func WriteStringToFileRule(ctx android.SingletonContext, content, out string) android.OutputPath {
+ outPath := android.PathForOutput(ctx, out)
+ android.WriteFileRule(ctx, outPath, content)
+ return outPath
+}
+
+func CopyFileRule(pctx android.PackageContext, ctx android.SingletonContext, path android.Path, out string) android.OutputPath {
+ outPath := android.PathForOutput(ctx, out)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: path,
+ Output: outPath,
+ Description: "copy " + path.String() + " -> " + out,
+ Args: map[string]string{
+ "cpFlags": "-f -L",
+ },
+ })
+ return outPath
+}
diff --git a/snapshot/vendor_snapshot.go b/snapshot/vendor_snapshot.go
new file mode 100644
index 0000000..9bd26c2
--- /dev/null
+++ b/snapshot/vendor_snapshot.go
@@ -0,0 +1,147 @@
+// Copyright 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 snapshot
+
+import "android/soong/android"
+
+// Interface for modules which can be captured in the vendor snapshot.
+type VendorSnapshotModuleInterface interface {
+ SnapshotModuleInterfaceBase
+ InVendor() bool
+ ExcludeFromVendorSnapshot() bool
+}
+
+var vendorSnapshotSingleton = SnapshotSingleton{
+ "vendor", // name
+ "SOONG_VENDOR_SNAPSHOT_ZIP", // makeVar
+ android.OptionalPath{}, // snapshotZipFile
+ VendorSnapshotImageSingleton, // Image
+ false, // Fake
+}
+
+var vendorFakeSnapshotSingleton = SnapshotSingleton{
+ "vendor", // name
+ "SOONG_VENDOR_FAKE_SNAPSHOT_ZIP", // makeVar
+ android.OptionalPath{}, // snapshotZipFile
+ VendorSnapshotImageSingleton, // Image
+ true, // Fake
+}
+
+func VendorSnapshotSingleton() android.Singleton {
+ return &vendorSnapshotSingleton
+}
+
+func VendorFakeSnapshotSingleton() android.Singleton {
+ return &vendorFakeSnapshotSingleton
+}
+
+// Determine if a dir under source tree is an SoC-owned proprietary directory based
+// on vendor snapshot configuration
+// Examples: device/, vendor/
+func isVendorProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
+ return VendorSnapshotSingleton().(*SnapshotSingleton).Image.IsProprietaryPath(dir, deviceConfig)
+}
+
+func IsVendorProprietaryModule(ctx android.BaseModuleContext) bool {
+ // Any module in a vendor proprietary path is a vendor proprietary
+ // module.
+ if isVendorProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) {
+ return true
+ }
+
+ // However if the module is not in a vendor proprietary path, it may
+ // still be a vendor proprietary module. This happens for cc modules
+ // that are excluded from the vendor snapshot, and it means that the
+ // vendor has assumed control of the framework-provided module.
+ if c, ok := ctx.Module().(VendorSnapshotModuleInterface); ok {
+ if c.ExcludeFromVendorSnapshot() {
+ return true
+ }
+ }
+
+ return false
+}
+
+var VendorSnapshotImageName = "vendor"
+
+type VendorSnapshotImage struct{}
+
+func (VendorSnapshotImage) Init(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
+ ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
+}
+
+func (VendorSnapshotImage) RegisterAdditionalModule(ctx android.RegistrationContext, name string, factory android.ModuleFactory) {
+ ctx.RegisterModuleType(name, factory)
+}
+
+func (VendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
+ // BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot.
+ return ctx.DeviceConfig().VndkVersion() == "current"
+}
+
+func (VendorSnapshotImage) InImage(m SnapshotModuleInterfaceBase) func() bool {
+ v, ok := m.(VendorSnapshotModuleInterface)
+
+ if !ok {
+ // This module does not support Vendor snapshot
+ return func() bool { return false }
+ }
+
+ return v.InVendor
+}
+
+func (VendorSnapshotImage) IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
+ return isDirectoryExcluded(dir, deviceConfig.VendorSnapshotDirsExcludedMap(), deviceConfig.VendorSnapshotDirsIncludedMap())
+}
+
+func (VendorSnapshotImage) ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool {
+ v, ok := m.(VendorSnapshotModuleInterface)
+
+ if !ok {
+ // This module does not support Vendor snapshot
+ return true
+ }
+
+ return v.ExcludeFromVendorSnapshot()
+}
+
+func (VendorSnapshotImage) IsUsingSnapshot(cfg android.DeviceConfig) bool {
+ vndkVersion := cfg.VndkVersion()
+ return vndkVersion != "current" && vndkVersion != ""
+}
+
+func (VendorSnapshotImage) TargetSnapshotVersion(cfg android.DeviceConfig) string {
+ return cfg.VndkVersion()
+}
+
+// returns true iff a given module SHOULD BE EXCLUDED, false if included
+func (VendorSnapshotImage) ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
+ // If we're using full snapshot, not directed snapshot, capture every module
+ if !cfg.DirectedVendorSnapshot() {
+ return false
+ }
+ // Else, checks if name is in VENDOR_SNAPSHOT_MODULES.
+ return !cfg.VendorSnapshotModules()[name]
+}
+
+func (VendorSnapshotImage) ImageName() string {
+ return VendorSnapshotImageName
+}
+
+var VendorSnapshotImageSingleton VendorSnapshotImage
+
+func init() {
+ VendorSnapshotImageSingleton.Init(android.InitRegistrationContext)
+}
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index f1c2d0d..a29d4c3 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -145,6 +145,9 @@
// If set to true, allow this module to be dexed and installed on devices.
Installable *bool
+ // Make this module available when building for ramdisk
+ Ramdisk_available *bool
+
// Make this module available when building for recovery
Recovery_available *bool
@@ -396,6 +399,7 @@
Recovery_available *bool
Vendor_available *bool
Product_available *bool
+ Ramdisk_available *bool
Host_supported *bool
Apex_available []string
Min_sdk_version *string
@@ -475,6 +479,7 @@
ccProps.Recovery_available = m.properties.Recovery_available
ccProps.Vendor_available = m.properties.Vendor_available
ccProps.Product_available = m.properties.Product_available
+ ccProps.Ramdisk_available = m.properties.Ramdisk_available
ccProps.Host_supported = m.properties.Host_supported
ccProps.Apex_available = m.ApexProperties.Apex_available
ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index 3f51114..1258684 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -7,6 +7,8 @@
source "$(dirname "$0")/lib.sh"
+readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
+
function test_smoke {
setup
run_soong
@@ -484,6 +486,39 @@
fi
}
+function test_write_to_source_tree {
+ setup
+ mkdir -p a
+ cat > a/Android.bp <<EOF
+genrule {
+ name: "write_to_source_tree",
+ out: ["write_to_source_tree"],
+ cmd: "touch file_in_source_tree && touch \$(out)",
+}
+EOF
+ readonly EXPECTED_OUT=out/soong/.intermediates/a/write_to_source_tree/gen/write_to_source_tree
+ readonly ERROR_LOG=${MOCK_TOP}/out/error.log
+ readonly ERROR_MSG="Read-only file system"
+ readonly ERROR_HINT_PATTERN="BUILD_BROKEN_SRC_DIR"
+ # Test in ReadOnly source tree
+ run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=false ${EXPECTED_OUT} &> /dev/null && \
+ fail "Write to source tree should not work in a ReadOnly source tree"
+
+ if grep -q "${ERROR_MSG}" ${ERROR_LOG} && grep -q "${ERROR_HINT_PATTERN}" ${ERROR_LOG} ; then
+ echo Error message and error hint found in logs >/dev/null
+ else
+ fail "Did not find Read-only error AND error hint in error.log"
+ fi
+
+ # Test in ReadWrite source tree
+ run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true ${EXPECTED_OUT} &> /dev/null || \
+ fail "Write to source tree did not succeed in a ReadWrite source tree"
+
+ if grep -q "${ERROR_MSG}\|${ERROR_HINT_PATTERN}" ${ERROR_LOG} ; then
+ fail "Found read-only error OR error hint in error.log"
+ fi
+}
+
function test_bp2build_smoke {
setup
GENERATE_BAZEL_FILES=1 run_soong
@@ -491,6 +526,21 @@
[[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
}
+function test_bp2build_generates_fake_ninja_file {
+ setup
+ create_mock_bazel
+
+ run_bp2build
+
+ if [[ ! -f "./out/soong/build.ninja" ]]; then
+ fail "./out/soong/build.ninja was not generated"
+ fi
+
+ if ! grep "build nothing: phony" "./out/soong/build.ninja"; then
+ fail "missing phony nothing target in out/soong/build.ninja"
+ fi
+}
+
function test_bp2build_add_android_bp {
setup
@@ -505,8 +555,8 @@
EOF
GENERATE_BAZEL_FILES=1 run_soong
- [[ -e out/soong/bp2build/a/BUILD ]] || fail "a/BUILD not created"
- [[ -L out/soong/workspace/a/BUILD ]] || fail "a/BUILD not symlinked"
+ [[ -e out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created"
+ [[ -L out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked"
mkdir -p b
touch b/b.txt
@@ -519,8 +569,8 @@
EOF
GENERATE_BAZEL_FILES=1 run_soong
- [[ -e out/soong/bp2build/b/BUILD ]] || fail "a/BUILD not created"
- [[ -L out/soong/workspace/b/BUILD ]] || fail "a/BUILD not symlinked"
+ [[ -e out/soong/bp2build/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created"
+ [[ -L out/soong/workspace/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked"
}
function test_bp2build_null_build {
@@ -551,11 +601,11 @@
EOF
GENERATE_BAZEL_FILES=1 run_soong
- grep -q a1.txt out/soong/bp2build/a/BUILD || fail "a1.txt not in BUILD file"
+ grep -q a1.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a1.txt not in ${GENERATED_BUILD_FILE_NAME} file"
touch a/a2.txt
GENERATE_BAZEL_FILES=1 run_soong
- grep -q a2.txt out/soong/bp2build/a/BUILD || fail "a2.txt not in BUILD file"
+ grep -q a2.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a2.txt not in ${GENERATED_BUILD_FILE_NAME} file"
}
function test_dump_json_module_graph() {
@@ -583,8 +633,8 @@
GENERATE_BAZEL_FILES=1 run_soong
[[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
[[ -d out/soong/workspace/a/b ]] || fail "module directory not a directory"
- [[ -L out/soong/workspace/a/b/BUILD ]] || fail "BUILD file not symlinked"
- [[ "$(readlink -f out/soong/workspace/a/b/BUILD)" =~ bp2build/a/b/BUILD$ ]] \
+ [[ -L "out/soong/workspace/a/b/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked"
+ [[ "$(readlink -f out/soong/workspace/a/b/${GENERATED_BUILD_FILE_NAME})" =~ "bp2build/a/b/${GENERATED_BUILD_FILE_NAME}"$ ]] \
|| fail "BUILD files symlinked at the wrong place"
[[ -L out/soong/workspace/a/b/b.txt ]] || fail "a/b/b.txt not symlinked"
[[ -L out/soong/workspace/a/a.txt ]] || fail "a/b/a.txt not symlinked"
@@ -616,7 +666,7 @@
mkdir -p a
touch a/a.txt
- touch a/BUILD
+ touch a/${GENERATED_BUILD_FILE_NAME}
cat > a/Android.bp <<EOF
filegroup {
name: "a",
@@ -626,15 +676,15 @@
EOF
GENERATE_BAZEL_FILES=1 run_soong
- [[ -L out/soong/workspace/a/BUILD ]] || fail "BUILD file not symlinked"
- [[ "$(readlink -f out/soong/workspace/a/BUILD)" =~ bp2build/a/BUILD$ ]] \
- || fail "BUILD files symlinked to the wrong place"
+ [[ -L "out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked"
+ [[ "$(readlink -f out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME})" =~ "bp2build/a/${GENERATED_BUILD_FILE_NAME}"$ ]] \
+ || fail "${GENERATED_BUILD_FILE_NAME} files symlinked to the wrong place"
}
function test_bp2build_reports_multiple_errors {
setup
- mkdir -p a/BUILD
+ mkdir -p "a/${GENERATED_BUILD_FILE_NAME}"
touch a/a.txt
cat > a/Android.bp <<EOF
filegroup {
@@ -644,7 +694,7 @@
}
EOF
- mkdir -p b/BUILD
+ mkdir -p "b/${GENERATED_BUILD_FILE_NAME}"
touch b/b.txt
cat > b/Android.bp <<EOF
filegroup {
@@ -658,8 +708,8 @@
fail "Build should have failed"
fi
- grep -q "a/BUILD' exist" "$MOCK_TOP/errors" || fail "Error for a/BUILD not found"
- grep -q "b/BUILD' exist" "$MOCK_TOP/errors" || fail "Error for b/BUILD not found"
+ grep -q "a/${GENERATED_BUILD_FILE_NAME}' exist" "$MOCK_TOP/errors" || fail "Error for a/${GENERATED_BUILD_FILE_NAME} not found"
+ grep -q "b/${GENERATED_BUILD_FILE_NAME}' exist" "$MOCK_TOP/errors" || fail "Error for b/${GENERATED_BUILD_FILE_NAME} not found"
}
test_smoke
@@ -675,7 +725,9 @@
test_glob_during_bootstrapping
test_soong_build_rerun_iff_environment_changes
test_dump_json_module_graph
+test_write_to_source_tree
test_bp2build_smoke
+test_bp2build_generates_fake_ninja_file
test_bp2build_null_build
test_bp2build_add_android_bp
test_bp2build_add_to_glob
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index 082cd06..e357710 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -6,6 +6,8 @@
source "$(dirname "$0")/lib.sh"
+readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
+
function test_bp2build_generates_all_buildfiles {
setup
create_mock_bazel
@@ -40,24 +42,24 @@
run_bp2build
- if [[ ! -f "./out/soong/workspace/foo/convertible_soong_module/BUILD" ]]; then
- fail "./out/soong/workspace/foo/convertible_soong_module/BUILD was not generated"
+ if [[ ! -f "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
+ fail "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
fi
- if [[ ! -f "./out/soong/workspace/foo/unconvertible_soong_module/BUILD" ]]; then
- fail "./out/soong/workspace/foo/unconvertible_soong_module/BUILD was not generated"
+ if [[ ! -f "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
+ fail "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
fi
- if ! grep "the_answer" "./out/soong/workspace/foo/convertible_soong_module/BUILD"; then
- fail "missing BUILD target the_answer in convertible_soong_module/BUILD"
+ if ! grep "the_answer" "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
+ fail "missing BUILD target the_answer in convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
fi
- if grep "not_the_answer" "./out/soong/workspace/foo/unconvertible_soong_module/BUILD"; then
- fail "found unexpected BUILD target not_the_answer in unconvertible_soong_module/BUILD"
+ if grep "not_the_answer" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
+ fail "found unexpected BUILD target not_the_answer in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
fi
- if ! grep "filegroup" "./out/soong/workspace/foo/unconvertible_soong_module/BUILD"; then
- fail "missing filegroup in unconvertible_soong_module/BUILD"
+ if ! grep "filegroup" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
+ fail "missing filegroup in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
fi
# NOTE: We don't actually use the extra BUILD file for anything here
diff --git a/tests/lib.sh b/tests/lib.sh
index e561a3d..1d9b8d4 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -86,6 +86,7 @@
symlink_directory prebuilts/go
symlink_directory prebuilts/build-tools
+ symlink_directory external/go-cmp
symlink_directory external/golang-protobuf
touch "$MOCK_TOP/Android.bp"
@@ -114,6 +115,7 @@
symlink_directory prebuilts/jdk
symlink_file WORKSPACE
+ symlink_file BUILD
symlink_file tools/bazel
}
@@ -125,6 +127,10 @@
GENERATE_BAZEL_FILES=true build/soong/soong_ui.bash --make-mode --skip-ninja --skip-make --skip-soong-tests nothing
}
+run_ninja() {
+ build/soong/soong_ui.bash --make-mode --skip-make --skip-soong-tests "$@"
+}
+
info "Starting Soong integration test suite $(basename $0)"
info "Mock top: $MOCK_TOP"
diff --git a/tests/mixed_mode_test.sh b/tests/mixed_mode_test.sh
index 80774bf..b408fd3 100755
--- a/tests/mixed_mode_test.sh
+++ b/tests/mixed_mode_test.sh
@@ -14,7 +14,7 @@
setup
create_mock_bazel
- run_bazel info
+ STANDALONE_BAZEL=true run_bazel info
}
test_bazel_smoke
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index d17b464..37940ba 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -60,6 +60,7 @@
"path.go",
"proc_sync.go",
"rbe.go",
+ "sandbox_config.go",
"signal.go",
"soong.go",
"test_build.go",
@@ -86,5 +87,8 @@
"config_linux.go",
"sandbox_linux.go",
],
+ testSrcs: [
+ "sandbox_linux_test.go",
+ ],
},
}
diff --git a/ui/build/build.go b/ui/build/build.go
index 8f050d9..1ed9014 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -28,16 +28,20 @@
func SetupOutDir(ctx Context, config Config) {
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "Android.mk"))
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
- if !config.SkipKati() {
- // Run soong_build with Kati for a hybrid build, e.g. running the
- // AndroidMk singleton and postinstall commands. Communicate this to
- // soong_build by writing an empty .soong.kati_enabled marker file in the
- // soong_build output directory for the soong_build primary builder to
- // know if the user wants to run Kati after.
- //
- // This does not preclude running Kati for *product configuration purposes*.
- ensureEmptyFileExists(ctx, filepath.Join(config.SoongOutDir(), ".soong.kati_enabled"))
+
+ // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
+ // potentially run the AndroidMk singleton and postinstall commands.
+ // Note that the absence of the file does not not preclude running Kati for product
+ // configuration purposes.
+ katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
+ if config.SkipKatiNinja() {
+ os.Remove(katiEnabledMarker)
+ // Note that we can not remove the file for SkipKati builds yet -- some continuous builds
+ // --skip-make builds rely on kati targets being defined.
+ } else if !config.SkipKati() {
+ ensureEmptyFileExists(ctx, katiEnabledMarker)
}
+
// The ninja_build file is used by our buildbots to understand that the output
// can be parsed as ninja output.
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
@@ -274,6 +278,11 @@
// Return early, if we're using Soong as solely the generator of BUILD files.
return
}
+
+ if config.bazelBuildMode() == generateJsonModuleGraph {
+ // Return early, if we're using Soong as solely the generator of the JSON module graph
+ return
+ }
}
if what&RunKati != 0 {
diff --git a/ui/build/config.go b/ui/build/config.go
index 862e09f..918a956 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -25,7 +25,7 @@
"android/soong/shared"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
smpb "android/soong/ui/metrics/metrics_proto"
)
@@ -58,6 +58,7 @@
katiSuffix string
targetDevice string
targetDeviceDir string
+ sandboxConfig *SandboxConfig
// Autodetected
totalRAM uint64
@@ -107,6 +108,9 @@
// Only generate build files (in a subdirectory of the out directory) and exit.
generateBuildFiles
+ // Only generate the Soong json module graph for use with jq, and exit.
+ generateJsonModuleGraph
+
// Generate synthetic build files and incorporate these files into a build which
// partially uses Bazel. Build metadata may come from Android.bp or BUILD files.
mixedBuild
@@ -124,7 +128,8 @@
func NewConfig(ctx Context, args ...string) Config {
ret := &configImpl{
- environ: OsEnvironment(),
+ environ: OsEnvironment(),
+ sandboxConfig: &SandboxConfig{},
}
// Default matching ninja
@@ -156,6 +161,10 @@
ret.distDir = filepath.Join(ret.OutDir(), "dist")
}
+ if srcDirIsWritable, ok := ret.environ.Get("BUILD_BROKEN_SRC_DIR_IS_WRITABLE"); ok {
+ ret.sandboxConfig.SetSrcDirIsRO(srcDirIsWritable == "false")
+ }
+
ret.environ.Unset(
// We're already using it
"USE_SOONG_UI",
@@ -336,12 +345,7 @@
return
}
- b := &smpb.BuildConfig{
- ForceUseGoma: proto.Bool(config.ForceUseGoma()),
- UseGoma: proto.Bool(config.UseGoma()),
- UseRbe: proto.Bool(config.UseRBE()),
- }
- ctx.Metrics.BuildConfig(b)
+ ctx.Metrics.BuildConfig(buildConfig(config))
s := &smpb.SystemResourceInfo{
TotalPhysicalMemory: proto.Uint64(config.TotalRAM()),
@@ -350,6 +354,16 @@
ctx.Metrics.SystemResourceInfo(s)
}
+func buildConfig(config Config) *smpb.BuildConfig {
+ return &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),
+ }
+}
+
// getConfigArgs processes the command arguments based on the build action and creates a set of new
// arguments to be accepted by Config.
func getConfigArgs(action BuildAction, dir string, ctx Context, args []string) []string {
@@ -571,6 +585,9 @@
} else if arg == "--skip-ninja" {
c.skipNinja = true
} else if arg == "--skip-make" {
+ // TODO(ccross): deprecate this, it has confusing behaviors. It doesn't run kati,
+ // but it does run a Kati ninja file if the .kati_enabled marker file was created
+ // by a previous build.
c.skipConfig = true
c.skipKati = true
} else if arg == "--skip-kati" {
@@ -579,6 +596,8 @@
} else if arg == "--soong-only" {
c.skipKati = true
c.skipKatiNinja = true
+ } else if arg == "--skip-config" {
+ c.skipConfig = true
} else if arg == "--skip-soong-tests" {
c.skipSoongTests = true
} else if len(arg) > 0 && arg[0] == '-' {
@@ -929,6 +948,8 @@
return mixedBuild
} else if c.Environment().IsEnvTrue("GENERATE_BAZEL_FILES") {
return generateBuildFiles
+ } else if v, ok := c.Environment().Get("SOONG_DUMP_JSON_MODULE_GRAPH"); ok && v != "" {
+ return generateJsonModuleGraph
} else {
return noBazel
}
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index 7b14c47..1f2158b 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -26,7 +26,10 @@
"testing"
"android/soong/ui/logger"
+ smpb "android/soong/ui/metrics/metrics_proto"
"android/soong/ui/status"
+
+ "google.golang.org/protobuf/proto"
)
func testContext() Context {
@@ -995,3 +998,111 @@
})
}
}
+
+func TestBuildConfig(t *testing.T) {
+ tests := []struct {
+ name string
+ environ Environment
+ useBazel bool
+ expectedBuildConfig *smpb.BuildConfig
+ }{
+ {
+ name: "none set",
+ environ: Environment{},
+ expectedBuildConfig: &smpb.BuildConfig{
+ ForceUseGoma: proto.Bool(false),
+ UseGoma: proto.Bool(false),
+ UseRbe: proto.Bool(false),
+ BazelAsNinja: proto.Bool(false),
+ BazelMixedBuild: proto.Bool(false),
+ },
+ },
+ {
+ name: "force use goma",
+ environ: Environment{"FORCE_USE_GOMA=1"},
+ expectedBuildConfig: &smpb.BuildConfig{
+ ForceUseGoma: proto.Bool(true),
+ UseGoma: proto.Bool(false),
+ UseRbe: proto.Bool(false),
+ BazelAsNinja: proto.Bool(false),
+ BazelMixedBuild: proto.Bool(false),
+ },
+ },
+ {
+ name: "use goma",
+ environ: Environment{"USE_GOMA=1"},
+ expectedBuildConfig: &smpb.BuildConfig{
+ ForceUseGoma: proto.Bool(false),
+ UseGoma: proto.Bool(true),
+ UseRbe: proto.Bool(false),
+ BazelAsNinja: proto.Bool(false),
+ BazelMixedBuild: proto.Bool(false),
+ },
+ },
+ {
+ name: "use rbe",
+ environ: Environment{"USE_RBE=1"},
+ expectedBuildConfig: &smpb.BuildConfig{
+ ForceUseGoma: proto.Bool(false),
+ UseGoma: proto.Bool(false),
+ UseRbe: proto.Bool(true),
+ BazelAsNinja: proto.Bool(false),
+ BazelMixedBuild: proto.Bool(false),
+ },
+ },
+ {
+ name: "use bazel as ninja",
+ environ: Environment{},
+ useBazel: true,
+ expectedBuildConfig: &smpb.BuildConfig{
+ ForceUseGoma: proto.Bool(false),
+ UseGoma: proto.Bool(false),
+ UseRbe: proto.Bool(false),
+ BazelAsNinja: proto.Bool(true),
+ BazelMixedBuild: proto.Bool(false),
+ },
+ },
+ {
+ name: "bazel mixed build",
+ environ: Environment{"USE_BAZEL_ANALYSIS=1"},
+ expectedBuildConfig: &smpb.BuildConfig{
+ ForceUseGoma: proto.Bool(false),
+ UseGoma: proto.Bool(false),
+ UseRbe: proto.Bool(false),
+ BazelAsNinja: proto.Bool(false),
+ BazelMixedBuild: proto.Bool(true),
+ },
+ },
+ {
+ name: "all set",
+ environ: Environment{
+ "FORCE_USE_GOMA=1",
+ "USE_GOMA=1",
+ "USE_RBE=1",
+ "USE_BAZEL_ANALYSIS=1",
+ },
+ useBazel: true,
+ expectedBuildConfig: &smpb.BuildConfig{
+ ForceUseGoma: proto.Bool(true),
+ UseGoma: proto.Bool(true),
+ UseRbe: proto.Bool(true),
+ BazelAsNinja: proto.Bool(true),
+ BazelMixedBuild: proto.Bool(true),
+ },
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ c := &configImpl{
+ environ: &tc.environ,
+ useBazel: tc.useBazel,
+ }
+ config := Config{c}
+ actualBuildConfig := buildConfig(config)
+ if expected := tc.expectedBuildConfig; !proto.Equal(expected, actualBuildConfig) {
+ t.Errorf("Expected build config != actual build config: %#v != %#v", *expected, *actualBuildConfig)
+ }
+ })
+ }
+}
diff --git a/ui/build/context.go b/ui/build/context.go
index 43e1e0f..f5e987e 100644
--- a/ui/build/context.go
+++ b/ui/build/context.go
@@ -20,7 +20,7 @@
"android/soong/ui/logger"
"android/soong/ui/metrics"
- "android/soong/ui/metrics/metrics_proto"
+ soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
"android/soong/ui/status"
"android/soong/ui/tracer"
)
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 54aeda0..3d16073 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_USE_SOURCE_CONFIG_VAR",
"SOONG_SDK_SNAPSHOT_VERSION",
}
@@ -225,6 +226,10 @@
// Extra environment variables to be exported to ninja
"BUILD_BROKEN_NINJA_USES_ENV_VARS",
+ // Used to restrict write access to source tree
+ "BUILD_BROKEN_SRC_DIR_IS_WRITABLE",
+ "BUILD_BROKEN_SRC_DIR_RW_ALLOWLIST",
+
// Not used, but useful to be in the soong.log
"BOARD_VNDK_VERSION",
@@ -256,6 +261,12 @@
"BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY",
}, exportEnvVars...), BannerVars...)
+ // We need Roboleaf converter and runner in the mixed mode
+ runMicrofactory(ctx, config, ".bootstrap/bin/mk2rbc", "android/soong/mk2rbc/cmd",
+ map[string]string{"android/soong": "build/soong"})
+ runMicrofactory(ctx, config, ".bootstrap/bin/rbcrun", "rbcrun/cmd",
+ map[string]string{"go.starlark.net": "external/starlark-go", "rbcrun": "build/make/tools/rbcrun"})
+
makeVars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true, "")
if err != nil {
ctx.Fatalln("Error dumping make vars:", err)
@@ -280,6 +291,8 @@
config.SetNinjaArgs(strings.Fields(makeVars["NINJA_GOALS"]))
config.SetTargetDevice(makeVars["TARGET_DEVICE"])
config.SetTargetDeviceDir(makeVars["TARGET_DEVICE_DIR"])
+ config.sandboxConfig.SetSrcDirIsRO(makeVars["BUILD_BROKEN_SRC_DIR_IS_WRITABLE"] == "false")
+ config.sandboxConfig.SetSrcDirRWAllowlist(strings.Fields(makeVars["BUILD_BROKEN_SRC_DIR_RW_ALLOWLIST"]))
config.SetBuildBrokenDupRules(makeVars["BUILD_BROKEN_DUP_RULES"] == "true")
config.SetBuildBrokenUsesNetwork(makeVars["BUILD_BROKEN_USES_NETWORK"] == "true")
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 2eb84ca..09d53cc 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -76,6 +76,8 @@
"Blueprints",
// Bazel build definitions.
"BUILD.bazel",
+ // Bazel build definitions.
+ "BUILD",
// Kati clean definitions.
"CleanSpec.mk",
// Ownership definition.
@@ -102,7 +104,7 @@
func findBazelFiles(entries finder.DirEntries) (dirNames []string, fileNames []string) {
matches := []string{}
for _, foundName := range entries.FileNames {
- if foundName == "BUILD.bazel" || foundName == "WORKSPACE" || strings.HasSuffix(foundName, ".bzl") {
+ if foundName == "BUILD.bazel" || foundName == "BUILD" || foundName == "WORKSPACE" || strings.HasSuffix(foundName, ".bzl") {
matches = append(matches, foundName)
}
}
diff --git a/ui/build/sandbox_config.go b/ui/build/sandbox_config.go
new file mode 100644
index 0000000..1b46459
--- /dev/null
+++ b/ui/build/sandbox_config.go
@@ -0,0 +1,36 @@
+// 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 build
+
+type SandboxConfig struct {
+ srcDirIsRO bool
+ srcDirRWAllowlist []string
+}
+
+func (sc *SandboxConfig) SetSrcDirIsRO(ro bool) {
+ sc.srcDirIsRO = ro
+}
+
+func (sc *SandboxConfig) SrcDirIsRO() bool {
+ return sc.srcDirIsRO
+}
+
+func (sc *SandboxConfig) SetSrcDirRWAllowlist(allowlist []string) {
+ sc.srcDirRWAllowlist = allowlist
+}
+
+func (sc *SandboxConfig) SrcDirRWAllowlist() []string {
+ return sc.srcDirRWAllowlist
+}
diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go
index dab0e75..5b2046e 100644
--- a/ui/build/sandbox_linux.go
+++ b/ui/build/sandbox_linux.go
@@ -97,8 +97,11 @@
"-u", "nobody",
"-g", sandboxConfig.group,
"-R", "/",
- "-B", sandboxConfig.srcDir,
+ // Mount tmp before srcDir
+ // srcDir is /tmp/.* in integration tests, which is a child dir of /tmp
+ // nsjail throws an error if a child dir is mounted before its parent
"-B", "/tmp",
+ "-B", sandboxConfig.srcDir,
"-B", sandboxConfig.outDir,
}
@@ -145,6 +148,13 @@
func (c *Cmd) wrapSandbox() {
wd, _ := os.Getwd()
+ var srcDirMountFlag string
+ if c.config.sandboxConfig.SrcDirIsRO() {
+ srcDirMountFlag = "-R"
+ } else {
+ srcDirMountFlag = "-B" //Read-Write
+ }
+
sandboxArgs := []string{
// The executable to run
"-x", c.Path,
@@ -184,8 +194,8 @@
// Mount a writable tmp dir
"-B", "/tmp",
- // Mount source are read-write
- "-B", sandboxConfig.srcDir,
+ // Mount source
+ srcDirMountFlag, sandboxConfig.srcDir,
//Mount out dir as read-write
"-B", sandboxConfig.outDir,
@@ -198,6 +208,18 @@
"-q",
}
+ // Mount srcDir RW allowlists as Read-Write
+ if len(c.config.sandboxConfig.SrcDirRWAllowlist()) > 0 && !c.config.sandboxConfig.SrcDirIsRO() {
+ errMsg := `Product source tree has been set as ReadWrite, RW allowlist not necessary.
+ To recover, either
+ 1. Unset BUILD_BROKEN_SRC_DIR_IS_WRITABLE #or
+ 2. Unset BUILD_BROKEN_SRC_DIR_RW_ALLOWLIST`
+ c.ctx.Fatalln(errMsg)
+ }
+ for _, srcDirChild := range c.config.sandboxConfig.SrcDirRWAllowlist() {
+ sandboxArgs = append(sandboxArgs, "-B", srcDirChild)
+ }
+
if _, err := os.Stat(sandboxConfig.distDir); !os.IsNotExist(err) {
//Mount dist dir as read-write if it already exists
sandboxArgs = append(sandboxArgs, "-B", sandboxConfig.distDir)
diff --git a/ui/build/sandbox_linux_test.go b/ui/build/sandbox_linux_test.go
new file mode 100644
index 0000000..7bfd750
--- /dev/null
+++ b/ui/build/sandbox_linux_test.go
@@ -0,0 +1,104 @@
+// 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 build
+
+import (
+ "os"
+ "testing"
+)
+
+func TestMain(m *testing.M) {
+ // set src dir of sandbox
+ sandboxConfig.srcDir = "/my/src/dir"
+ os.Exit(m.Run())
+}
+
+func TestMountFlagsSrcDir(t *testing.T) {
+ testCases := []struct {
+ srcDirIsRO bool
+ expectedSrcDirFlag string
+ }{
+ {
+ srcDirIsRO: false,
+ expectedSrcDirFlag: "-B",
+ },
+ {
+ srcDirIsRO: true,
+ expectedSrcDirFlag: "-R",
+ },
+ }
+ for _, testCase := range testCases {
+ c := testCmd()
+ c.config.sandboxConfig.SetSrcDirIsRO(testCase.srcDirIsRO)
+ c.wrapSandbox()
+ if !isExpectedMountFlag(c.Args, sandboxConfig.srcDir, testCase.expectedSrcDirFlag) {
+ t.Error("Mount flag of srcDir is not correct")
+ }
+ }
+}
+
+func TestMountFlagsSrcDirRWAllowlist(t *testing.T) {
+ testCases := []struct {
+ srcDirRWAllowlist []string
+ }{
+ {
+ srcDirRWAllowlist: []string{},
+ },
+ {
+ srcDirRWAllowlist: []string{"my/path"},
+ },
+ {
+ srcDirRWAllowlist: []string{"my/path1", "my/path2"},
+ },
+ }
+ for _, testCase := range testCases {
+ c := testCmd()
+ c.config.sandboxConfig.SetSrcDirIsRO(true)
+ c.config.sandboxConfig.SetSrcDirRWAllowlist(testCase.srcDirRWAllowlist)
+ c.wrapSandbox()
+ for _, allowlistPath := range testCase.srcDirRWAllowlist {
+ if !isExpectedMountFlag(c.Args, allowlistPath, "-B") {
+ t.Error("Mount flag of srcDirRWAllowlist is not correct, expect -B")
+ }
+ }
+ }
+}
+
+// utils for setting up test
+func testConfig() Config {
+ // create a minimal testConfig
+ env := Environment([]string{})
+ sandboxConfig := SandboxConfig{}
+ return Config{&configImpl{environ: &env,
+ sandboxConfig: &sandboxConfig}}
+}
+
+func testCmd() *Cmd {
+ return Command(testContext(), testConfig(), "sandbox_test", "path/to/nsjail")
+}
+
+func isExpectedMountFlag(cmdArgs []string, dirName string, expectedFlag string) bool {
+ indexOfSrcDir := index(cmdArgs, dirName)
+ return cmdArgs[indexOfSrcDir-1] == expectedFlag
+}
+
+func index(arr []string, target string) int {
+ for idx, element := range arr {
+ if element == target {
+ return idx
+ }
+ }
+ panic("element could not be located in input array")
+}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 87818e3..190c955 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -20,18 +20,18 @@
"path/filepath"
"strconv"
- "android/soong/shared"
- "github.com/google/blueprint/deptools"
-
+ "android/soong/ui/metrics"
soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
+ "android/soong/ui/status"
+
+ "android/soong/shared"
+
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
-
- "github.com/golang/protobuf/proto"
+ "github.com/google/blueprint/deptools"
"github.com/google/blueprint/microfactory"
- "android/soong/ui/metrics"
- "android/soong/ui/status"
+ "google.golang.org/protobuf/proto"
)
const (
@@ -99,6 +99,21 @@
"--used_env", shared.JoinPath(config.SoongOutDir(), usedEnvFile+suffix),
}
}
+
+func writeEmptyGlobFile(ctx Context, path string) {
+ err := os.MkdirAll(filepath.Dir(path), 0777)
+ if err != nil {
+ ctx.Fatalf("Failed to create parent directories of empty ninja glob file '%s': %s", path, err)
+ }
+
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ err = ioutil.WriteFile(path, nil, 0666)
+ if err != nil {
+ ctx.Fatalf("Failed to create empty ninja glob file '%s': %s", path, err)
+ }
+ }
+}
+
func bootstrapBlueprint(ctx Context, config Config, integratedBp2Build bool) {
ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap")
defer ctx.EndTrace()
@@ -106,8 +121,10 @@
var args bootstrap.Args
mainNinjaFile := shared.JoinPath(config.SoongOutDir(), "build.ninja")
- globFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/soong-build-globs.ninja")
bootstrapGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.ninja")
+ // .bootstrap/build.ninja "includes" .bootstrap/build-globs.ninja for incremental builds
+ // generate an empty glob before running any rule in .bootstrap/build.ninja
+ writeEmptyGlobFile(ctx, bootstrapGlobFile)
bootstrapDepFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build.ninja.d")
args.RunGoTests = !config.skipSoongTests
@@ -117,7 +134,10 @@
args.TopFile = "Android.bp"
args.ModuleListFile = filepath.Join(config.FileListDir(), "Android.bp.list")
args.OutFile = shared.JoinPath(config.SoongOutDir(), ".bootstrap/build.ninja")
- args.GlobFile = globFile
+ // The primary builder (aka soong_build) will use bootstrapGlobFile as the globFile to generate build.ninja(.d)
+ // Building soong_build does not require a glob file
+ // Using "" instead of "<soong_build_glob>.ninja" will ensure that an unused glob file is not written to out/soong/.bootstrap during StagePrimary
+ args.GlobFile = ""
args.GeneratingPrimaryBuilder = true
args.EmptyNinjaFile = config.EmptyNinjaFile()
@@ -156,9 +176,9 @@
Outputs: []string{bp2BuildMarkerFile},
Args: bp2buildArgs,
}
- args.PrimaryBuilderInvocations = []bootstrap.PrimaryBuilderInvocation{
- bp2buildInvocation,
- mainSoongBuildInvocation,
+ args.PrimaryBuilderInvocations = []bootstrap.PrimaryBuilderInvocation{bp2buildInvocation}
+ if config.bazelBuildMode() == mixedBuild {
+ args.PrimaryBuilderInvocations = append(args.PrimaryBuilderInvocations, mainSoongBuildInvocation)
}
} else {
args.PrimaryBuilderInvocations = []bootstrap.PrimaryBuilderInvocation{mainSoongBuildInvocation}
@@ -245,20 +265,8 @@
}
}()
- var cfg microfactory.Config
- cfg.Map("github.com/google/blueprint", "build/blueprint")
-
- cfg.TrimPath = absPath(ctx, ".")
-
- func() {
- ctx.BeginTrace(metrics.RunSoong, "bpglob")
- defer ctx.EndTrace()
-
- bpglob := filepath.Join(config.SoongOutDir(), ".minibootstrap/bpglob")
- if _, err := microfactory.Build(&cfg, bpglob, "github.com/google/blueprint/bootstrap/bpglob"); err != nil {
- ctx.Fatalln("Failed to build bpglob:", err)
- }
- }()
+ runMicrofactory(ctx, config, ".minibootstrap/bpglob", "github.com/google/blueprint/bootstrap/bpglob",
+ map[string]string{"github.com/google/blueprint": "build/blueprint"})
ninja := func(name, file string) {
ctx.BeginTrace(metrics.RunSoong, name)
@@ -312,9 +320,29 @@
}
}
+func runMicrofactory(ctx Context, config Config, relExePath string, pkg string, mapping map[string]string) {
+ name := filepath.Base(relExePath)
+ ctx.BeginTrace(metrics.RunSoong, name)
+ defer ctx.EndTrace()
+ cfg := microfactory.Config{TrimPath: absPath(ctx, ".")}
+ for pkgPrefix, pathPrefix := range mapping {
+ cfg.Map(pkgPrefix, pathPrefix)
+ }
+
+ exePath := filepath.Join(config.SoongOutDir(), relExePath)
+ dir := filepath.Dir(exePath)
+ if err := os.MkdirAll(dir, 0777); err != nil {
+ ctx.Fatalf("cannot create %s: %s", dir, err)
+ }
+ if _, err := microfactory.Build(&cfg, exePath, pkg); err != nil {
+ ctx.Fatalf("failed to build %s: %s", name, err)
+ }
+}
+
func shouldCollectBuildSoongMetrics(config Config) bool {
- // Do not collect metrics protobuf if the soong_build binary ran as the bp2build converter.
- return config.bazelBuildMode() != generateBuildFiles
+ // Do not collect metrics protobuf if the soong_build binary ran as the
+ // bp2build converter or the JSON graph dump.
+ return config.bazelBuildMode() != generateBuildFiles && config.bazelBuildMode() != generateJsonModuleGraph
}
func loadSoongBuildMetrics(ctx Context, config Config) *soong_metrics_proto.SoongBuildMetrics {
diff --git a/ui/build/upload.go b/ui/build/upload.go
index 55ca800..55ada33 100644
--- a/ui/build/upload.go
+++ b/ui/build/upload.go
@@ -24,7 +24,8 @@
"time"
"android/soong/ui/metrics"
- "github.com/golang/protobuf/proto"
+
+ "google.golang.org/protobuf/proto"
upload_proto "android/soong/ui/metrics/upload_proto"
)
diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp
index c428ec4..1590ab0 100644
--- a/ui/metrics/Android.bp
+++ b/ui/metrics/Android.bp
@@ -37,7 +37,10 @@
bootstrap_go_package {
name: "soong-ui-metrics_proto",
pkgPath: "android/soong/ui/metrics/metrics_proto",
- deps: ["golang-protobuf-proto"],
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
srcs: [
"metrics_proto/metrics.pb.go",
],
@@ -46,7 +49,10 @@
bootstrap_go_package {
name: "soong-ui-metrics_upload_proto",
pkgPath: "android/soong/ui/metrics/upload_proto",
- deps: ["golang-protobuf-proto"],
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
srcs: [
"upload_proto/upload.pb.go",
],
diff --git a/ui/metrics/event.go b/ui/metrics/event.go
index 87c1b84..c3367e3 100644
--- a/ui/metrics/event.go
+++ b/ui/metrics/event.go
@@ -30,10 +30,10 @@
"syscall"
"time"
- "android/soong/ui/metrics/metrics_proto"
+ soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
"android/soong/ui/tracer"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
)
// _now wraps the time.Now() function. _now is declared for unit testing purpose.
diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go
index efb572c..ccf9bd8 100644
--- a/ui/metrics/metrics.go
+++ b/ui/metrics/metrics.go
@@ -43,9 +43,9 @@
"strings"
"time"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
- "android/soong/ui/metrics/metrics_proto"
+ soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
)
const (
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index fc2cfa4..697e954 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -1,24 +1,38 @@
+// Copyright 2018 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: metrics.proto
-package soong_metrics_proto
+package metrics_proto
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
type MetricsBase_BuildVariant int32
@@ -28,17 +42,19 @@
MetricsBase_ENG MetricsBase_BuildVariant = 2
)
-var MetricsBase_BuildVariant_name = map[int32]string{
- 0: "USER",
- 1: "USERDEBUG",
- 2: "ENG",
-}
-
-var MetricsBase_BuildVariant_value = map[string]int32{
- "USER": 0,
- "USERDEBUG": 1,
- "ENG": 2,
-}
+// Enum value maps for MetricsBase_BuildVariant.
+var (
+ MetricsBase_BuildVariant_name = map[int32]string{
+ 0: "USER",
+ 1: "USERDEBUG",
+ 2: "ENG",
+ }
+ MetricsBase_BuildVariant_value = map[string]int32{
+ "USER": 0,
+ "USERDEBUG": 1,
+ "ENG": 2,
+ }
+)
func (x MetricsBase_BuildVariant) Enum() *MetricsBase_BuildVariant {
p := new(MetricsBase_BuildVariant)
@@ -47,20 +63,34 @@
}
func (x MetricsBase_BuildVariant) String() string {
- return proto.EnumName(MetricsBase_BuildVariant_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
-func (x *MetricsBase_BuildVariant) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(MetricsBase_BuildVariant_value, data, "MetricsBase_BuildVariant")
+func (MetricsBase_BuildVariant) Descriptor() protoreflect.EnumDescriptor {
+ return file_metrics_proto_enumTypes[0].Descriptor()
+}
+
+func (MetricsBase_BuildVariant) Type() protoreflect.EnumType {
+ return &file_metrics_proto_enumTypes[0]
+}
+
+func (x MetricsBase_BuildVariant) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *MetricsBase_BuildVariant) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
if err != nil {
return err
}
- *x = MetricsBase_BuildVariant(value)
+ *x = MetricsBase_BuildVariant(num)
return nil
}
+// Deprecated: Use MetricsBase_BuildVariant.Descriptor instead.
func (MetricsBase_BuildVariant) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{0, 0}
+ return file_metrics_proto_rawDescGZIP(), []int{0, 0}
}
type MetricsBase_Arch int32
@@ -73,21 +103,23 @@
MetricsBase_X86_64 MetricsBase_Arch = 4
)
-var MetricsBase_Arch_name = map[int32]string{
- 0: "UNKNOWN",
- 1: "ARM",
- 2: "ARM64",
- 3: "X86",
- 4: "X86_64",
-}
-
-var MetricsBase_Arch_value = map[string]int32{
- "UNKNOWN": 0,
- "ARM": 1,
- "ARM64": 2,
- "X86": 3,
- "X86_64": 4,
-}
+// Enum value maps for MetricsBase_Arch.
+var (
+ MetricsBase_Arch_name = map[int32]string{
+ 0: "UNKNOWN",
+ 1: "ARM",
+ 2: "ARM64",
+ 3: "X86",
+ 4: "X86_64",
+ }
+ MetricsBase_Arch_value = map[string]int32{
+ "UNKNOWN": 0,
+ "ARM": 1,
+ "ARM64": 2,
+ "X86": 3,
+ "X86_64": 4,
+ }
+)
func (x MetricsBase_Arch) Enum() *MetricsBase_Arch {
p := new(MetricsBase_Arch)
@@ -96,20 +128,34 @@
}
func (x MetricsBase_Arch) String() string {
- return proto.EnumName(MetricsBase_Arch_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
-func (x *MetricsBase_Arch) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(MetricsBase_Arch_value, data, "MetricsBase_Arch")
+func (MetricsBase_Arch) Descriptor() protoreflect.EnumDescriptor {
+ return file_metrics_proto_enumTypes[1].Descriptor()
+}
+
+func (MetricsBase_Arch) Type() protoreflect.EnumType {
+ return &file_metrics_proto_enumTypes[1]
+}
+
+func (x MetricsBase_Arch) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *MetricsBase_Arch) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
if err != nil {
return err
}
- *x = MetricsBase_Arch(value)
+ *x = MetricsBase_Arch(num)
return nil
}
+// Deprecated: Use MetricsBase_Arch.Descriptor instead.
func (MetricsBase_Arch) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{0, 1}
+ return file_metrics_proto_rawDescGZIP(), []int{0, 1}
}
type ModuleTypeInfo_BuildSystem int32
@@ -120,17 +166,19 @@
ModuleTypeInfo_MAKE ModuleTypeInfo_BuildSystem = 2
)
-var ModuleTypeInfo_BuildSystem_name = map[int32]string{
- 0: "UNKNOWN",
- 1: "SOONG",
- 2: "MAKE",
-}
-
-var ModuleTypeInfo_BuildSystem_value = map[string]int32{
- "UNKNOWN": 0,
- "SOONG": 1,
- "MAKE": 2,
-}
+// Enum value maps for ModuleTypeInfo_BuildSystem.
+var (
+ ModuleTypeInfo_BuildSystem_name = map[int32]string{
+ 0: "UNKNOWN",
+ 1: "SOONG",
+ 2: "MAKE",
+ }
+ ModuleTypeInfo_BuildSystem_value = map[string]int32{
+ "UNKNOWN": 0,
+ "SOONG": 1,
+ "MAKE": 2,
+ }
+)
func (x ModuleTypeInfo_BuildSystem) Enum() *ModuleTypeInfo_BuildSystem {
p := new(ModuleTypeInfo_BuildSystem)
@@ -139,23 +187,41 @@
}
func (x ModuleTypeInfo_BuildSystem) String() string {
- return proto.EnumName(ModuleTypeInfo_BuildSystem_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
-func (x *ModuleTypeInfo_BuildSystem) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(ModuleTypeInfo_BuildSystem_value, data, "ModuleTypeInfo_BuildSystem")
+func (ModuleTypeInfo_BuildSystem) Descriptor() protoreflect.EnumDescriptor {
+ return file_metrics_proto_enumTypes[2].Descriptor()
+}
+
+func (ModuleTypeInfo_BuildSystem) Type() protoreflect.EnumType {
+ return &file_metrics_proto_enumTypes[2]
+}
+
+func (x ModuleTypeInfo_BuildSystem) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *ModuleTypeInfo_BuildSystem) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
if err != nil {
return err
}
- *x = ModuleTypeInfo_BuildSystem(value)
+ *x = ModuleTypeInfo_BuildSystem(num)
return nil
}
+// Deprecated: Use ModuleTypeInfo_BuildSystem.Descriptor instead.
func (ModuleTypeInfo_BuildSystem) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{5, 0}
+ return file_metrics_proto_rawDescGZIP(), []int{5, 0}
}
type MetricsBase struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Timestamp generated when the build starts.
BuildDateTimestamp *int64 `protobuf:"varint,1,opt,name=build_date_timestamp,json=buildDateTimestamp" json:"build_date_timestamp,omitempty"`
// It is usually used to specify the branch name [and release candidate].
@@ -207,336 +273,382 @@
// The build command that the user entered to the build system.
BuildCommand *string `protobuf:"bytes,26,opt,name=build_command,json=buildCommand" json:"build_command,omitempty"`
// The metrics for calling Bazel.
- BazelRuns []*PerfInfo `protobuf:"bytes,27,rep,name=bazel_runs,json=bazelRuns" json:"bazel_runs,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ BazelRuns []*PerfInfo `protobuf:"bytes,27,rep,name=bazel_runs,json=bazelRuns" json:"bazel_runs,omitempty"`
}
-func (m *MetricsBase) Reset() { *m = MetricsBase{} }
-func (m *MetricsBase) String() string { return proto.CompactTextString(m) }
-func (*MetricsBase) ProtoMessage() {}
+// Default values for MetricsBase fields.
+const (
+ Default_MetricsBase_TargetBuildVariant = MetricsBase_ENG
+ Default_MetricsBase_TargetArch = MetricsBase_UNKNOWN
+ Default_MetricsBase_HostArch = MetricsBase_UNKNOWN
+ Default_MetricsBase_Host_2NdArch = MetricsBase_UNKNOWN
+)
+
+func (x *MetricsBase) Reset() {
+ *x = MetricsBase{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *MetricsBase) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MetricsBase) ProtoMessage() {}
+
+func (x *MetricsBase) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use MetricsBase.ProtoReflect.Descriptor instead.
func (*MetricsBase) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{0}
+ return file_metrics_proto_rawDescGZIP(), []int{0}
}
-func (m *MetricsBase) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_MetricsBase.Unmarshal(m, b)
-}
-func (m *MetricsBase) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_MetricsBase.Marshal(b, m, deterministic)
-}
-func (m *MetricsBase) XXX_Merge(src proto.Message) {
- xxx_messageInfo_MetricsBase.Merge(m, src)
-}
-func (m *MetricsBase) XXX_Size() int {
- return xxx_messageInfo_MetricsBase.Size(m)
-}
-func (m *MetricsBase) XXX_DiscardUnknown() {
- xxx_messageInfo_MetricsBase.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_MetricsBase proto.InternalMessageInfo
-
-const Default_MetricsBase_TargetBuildVariant MetricsBase_BuildVariant = MetricsBase_ENG
-const Default_MetricsBase_TargetArch MetricsBase_Arch = MetricsBase_UNKNOWN
-const Default_MetricsBase_HostArch MetricsBase_Arch = MetricsBase_UNKNOWN
-const Default_MetricsBase_Host_2NdArch MetricsBase_Arch = MetricsBase_UNKNOWN
-
-func (m *MetricsBase) GetBuildDateTimestamp() int64 {
- if m != nil && m.BuildDateTimestamp != nil {
- return *m.BuildDateTimestamp
+func (x *MetricsBase) GetBuildDateTimestamp() int64 {
+ if x != nil && x.BuildDateTimestamp != nil {
+ return *x.BuildDateTimestamp
}
return 0
}
-func (m *MetricsBase) GetBuildId() string {
- if m != nil && m.BuildId != nil {
- return *m.BuildId
+func (x *MetricsBase) GetBuildId() string {
+ if x != nil && x.BuildId != nil {
+ return *x.BuildId
}
return ""
}
-func (m *MetricsBase) GetPlatformVersionCodename() string {
- if m != nil && m.PlatformVersionCodename != nil {
- return *m.PlatformVersionCodename
+func (x *MetricsBase) GetPlatformVersionCodename() string {
+ if x != nil && x.PlatformVersionCodename != nil {
+ return *x.PlatformVersionCodename
}
return ""
}
-func (m *MetricsBase) GetTargetProduct() string {
- if m != nil && m.TargetProduct != nil {
- return *m.TargetProduct
+func (x *MetricsBase) GetTargetProduct() string {
+ if x != nil && x.TargetProduct != nil {
+ return *x.TargetProduct
}
return ""
}
-func (m *MetricsBase) GetTargetBuildVariant() MetricsBase_BuildVariant {
- if m != nil && m.TargetBuildVariant != nil {
- return *m.TargetBuildVariant
+func (x *MetricsBase) GetTargetBuildVariant() MetricsBase_BuildVariant {
+ if x != nil && x.TargetBuildVariant != nil {
+ return *x.TargetBuildVariant
}
return Default_MetricsBase_TargetBuildVariant
}
-func (m *MetricsBase) GetTargetArch() MetricsBase_Arch {
- if m != nil && m.TargetArch != nil {
- return *m.TargetArch
+func (x *MetricsBase) GetTargetArch() MetricsBase_Arch {
+ if x != nil && x.TargetArch != nil {
+ return *x.TargetArch
}
return Default_MetricsBase_TargetArch
}
-func (m *MetricsBase) GetTargetArchVariant() string {
- if m != nil && m.TargetArchVariant != nil {
- return *m.TargetArchVariant
+func (x *MetricsBase) GetTargetArchVariant() string {
+ if x != nil && x.TargetArchVariant != nil {
+ return *x.TargetArchVariant
}
return ""
}
-func (m *MetricsBase) GetTargetCpuVariant() string {
- if m != nil && m.TargetCpuVariant != nil {
- return *m.TargetCpuVariant
+func (x *MetricsBase) GetTargetCpuVariant() string {
+ if x != nil && x.TargetCpuVariant != nil {
+ return *x.TargetCpuVariant
}
return ""
}
-func (m *MetricsBase) GetHostArch() MetricsBase_Arch {
- if m != nil && m.HostArch != nil {
- return *m.HostArch
+func (x *MetricsBase) GetHostArch() MetricsBase_Arch {
+ if x != nil && x.HostArch != nil {
+ return *x.HostArch
}
return Default_MetricsBase_HostArch
}
-func (m *MetricsBase) GetHost_2NdArch() MetricsBase_Arch {
- if m != nil && m.Host_2NdArch != nil {
- return *m.Host_2NdArch
+func (x *MetricsBase) GetHost_2NdArch() MetricsBase_Arch {
+ if x != nil && x.Host_2NdArch != nil {
+ return *x.Host_2NdArch
}
return Default_MetricsBase_Host_2NdArch
}
-func (m *MetricsBase) GetHostOs() string {
- if m != nil && m.HostOs != nil {
- return *m.HostOs
+func (x *MetricsBase) GetHostOs() string {
+ if x != nil && x.HostOs != nil {
+ return *x.HostOs
}
return ""
}
-func (m *MetricsBase) GetHostOsExtra() string {
- if m != nil && m.HostOsExtra != nil {
- return *m.HostOsExtra
+func (x *MetricsBase) GetHostOsExtra() string {
+ if x != nil && x.HostOsExtra != nil {
+ return *x.HostOsExtra
}
return ""
}
-func (m *MetricsBase) GetHostCrossOs() string {
- if m != nil && m.HostCrossOs != nil {
- return *m.HostCrossOs
+func (x *MetricsBase) GetHostCrossOs() string {
+ if x != nil && x.HostCrossOs != nil {
+ return *x.HostCrossOs
}
return ""
}
-func (m *MetricsBase) GetHostCrossArch() string {
- if m != nil && m.HostCrossArch != nil {
- return *m.HostCrossArch
+func (x *MetricsBase) GetHostCrossArch() string {
+ if x != nil && x.HostCrossArch != nil {
+ return *x.HostCrossArch
}
return ""
}
-func (m *MetricsBase) GetHostCross_2NdArch() string {
- if m != nil && m.HostCross_2NdArch != nil {
- return *m.HostCross_2NdArch
+func (x *MetricsBase) GetHostCross_2NdArch() string {
+ if x != nil && x.HostCross_2NdArch != nil {
+ return *x.HostCross_2NdArch
}
return ""
}
-func (m *MetricsBase) GetOutDir() string {
- if m != nil && m.OutDir != nil {
- return *m.OutDir
+func (x *MetricsBase) GetOutDir() string {
+ if x != nil && x.OutDir != nil {
+ return *x.OutDir
}
return ""
}
-func (m *MetricsBase) GetSetupTools() []*PerfInfo {
- if m != nil {
- return m.SetupTools
+func (x *MetricsBase) GetSetupTools() []*PerfInfo {
+ if x != nil {
+ return x.SetupTools
}
return nil
}
-func (m *MetricsBase) GetKatiRuns() []*PerfInfo {
- if m != nil {
- return m.KatiRuns
+func (x *MetricsBase) GetKatiRuns() []*PerfInfo {
+ if x != nil {
+ return x.KatiRuns
}
return nil
}
-func (m *MetricsBase) GetSoongRuns() []*PerfInfo {
- if m != nil {
- return m.SoongRuns
+func (x *MetricsBase) GetSoongRuns() []*PerfInfo {
+ if x != nil {
+ return x.SoongRuns
}
return nil
}
-func (m *MetricsBase) GetNinjaRuns() []*PerfInfo {
- if m != nil {
- return m.NinjaRuns
+func (x *MetricsBase) GetNinjaRuns() []*PerfInfo {
+ if x != nil {
+ return x.NinjaRuns
}
return nil
}
-func (m *MetricsBase) GetTotal() *PerfInfo {
- if m != nil {
- return m.Total
+func (x *MetricsBase) GetTotal() *PerfInfo {
+ if x != nil {
+ return x.Total
}
return nil
}
-func (m *MetricsBase) GetSoongBuildMetrics() *SoongBuildMetrics {
- if m != nil {
- return m.SoongBuildMetrics
+func (x *MetricsBase) GetSoongBuildMetrics() *SoongBuildMetrics {
+ if x != nil {
+ return x.SoongBuildMetrics
}
return nil
}
-func (m *MetricsBase) GetBuildConfig() *BuildConfig {
- if m != nil {
- return m.BuildConfig
+func (x *MetricsBase) GetBuildConfig() *BuildConfig {
+ if x != nil {
+ return x.BuildConfig
}
return nil
}
-func (m *MetricsBase) GetHostname() string {
- if m != nil && m.Hostname != nil {
- return *m.Hostname
+func (x *MetricsBase) GetHostname() string {
+ if x != nil && x.Hostname != nil {
+ return *x.Hostname
}
return ""
}
-func (m *MetricsBase) GetSystemResourceInfo() *SystemResourceInfo {
- if m != nil {
- return m.SystemResourceInfo
+func (x *MetricsBase) GetSystemResourceInfo() *SystemResourceInfo {
+ if x != nil {
+ return x.SystemResourceInfo
}
return nil
}
-func (m *MetricsBase) GetBuildCommand() string {
- if m != nil && m.BuildCommand != nil {
- return *m.BuildCommand
+func (x *MetricsBase) GetBuildCommand() string {
+ if x != nil && x.BuildCommand != nil {
+ return *x.BuildCommand
}
return ""
}
-func (m *MetricsBase) GetBazelRuns() []*PerfInfo {
- if m != nil {
- return m.BazelRuns
+func (x *MetricsBase) GetBazelRuns() []*PerfInfo {
+ if x != nil {
+ return x.BazelRuns
}
return nil
}
type BuildConfig struct {
- UseGoma *bool `protobuf:"varint,1,opt,name=use_goma,json=useGoma" json:"use_goma,omitempty"`
- UseRbe *bool `protobuf:"varint,2,opt,name=use_rbe,json=useRbe" json:"use_rbe,omitempty"`
- ForceUseGoma *bool `protobuf:"varint,3,opt,name=force_use_goma,json=forceUseGoma" json:"force_use_goma,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ UseGoma *bool `protobuf:"varint,1,opt,name=use_goma,json=useGoma" json:"use_goma,omitempty"`
+ UseRbe *bool `protobuf:"varint,2,opt,name=use_rbe,json=useRbe" json:"use_rbe,omitempty"`
+ ForceUseGoma *bool `protobuf:"varint,3,opt,name=force_use_goma,json=forceUseGoma" json:"force_use_goma,omitempty"`
+ // Whether the Bazel is acting as the Ninja executor for this build.
+ BazelAsNinja *bool `protobuf:"varint,4,opt,name=bazel_as_ninja,json=bazelAsNinja" json:"bazel_as_ninja,omitempty"`
+ // 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"`
}
-func (m *BuildConfig) Reset() { *m = BuildConfig{} }
-func (m *BuildConfig) String() string { return proto.CompactTextString(m) }
-func (*BuildConfig) ProtoMessage() {}
+func (x *BuildConfig) Reset() {
+ *x = BuildConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BuildConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BuildConfig) ProtoMessage() {}
+
+func (x *BuildConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BuildConfig.ProtoReflect.Descriptor instead.
func (*BuildConfig) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{1}
+ return file_metrics_proto_rawDescGZIP(), []int{1}
}
-func (m *BuildConfig) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_BuildConfig.Unmarshal(m, b)
-}
-func (m *BuildConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_BuildConfig.Marshal(b, m, deterministic)
-}
-func (m *BuildConfig) XXX_Merge(src proto.Message) {
- xxx_messageInfo_BuildConfig.Merge(m, src)
-}
-func (m *BuildConfig) XXX_Size() int {
- return xxx_messageInfo_BuildConfig.Size(m)
-}
-func (m *BuildConfig) XXX_DiscardUnknown() {
- xxx_messageInfo_BuildConfig.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BuildConfig proto.InternalMessageInfo
-
-func (m *BuildConfig) GetUseGoma() bool {
- if m != nil && m.UseGoma != nil {
- return *m.UseGoma
+func (x *BuildConfig) GetUseGoma() bool {
+ if x != nil && x.UseGoma != nil {
+ return *x.UseGoma
}
return false
}
-func (m *BuildConfig) GetUseRbe() bool {
- if m != nil && m.UseRbe != nil {
- return *m.UseRbe
+func (x *BuildConfig) GetUseRbe() bool {
+ if x != nil && x.UseRbe != nil {
+ return *x.UseRbe
}
return false
}
-func (m *BuildConfig) GetForceUseGoma() bool {
- if m != nil && m.ForceUseGoma != nil {
- return *m.ForceUseGoma
+func (x *BuildConfig) GetForceUseGoma() bool {
+ if x != nil && x.ForceUseGoma != nil {
+ return *x.ForceUseGoma
+ }
+ return false
+}
+
+func (x *BuildConfig) GetBazelAsNinja() bool {
+ if x != nil && x.BazelAsNinja != nil {
+ return *x.BazelAsNinja
+ }
+ return false
+}
+
+func (x *BuildConfig) GetBazelMixedBuild() bool {
+ if x != nil && x.BazelMixedBuild != nil {
+ return *x.BazelMixedBuild
}
return false
}
type SystemResourceInfo struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The total physical memory in bytes.
TotalPhysicalMemory *uint64 `protobuf:"varint,1,opt,name=total_physical_memory,json=totalPhysicalMemory" json:"total_physical_memory,omitempty"`
// The total of available cores for building
- AvailableCpus *int32 `protobuf:"varint,2,opt,name=available_cpus,json=availableCpus" json:"available_cpus,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ AvailableCpus *int32 `protobuf:"varint,2,opt,name=available_cpus,json=availableCpus" json:"available_cpus,omitempty"`
}
-func (m *SystemResourceInfo) Reset() { *m = SystemResourceInfo{} }
-func (m *SystemResourceInfo) String() string { return proto.CompactTextString(m) }
-func (*SystemResourceInfo) ProtoMessage() {}
+func (x *SystemResourceInfo) Reset() {
+ *x = SystemResourceInfo{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SystemResourceInfo) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SystemResourceInfo) ProtoMessage() {}
+
+func (x *SystemResourceInfo) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SystemResourceInfo.ProtoReflect.Descriptor instead.
func (*SystemResourceInfo) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{2}
+ return file_metrics_proto_rawDescGZIP(), []int{2}
}
-func (m *SystemResourceInfo) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SystemResourceInfo.Unmarshal(m, b)
-}
-func (m *SystemResourceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SystemResourceInfo.Marshal(b, m, deterministic)
-}
-func (m *SystemResourceInfo) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SystemResourceInfo.Merge(m, src)
-}
-func (m *SystemResourceInfo) XXX_Size() int {
- return xxx_messageInfo_SystemResourceInfo.Size(m)
-}
-func (m *SystemResourceInfo) XXX_DiscardUnknown() {
- xxx_messageInfo_SystemResourceInfo.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SystemResourceInfo proto.InternalMessageInfo
-
-func (m *SystemResourceInfo) GetTotalPhysicalMemory() uint64 {
- if m != nil && m.TotalPhysicalMemory != nil {
- return *m.TotalPhysicalMemory
+func (x *SystemResourceInfo) GetTotalPhysicalMemory() uint64 {
+ if x != nil && x.TotalPhysicalMemory != nil {
+ return *x.TotalPhysicalMemory
}
return 0
}
-func (m *SystemResourceInfo) GetAvailableCpus() int32 {
- if m != nil && m.AvailableCpus != nil {
- return *m.AvailableCpus
+func (x *SystemResourceInfo) GetAvailableCpus() int32 {
+ if x != nil && x.AvailableCpus != nil {
+ return *x.AvailableCpus
}
return 0
}
type PerfInfo struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ 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"`
// The name for the running phase/action/part.
@@ -548,83 +660,93 @@
// The number of nanoseconds elapsed since start_time.
RealTime *uint64 `protobuf:"varint,4,opt,name=real_time,json=realTime" json:"real_time,omitempty"`
// The number of MB for memory use (deprecated as it is too generic).
- MemoryUse *uint64 `protobuf:"varint,5,opt,name=memory_use,json=memoryUse" json:"memory_use,omitempty"` // Deprecated: Do not use.
+ //
+ // Deprecated: Do not use.
+ MemoryUse *uint64 `protobuf:"varint,5,opt,name=memory_use,json=memoryUse" json:"memory_use,omitempty"`
// The resource information of each executed process.
ProcessesResourceInfo []*ProcessResourceInfo `protobuf:"bytes,6,rep,name=processes_resource_info,json=processesResourceInfo" json:"processes_resource_info,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
}
-func (m *PerfInfo) Reset() { *m = PerfInfo{} }
-func (m *PerfInfo) String() string { return proto.CompactTextString(m) }
-func (*PerfInfo) ProtoMessage() {}
+func (x *PerfInfo) Reset() {
+ *x = PerfInfo{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *PerfInfo) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PerfInfo) ProtoMessage() {}
+
+func (x *PerfInfo) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use PerfInfo.ProtoReflect.Descriptor instead.
func (*PerfInfo) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{3}
+ return file_metrics_proto_rawDescGZIP(), []int{3}
}
-func (m *PerfInfo) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_PerfInfo.Unmarshal(m, b)
-}
-func (m *PerfInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_PerfInfo.Marshal(b, m, deterministic)
-}
-func (m *PerfInfo) XXX_Merge(src proto.Message) {
- xxx_messageInfo_PerfInfo.Merge(m, src)
-}
-func (m *PerfInfo) XXX_Size() int {
- return xxx_messageInfo_PerfInfo.Size(m)
-}
-func (m *PerfInfo) XXX_DiscardUnknown() {
- xxx_messageInfo_PerfInfo.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_PerfInfo proto.InternalMessageInfo
-
-func (m *PerfInfo) GetDesc() string {
- if m != nil && m.Desc != nil {
- return *m.Desc
+func (x *PerfInfo) GetDesc() string {
+ if x != nil && x.Desc != nil {
+ return *x.Desc
}
return ""
}
-func (m *PerfInfo) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
+func (x *PerfInfo) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
}
return ""
}
-func (m *PerfInfo) GetStartTime() uint64 {
- if m != nil && m.StartTime != nil {
- return *m.StartTime
+func (x *PerfInfo) GetStartTime() uint64 {
+ if x != nil && x.StartTime != nil {
+ return *x.StartTime
}
return 0
}
-func (m *PerfInfo) GetRealTime() uint64 {
- if m != nil && m.RealTime != nil {
- return *m.RealTime
+func (x *PerfInfo) GetRealTime() uint64 {
+ if x != nil && x.RealTime != nil {
+ return *x.RealTime
}
return 0
}
// Deprecated: Do not use.
-func (m *PerfInfo) GetMemoryUse() uint64 {
- if m != nil && m.MemoryUse != nil {
- return *m.MemoryUse
+func (x *PerfInfo) GetMemoryUse() uint64 {
+ if x != nil && x.MemoryUse != nil {
+ return *x.MemoryUse
}
return 0
}
-func (m *PerfInfo) GetProcessesResourceInfo() []*ProcessResourceInfo {
- if m != nil {
- return m.ProcessesResourceInfo
+func (x *PerfInfo) GetProcessesResourceInfo() []*ProcessResourceInfo {
+ if x != nil {
+ return x.ProcessesResourceInfo
}
return nil
}
type ProcessResourceInfo struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The name of the process for identification.
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
// The amount of time spent executing in user space in microseconds.
@@ -644,257 +766,292 @@
// The number of voluntary context switches
VoluntaryContextSwitches *uint64 `protobuf:"varint,9,opt,name=voluntary_context_switches,json=voluntaryContextSwitches" json:"voluntary_context_switches,omitempty"`
// The number of involuntary context switches
- InvoluntaryContextSwitches *uint64 `protobuf:"varint,10,opt,name=involuntary_context_switches,json=involuntaryContextSwitches" json:"involuntary_context_switches,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ InvoluntaryContextSwitches *uint64 `protobuf:"varint,10,opt,name=involuntary_context_switches,json=involuntaryContextSwitches" json:"involuntary_context_switches,omitempty"`
}
-func (m *ProcessResourceInfo) Reset() { *m = ProcessResourceInfo{} }
-func (m *ProcessResourceInfo) String() string { return proto.CompactTextString(m) }
-func (*ProcessResourceInfo) ProtoMessage() {}
+func (x *ProcessResourceInfo) Reset() {
+ *x = ProcessResourceInfo{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ProcessResourceInfo) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ProcessResourceInfo) ProtoMessage() {}
+
+func (x *ProcessResourceInfo) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ProcessResourceInfo.ProtoReflect.Descriptor instead.
func (*ProcessResourceInfo) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{4}
+ return file_metrics_proto_rawDescGZIP(), []int{4}
}
-func (m *ProcessResourceInfo) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ProcessResourceInfo.Unmarshal(m, b)
-}
-func (m *ProcessResourceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ProcessResourceInfo.Marshal(b, m, deterministic)
-}
-func (m *ProcessResourceInfo) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ProcessResourceInfo.Merge(m, src)
-}
-func (m *ProcessResourceInfo) XXX_Size() int {
- return xxx_messageInfo_ProcessResourceInfo.Size(m)
-}
-func (m *ProcessResourceInfo) XXX_DiscardUnknown() {
- xxx_messageInfo_ProcessResourceInfo.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ProcessResourceInfo proto.InternalMessageInfo
-
-func (m *ProcessResourceInfo) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
+func (x *ProcessResourceInfo) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
}
return ""
}
-func (m *ProcessResourceInfo) GetUserTimeMicros() uint64 {
- if m != nil && m.UserTimeMicros != nil {
- return *m.UserTimeMicros
+func (x *ProcessResourceInfo) GetUserTimeMicros() uint64 {
+ if x != nil && x.UserTimeMicros != nil {
+ return *x.UserTimeMicros
}
return 0
}
-func (m *ProcessResourceInfo) GetSystemTimeMicros() uint64 {
- if m != nil && m.SystemTimeMicros != nil {
- return *m.SystemTimeMicros
+func (x *ProcessResourceInfo) GetSystemTimeMicros() uint64 {
+ if x != nil && x.SystemTimeMicros != nil {
+ return *x.SystemTimeMicros
}
return 0
}
-func (m *ProcessResourceInfo) GetMaxRssKb() uint64 {
- if m != nil && m.MaxRssKb != nil {
- return *m.MaxRssKb
+func (x *ProcessResourceInfo) GetMaxRssKb() uint64 {
+ if x != nil && x.MaxRssKb != nil {
+ return *x.MaxRssKb
}
return 0
}
-func (m *ProcessResourceInfo) GetMinorPageFaults() uint64 {
- if m != nil && m.MinorPageFaults != nil {
- return *m.MinorPageFaults
+func (x *ProcessResourceInfo) GetMinorPageFaults() uint64 {
+ if x != nil && x.MinorPageFaults != nil {
+ return *x.MinorPageFaults
}
return 0
}
-func (m *ProcessResourceInfo) GetMajorPageFaults() uint64 {
- if m != nil && m.MajorPageFaults != nil {
- return *m.MajorPageFaults
+func (x *ProcessResourceInfo) GetMajorPageFaults() uint64 {
+ if x != nil && x.MajorPageFaults != nil {
+ return *x.MajorPageFaults
}
return 0
}
-func (m *ProcessResourceInfo) GetIoInputKb() uint64 {
- if m != nil && m.IoInputKb != nil {
- return *m.IoInputKb
+func (x *ProcessResourceInfo) GetIoInputKb() uint64 {
+ if x != nil && x.IoInputKb != nil {
+ return *x.IoInputKb
}
return 0
}
-func (m *ProcessResourceInfo) GetIoOutputKb() uint64 {
- if m != nil && m.IoOutputKb != nil {
- return *m.IoOutputKb
+func (x *ProcessResourceInfo) GetIoOutputKb() uint64 {
+ if x != nil && x.IoOutputKb != nil {
+ return *x.IoOutputKb
}
return 0
}
-func (m *ProcessResourceInfo) GetVoluntaryContextSwitches() uint64 {
- if m != nil && m.VoluntaryContextSwitches != nil {
- return *m.VoluntaryContextSwitches
+func (x *ProcessResourceInfo) GetVoluntaryContextSwitches() uint64 {
+ if x != nil && x.VoluntaryContextSwitches != nil {
+ return *x.VoluntaryContextSwitches
}
return 0
}
-func (m *ProcessResourceInfo) GetInvoluntaryContextSwitches() uint64 {
- if m != nil && m.InvoluntaryContextSwitches != nil {
- return *m.InvoluntaryContextSwitches
+func (x *ProcessResourceInfo) GetInvoluntaryContextSwitches() uint64 {
+ if x != nil && x.InvoluntaryContextSwitches != nil {
+ return *x.InvoluntaryContextSwitches
}
return 0
}
type ModuleTypeInfo struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The build system, eg. Soong or Make.
BuildSystem *ModuleTypeInfo_BuildSystem `protobuf:"varint,1,opt,name=build_system,json=buildSystem,enum=soong_build_metrics.ModuleTypeInfo_BuildSystem,def=0" json:"build_system,omitempty"`
// The module type, eg. java_library, cc_binary, and etc.
ModuleType *string `protobuf:"bytes,2,opt,name=module_type,json=moduleType" json:"module_type,omitempty"`
// The number of logical modules.
- NumOfModules *uint32 `protobuf:"varint,3,opt,name=num_of_modules,json=numOfModules" json:"num_of_modules,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ NumOfModules *uint32 `protobuf:"varint,3,opt,name=num_of_modules,json=numOfModules" json:"num_of_modules,omitempty"`
}
-func (m *ModuleTypeInfo) Reset() { *m = ModuleTypeInfo{} }
-func (m *ModuleTypeInfo) String() string { return proto.CompactTextString(m) }
-func (*ModuleTypeInfo) ProtoMessage() {}
+// Default values for ModuleTypeInfo fields.
+const (
+ Default_ModuleTypeInfo_BuildSystem = ModuleTypeInfo_UNKNOWN
+)
+
+func (x *ModuleTypeInfo) Reset() {
+ *x = ModuleTypeInfo{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ModuleTypeInfo) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ModuleTypeInfo) ProtoMessage() {}
+
+func (x *ModuleTypeInfo) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ModuleTypeInfo.ProtoReflect.Descriptor instead.
func (*ModuleTypeInfo) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{5}
+ return file_metrics_proto_rawDescGZIP(), []int{5}
}
-func (m *ModuleTypeInfo) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_ModuleTypeInfo.Unmarshal(m, b)
-}
-func (m *ModuleTypeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_ModuleTypeInfo.Marshal(b, m, deterministic)
-}
-func (m *ModuleTypeInfo) XXX_Merge(src proto.Message) {
- xxx_messageInfo_ModuleTypeInfo.Merge(m, src)
-}
-func (m *ModuleTypeInfo) XXX_Size() int {
- return xxx_messageInfo_ModuleTypeInfo.Size(m)
-}
-func (m *ModuleTypeInfo) XXX_DiscardUnknown() {
- xxx_messageInfo_ModuleTypeInfo.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_ModuleTypeInfo proto.InternalMessageInfo
-
-const Default_ModuleTypeInfo_BuildSystem ModuleTypeInfo_BuildSystem = ModuleTypeInfo_UNKNOWN
-
-func (m *ModuleTypeInfo) GetBuildSystem() ModuleTypeInfo_BuildSystem {
- if m != nil && m.BuildSystem != nil {
- return *m.BuildSystem
+func (x *ModuleTypeInfo) GetBuildSystem() ModuleTypeInfo_BuildSystem {
+ if x != nil && x.BuildSystem != nil {
+ return *x.BuildSystem
}
return Default_ModuleTypeInfo_BuildSystem
}
-func (m *ModuleTypeInfo) GetModuleType() string {
- if m != nil && m.ModuleType != nil {
- return *m.ModuleType
+func (x *ModuleTypeInfo) GetModuleType() string {
+ if x != nil && x.ModuleType != nil {
+ return *x.ModuleType
}
return ""
}
-func (m *ModuleTypeInfo) GetNumOfModules() uint32 {
- if m != nil && m.NumOfModules != nil {
- return *m.NumOfModules
+func (x *ModuleTypeInfo) GetNumOfModules() uint32 {
+ if x != nil && x.NumOfModules != nil {
+ return *x.NumOfModules
}
return 0
}
type CriticalUserJourneyMetrics struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The name of a critical user journey test.
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
// The metrics produced when running the critical user journey test.
- Metrics *MetricsBase `protobuf:"bytes,2,opt,name=metrics" json:"metrics,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Metrics *MetricsBase `protobuf:"bytes,2,opt,name=metrics" json:"metrics,omitempty"`
}
-func (m *CriticalUserJourneyMetrics) Reset() { *m = CriticalUserJourneyMetrics{} }
-func (m *CriticalUserJourneyMetrics) String() string { return proto.CompactTextString(m) }
-func (*CriticalUserJourneyMetrics) ProtoMessage() {}
+func (x *CriticalUserJourneyMetrics) Reset() {
+ *x = CriticalUserJourneyMetrics{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CriticalUserJourneyMetrics) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CriticalUserJourneyMetrics) ProtoMessage() {}
+
+func (x *CriticalUserJourneyMetrics) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CriticalUserJourneyMetrics.ProtoReflect.Descriptor instead.
func (*CriticalUserJourneyMetrics) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{6}
+ return file_metrics_proto_rawDescGZIP(), []int{6}
}
-func (m *CriticalUserJourneyMetrics) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_CriticalUserJourneyMetrics.Unmarshal(m, b)
-}
-func (m *CriticalUserJourneyMetrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_CriticalUserJourneyMetrics.Marshal(b, m, deterministic)
-}
-func (m *CriticalUserJourneyMetrics) XXX_Merge(src proto.Message) {
- xxx_messageInfo_CriticalUserJourneyMetrics.Merge(m, src)
-}
-func (m *CriticalUserJourneyMetrics) XXX_Size() int {
- return xxx_messageInfo_CriticalUserJourneyMetrics.Size(m)
-}
-func (m *CriticalUserJourneyMetrics) XXX_DiscardUnknown() {
- xxx_messageInfo_CriticalUserJourneyMetrics.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_CriticalUserJourneyMetrics proto.InternalMessageInfo
-
-func (m *CriticalUserJourneyMetrics) GetName() string {
- if m != nil && m.Name != nil {
- return *m.Name
+func (x *CriticalUserJourneyMetrics) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
}
return ""
}
-func (m *CriticalUserJourneyMetrics) GetMetrics() *MetricsBase {
- if m != nil {
- return m.Metrics
+func (x *CriticalUserJourneyMetrics) GetMetrics() *MetricsBase {
+ if x != nil {
+ return x.Metrics
}
return nil
}
type CriticalUserJourneysMetrics struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// A set of metrics from a run of the critical user journey tests.
- Cujs []*CriticalUserJourneyMetrics `protobuf:"bytes,1,rep,name=cujs" json:"cujs,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Cujs []*CriticalUserJourneyMetrics `protobuf:"bytes,1,rep,name=cujs" json:"cujs,omitempty"`
}
-func (m *CriticalUserJourneysMetrics) Reset() { *m = CriticalUserJourneysMetrics{} }
-func (m *CriticalUserJourneysMetrics) String() string { return proto.CompactTextString(m) }
-func (*CriticalUserJourneysMetrics) ProtoMessage() {}
+func (x *CriticalUserJourneysMetrics) Reset() {
+ *x = CriticalUserJourneysMetrics{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CriticalUserJourneysMetrics) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CriticalUserJourneysMetrics) ProtoMessage() {}
+
+func (x *CriticalUserJourneysMetrics) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CriticalUserJourneysMetrics.ProtoReflect.Descriptor instead.
func (*CriticalUserJourneysMetrics) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{7}
+ return file_metrics_proto_rawDescGZIP(), []int{7}
}
-func (m *CriticalUserJourneysMetrics) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_CriticalUserJourneysMetrics.Unmarshal(m, b)
-}
-func (m *CriticalUserJourneysMetrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_CriticalUserJourneysMetrics.Marshal(b, m, deterministic)
-}
-func (m *CriticalUserJourneysMetrics) XXX_Merge(src proto.Message) {
- xxx_messageInfo_CriticalUserJourneysMetrics.Merge(m, src)
-}
-func (m *CriticalUserJourneysMetrics) XXX_Size() int {
- return xxx_messageInfo_CriticalUserJourneysMetrics.Size(m)
-}
-func (m *CriticalUserJourneysMetrics) XXX_DiscardUnknown() {
- xxx_messageInfo_CriticalUserJourneysMetrics.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_CriticalUserJourneysMetrics proto.InternalMessageInfo
-
-func (m *CriticalUserJourneysMetrics) GetCujs() []*CriticalUserJourneyMetrics {
- if m != nil {
- return m.Cujs
+func (x *CriticalUserJourneysMetrics) GetCujs() []*CriticalUserJourneyMetrics {
+ if x != nil {
+ return x.Cujs
}
return nil
}
type SoongBuildMetrics struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The number of modules handled by soong_build.
Modules *uint32 `protobuf:"varint,1,opt,name=modules" json:"modules,omitempty"`
// The total number of variants handled by soong_build.
@@ -904,178 +1061,475 @@
// The total size of allocations in soong_build in bytes.
TotalAllocSize *uint64 `protobuf:"varint,4,opt,name=total_alloc_size,json=totalAllocSize" json:"total_alloc_size,omitempty"`
// The approximate maximum size of the heap in soong_build in bytes.
- MaxHeapSize *uint64 `protobuf:"varint,5,opt,name=max_heap_size,json=maxHeapSize" json:"max_heap_size,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ MaxHeapSize *uint64 `protobuf:"varint,5,opt,name=max_heap_size,json=maxHeapSize" json:"max_heap_size,omitempty"`
}
-func (m *SoongBuildMetrics) Reset() { *m = SoongBuildMetrics{} }
-func (m *SoongBuildMetrics) String() string { return proto.CompactTextString(m) }
-func (*SoongBuildMetrics) ProtoMessage() {}
+func (x *SoongBuildMetrics) Reset() {
+ *x = SoongBuildMetrics{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SoongBuildMetrics) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SoongBuildMetrics) ProtoMessage() {}
+
+func (x *SoongBuildMetrics) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_proto_msgTypes[8]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SoongBuildMetrics.ProtoReflect.Descriptor instead.
func (*SoongBuildMetrics) Descriptor() ([]byte, []int) {
- return fileDescriptor_6039342a2ba47b72, []int{8}
+ return file_metrics_proto_rawDescGZIP(), []int{8}
}
-func (m *SoongBuildMetrics) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_SoongBuildMetrics.Unmarshal(m, b)
-}
-func (m *SoongBuildMetrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_SoongBuildMetrics.Marshal(b, m, deterministic)
-}
-func (m *SoongBuildMetrics) XXX_Merge(src proto.Message) {
- xxx_messageInfo_SoongBuildMetrics.Merge(m, src)
-}
-func (m *SoongBuildMetrics) XXX_Size() int {
- return xxx_messageInfo_SoongBuildMetrics.Size(m)
-}
-func (m *SoongBuildMetrics) XXX_DiscardUnknown() {
- xxx_messageInfo_SoongBuildMetrics.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_SoongBuildMetrics proto.InternalMessageInfo
-
-func (m *SoongBuildMetrics) GetModules() uint32 {
- if m != nil && m.Modules != nil {
- return *m.Modules
+func (x *SoongBuildMetrics) GetModules() uint32 {
+ if x != nil && x.Modules != nil {
+ return *x.Modules
}
return 0
}
-func (m *SoongBuildMetrics) GetVariants() uint32 {
- if m != nil && m.Variants != nil {
- return *m.Variants
+func (x *SoongBuildMetrics) GetVariants() uint32 {
+ if x != nil && x.Variants != nil {
+ return *x.Variants
}
return 0
}
-func (m *SoongBuildMetrics) GetTotalAllocCount() uint64 {
- if m != nil && m.TotalAllocCount != nil {
- return *m.TotalAllocCount
+func (x *SoongBuildMetrics) GetTotalAllocCount() uint64 {
+ if x != nil && x.TotalAllocCount != nil {
+ return *x.TotalAllocCount
}
return 0
}
-func (m *SoongBuildMetrics) GetTotalAllocSize() uint64 {
- if m != nil && m.TotalAllocSize != nil {
- return *m.TotalAllocSize
+func (x *SoongBuildMetrics) GetTotalAllocSize() uint64 {
+ if x != nil && x.TotalAllocSize != nil {
+ return *x.TotalAllocSize
}
return 0
}
-func (m *SoongBuildMetrics) GetMaxHeapSize() uint64 {
- if m != nil && m.MaxHeapSize != nil {
- return *m.MaxHeapSize
+func (x *SoongBuildMetrics) GetMaxHeapSize() uint64 {
+ if x != nil && x.MaxHeapSize != nil {
+ return *x.MaxHeapSize
}
return 0
}
-func init() {
- proto.RegisterEnum("soong_build_metrics.MetricsBase_BuildVariant", MetricsBase_BuildVariant_name, MetricsBase_BuildVariant_value)
- proto.RegisterEnum("soong_build_metrics.MetricsBase_Arch", MetricsBase_Arch_name, MetricsBase_Arch_value)
- proto.RegisterEnum("soong_build_metrics.ModuleTypeInfo_BuildSystem", ModuleTypeInfo_BuildSystem_name, ModuleTypeInfo_BuildSystem_value)
- proto.RegisterType((*MetricsBase)(nil), "soong_build_metrics.MetricsBase")
- proto.RegisterType((*BuildConfig)(nil), "soong_build_metrics.BuildConfig")
- proto.RegisterType((*SystemResourceInfo)(nil), "soong_build_metrics.SystemResourceInfo")
- proto.RegisterType((*PerfInfo)(nil), "soong_build_metrics.PerfInfo")
- proto.RegisterType((*ProcessResourceInfo)(nil), "soong_build_metrics.ProcessResourceInfo")
- proto.RegisterType((*ModuleTypeInfo)(nil), "soong_build_metrics.ModuleTypeInfo")
- proto.RegisterType((*CriticalUserJourneyMetrics)(nil), "soong_build_metrics.CriticalUserJourneyMetrics")
- proto.RegisterType((*CriticalUserJourneysMetrics)(nil), "soong_build_metrics.CriticalUserJourneysMetrics")
- proto.RegisterType((*SoongBuildMetrics)(nil), "soong_build_metrics.SoongBuildMetrics")
+var File_metrics_proto protoreflect.FileDescriptor
+
+var file_metrics_proto_rawDesc = []byte{
+ 0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+ 0x13, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x73, 0x22, 0xd8, 0x0c, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x42, 0x61, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x61,
+ 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x03, 0x52, 0x12, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d,
+ 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
+ 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49,
+ 0x64, 0x12, 0x3a, 0x0a, 0x19, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x65,
+ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a,
+ 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f,
+ 0x64, 0x75, 0x63, 0x74, 0x12, 0x64, 0x0a, 0x14, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x62,
+ 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x2d, 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, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e,
+ 0x74, 0x3a, 0x03, 0x45, 0x4e, 0x47, 0x52, 0x12, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x42, 0x75,
+ 0x69, 0x6c, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x4f, 0x0a, 0x0b, 0x74, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x25, 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, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x3a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52,
+ 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x12, 0x2e, 0x0a, 0x13, 0x74,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61,
+ 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
+ 0x41, 0x72, 0x63, 0x68, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x74,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e,
+ 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43,
+ 0x70, 0x75, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x09, 0x68, 0x6f, 0x73,
+ 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 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, 0x2e, 0x41,
+ 0x72, 0x63, 0x68, 0x3a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x08, 0x68, 0x6f,
+ 0x73, 0x74, 0x41, 0x72, 0x63, 0x68, 0x12, 0x52, 0x0a, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x32,
+ 0x6e, 0x64, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 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, 0x2e,
+ 0x41, 0x72, 0x63, 0x68, 0x3a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x0b, 0x68,
+ 0x6f, 0x73, 0x74, 0x32, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f,
+ 0x73, 0x74, 0x5f, 0x6f, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73,
+ 0x74, 0x4f, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6f, 0x73, 0x5f, 0x65,
+ 0x78, 0x74, 0x72, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x6f, 0x73, 0x74,
+ 0x4f, 0x73, 0x45, 0x78, 0x74, 0x72, 0x61, 0x12, 0x22, 0x0a, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x5f,
+ 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x6f, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+ 0x68, 0x6f, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x4f, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x68,
+ 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x18, 0x0e,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x41,
+ 0x72, 0x63, 0x68, 0x12, 0x2d, 0x0a, 0x13, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x72, 0x6f, 0x73,
+ 0x73, 0x5f, 0x32, 0x6e, 0x64, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x10, 0x68, 0x6f, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x32, 0x6e, 0x64, 0x41, 0x72,
+ 0x63, 0x68, 0x12, 0x17, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x10, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x44, 0x69, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x73,
+ 0x65, 0x74, 0x75, 0x70, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d,
+ 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52,
+ 0x0a, 0x73, 0x65, 0x74, 0x75, 0x70, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x3a, 0x0a, 0x09, 0x6b,
+ 0x61, 0x74, 0x69, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d,
+ 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6b,
+ 0x61, 0x74, 0x69, 0x52, 0x75, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0a, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
+ 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f,
+ 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x52, 0x75, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0a, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x5f, 0x72,
+ 0x75, 0x6e, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
+ 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x52,
+ 0x75, 0x6e, 0x73, 0x12, 0x33, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x15, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
+ 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66,
+ 0x6f, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x56, 0x0a, 0x13, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18,
+ 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x11, 0x73,
+ 0x6f, 0x6f, 0x6e, 0x67, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+ 0x12, 0x43, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x18, 0x17, 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, 0x42, 0x75, 0x69,
+ 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d,
+ 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d,
+ 0x65, 0x12, 0x59, 0x0a, 0x14, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x27, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
+ 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
+ 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x0a, 0x0d,
+ 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x1a, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
+ 0x64, 0x12, 0x3c, 0x0a, 0x0a, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x72, 0x75, 0x6e, 0x73, 0x18,
+ 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x65, 0x72, 0x66,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x52, 0x75, 0x6e, 0x73, 0x22,
+ 0x30, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12,
+ 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x53, 0x45,
+ 0x52, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x45, 0x4e, 0x47, 0x10,
+ 0x02, 0x22, 0x3c, 0x0a, 0x04, 0x41, 0x72, 0x63, 0x68, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b,
+ 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,
+ 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,
+ 0x52, 0x62, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x73, 0x65,
+ 0x5f, 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x6f, 0x72,
+ 0x63, 0x65, 0x55, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x61, 0x7a,
+ 0x65, 0x6c, 0x5f, 0x61, 0x73, 0x5f, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 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,
+ 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,
}
-func init() {
- proto.RegisterFile("metrics.proto", fileDescriptor_6039342a2ba47b72)
+var (
+ file_metrics_proto_rawDescOnce sync.Once
+ file_metrics_proto_rawDescData = file_metrics_proto_rawDesc
+)
+
+func file_metrics_proto_rawDescGZIP() []byte {
+ file_metrics_proto_rawDescOnce.Do(func() {
+ file_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_metrics_proto_rawDescData)
+ })
+ return file_metrics_proto_rawDescData
}
-var fileDescriptor_6039342a2ba47b72 = []byte{
- // 1380 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xef, 0x52, 0x1b, 0x37,
- 0x10, 0x8f, 0xc1, 0x60, 0x7b, 0xfd, 0x07, 0x23, 0xa0, 0x5c, 0x48, 0xd2, 0x52, 0xb7, 0x49, 0x99,
- 0x4e, 0x43, 0x32, 0x34, 0xc3, 0x64, 0x98, 0x4c, 0xa7, 0xe0, 0xd0, 0x34, 0x65, 0xc0, 0x8c, 0x08,
- 0x69, 0xda, 0x7e, 0x50, 0xe5, 0xb3, 0x0c, 0x97, 0xdc, 0x9d, 0x6e, 0x24, 0x1d, 0xc5, 0x79, 0xb3,
- 0x7e, 0xee, 0x4b, 0xf4, 0x05, 0xfa, 0x04, 0x7d, 0x81, 0x8e, 0x56, 0x77, 0xe6, 0x20, 0x6e, 0xc2,
- 0xe4, 0xdb, 0xe9, 0xb7, 0xbf, 0xdf, 0x6a, 0xb5, 0xd2, 0xee, 0xda, 0xd0, 0x8c, 0x84, 0x51, 0x81,
- 0xaf, 0xd7, 0x13, 0x25, 0x8d, 0x24, 0x0b, 0x5a, 0xca, 0xf8, 0x84, 0xf5, 0xd3, 0x20, 0x1c, 0xb0,
- 0xcc, 0xd4, 0xf9, 0xbb, 0x01, 0xf5, 0x7d, 0xf7, 0xbd, 0xc3, 0xb5, 0x20, 0x0f, 0x61, 0xd1, 0x11,
- 0x06, 0xdc, 0x08, 0x66, 0x82, 0x48, 0x68, 0xc3, 0xa3, 0xc4, 0x2b, 0xad, 0x96, 0xd6, 0xa6, 0x29,
- 0x41, 0xdb, 0x53, 0x6e, 0xc4, 0x8b, 0xdc, 0x42, 0x6e, 0x42, 0xd5, 0x29, 0x82, 0x81, 0x37, 0xb5,
- 0x5a, 0x5a, 0xab, 0xd1, 0x0a, 0xae, 0x9f, 0x0f, 0xc8, 0x16, 0xdc, 0x4c, 0x42, 0x6e, 0x86, 0x52,
- 0x45, 0xec, 0x4c, 0x28, 0x1d, 0xc8, 0x98, 0xf9, 0x72, 0x20, 0x62, 0x1e, 0x09, 0x6f, 0x1a, 0xb9,
- 0xcb, 0x39, 0xe1, 0xa5, 0xb3, 0x77, 0x33, 0x33, 0xb9, 0x0b, 0x2d, 0xc3, 0xd5, 0x89, 0x30, 0x2c,
- 0x51, 0x72, 0x90, 0xfa, 0xc6, 0x2b, 0xa3, 0xa0, 0xe9, 0xd0, 0x43, 0x07, 0x92, 0x01, 0x2c, 0x66,
- 0x34, 0x17, 0xc4, 0x19, 0x57, 0x01, 0x8f, 0x8d, 0x37, 0xb3, 0x5a, 0x5a, 0x6b, 0x6d, 0xdc, 0x5f,
- 0x9f, 0x70, 0xe6, 0xf5, 0xc2, 0x79, 0xd7, 0x77, 0xac, 0xe5, 0xa5, 0x13, 0x6d, 0x4d, 0xef, 0x1e,
- 0x3c, 0xa3, 0xc4, 0xf9, 0x2b, 0x1a, 0x48, 0x0f, 0xea, 0xd9, 0x2e, 0x5c, 0xf9, 0xa7, 0xde, 0x2c,
- 0x3a, 0xbf, 0xfb, 0x41, 0xe7, 0xdb, 0xca, 0x3f, 0xdd, 0xaa, 0x1c, 0x1f, 0xec, 0x1d, 0xf4, 0x7e,
- 0x3e, 0xa0, 0xe0, 0x5c, 0x58, 0x90, 0xac, 0xc3, 0x42, 0xc1, 0xe1, 0x38, 0xea, 0x0a, 0x1e, 0x71,
- 0xfe, 0x82, 0x98, 0x07, 0xf0, 0x0d, 0x64, 0x61, 0x31, 0x3f, 0x49, 0xc7, 0xf4, 0x2a, 0xd2, 0xdb,
- 0xce, 0xd2, 0x4d, 0xd2, 0x9c, 0xbd, 0x07, 0xb5, 0x53, 0xa9, 0xb3, 0x60, 0x6b, 0x1f, 0x15, 0x6c,
- 0xd5, 0x3a, 0xc0, 0x50, 0x29, 0x34, 0xd1, 0xd9, 0x46, 0x3c, 0x70, 0x0e, 0xe1, 0xa3, 0x1c, 0xd6,
- 0xad, 0x93, 0x8d, 0x78, 0x80, 0x3e, 0x97, 0xa1, 0x82, 0x3e, 0xa5, 0xf6, 0xea, 0x78, 0x86, 0x59,
- 0xbb, 0xec, 0x69, 0xd2, 0xc9, 0x36, 0x93, 0x9a, 0x89, 0x73, 0xa3, 0xb8, 0xd7, 0x40, 0x73, 0xdd,
- 0x99, 0x77, 0x2d, 0x34, 0xe6, 0xf8, 0x4a, 0x6a, 0x6d, 0x5d, 0x34, 0x2f, 0x38, 0x5d, 0x8b, 0xf5,
- 0x34, 0xb9, 0x07, 0x73, 0x05, 0x0e, 0x86, 0xdd, 0x72, 0xcf, 0x67, 0xcc, 0xc2, 0x40, 0xee, 0xc3,
- 0x42, 0x81, 0x37, 0x3e, 0xe2, 0x9c, 0x4b, 0xec, 0x98, 0x5b, 0x88, 0x5b, 0xa6, 0x86, 0x0d, 0x02,
- 0xe5, 0xb5, 0x5d, 0xdc, 0x32, 0x35, 0x4f, 0x03, 0x45, 0xbe, 0x83, 0xba, 0x16, 0x26, 0x4d, 0x98,
- 0x91, 0x32, 0xd4, 0xde, 0xfc, 0xea, 0xf4, 0x5a, 0x7d, 0xe3, 0xce, 0xc4, 0x14, 0x1d, 0x0a, 0x35,
- 0x7c, 0x1e, 0x0f, 0x25, 0x05, 0x54, 0xbc, 0xb0, 0x02, 0xb2, 0x05, 0xb5, 0x37, 0xdc, 0x04, 0x4c,
- 0xa5, 0xb1, 0xf6, 0xc8, 0x75, 0xd4, 0x55, 0xcb, 0xa7, 0x69, 0xac, 0xc9, 0x13, 0x00, 0xc7, 0x44,
- 0xf1, 0xc2, 0x75, 0xc4, 0x35, 0xb4, 0xe6, 0xea, 0x38, 0x88, 0x5f, 0x73, 0xa7, 0x5e, 0xbc, 0x96,
- 0x1a, 0x05, 0xa8, 0xfe, 0x16, 0x66, 0x8c, 0x34, 0x3c, 0xf4, 0x96, 0x56, 0x4b, 0x1f, 0x16, 0x3a,
- 0x2e, 0x79, 0x09, 0x93, 0x5a, 0x91, 0xf7, 0x09, 0xba, 0xb8, 0x37, 0xd1, 0xc5, 0x91, 0xc5, 0xb0,
- 0x24, 0xb3, 0x17, 0x46, 0xe7, 0xf5, 0x55, 0x88, 0x74, 0xa1, 0xe1, 0x54, 0xbe, 0x8c, 0x87, 0xc1,
- 0x89, 0xb7, 0x8c, 0x0e, 0x57, 0x27, 0x3a, 0x44, 0x61, 0x17, 0x79, 0xb4, 0xde, 0xbf, 0x58, 0x90,
- 0x15, 0xc0, 0xa7, 0x8f, 0x2d, 0xca, 0xc3, 0x3b, 0x1e, 0xaf, 0xc9, 0x2f, 0xb0, 0xa8, 0x47, 0xda,
- 0x88, 0x88, 0x29, 0xa1, 0x65, 0xaa, 0x7c, 0xc1, 0x82, 0x78, 0x28, 0xbd, 0x9b, 0xb8, 0xd1, 0x57,
- 0x93, 0x23, 0x47, 0x01, 0xcd, 0xf8, 0x98, 0x06, 0xa2, 0xdf, 0xc1, 0xc8, 0x17, 0xd0, 0xcc, 0x63,
- 0x8f, 0x22, 0x1e, 0x0f, 0xbc, 0x15, 0xdc, 0xbb, 0x91, 0x85, 0x86, 0x98, 0xbd, 0xab, 0x3e, 0x7f,
- 0x2b, 0x42, 0x77, 0x57, 0xb7, 0xae, 0x75, 0x57, 0x28, 0xb0, 0x77, 0xd5, 0x79, 0x08, 0x8d, 0x4b,
- 0x4d, 0xad, 0x0a, 0xe5, 0xe3, 0xa3, 0x5d, 0xda, 0xbe, 0x41, 0x9a, 0x50, 0xb3, 0x5f, 0x4f, 0x77,
- 0x77, 0x8e, 0x9f, 0xb5, 0x4b, 0xa4, 0x02, 0xb6, 0x11, 0xb6, 0xa7, 0x3a, 0x4f, 0xa0, 0x8c, 0xcf,
- 0xbe, 0x0e, 0x79, 0x19, 0xb7, 0x6f, 0x58, 0xeb, 0x36, 0xdd, 0x6f, 0x97, 0x48, 0x0d, 0x66, 0xb6,
- 0xe9, 0xfe, 0xe6, 0xa3, 0xf6, 0x94, 0xc5, 0x5e, 0x3d, 0xde, 0x6c, 0x4f, 0x13, 0x80, 0xd9, 0x57,
- 0x8f, 0x37, 0xd9, 0xe6, 0xa3, 0x76, 0xb9, 0x73, 0x02, 0xf5, 0x42, 0x96, 0xed, 0x9c, 0x48, 0xb5,
- 0x60, 0x27, 0x32, 0xe2, 0x38, 0x4d, 0xaa, 0xb4, 0x92, 0x6a, 0xf1, 0x4c, 0x46, 0xdc, 0x96, 0x95,
- 0x35, 0xa9, 0xbe, 0xc0, 0x09, 0x52, 0xa5, 0xb3, 0xa9, 0x16, 0xb4, 0x2f, 0xc8, 0x97, 0xd0, 0x1a,
- 0x4a, 0x9b, 0xe6, 0xb1, 0x72, 0x1a, 0xed, 0x0d, 0x44, 0x8f, 0x9d, 0xbc, 0x23, 0x81, 0xbc, 0x9b,
- 0x65, 0xb2, 0x01, 0x4b, 0xf8, 0xdc, 0x58, 0x72, 0x3a, 0xd2, 0x81, 0xcf, 0x43, 0x16, 0x89, 0x48,
- 0xaa, 0x11, 0x6e, 0x5e, 0xa6, 0x0b, 0x68, 0x3c, 0xcc, 0x6c, 0xfb, 0x68, 0xb2, 0x43, 0x87, 0x9f,
- 0xf1, 0x20, 0xe4, 0xfd, 0x50, 0xd8, 0x4e, 0xab, 0x31, 0x9e, 0x19, 0xda, 0x1c, 0xa3, 0xdd, 0x24,
- 0xd5, 0x9d, 0x7f, 0x4b, 0x50, 0xcd, 0x33, 0x4c, 0x08, 0x94, 0x07, 0x42, 0xfb, 0xe8, 0xb6, 0x46,
- 0xf1, 0xdb, 0x62, 0xf8, 0x80, 0xdc, 0x3c, 0xc4, 0x6f, 0x72, 0x07, 0x40, 0x1b, 0xae, 0x0c, 0x0e,
- 0x55, 0x3c, 0x47, 0x99, 0xd6, 0x10, 0xb1, 0xb3, 0x94, 0xdc, 0x82, 0x9a, 0x12, 0x3c, 0x74, 0xd6,
- 0x32, 0x5a, 0xab, 0x16, 0x40, 0xe3, 0xe7, 0x00, 0x2e, 0x78, 0x9b, 0x08, 0x9c, 0x6d, 0xe5, 0x9d,
- 0x29, 0xaf, 0x44, 0x6b, 0x0e, 0x3d, 0xd6, 0x82, 0xfc, 0x0e, 0xcb, 0x89, 0x92, 0xbe, 0xd0, 0x5a,
- 0xe8, 0x2b, 0xcf, 0x73, 0x16, 0x1f, 0xca, 0xda, 0xe4, 0x87, 0xe2, 0x34, 0x97, 0xde, 0xe7, 0xd2,
- 0xd8, 0x51, 0x11, 0xee, 0xfc, 0x39, 0x0d, 0x0b, 0x13, 0xe8, 0xe3, 0xc3, 0x96, 0x0a, 0x87, 0x5d,
- 0x83, 0x76, 0xaa, 0x85, 0xc2, 0xd3, 0xb0, 0x28, 0xb0, 0xed, 0x15, 0x93, 0x51, 0xa6, 0x2d, 0x8b,
- 0xdb, 0x43, 0xed, 0x23, 0x6a, 0x27, 0x5b, 0x56, 0x53, 0x45, 0xae, 0x4b, 0x4f, 0xdb, 0x59, 0x0a,
- 0xec, 0xdb, 0x00, 0x11, 0x3f, 0x67, 0x4a, 0x6b, 0xf6, 0xa6, 0x9f, 0xa7, 0x29, 0xe2, 0xe7, 0x54,
- 0xeb, 0xbd, 0x3e, 0xf9, 0x1a, 0xe6, 0xa3, 0x20, 0x96, 0x8a, 0x25, 0xfc, 0x44, 0xb0, 0x21, 0x4f,
- 0x43, 0xa3, 0x5d, 0xb6, 0xe8, 0x1c, 0x1a, 0x0e, 0xf9, 0x89, 0xf8, 0x01, 0x61, 0xe4, 0xf2, 0xd7,
- 0x57, 0xb8, 0xb3, 0x19, 0xd7, 0x1a, 0x0a, 0xdc, 0x4f, 0xa1, 0x1e, 0x48, 0x16, 0xc4, 0x49, 0x6a,
- 0xec, 0xb6, 0x15, 0x77, 0x77, 0x81, 0x7c, 0x6e, 0x91, 0xbd, 0x3e, 0x59, 0x85, 0x46, 0x20, 0x99,
- 0x4c, 0x4d, 0x46, 0xa8, 0x22, 0x01, 0x02, 0xd9, 0x43, 0x68, 0xaf, 0x4f, 0x9e, 0xc0, 0xca, 0x99,
- 0x0c, 0xd3, 0xd8, 0x70, 0x35, 0xb2, 0xed, 0xc9, 0x88, 0x73, 0xc3, 0xf4, 0x1f, 0x81, 0xf1, 0x4f,
- 0x85, 0xc6, 0x11, 0x5d, 0xa6, 0xde, 0x98, 0xd1, 0x75, 0x84, 0xa3, 0xcc, 0x4e, 0xbe, 0x87, 0xdb,
- 0x41, 0xfc, 0x1e, 0x3d, 0xa0, 0x7e, 0xa5, 0xc0, 0xb9, 0xe2, 0xa1, 0xf3, 0x4f, 0x09, 0x5a, 0xfb,
- 0x72, 0x90, 0x86, 0xe2, 0xc5, 0x28, 0x71, 0xd7, 0xf6, 0x5b, 0xde, 0x2d, 0x5d, 0x92, 0xf1, 0xfa,
- 0x5a, 0x1b, 0x0f, 0x26, 0x8f, 0xf5, 0x4b, 0x52, 0xd7, 0x3c, 0x5d, 0xc9, 0x15, 0x06, 0x7c, 0xff,
- 0x02, 0x25, 0x9f, 0x41, 0x3d, 0x42, 0x0d, 0x33, 0xa3, 0x24, 0xaf, 0x03, 0x88, 0xc6, 0x6e, 0x6c,
- 0x65, 0xc7, 0x69, 0xc4, 0xe4, 0x90, 0x39, 0xd0, 0x5d, 0x79, 0x93, 0x36, 0xe2, 0x34, 0xea, 0x0d,
- 0xdd, 0x7e, 0xba, 0xf3, 0x20, 0x6b, 0x21, 0x99, 0xd7, 0x4b, 0x7d, 0xa8, 0x06, 0x33, 0x47, 0xbd,
- 0xde, 0x81, 0x6d, 0x58, 0x55, 0x28, 0xef, 0x6f, 0xef, 0xed, 0xb6, 0xa7, 0x3a, 0x21, 0xac, 0x74,
- 0x55, 0x60, 0x6c, 0x49, 0x1f, 0x6b, 0xa1, 0x7e, 0x92, 0xa9, 0x8a, 0xc5, 0x28, 0x1f, 0x10, 0x93,
- 0x5e, 0xea, 0x16, 0x54, 0xf2, 0x01, 0x34, 0xf5, 0x9e, 0x79, 0x51, 0xf8, 0x61, 0x43, 0x73, 0x41,
- 0xa7, 0x0f, 0xb7, 0x26, 0xec, 0xa6, 0x2f, 0xe6, 0x51, 0xd9, 0x4f, 0x5f, 0x6b, 0xaf, 0x84, 0xf5,
- 0x37, 0x39, 0xb3, 0xff, 0x1f, 0x2d, 0x45, 0x71, 0xe7, 0xaf, 0x12, 0xcc, 0xbf, 0x33, 0xfd, 0x88,
- 0x07, 0x95, 0x3c, 0x6f, 0x25, 0xcc, 0x5b, 0xbe, 0xb4, 0xf3, 0x2b, 0xfb, 0x79, 0xe8, 0x0e, 0xd4,
- 0xa4, 0xe3, 0xb5, 0x7d, 0xf3, 0xae, 0x25, 0xf2, 0x30, 0x94, 0x3e, 0xf3, 0x65, 0x1a, 0x9b, 0xac,
- 0xd4, 0xe6, 0xd0, 0xb0, 0x6d, 0xf1, 0xae, 0x85, 0x6d, 0x05, 0x17, 0xb9, 0x3a, 0x78, 0x9b, 0xb7,
- 0xa5, 0xd6, 0x05, 0xf5, 0x28, 0x78, 0x2b, 0xec, 0xef, 0x31, 0x5b, 0x93, 0xa7, 0x82, 0x27, 0x8e,
- 0xe6, 0x2a, 0xae, 0x1e, 0xf1, 0xf3, 0x1f, 0x05, 0x4f, 0x2c, 0x67, 0x67, 0xe9, 0xd7, 0x6c, 0xe4,
- 0x67, 0xe7, 0x66, 0xf8, 0x97, 0xe4, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xfb, 0x8e, 0xf5,
- 0xa2, 0x0c, 0x00, 0x00,
+var file_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
+var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
+var file_metrics_proto_goTypes = []interface{}{
+ (MetricsBase_BuildVariant)(0), // 0: soong_build_metrics.MetricsBase.BuildVariant
+ (MetricsBase_Arch)(0), // 1: soong_build_metrics.MetricsBase.Arch
+ (ModuleTypeInfo_BuildSystem)(0), // 2: soong_build_metrics.ModuleTypeInfo.BuildSystem
+ (*MetricsBase)(nil), // 3: soong_build_metrics.MetricsBase
+ (*BuildConfig)(nil), // 4: soong_build_metrics.BuildConfig
+ (*SystemResourceInfo)(nil), // 5: soong_build_metrics.SystemResourceInfo
+ (*PerfInfo)(nil), // 6: soong_build_metrics.PerfInfo
+ (*ProcessResourceInfo)(nil), // 7: soong_build_metrics.ProcessResourceInfo
+ (*ModuleTypeInfo)(nil), // 8: soong_build_metrics.ModuleTypeInfo
+ (*CriticalUserJourneyMetrics)(nil), // 9: soong_build_metrics.CriticalUserJourneyMetrics
+ (*CriticalUserJourneysMetrics)(nil), // 10: soong_build_metrics.CriticalUserJourneysMetrics
+ (*SoongBuildMetrics)(nil), // 11: soong_build_metrics.SoongBuildMetrics
+}
+var file_metrics_proto_depIdxs = []int32{
+ 0, // 0: soong_build_metrics.MetricsBase.target_build_variant:type_name -> soong_build_metrics.MetricsBase.BuildVariant
+ 1, // 1: soong_build_metrics.MetricsBase.target_arch:type_name -> soong_build_metrics.MetricsBase.Arch
+ 1, // 2: soong_build_metrics.MetricsBase.host_arch:type_name -> soong_build_metrics.MetricsBase.Arch
+ 1, // 3: soong_build_metrics.MetricsBase.host_2nd_arch:type_name -> soong_build_metrics.MetricsBase.Arch
+ 6, // 4: soong_build_metrics.MetricsBase.setup_tools:type_name -> soong_build_metrics.PerfInfo
+ 6, // 5: soong_build_metrics.MetricsBase.kati_runs:type_name -> soong_build_metrics.PerfInfo
+ 6, // 6: soong_build_metrics.MetricsBase.soong_runs:type_name -> soong_build_metrics.PerfInfo
+ 6, // 7: soong_build_metrics.MetricsBase.ninja_runs:type_name -> soong_build_metrics.PerfInfo
+ 6, // 8: soong_build_metrics.MetricsBase.total:type_name -> soong_build_metrics.PerfInfo
+ 11, // 9: soong_build_metrics.MetricsBase.soong_build_metrics:type_name -> soong_build_metrics.SoongBuildMetrics
+ 4, // 10: soong_build_metrics.MetricsBase.build_config:type_name -> soong_build_metrics.BuildConfig
+ 5, // 11: soong_build_metrics.MetricsBase.system_resource_info:type_name -> soong_build_metrics.SystemResourceInfo
+ 6, // 12: soong_build_metrics.MetricsBase.bazel_runs:type_name -> soong_build_metrics.PerfInfo
+ 7, // 13: soong_build_metrics.PerfInfo.processes_resource_info:type_name -> soong_build_metrics.ProcessResourceInfo
+ 2, // 14: soong_build_metrics.ModuleTypeInfo.build_system:type_name -> soong_build_metrics.ModuleTypeInfo.BuildSystem
+ 3, // 15: soong_build_metrics.CriticalUserJourneyMetrics.metrics:type_name -> soong_build_metrics.MetricsBase
+ 9, // 16: soong_build_metrics.CriticalUserJourneysMetrics.cujs:type_name -> soong_build_metrics.CriticalUserJourneyMetrics
+ 17, // [17:17] is the sub-list for method output_type
+ 17, // [17:17] is the sub-list for method input_type
+ 17, // [17:17] is the sub-list for extension type_name
+ 17, // [17:17] is the sub-list for extension extendee
+ 0, // [0:17] is the sub-list for field type_name
+}
+
+func init() { file_metrics_proto_init() }
+func file_metrics_proto_init() {
+ if File_metrics_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*MetricsBase); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_metrics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BuildConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_metrics_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SystemResourceInfo); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_metrics_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*PerfInfo); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_metrics_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ProcessResourceInfo); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_metrics_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ModuleTypeInfo); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_metrics_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CriticalUserJourneyMetrics); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_metrics_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CriticalUserJourneysMetrics); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_metrics_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SoongBuildMetrics); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_metrics_proto_rawDesc,
+ NumEnums: 3,
+ NumMessages: 9,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_metrics_proto_goTypes,
+ DependencyIndexes: file_metrics_proto_depIdxs,
+ EnumInfos: file_metrics_proto_enumTypes,
+ MessageInfos: file_metrics_proto_msgTypes,
+ }.Build()
+ File_metrics_proto = out.File
+ file_metrics_proto_rawDesc = nil
+ file_metrics_proto_goTypes = nil
+ file_metrics_proto_depIdxs = nil
}
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index 91d8dd9..ef42f54 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -15,7 +15,7 @@
syntax = "proto2";
package soong_build_metrics;
-option go_package = "soong_metrics_proto";
+option go_package = "android/soong/ui/metrics/metrics_proto";
message MetricsBase {
// Timestamp generated when the build starts.
@@ -116,6 +116,13 @@
optional bool use_rbe = 2;
optional bool force_use_goma = 3;
+
+ // Whether the Bazel is acting as the Ninja executor for this build.
+ optional bool bazel_as_ninja = 4;
+
+ // 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;
}
message SystemResourceInfo {
diff --git a/ui/metrics/upload_proto/upload.pb.go b/ui/metrics/upload_proto/upload.pb.go
index 614d4c7..9c8fb06 100644
--- a/ui/metrics/upload_proto/upload.pb.go
+++ b/ui/metrics/upload_proto/upload.pb.go
@@ -1,26 +1,44 @@
+// Copyright 2020 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: upload.proto
-package soong_metrics_upload_proto
+package upload_proto
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
type Upload struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// The timestamp in milliseconds that the build was created.
CreationTimestampMs *uint64 `protobuf:"varint,1,opt,name=creation_timestamp_ms,json=creationTimestampMs" json:"creation_timestamp_ms,omitempty"`
// The timestamp in milliseconds when the build was completed.
@@ -33,102 +51,169 @@
MetricsFiles []string `protobuf:"bytes,5,rep,name=metrics_files,json=metricsFiles" json:"metrics_files,omitempty"`
// A list of directories to delete after the copy of metrics files
// is completed for uploading.
- DirectoriesToDelete []string `protobuf:"bytes,6,rep,name=directories_to_delete,json=directoriesToDelete" json:"directories_to_delete,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ DirectoriesToDelete []string `protobuf:"bytes,6,rep,name=directories_to_delete,json=directoriesToDelete" json:"directories_to_delete,omitempty"`
}
-func (m *Upload) Reset() { *m = Upload{} }
-func (m *Upload) String() string { return proto.CompactTextString(m) }
-func (*Upload) ProtoMessage() {}
+func (x *Upload) Reset() {
+ *x = Upload{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_upload_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Upload) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Upload) ProtoMessage() {}
+
+func (x *Upload) ProtoReflect() protoreflect.Message {
+ mi := &file_upload_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Upload.ProtoReflect.Descriptor instead.
func (*Upload) Descriptor() ([]byte, []int) {
- return fileDescriptor_91b94b655bd2a7e5, []int{0}
+ return file_upload_proto_rawDescGZIP(), []int{0}
}
-func (m *Upload) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Upload.Unmarshal(m, b)
-}
-func (m *Upload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Upload.Marshal(b, m, deterministic)
-}
-func (m *Upload) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Upload.Merge(m, src)
-}
-func (m *Upload) XXX_Size() int {
- return xxx_messageInfo_Upload.Size(m)
-}
-func (m *Upload) XXX_DiscardUnknown() {
- xxx_messageInfo_Upload.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Upload proto.InternalMessageInfo
-
-func (m *Upload) GetCreationTimestampMs() uint64 {
- if m != nil && m.CreationTimestampMs != nil {
- return *m.CreationTimestampMs
+func (x *Upload) GetCreationTimestampMs() uint64 {
+ if x != nil && x.CreationTimestampMs != nil {
+ return *x.CreationTimestampMs
}
return 0
}
-func (m *Upload) GetCompletionTimestampMs() uint64 {
- if m != nil && m.CompletionTimestampMs != nil {
- return *m.CompletionTimestampMs
+func (x *Upload) GetCompletionTimestampMs() uint64 {
+ if x != nil && x.CompletionTimestampMs != nil {
+ return *x.CompletionTimestampMs
}
return 0
}
-func (m *Upload) GetBranchName() string {
- if m != nil && m.BranchName != nil {
- return *m.BranchName
+func (x *Upload) GetBranchName() string {
+ if x != nil && x.BranchName != nil {
+ return *x.BranchName
}
return ""
}
-func (m *Upload) GetTargetName() string {
- if m != nil && m.TargetName != nil {
- return *m.TargetName
+func (x *Upload) GetTargetName() string {
+ if x != nil && x.TargetName != nil {
+ return *x.TargetName
}
return ""
}
-func (m *Upload) GetMetricsFiles() []string {
- if m != nil {
- return m.MetricsFiles
+func (x *Upload) GetMetricsFiles() []string {
+ if x != nil {
+ return x.MetricsFiles
}
return nil
}
-func (m *Upload) GetDirectoriesToDelete() []string {
- if m != nil {
- return m.DirectoriesToDelete
+func (x *Upload) GetDirectoriesToDelete() []string {
+ if x != nil {
+ return x.DirectoriesToDelete
}
return nil
}
-func init() {
- proto.RegisterType((*Upload)(nil), "soong_metrics_upload.Upload")
+var File_upload_proto protoreflect.FileDescriptor
+
+var file_upload_proto_rawDesc = []byte{
+ 0x0a, 0x0c, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14,
+ 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x75, 0x70,
+ 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x8f, 0x02, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12,
+ 0x32, 0x0a, 0x15, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+ 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13,
+ 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+ 0x70, 0x4d, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x6d, 0x73, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e,
+ 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x62,
+ 0x72, 0x61, 0x6e, 0x63, 0x68, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0a, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b,
+ 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a,
+ 0x0d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x05,
+ 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x46, 0x69, 0x6c,
+ 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65,
+ 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x13, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x54, 0x6f,
+ 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x27, 0x5a, 0x25, 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, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
}
-func init() {
- proto.RegisterFile("upload.proto", fileDescriptor_91b94b655bd2a7e5)
+var (
+ file_upload_proto_rawDescOnce sync.Once
+ file_upload_proto_rawDescData = file_upload_proto_rawDesc
+)
+
+func file_upload_proto_rawDescGZIP() []byte {
+ file_upload_proto_rawDescOnce.Do(func() {
+ file_upload_proto_rawDescData = protoimpl.X.CompressGZIP(file_upload_proto_rawDescData)
+ })
+ return file_upload_proto_rawDescData
}
-var fileDescriptor_91b94b655bd2a7e5 = []byte{
- // 230 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xb1, 0x4a, 0x04, 0x31,
- 0x10, 0x86, 0xd9, 0xbb, 0xf3, 0xe0, 0xe2, 0xd9, 0xec, 0x79, 0x18, 0x44, 0x70, 0xd1, 0x66, 0x2b,
- 0x0b, 0x0b, 0x1f, 0x40, 0xc4, 0x4e, 0x8b, 0xe5, 0x6c, 0x6c, 0x86, 0x98, 0x1d, 0xd7, 0x40, 0x92,
- 0x09, 0xc9, 0xf8, 0x1c, 0xbe, 0xb2, 0x6c, 0xe2, 0xe2, 0x82, 0x76, 0xc3, 0xff, 0x7d, 0x7f, 0x31,
- 0xbf, 0xd8, 0x7e, 0x06, 0x4b, 0xaa, 0xbf, 0x09, 0x91, 0x98, 0xea, 0xd3, 0x44, 0xe4, 0x07, 0x70,
- 0xc8, 0xd1, 0xe8, 0x04, 0x85, 0x5d, 0x7d, 0x2d, 0xc4, 0xfa, 0x25, 0x9f, 0xf5, 0xad, 0xd8, 0xeb,
- 0x88, 0x8a, 0x0d, 0x79, 0x60, 0xe3, 0x30, 0xb1, 0x72, 0x01, 0x5c, 0x92, 0x55, 0x53, 0xb5, 0xab,
- 0x6e, 0x37, 0xc1, 0xc3, 0xc4, 0x9e, 0x52, 0x7d, 0x27, 0xce, 0x34, 0xb9, 0x60, 0xf1, 0x6f, 0x6b,
- 0x91, 0x5b, 0xfb, 0x5f, 0x3c, 0xef, 0x5d, 0x8a, 0xe3, 0xb7, 0xa8, 0xbc, 0xfe, 0x00, 0xaf, 0x1c,
- 0xca, 0x65, 0x53, 0xb5, 0x9b, 0x4e, 0x94, 0xe8, 0x59, 0x39, 0x1c, 0x05, 0x56, 0x71, 0x40, 0x2e,
- 0xc2, 0xaa, 0x08, 0x25, 0xca, 0xc2, 0xb5, 0x38, 0x99, 0x5e, 0x79, 0x37, 0x16, 0x93, 0x3c, 0x6a,
- 0x96, 0xed, 0xa6, 0xdb, 0xfe, 0x84, 0x8f, 0x63, 0x36, 0xbe, 0xd4, 0x9b, 0x88, 0x9a, 0x29, 0x1a,
- 0x4c, 0xc0, 0x04, 0x3d, 0x5a, 0x64, 0x94, 0xeb, 0x2c, 0xef, 0x66, 0xf0, 0x40, 0x0f, 0x19, 0xdd,
- 0x5f, 0xbc, 0x9e, 0xff, 0xb7, 0x14, 0xe4, 0x15, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x64, 0x04,
- 0xa8, 0xf4, 0x54, 0x01, 0x00, 0x00,
+var file_upload_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_upload_proto_goTypes = []interface{}{
+ (*Upload)(nil), // 0: soong_metrics_upload.Upload
+}
+var file_upload_proto_depIdxs = []int32{
+ 0, // [0:0] is the sub-list for method output_type
+ 0, // [0:0] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_upload_proto_init() }
+func file_upload_proto_init() {
+ if File_upload_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_upload_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Upload); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_upload_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_upload_proto_goTypes,
+ DependencyIndexes: file_upload_proto_depIdxs,
+ MessageInfos: file_upload_proto_msgTypes,
+ }.Build()
+ File_upload_proto = out.File
+ file_upload_proto_rawDesc = nil
+ file_upload_proto_goTypes = nil
+ file_upload_proto_depIdxs = nil
}
diff --git a/ui/metrics/upload_proto/upload.proto b/ui/metrics/upload_proto/upload.proto
index bcd0ab2..e621fd1 100644
--- a/ui/metrics/upload_proto/upload.proto
+++ b/ui/metrics/upload_proto/upload.proto
@@ -15,7 +15,7 @@
syntax = "proto2";
package soong_metrics_upload;
-option go_package = "soong_metrics_upload_proto";
+option go_package = "android/soong/ui/metrics/upload_proto";
message Upload {
// The timestamp in milliseconds that the build was created.
diff --git a/ui/status/Android.bp b/ui/status/Android.bp
index ac31390..a46a007 100644
--- a/ui/status/Android.bp
+++ b/ui/status/Android.bp
@@ -44,7 +44,10 @@
bootstrap_go_package {
name: "soong-ui-status-ninja_frontend",
pkgPath: "android/soong/ui/status/ninja_frontend",
- deps: ["golang-protobuf-proto"],
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
srcs: [
"ninja_frontend/frontend.pb.go",
],
@@ -53,7 +56,10 @@
bootstrap_go_package {
name: "soong-ui-status-build_error_proto",
pkgPath: "android/soong/ui/status/build_error_proto",
- deps: ["golang-protobuf-proto"],
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
srcs: [
"build_error_proto/build_error.pb.go",
],
@@ -62,7 +68,10 @@
bootstrap_go_package {
name: "soong-ui-status-build_progress_proto",
pkgPath: "android/soong/ui/status/build_progress_proto",
- deps: ["golang-protobuf-proto"],
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
srcs: [
"build_progress_proto/build_progress.pb.go",
],
diff --git a/ui/status/build_error_proto/build_error.pb.go b/ui/status/build_error_proto/build_error.pb.go
index d4d0a6e..22125c2 100644
--- a/ui/status/build_error_proto/build_error.pb.go
+++ b/ui/status/build_error_proto/build_error.pb.go
@@ -1,71 +1,93 @@
+// Copyright 2019 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: build_error.proto
-package soong_build_error_proto
+package build_error_proto
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
type BuildError struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// List of error messages of the overall build. The error messages
// are not associated with a build action.
ErrorMessages []string `protobuf:"bytes,1,rep,name=error_messages,json=errorMessages" json:"error_messages,omitempty"`
// List of build action errors.
- ActionErrors []*BuildActionError `protobuf:"bytes,2,rep,name=action_errors,json=actionErrors" json:"action_errors,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ ActionErrors []*BuildActionError `protobuf:"bytes,2,rep,name=action_errors,json=actionErrors" json:"action_errors,omitempty"`
}
-func (m *BuildError) Reset() { *m = BuildError{} }
-func (m *BuildError) String() string { return proto.CompactTextString(m) }
-func (*BuildError) ProtoMessage() {}
+func (x *BuildError) Reset() {
+ *x = BuildError{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_error_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BuildError) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BuildError) ProtoMessage() {}
+
+func (x *BuildError) ProtoReflect() protoreflect.Message {
+ mi := &file_build_error_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BuildError.ProtoReflect.Descriptor instead.
func (*BuildError) Descriptor() ([]byte, []int) {
- return fileDescriptor_a2e15b05802a5501, []int{0}
+ return file_build_error_proto_rawDescGZIP(), []int{0}
}
-func (m *BuildError) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_BuildError.Unmarshal(m, b)
-}
-func (m *BuildError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_BuildError.Marshal(b, m, deterministic)
-}
-func (m *BuildError) XXX_Merge(src proto.Message) {
- xxx_messageInfo_BuildError.Merge(m, src)
-}
-func (m *BuildError) XXX_Size() int {
- return xxx_messageInfo_BuildError.Size(m)
-}
-func (m *BuildError) XXX_DiscardUnknown() {
- xxx_messageInfo_BuildError.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BuildError proto.InternalMessageInfo
-
-func (m *BuildError) GetErrorMessages() []string {
- if m != nil {
- return m.ErrorMessages
+func (x *BuildError) GetErrorMessages() []string {
+ if x != nil {
+ return x.ErrorMessages
}
return nil
}
-func (m *BuildError) GetActionErrors() []*BuildActionError {
- if m != nil {
- return m.ActionErrors
+func (x *BuildError) GetActionErrors() []*BuildActionError {
+ if x != nil {
+ return x.ActionErrors
}
return nil
}
@@ -73,6 +95,10 @@
// Build is composed of a list of build action. There can be a set of build
// actions that can failed.
type BuildActionError struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Description of the command.
Description *string `protobuf:"bytes,1,opt,name=description" json:"description,omitempty"`
// The command name that raised the error.
@@ -82,94 +108,177 @@
// List of artifacts (i.e. files) that was produced by the command.
Artifacts []string `protobuf:"bytes,4,rep,name=artifacts" json:"artifacts,omitempty"`
// The error string produced by the build action.
- Error *string `protobuf:"bytes,5,opt,name=error" json:"error,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Error *string `protobuf:"bytes,5,opt,name=error" json:"error,omitempty"`
}
-func (m *BuildActionError) Reset() { *m = BuildActionError{} }
-func (m *BuildActionError) String() string { return proto.CompactTextString(m) }
-func (*BuildActionError) ProtoMessage() {}
+func (x *BuildActionError) Reset() {
+ *x = BuildActionError{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_error_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BuildActionError) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BuildActionError) ProtoMessage() {}
+
+func (x *BuildActionError) ProtoReflect() protoreflect.Message {
+ mi := &file_build_error_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BuildActionError.ProtoReflect.Descriptor instead.
func (*BuildActionError) Descriptor() ([]byte, []int) {
- return fileDescriptor_a2e15b05802a5501, []int{1}
+ return file_build_error_proto_rawDescGZIP(), []int{1}
}
-func (m *BuildActionError) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_BuildActionError.Unmarshal(m, b)
-}
-func (m *BuildActionError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_BuildActionError.Marshal(b, m, deterministic)
-}
-func (m *BuildActionError) XXX_Merge(src proto.Message) {
- xxx_messageInfo_BuildActionError.Merge(m, src)
-}
-func (m *BuildActionError) XXX_Size() int {
- return xxx_messageInfo_BuildActionError.Size(m)
-}
-func (m *BuildActionError) XXX_DiscardUnknown() {
- xxx_messageInfo_BuildActionError.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BuildActionError proto.InternalMessageInfo
-
-func (m *BuildActionError) GetDescription() string {
- if m != nil && m.Description != nil {
- return *m.Description
+func (x *BuildActionError) GetDescription() string {
+ if x != nil && x.Description != nil {
+ return *x.Description
}
return ""
}
-func (m *BuildActionError) GetCommand() string {
- if m != nil && m.Command != nil {
- return *m.Command
+func (x *BuildActionError) GetCommand() string {
+ if x != nil && x.Command != nil {
+ return *x.Command
}
return ""
}
-func (m *BuildActionError) GetOutput() string {
- if m != nil && m.Output != nil {
- return *m.Output
+func (x *BuildActionError) GetOutput() string {
+ if x != nil && x.Output != nil {
+ return *x.Output
}
return ""
}
-func (m *BuildActionError) GetArtifacts() []string {
- if m != nil {
- return m.Artifacts
+func (x *BuildActionError) GetArtifacts() []string {
+ if x != nil {
+ return x.Artifacts
}
return nil
}
-func (m *BuildActionError) GetError() string {
- if m != nil && m.Error != nil {
- return *m.Error
+func (x *BuildActionError) GetError() string {
+ if x != nil && x.Error != nil {
+ return *x.Error
}
return ""
}
-func init() {
- proto.RegisterType((*BuildError)(nil), "soong_build_error.BuildError")
- proto.RegisterType((*BuildActionError)(nil), "soong_build_error.BuildActionError")
+var File_build_error_proto protoreflect.FileDescriptor
+
+var file_build_error_proto_rawDesc = []byte{
+ 0x0a, 0x11, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
+ 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x7d, 0x0a, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x45,
+ 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65,
+ 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x72,
+ 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x0d, 0x61,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64,
+ 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x41, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x0c, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45,
+ 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x9a, 0x01, 0x0a, 0x10, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x41,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 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, 0x18, 0x0a, 0x07,
+ 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63,
+ 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1c,
+ 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05,
+ 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72,
+ 0x6f, 0x72, 0x42, 0x2b, 0x5a, 0x29, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f,
+ 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
}
-func init() { proto.RegisterFile("build_error.proto", fileDescriptor_a2e15b05802a5501) }
+var (
+ file_build_error_proto_rawDescOnce sync.Once
+ file_build_error_proto_rawDescData = file_build_error_proto_rawDesc
+)
-var fileDescriptor_a2e15b05802a5501 = []byte{
- // 229 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xc1, 0x4a, 0xc3, 0x40,
- 0x10, 0x86, 0x49, 0x63, 0x95, 0x4c, 0xad, 0xd8, 0x41, 0x74, 0x04, 0x0f, 0xa1, 0x22, 0xe4, 0x94,
- 0x83, 0x6f, 0x60, 0x41, 0xf0, 0xe2, 0x25, 0x47, 0x2f, 0x61, 0xdd, 0xac, 0x65, 0xc1, 0x64, 0xc2,
- 0xce, 0xe6, 0xe8, 0x8b, 0xf8, 0xb4, 0x92, 0x69, 0xa5, 0xa5, 0x39, 0x7e, 0xdf, 0x3f, 0xfb, 0xef,
- 0xce, 0xc2, 0xea, 0x73, 0xf0, 0xdf, 0x4d, 0xed, 0x42, 0xe0, 0x50, 0xf6, 0x81, 0x23, 0xe3, 0x4a,
- 0x98, 0xbb, 0x6d, 0x7d, 0x14, 0xac, 0x7f, 0x00, 0x36, 0x23, 0xbe, 0x8e, 0x84, 0x4f, 0x70, 0xa5,
- 0xba, 0x6e, 0x9d, 0x88, 0xd9, 0x3a, 0xa1, 0x24, 0x4f, 0x8b, 0xac, 0x5a, 0xaa, 0x7d, 0xdf, 0x4b,
- 0x7c, 0x83, 0xa5, 0xb1, 0xd1, 0x73, 0xb7, 0x2b, 0x11, 0x9a, 0xe5, 0x69, 0xb1, 0x78, 0x7e, 0x2c,
- 0x27, 0xfd, 0xa5, 0x96, 0xbf, 0xe8, 0xb0, 0x5e, 0x51, 0x5d, 0x9a, 0x03, 0xc8, 0xfa, 0x37, 0x81,
- 0xeb, 0xd3, 0x11, 0xcc, 0x61, 0xd1, 0x38, 0xb1, 0xc1, 0xf7, 0xa3, 0xa3, 0x24, 0x4f, 0x8a, 0xac,
- 0x3a, 0x56, 0x48, 0x70, 0x61, 0xb9, 0x6d, 0x4d, 0xd7, 0xd0, 0x4c, 0xd3, 0x7f, 0xc4, 0x5b, 0x38,
- 0xe7, 0x21, 0xf6, 0x43, 0xa4, 0x54, 0x83, 0x3d, 0xe1, 0x03, 0x64, 0x26, 0x44, 0xff, 0x65, 0x6c,
- 0x14, 0x3a, 0xd3, 0xa5, 0x0e, 0x02, 0x6f, 0x60, 0xae, 0xcf, 0xa5, 0xb9, 0x1e, 0xda, 0xc1, 0xe6,
- 0xfe, 0xe3, 0x6e, 0xb2, 0x50, 0xad, 0x3f, 0xf9, 0x17, 0x00, 0x00, 0xff, 0xff, 0xb6, 0x18, 0x9e,
- 0x17, 0x5d, 0x01, 0x00, 0x00,
+func file_build_error_proto_rawDescGZIP() []byte {
+ file_build_error_proto_rawDescOnce.Do(func() {
+ file_build_error_proto_rawDescData = protoimpl.X.CompressGZIP(file_build_error_proto_rawDescData)
+ })
+ return file_build_error_proto_rawDescData
+}
+
+var file_build_error_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_build_error_proto_goTypes = []interface{}{
+ (*BuildError)(nil), // 0: soong_build_error.BuildError
+ (*BuildActionError)(nil), // 1: soong_build_error.BuildActionError
+}
+var file_build_error_proto_depIdxs = []int32{
+ 1, // 0: soong_build_error.BuildError.action_errors:type_name -> soong_build_error.BuildActionError
+ 1, // [1:1] is the sub-list for method output_type
+ 1, // [1:1] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_build_error_proto_init() }
+func file_build_error_proto_init() {
+ if File_build_error_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_build_error_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BuildError); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_error_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BuildActionError); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_build_error_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 2,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_build_error_proto_goTypes,
+ DependencyIndexes: file_build_error_proto_depIdxs,
+ MessageInfos: file_build_error_proto_msgTypes,
+ }.Build()
+ File_build_error_proto = out.File
+ file_build_error_proto_rawDesc = nil
+ file_build_error_proto_goTypes = nil
+ file_build_error_proto_depIdxs = nil
}
diff --git a/ui/status/build_error_proto/build_error.proto b/ui/status/build_error_proto/build_error.proto
index 9c8470d..ecd6074 100644
--- a/ui/status/build_error_proto/build_error.proto
+++ b/ui/status/build_error_proto/build_error.proto
@@ -15,7 +15,7 @@
syntax = "proto2";
package soong_build_error;
-option go_package = "soong_build_error_proto";
+option go_package = "android/soong/ui/status/build_error_proto";
message BuildError {
// List of error messages of the overall build. The error messages
diff --git a/ui/status/build_progress_proto/build_progress.pb.go b/ui/status/build_progress_proto/build_progress.pb.go
index f63c157..e243fe0 100644
--- a/ui/status/build_progress_proto/build_progress.pb.go
+++ b/ui/status/build_progress_proto/build_progress.pb.go
@@ -1,26 +1,44 @@
+// Copyright 2020 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: build_progress.proto
-package soong_build_progress_proto
+package build_progress_proto
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
type BuildProgress struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Total number of actions in a build. The total actions will increase
// and might decrease during the course of a build.
TotalActions *uint64 `protobuf:"varint,1,opt,name=total_actions,json=totalActions" json:"total_actions,omitempty"`
@@ -34,82 +52,150 @@
// build and current_actions + finished_actions <= total_actions.
CurrentActions *uint64 `protobuf:"varint,3,opt,name=current_actions,json=currentActions" json:"current_actions,omitempty"`
// Total number of actions that reported as a failure.
- FailedActions *uint64 `protobuf:"varint,4,opt,name=failed_actions,json=failedActions" json:"failed_actions,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ FailedActions *uint64 `protobuf:"varint,4,opt,name=failed_actions,json=failedActions" json:"failed_actions,omitempty"`
}
-func (m *BuildProgress) Reset() { *m = BuildProgress{} }
-func (m *BuildProgress) String() string { return proto.CompactTextString(m) }
-func (*BuildProgress) ProtoMessage() {}
+func (x *BuildProgress) Reset() {
+ *x = BuildProgress{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_progress_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BuildProgress) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BuildProgress) ProtoMessage() {}
+
+func (x *BuildProgress) ProtoReflect() protoreflect.Message {
+ mi := &file_build_progress_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BuildProgress.ProtoReflect.Descriptor instead.
func (*BuildProgress) Descriptor() ([]byte, []int) {
- return fileDescriptor_a8a463f8e30dab2e, []int{0}
+ return file_build_progress_proto_rawDescGZIP(), []int{0}
}
-func (m *BuildProgress) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_BuildProgress.Unmarshal(m, b)
-}
-func (m *BuildProgress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_BuildProgress.Marshal(b, m, deterministic)
-}
-func (m *BuildProgress) XXX_Merge(src proto.Message) {
- xxx_messageInfo_BuildProgress.Merge(m, src)
-}
-func (m *BuildProgress) XXX_Size() int {
- return xxx_messageInfo_BuildProgress.Size(m)
-}
-func (m *BuildProgress) XXX_DiscardUnknown() {
- xxx_messageInfo_BuildProgress.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_BuildProgress proto.InternalMessageInfo
-
-func (m *BuildProgress) GetTotalActions() uint64 {
- if m != nil && m.TotalActions != nil {
- return *m.TotalActions
+func (x *BuildProgress) GetTotalActions() uint64 {
+ if x != nil && x.TotalActions != nil {
+ return *x.TotalActions
}
return 0
}
-func (m *BuildProgress) GetFinishedActions() uint64 {
- if m != nil && m.FinishedActions != nil {
- return *m.FinishedActions
+func (x *BuildProgress) GetFinishedActions() uint64 {
+ if x != nil && x.FinishedActions != nil {
+ return *x.FinishedActions
}
return 0
}
-func (m *BuildProgress) GetCurrentActions() uint64 {
- if m != nil && m.CurrentActions != nil {
- return *m.CurrentActions
+func (x *BuildProgress) GetCurrentActions() uint64 {
+ if x != nil && x.CurrentActions != nil {
+ return *x.CurrentActions
}
return 0
}
-func (m *BuildProgress) GetFailedActions() uint64 {
- if m != nil && m.FailedActions != nil {
- return *m.FailedActions
+func (x *BuildProgress) GetFailedActions() uint64 {
+ if x != nil && x.FailedActions != nil {
+ return *x.FailedActions
}
return 0
}
-func init() {
- proto.RegisterType((*BuildProgress)(nil), "soong_build_progress.BuildProgress")
+var File_build_progress_proto protoreflect.FileDescriptor
+
+var file_build_progress_proto_rawDesc = []byte{
+ 0x0a, 0x14, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
+ 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0xaf, 0x01, 0x0a,
+ 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23,
+ 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x5f,
+ 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x66,
+ 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27,
+ 0x0a, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
+ 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x65,
+ 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x2e,
+ 0x5a, 0x2c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f,
+ 0x75, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
+ 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
}
-func init() { proto.RegisterFile("build_progress.proto", fileDescriptor_a8a463f8e30dab2e) }
+var (
+ file_build_progress_proto_rawDescOnce sync.Once
+ file_build_progress_proto_rawDescData = file_build_progress_proto_rawDesc
+)
-var fileDescriptor_a8a463f8e30dab2e = []byte{
- // 165 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x49, 0x2a, 0xcd, 0xcc,
- 0x49, 0x89, 0x2f, 0x28, 0xca, 0x4f, 0x2f, 0x4a, 0x2d, 0x2e, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9,
- 0x17, 0x12, 0x29, 0xce, 0xcf, 0xcf, 0x4b, 0x8f, 0x47, 0x95, 0x53, 0x5a, 0xcf, 0xc8, 0xc5, 0xeb,
- 0x04, 0x12, 0x0a, 0x80, 0x8a, 0x08, 0x29, 0x73, 0xf1, 0x96, 0xe4, 0x97, 0x24, 0xe6, 0xc4, 0x27,
- 0x26, 0x97, 0x64, 0xe6, 0xe7, 0x15, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x04, 0xf1, 0x80, 0x05,
- 0x1d, 0x21, 0x62, 0x42, 0x9a, 0x5c, 0x02, 0x69, 0x99, 0x79, 0x99, 0xc5, 0x19, 0xa9, 0x29, 0x70,
- 0x75, 0x4c, 0x60, 0x75, 0xfc, 0x30, 0x71, 0x98, 0x52, 0x75, 0x2e, 0xfe, 0xe4, 0xd2, 0xa2, 0xa2,
- 0xd4, 0xbc, 0x12, 0xb8, 0x4a, 0x66, 0xb0, 0x4a, 0x3e, 0xa8, 0x30, 0x4c, 0xa1, 0x2a, 0x17, 0x5f,
- 0x5a, 0x62, 0x66, 0x0e, 0x92, 0x89, 0x2c, 0x60, 0x75, 0xbc, 0x10, 0x51, 0xa8, 0x32, 0x27, 0x99,
- 0x28, 0x29, 0x6c, 0x3e, 0x89, 0x07, 0xfb, 0x12, 0x10, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x6e, 0xc1,
- 0xef, 0xfc, 0x00, 0x00, 0x00,
+func file_build_progress_proto_rawDescGZIP() []byte {
+ file_build_progress_proto_rawDescOnce.Do(func() {
+ file_build_progress_proto_rawDescData = protoimpl.X.CompressGZIP(file_build_progress_proto_rawDescData)
+ })
+ return file_build_progress_proto_rawDescData
+}
+
+var file_build_progress_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_build_progress_proto_goTypes = []interface{}{
+ (*BuildProgress)(nil), // 0: soong_build_progress.BuildProgress
+}
+var file_build_progress_proto_depIdxs = []int32{
+ 0, // [0:0] is the sub-list for method output_type
+ 0, // [0:0] is the sub-list for method input_type
+ 0, // [0:0] is the sub-list for extension type_name
+ 0, // [0:0] is the sub-list for extension extendee
+ 0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_build_progress_proto_init() }
+func file_build_progress_proto_init() {
+ if File_build_progress_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_build_progress_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BuildProgress); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_build_progress_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_build_progress_proto_goTypes,
+ DependencyIndexes: file_build_progress_proto_depIdxs,
+ MessageInfos: file_build_progress_proto_msgTypes,
+ }.Build()
+ File_build_progress_proto = out.File
+ file_build_progress_proto_rawDesc = nil
+ file_build_progress_proto_goTypes = nil
+ file_build_progress_proto_depIdxs = nil
}
diff --git a/ui/status/build_progress_proto/build_progress.proto b/ui/status/build_progress_proto/build_progress.proto
index d78060a..2672622 100644
--- a/ui/status/build_progress_proto/build_progress.proto
+++ b/ui/status/build_progress_proto/build_progress.proto
@@ -15,7 +15,7 @@
syntax = "proto2";
package soong_build_progress;
-option go_package = "soong_build_progress_proto";
+option go_package = "android/soong/ui/status/build_progress_proto";
message BuildProgress {
// Total number of actions in a build. The total actions will increase
diff --git a/ui/status/log.go b/ui/status/log.go
index 4a08acb..14df346 100644
--- a/ui/status/log.go
+++ b/ui/status/log.go
@@ -23,11 +23,11 @@
"os"
"strings"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
"android/soong/ui/logger"
- "android/soong/ui/status/build_error_proto"
- "android/soong/ui/status/build_progress_proto"
+ soong_build_error_proto "android/soong/ui/status/build_error_proto"
+ soong_build_progress_proto "android/soong/ui/status/build_progress_proto"
)
type verboseLog struct {
diff --git a/ui/status/ninja.go b/ui/status/ninja.go
index 765679f..4d99621 100644
--- a/ui/status/ninja.go
+++ b/ui/status/ninja.go
@@ -19,10 +19,12 @@
"fmt"
"io"
"os"
+ "regexp"
+ "strings"
"syscall"
"time"
- "github.com/golang/protobuf/proto"
+ "google.golang.org/protobuf/proto"
"android/soong/ui/logger"
"android/soong/ui/status/ninja_frontend"
@@ -158,9 +160,10 @@
err = fmt.Errorf("exited with code: %d", exitCode)
}
+ outputWithErrorHint := errorHintGenerator.GetOutputWithErrorHint(msg.EdgeFinished.GetOutput(), exitCode)
n.status.FinishAction(ActionResult{
Action: started,
- Output: msg.EdgeFinished.GetOutput(),
+ Output: outputWithErrorHint,
Error: err,
Stats: ActionResultStats{
UserTime: msg.EdgeFinished.GetUserTime(),
@@ -219,3 +222,53 @@
return ret, nil
}
+
+// key is pattern in stdout/stderr
+// value is error hint
+var allErrorHints = map[string]string{
+ "Read-only file system": `\nWrite to a read-only file system detected. Possible fixes include
+1. Generate file directly to out/ which is ReadWrite, #recommend solution
+2. BUILD_BROKEN_SRC_DIR_RW_ALLOWLIST := <my/path/1> <my/path/2> #discouraged, subset of source tree will be RW
+3. BUILD_BROKEN_SRC_DIR_IS_WRITABLE := true #highly discouraged, entire source tree will be RW
+`,
+}
+var errorHintGenerator = *newErrorHintGenerator(allErrorHints)
+
+type ErrorHintGenerator struct {
+ allErrorHints map[string]string
+ allErrorHintPatternsCompiled *regexp.Regexp
+}
+
+func newErrorHintGenerator(allErrorHints map[string]string) *ErrorHintGenerator {
+ var allErrorHintPatterns []string
+ for errorHintPattern, _ := range allErrorHints {
+ allErrorHintPatterns = append(allErrorHintPatterns, errorHintPattern)
+ }
+ allErrorHintPatternsRegex := strings.Join(allErrorHintPatterns[:], "|")
+ re := regexp.MustCompile(allErrorHintPatternsRegex)
+ return &ErrorHintGenerator{
+ allErrorHints: allErrorHints,
+ allErrorHintPatternsCompiled: re,
+ }
+}
+
+func (errorHintGenerator *ErrorHintGenerator) GetOutputWithErrorHint(rawOutput string, buildExitCode int) string {
+ if buildExitCode == 0 {
+ return rawOutput
+ }
+ errorHint := errorHintGenerator.getErrorHint(rawOutput)
+ if errorHint == nil {
+ return rawOutput
+ }
+ return rawOutput + *errorHint
+}
+
+// Returns the error hint corresponding to the FIRST match in raw output
+func (errorHintGenerator *ErrorHintGenerator) getErrorHint(rawOutput string) *string {
+ firstMatch := errorHintGenerator.allErrorHintPatternsCompiled.FindString(rawOutput)
+ if _, found := errorHintGenerator.allErrorHints[firstMatch]; found {
+ errorHint := errorHintGenerator.allErrorHints[firstMatch]
+ return &errorHint
+ }
+ return nil
+}
diff --git a/ui/status/ninja_frontend/frontend.pb.go b/ui/status/ninja_frontend/frontend.pb.go
index 86e474b..bcadc67 100644
--- a/ui/status/ninja_frontend/frontend.pb.go
+++ b/ui/status/ninja_frontend/frontend.pb.go
@@ -1,24 +1,38 @@
+// 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.
+
// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.26.0
+// protoc v3.9.1
// source: frontend.proto
package ninja_frontend
import (
- fmt "fmt"
- proto "github.com/golang/protobuf/proto"
- math "math"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
)
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = fmt.Errorf
-var _ = math.Inf
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
type Status_Message_Level int32
@@ -29,19 +43,21 @@
Status_Message_DEBUG Status_Message_Level = 3
)
-var Status_Message_Level_name = map[int32]string{
- 0: "INFO",
- 1: "WARNING",
- 2: "ERROR",
- 3: "DEBUG",
-}
-
-var Status_Message_Level_value = map[string]int32{
- "INFO": 0,
- "WARNING": 1,
- "ERROR": 2,
- "DEBUG": 3,
-}
+// Enum value maps for Status_Message_Level.
+var (
+ Status_Message_Level_name = map[int32]string{
+ 0: "INFO",
+ 1: "WARNING",
+ 2: "ERROR",
+ 3: "DEBUG",
+ }
+ Status_Message_Level_value = map[string]int32{
+ "INFO": 0,
+ "WARNING": 1,
+ "ERROR": 2,
+ "DEBUG": 3,
+ }
+)
func (x Status_Message_Level) Enum() *Status_Message_Level {
p := new(Status_Message_Level)
@@ -50,222 +66,271 @@
}
func (x Status_Message_Level) String() string {
- return proto.EnumName(Status_Message_Level_name, int32(x))
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
-func (x *Status_Message_Level) UnmarshalJSON(data []byte) error {
- value, err := proto.UnmarshalJSONEnum(Status_Message_Level_value, data, "Status_Message_Level")
+func (Status_Message_Level) Descriptor() protoreflect.EnumDescriptor {
+ return file_frontend_proto_enumTypes[0].Descriptor()
+}
+
+func (Status_Message_Level) Type() protoreflect.EnumType {
+ return &file_frontend_proto_enumTypes[0]
+}
+
+func (x Status_Message_Level) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *Status_Message_Level) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
if err != nil {
return err
}
- *x = Status_Message_Level(value)
+ *x = Status_Message_Level(num)
return nil
}
+// Deprecated: Use Status_Message_Level.Descriptor instead.
func (Status_Message_Level) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_eca3873955a29cfe, []int{0, 5, 0}
+ return file_frontend_proto_rawDescGZIP(), []int{0, 5, 0}
}
type Status struct {
- TotalEdges *Status_TotalEdges `protobuf:"bytes,1,opt,name=total_edges,json=totalEdges" json:"total_edges,omitempty"`
- BuildStarted *Status_BuildStarted `protobuf:"bytes,2,opt,name=build_started,json=buildStarted" json:"build_started,omitempty"`
- BuildFinished *Status_BuildFinished `protobuf:"bytes,3,opt,name=build_finished,json=buildFinished" json:"build_finished,omitempty"`
- EdgeStarted *Status_EdgeStarted `protobuf:"bytes,4,opt,name=edge_started,json=edgeStarted" json:"edge_started,omitempty"`
- EdgeFinished *Status_EdgeFinished `protobuf:"bytes,5,opt,name=edge_finished,json=edgeFinished" json:"edge_finished,omitempty"`
- Message *Status_Message `protobuf:"bytes,6,opt,name=message" json:"message,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ TotalEdges *Status_TotalEdges `protobuf:"bytes,1,opt,name=total_edges,json=totalEdges" json:"total_edges,omitempty"`
+ BuildStarted *Status_BuildStarted `protobuf:"bytes,2,opt,name=build_started,json=buildStarted" json:"build_started,omitempty"`
+ BuildFinished *Status_BuildFinished `protobuf:"bytes,3,opt,name=build_finished,json=buildFinished" json:"build_finished,omitempty"`
+ EdgeStarted *Status_EdgeStarted `protobuf:"bytes,4,opt,name=edge_started,json=edgeStarted" json:"edge_started,omitempty"`
+ EdgeFinished *Status_EdgeFinished `protobuf:"bytes,5,opt,name=edge_finished,json=edgeFinished" json:"edge_finished,omitempty"`
+ Message *Status_Message `protobuf:"bytes,6,opt,name=message" json:"message,omitempty"`
}
-func (m *Status) Reset() { *m = Status{} }
-func (m *Status) String() string { return proto.CompactTextString(m) }
-func (*Status) ProtoMessage() {}
+func (x *Status) Reset() {
+ *x = Status{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_frontend_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status) ProtoMessage() {}
+
+func (x *Status) ProtoReflect() protoreflect.Message {
+ mi := &file_frontend_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status.ProtoReflect.Descriptor instead.
func (*Status) Descriptor() ([]byte, []int) {
- return fileDescriptor_eca3873955a29cfe, []int{0}
+ return file_frontend_proto_rawDescGZIP(), []int{0}
}
-func (m *Status) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Status.Unmarshal(m, b)
-}
-func (m *Status) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Status.Marshal(b, m, deterministic)
-}
-func (m *Status) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Status.Merge(m, src)
-}
-func (m *Status) XXX_Size() int {
- return xxx_messageInfo_Status.Size(m)
-}
-func (m *Status) XXX_DiscardUnknown() {
- xxx_messageInfo_Status.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Status proto.InternalMessageInfo
-
-func (m *Status) GetTotalEdges() *Status_TotalEdges {
- if m != nil {
- return m.TotalEdges
+func (x *Status) GetTotalEdges() *Status_TotalEdges {
+ if x != nil {
+ return x.TotalEdges
}
return nil
}
-func (m *Status) GetBuildStarted() *Status_BuildStarted {
- if m != nil {
- return m.BuildStarted
+func (x *Status) GetBuildStarted() *Status_BuildStarted {
+ if x != nil {
+ return x.BuildStarted
}
return nil
}
-func (m *Status) GetBuildFinished() *Status_BuildFinished {
- if m != nil {
- return m.BuildFinished
+func (x *Status) GetBuildFinished() *Status_BuildFinished {
+ if x != nil {
+ return x.BuildFinished
}
return nil
}
-func (m *Status) GetEdgeStarted() *Status_EdgeStarted {
- if m != nil {
- return m.EdgeStarted
+func (x *Status) GetEdgeStarted() *Status_EdgeStarted {
+ if x != nil {
+ return x.EdgeStarted
}
return nil
}
-func (m *Status) GetEdgeFinished() *Status_EdgeFinished {
- if m != nil {
- return m.EdgeFinished
+func (x *Status) GetEdgeFinished() *Status_EdgeFinished {
+ if x != nil {
+ return x.EdgeFinished
}
return nil
}
-func (m *Status) GetMessage() *Status_Message {
- if m != nil {
- return m.Message
+func (x *Status) GetMessage() *Status_Message {
+ if x != nil {
+ return x.Message
}
return nil
}
type Status_TotalEdges struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// New value for total edges in the build.
- TotalEdges *uint32 `protobuf:"varint,1,opt,name=total_edges,json=totalEdges" json:"total_edges,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ TotalEdges *uint32 `protobuf:"varint,1,opt,name=total_edges,json=totalEdges" json:"total_edges,omitempty"`
}
-func (m *Status_TotalEdges) Reset() { *m = Status_TotalEdges{} }
-func (m *Status_TotalEdges) String() string { return proto.CompactTextString(m) }
-func (*Status_TotalEdges) ProtoMessage() {}
+func (x *Status_TotalEdges) Reset() {
+ *x = Status_TotalEdges{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_frontend_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status_TotalEdges) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status_TotalEdges) ProtoMessage() {}
+
+func (x *Status_TotalEdges) ProtoReflect() protoreflect.Message {
+ mi := &file_frontend_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status_TotalEdges.ProtoReflect.Descriptor instead.
func (*Status_TotalEdges) Descriptor() ([]byte, []int) {
- return fileDescriptor_eca3873955a29cfe, []int{0, 0}
+ return file_frontend_proto_rawDescGZIP(), []int{0, 0}
}
-func (m *Status_TotalEdges) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Status_TotalEdges.Unmarshal(m, b)
-}
-func (m *Status_TotalEdges) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Status_TotalEdges.Marshal(b, m, deterministic)
-}
-func (m *Status_TotalEdges) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Status_TotalEdges.Merge(m, src)
-}
-func (m *Status_TotalEdges) XXX_Size() int {
- return xxx_messageInfo_Status_TotalEdges.Size(m)
-}
-func (m *Status_TotalEdges) XXX_DiscardUnknown() {
- xxx_messageInfo_Status_TotalEdges.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Status_TotalEdges proto.InternalMessageInfo
-
-func (m *Status_TotalEdges) GetTotalEdges() uint32 {
- if m != nil && m.TotalEdges != nil {
- return *m.TotalEdges
+func (x *Status_TotalEdges) GetTotalEdges() uint32 {
+ if x != nil && x.TotalEdges != nil {
+ return *x.TotalEdges
}
return 0
}
type Status_BuildStarted struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Number of jobs Ninja will run in parallel.
Parallelism *uint32 `protobuf:"varint,1,opt,name=parallelism" json:"parallelism,omitempty"`
// Verbose value passed to ninja.
- Verbose *bool `protobuf:"varint,2,opt,name=verbose" json:"verbose,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Verbose *bool `protobuf:"varint,2,opt,name=verbose" json:"verbose,omitempty"`
}
-func (m *Status_BuildStarted) Reset() { *m = Status_BuildStarted{} }
-func (m *Status_BuildStarted) String() string { return proto.CompactTextString(m) }
-func (*Status_BuildStarted) ProtoMessage() {}
+func (x *Status_BuildStarted) Reset() {
+ *x = Status_BuildStarted{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_frontend_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status_BuildStarted) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status_BuildStarted) ProtoMessage() {}
+
+func (x *Status_BuildStarted) ProtoReflect() protoreflect.Message {
+ mi := &file_frontend_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status_BuildStarted.ProtoReflect.Descriptor instead.
func (*Status_BuildStarted) Descriptor() ([]byte, []int) {
- return fileDescriptor_eca3873955a29cfe, []int{0, 1}
+ return file_frontend_proto_rawDescGZIP(), []int{0, 1}
}
-func (m *Status_BuildStarted) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Status_BuildStarted.Unmarshal(m, b)
-}
-func (m *Status_BuildStarted) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Status_BuildStarted.Marshal(b, m, deterministic)
-}
-func (m *Status_BuildStarted) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Status_BuildStarted.Merge(m, src)
-}
-func (m *Status_BuildStarted) XXX_Size() int {
- return xxx_messageInfo_Status_BuildStarted.Size(m)
-}
-func (m *Status_BuildStarted) XXX_DiscardUnknown() {
- xxx_messageInfo_Status_BuildStarted.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Status_BuildStarted proto.InternalMessageInfo
-
-func (m *Status_BuildStarted) GetParallelism() uint32 {
- if m != nil && m.Parallelism != nil {
- return *m.Parallelism
+func (x *Status_BuildStarted) GetParallelism() uint32 {
+ if x != nil && x.Parallelism != nil {
+ return *x.Parallelism
}
return 0
}
-func (m *Status_BuildStarted) GetVerbose() bool {
- if m != nil && m.Verbose != nil {
- return *m.Verbose
+func (x *Status_BuildStarted) GetVerbose() bool {
+ if x != nil && x.Verbose != nil {
+ return *x.Verbose
}
return false
}
type Status_BuildFinished struct {
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
}
-func (m *Status_BuildFinished) Reset() { *m = Status_BuildFinished{} }
-func (m *Status_BuildFinished) String() string { return proto.CompactTextString(m) }
-func (*Status_BuildFinished) ProtoMessage() {}
+func (x *Status_BuildFinished) Reset() {
+ *x = Status_BuildFinished{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_frontend_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status_BuildFinished) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status_BuildFinished) ProtoMessage() {}
+
+func (x *Status_BuildFinished) ProtoReflect() protoreflect.Message {
+ mi := &file_frontend_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status_BuildFinished.ProtoReflect.Descriptor instead.
func (*Status_BuildFinished) Descriptor() ([]byte, []int) {
- return fileDescriptor_eca3873955a29cfe, []int{0, 2}
+ return file_frontend_proto_rawDescGZIP(), []int{0, 2}
}
-func (m *Status_BuildFinished) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Status_BuildFinished.Unmarshal(m, b)
-}
-func (m *Status_BuildFinished) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Status_BuildFinished.Marshal(b, m, deterministic)
-}
-func (m *Status_BuildFinished) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Status_BuildFinished.Merge(m, src)
-}
-func (m *Status_BuildFinished) XXX_Size() int {
- return xxx_messageInfo_Status_BuildFinished.Size(m)
-}
-func (m *Status_BuildFinished) XXX_DiscardUnknown() {
- xxx_messageInfo_Status_BuildFinished.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Status_BuildFinished proto.InternalMessageInfo
-
type Status_EdgeStarted struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Edge identification number, unique to a Ninja run.
Id *uint32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
// Edge start time in milliseconds since Ninja started.
@@ -279,87 +344,95 @@
// Command field from the edge.
Command *string `protobuf:"bytes,6,opt,name=command" json:"command,omitempty"`
// Edge uses console.
- Console *bool `protobuf:"varint,7,opt,name=console" json:"console,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Console *bool `protobuf:"varint,7,opt,name=console" json:"console,omitempty"`
}
-func (m *Status_EdgeStarted) Reset() { *m = Status_EdgeStarted{} }
-func (m *Status_EdgeStarted) String() string { return proto.CompactTextString(m) }
-func (*Status_EdgeStarted) ProtoMessage() {}
+func (x *Status_EdgeStarted) Reset() {
+ *x = Status_EdgeStarted{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_frontend_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status_EdgeStarted) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status_EdgeStarted) ProtoMessage() {}
+
+func (x *Status_EdgeStarted) ProtoReflect() protoreflect.Message {
+ mi := &file_frontend_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status_EdgeStarted.ProtoReflect.Descriptor instead.
func (*Status_EdgeStarted) Descriptor() ([]byte, []int) {
- return fileDescriptor_eca3873955a29cfe, []int{0, 3}
+ return file_frontend_proto_rawDescGZIP(), []int{0, 3}
}
-func (m *Status_EdgeStarted) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Status_EdgeStarted.Unmarshal(m, b)
-}
-func (m *Status_EdgeStarted) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Status_EdgeStarted.Marshal(b, m, deterministic)
-}
-func (m *Status_EdgeStarted) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Status_EdgeStarted.Merge(m, src)
-}
-func (m *Status_EdgeStarted) XXX_Size() int {
- return xxx_messageInfo_Status_EdgeStarted.Size(m)
-}
-func (m *Status_EdgeStarted) XXX_DiscardUnknown() {
- xxx_messageInfo_Status_EdgeStarted.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Status_EdgeStarted proto.InternalMessageInfo
-
-func (m *Status_EdgeStarted) GetId() uint32 {
- if m != nil && m.Id != nil {
- return *m.Id
+func (x *Status_EdgeStarted) GetId() uint32 {
+ if x != nil && x.Id != nil {
+ return *x.Id
}
return 0
}
-func (m *Status_EdgeStarted) GetStartTime() uint32 {
- if m != nil && m.StartTime != nil {
- return *m.StartTime
+func (x *Status_EdgeStarted) GetStartTime() uint32 {
+ if x != nil && x.StartTime != nil {
+ return *x.StartTime
}
return 0
}
-func (m *Status_EdgeStarted) GetInputs() []string {
- if m != nil {
- return m.Inputs
+func (x *Status_EdgeStarted) GetInputs() []string {
+ if x != nil {
+ return x.Inputs
}
return nil
}
-func (m *Status_EdgeStarted) GetOutputs() []string {
- if m != nil {
- return m.Outputs
+func (x *Status_EdgeStarted) GetOutputs() []string {
+ if x != nil {
+ return x.Outputs
}
return nil
}
-func (m *Status_EdgeStarted) GetDesc() string {
- if m != nil && m.Desc != nil {
- return *m.Desc
+func (x *Status_EdgeStarted) GetDesc() string {
+ if x != nil && x.Desc != nil {
+ return *x.Desc
}
return ""
}
-func (m *Status_EdgeStarted) GetCommand() string {
- if m != nil && m.Command != nil {
- return *m.Command
+func (x *Status_EdgeStarted) GetCommand() string {
+ if x != nil && x.Command != nil {
+ return *x.Command
}
return ""
}
-func (m *Status_EdgeStarted) GetConsole() bool {
- if m != nil && m.Console != nil {
- return *m.Console
+func (x *Status_EdgeStarted) GetConsole() bool {
+ if x != nil && x.Console != nil {
+ return *x.Console
}
return false
}
type Status_EdgeFinished struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Edge identification number, unique to a Ninja run.
Id *uint32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
// Edge end time in milliseconds since Ninja started.
@@ -385,237 +458,434 @@
// Voluntary context switches
VoluntaryContextSwitches *uint64 `protobuf:"varint,12,opt,name=voluntary_context_switches,json=voluntaryContextSwitches" json:"voluntary_context_switches,omitempty"`
// Involuntary context switches
- InvoluntaryContextSwitches *uint64 `protobuf:"varint,13,opt,name=involuntary_context_switches,json=involuntaryContextSwitches" json:"involuntary_context_switches,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ InvoluntaryContextSwitches *uint64 `protobuf:"varint,13,opt,name=involuntary_context_switches,json=involuntaryContextSwitches" json:"involuntary_context_switches,omitempty"`
}
-func (m *Status_EdgeFinished) Reset() { *m = Status_EdgeFinished{} }
-func (m *Status_EdgeFinished) String() string { return proto.CompactTextString(m) }
-func (*Status_EdgeFinished) ProtoMessage() {}
+func (x *Status_EdgeFinished) Reset() {
+ *x = Status_EdgeFinished{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_frontend_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status_EdgeFinished) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status_EdgeFinished) ProtoMessage() {}
+
+func (x *Status_EdgeFinished) ProtoReflect() protoreflect.Message {
+ mi := &file_frontend_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status_EdgeFinished.ProtoReflect.Descriptor instead.
func (*Status_EdgeFinished) Descriptor() ([]byte, []int) {
- return fileDescriptor_eca3873955a29cfe, []int{0, 4}
+ return file_frontend_proto_rawDescGZIP(), []int{0, 4}
}
-func (m *Status_EdgeFinished) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Status_EdgeFinished.Unmarshal(m, b)
-}
-func (m *Status_EdgeFinished) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Status_EdgeFinished.Marshal(b, m, deterministic)
-}
-func (m *Status_EdgeFinished) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Status_EdgeFinished.Merge(m, src)
-}
-func (m *Status_EdgeFinished) XXX_Size() int {
- return xxx_messageInfo_Status_EdgeFinished.Size(m)
-}
-func (m *Status_EdgeFinished) XXX_DiscardUnknown() {
- xxx_messageInfo_Status_EdgeFinished.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Status_EdgeFinished proto.InternalMessageInfo
-
-func (m *Status_EdgeFinished) GetId() uint32 {
- if m != nil && m.Id != nil {
- return *m.Id
+func (x *Status_EdgeFinished) GetId() uint32 {
+ if x != nil && x.Id != nil {
+ return *x.Id
}
return 0
}
-func (m *Status_EdgeFinished) GetEndTime() uint32 {
- if m != nil && m.EndTime != nil {
- return *m.EndTime
+func (x *Status_EdgeFinished) GetEndTime() uint32 {
+ if x != nil && x.EndTime != nil {
+ return *x.EndTime
}
return 0
}
-func (m *Status_EdgeFinished) GetStatus() int32 {
- if m != nil && m.Status != nil {
- return *m.Status
+func (x *Status_EdgeFinished) GetStatus() int32 {
+ if x != nil && x.Status != nil {
+ return *x.Status
}
return 0
}
-func (m *Status_EdgeFinished) GetOutput() string {
- if m != nil && m.Output != nil {
- return *m.Output
+func (x *Status_EdgeFinished) GetOutput() string {
+ if x != nil && x.Output != nil {
+ return *x.Output
}
return ""
}
-func (m *Status_EdgeFinished) GetUserTime() uint32 {
- if m != nil && m.UserTime != nil {
- return *m.UserTime
+func (x *Status_EdgeFinished) GetUserTime() uint32 {
+ if x != nil && x.UserTime != nil {
+ return *x.UserTime
}
return 0
}
-func (m *Status_EdgeFinished) GetSystemTime() uint32 {
- if m != nil && m.SystemTime != nil {
- return *m.SystemTime
+func (x *Status_EdgeFinished) GetSystemTime() uint32 {
+ if x != nil && x.SystemTime != nil {
+ return *x.SystemTime
}
return 0
}
-func (m *Status_EdgeFinished) GetMaxRssKb() uint64 {
- if m != nil && m.MaxRssKb != nil {
- return *m.MaxRssKb
+func (x *Status_EdgeFinished) GetMaxRssKb() uint64 {
+ if x != nil && x.MaxRssKb != nil {
+ return *x.MaxRssKb
}
return 0
}
-func (m *Status_EdgeFinished) GetMinorPageFaults() uint64 {
- if m != nil && m.MinorPageFaults != nil {
- return *m.MinorPageFaults
+func (x *Status_EdgeFinished) GetMinorPageFaults() uint64 {
+ if x != nil && x.MinorPageFaults != nil {
+ return *x.MinorPageFaults
}
return 0
}
-func (m *Status_EdgeFinished) GetMajorPageFaults() uint64 {
- if m != nil && m.MajorPageFaults != nil {
- return *m.MajorPageFaults
+func (x *Status_EdgeFinished) GetMajorPageFaults() uint64 {
+ if x != nil && x.MajorPageFaults != nil {
+ return *x.MajorPageFaults
}
return 0
}
-func (m *Status_EdgeFinished) GetIoInputKb() uint64 {
- if m != nil && m.IoInputKb != nil {
- return *m.IoInputKb
+func (x *Status_EdgeFinished) GetIoInputKb() uint64 {
+ if x != nil && x.IoInputKb != nil {
+ return *x.IoInputKb
}
return 0
}
-func (m *Status_EdgeFinished) GetIoOutputKb() uint64 {
- if m != nil && m.IoOutputKb != nil {
- return *m.IoOutputKb
+func (x *Status_EdgeFinished) GetIoOutputKb() uint64 {
+ if x != nil && x.IoOutputKb != nil {
+ return *x.IoOutputKb
}
return 0
}
-func (m *Status_EdgeFinished) GetVoluntaryContextSwitches() uint64 {
- if m != nil && m.VoluntaryContextSwitches != nil {
- return *m.VoluntaryContextSwitches
+func (x *Status_EdgeFinished) GetVoluntaryContextSwitches() uint64 {
+ if x != nil && x.VoluntaryContextSwitches != nil {
+ return *x.VoluntaryContextSwitches
}
return 0
}
-func (m *Status_EdgeFinished) GetInvoluntaryContextSwitches() uint64 {
- if m != nil && m.InvoluntaryContextSwitches != nil {
- return *m.InvoluntaryContextSwitches
+func (x *Status_EdgeFinished) GetInvoluntaryContextSwitches() uint64 {
+ if x != nil && x.InvoluntaryContextSwitches != nil {
+ return *x.InvoluntaryContextSwitches
}
return 0
}
type Status_Message struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
// Message priority level (DEBUG, INFO, WARNING, ERROR).
Level *Status_Message_Level `protobuf:"varint,1,opt,name=level,enum=ninja.Status_Message_Level,def=0" json:"level,omitempty"`
// Info/warning/error message from Ninja.
- Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"`
}
-func (m *Status_Message) Reset() { *m = Status_Message{} }
-func (m *Status_Message) String() string { return proto.CompactTextString(m) }
-func (*Status_Message) ProtoMessage() {}
+// Default values for Status_Message fields.
+const (
+ Default_Status_Message_Level = Status_Message_INFO
+)
+
+func (x *Status_Message) Reset() {
+ *x = Status_Message{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_frontend_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Status_Message) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Status_Message) ProtoMessage() {}
+
+func (x *Status_Message) ProtoReflect() protoreflect.Message {
+ mi := &file_frontend_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Status_Message.ProtoReflect.Descriptor instead.
func (*Status_Message) Descriptor() ([]byte, []int) {
- return fileDescriptor_eca3873955a29cfe, []int{0, 5}
+ return file_frontend_proto_rawDescGZIP(), []int{0, 5}
}
-func (m *Status_Message) XXX_Unmarshal(b []byte) error {
- return xxx_messageInfo_Status_Message.Unmarshal(m, b)
-}
-func (m *Status_Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
- return xxx_messageInfo_Status_Message.Marshal(b, m, deterministic)
-}
-func (m *Status_Message) XXX_Merge(src proto.Message) {
- xxx_messageInfo_Status_Message.Merge(m, src)
-}
-func (m *Status_Message) XXX_Size() int {
- return xxx_messageInfo_Status_Message.Size(m)
-}
-func (m *Status_Message) XXX_DiscardUnknown() {
- xxx_messageInfo_Status_Message.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Status_Message proto.InternalMessageInfo
-
-const Default_Status_Message_Level Status_Message_Level = Status_Message_INFO
-
-func (m *Status_Message) GetLevel() Status_Message_Level {
- if m != nil && m.Level != nil {
- return *m.Level
+func (x *Status_Message) GetLevel() Status_Message_Level {
+ if x != nil && x.Level != nil {
+ return *x.Level
}
return Default_Status_Message_Level
}
-func (m *Status_Message) GetMessage() string {
- if m != nil && m.Message != nil {
- return *m.Message
+func (x *Status_Message) GetMessage() string {
+ if x != nil && x.Message != nil {
+ return *x.Message
}
return ""
}
-func init() {
- proto.RegisterEnum("ninja.Status_Message_Level", Status_Message_Level_name, Status_Message_Level_value)
- proto.RegisterType((*Status)(nil), "ninja.Status")
- proto.RegisterType((*Status_TotalEdges)(nil), "ninja.Status.TotalEdges")
- proto.RegisterType((*Status_BuildStarted)(nil), "ninja.Status.BuildStarted")
- proto.RegisterType((*Status_BuildFinished)(nil), "ninja.Status.BuildFinished")
- proto.RegisterType((*Status_EdgeStarted)(nil), "ninja.Status.EdgeStarted")
- proto.RegisterType((*Status_EdgeFinished)(nil), "ninja.Status.EdgeFinished")
- proto.RegisterType((*Status_Message)(nil), "ninja.Status.Message")
+var File_frontend_proto protoreflect.FileDescriptor
+
+var file_frontend_proto_rawDesc = []byte{
+ 0x0a, 0x0e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x12, 0x05, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x22, 0xb4, 0x0a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x2e,
+ 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65,
+ 0x73, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x73, 0x12, 0x3f, 0x0a,
+ 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x2e, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64,
+ 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x42,
+ 0x0a, 0x0e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x2e, 0x53,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x69, 0x6e, 0x69, 0x73,
+ 0x68, 0x65, 0x64, 0x52, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68,
+ 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x0c, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74,
+ 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61,
+ 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x45, 0x64, 0x67, 0x65, 0x53, 0x74, 0x61, 0x72,
+ 0x74, 0x65, 0x64, 0x52, 0x0b, 0x65, 0x64, 0x67, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64,
+ 0x12, 0x3f, 0x0a, 0x0d, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65,
+ 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x2e,
+ 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x45, 0x64, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73,
+ 0x68, 0x65, 0x64, 0x52, 0x0c, 0x65, 0x64, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65,
+ 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x1a, 0x2d, 0x0a, 0x0a, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65, 0x73,
+ 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x73, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65,
+ 0x73, 0x1a, 0x4a, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65,
+ 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c,
+ 0x69, 0x73, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x1a, 0x0f, 0x0a,
+ 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x1a, 0xb6,
+ 0x01, 0x0a, 0x0b, 0x45, 0x64, 0x67, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x0e,
+ 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d,
+ 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a,
+ 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x69,
+ 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73,
+ 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x12,
+ 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64,
+ 0x65, 0x73, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x06,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18, 0x0a,
+ 0x07, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,
+ 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x1a, 0xdf, 0x03, 0x0a, 0x0c, 0x45, 0x64, 0x67, 0x65,
+ 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f,
+ 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54,
+ 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x11, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f,
+ 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74,
+ 0x70, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65,
+ 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18,
+ 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x69, 0x6d,
+ 0x65, 0x12, 0x1c, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f, 0x6b, 0x62, 0x18,
+ 0x07, 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, 0x08, 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, 0x09, 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, 0x0a, 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, 0x0b, 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, 0x0c, 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, 0x0d, 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, 0x1a, 0x92, 0x01, 0x0a, 0x07, 0x4d, 0x65,
+ 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x2e, 0x53, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x65, 0x76, 0x65,
+ 0x6c, 0x3a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x18,
+ 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x34, 0x0a, 0x05, 0x4c, 0x65, 0x76, 0x65,
+ 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x57,
+ 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f,
+ 0x52, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x03, 0x42, 0x2a,
+ 0x48, 0x03, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x6e, 0x69, 0x6e, 0x6a,
+ 0x61, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64,
}
-func init() {
- proto.RegisterFile("frontend.proto", fileDescriptor_eca3873955a29cfe)
+var (
+ file_frontend_proto_rawDescOnce sync.Once
+ file_frontend_proto_rawDescData = file_frontend_proto_rawDesc
+)
+
+func file_frontend_proto_rawDescGZIP() []byte {
+ file_frontend_proto_rawDescOnce.Do(func() {
+ file_frontend_proto_rawDescData = protoimpl.X.CompressGZIP(file_frontend_proto_rawDescData)
+ })
+ return file_frontend_proto_rawDescData
}
-var fileDescriptor_eca3873955a29cfe = []byte{
- // 678 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xff, 0x4e, 0xd4, 0x40,
- 0x10, 0xc7, 0xbd, 0xdf, 0xd7, 0xe9, 0xdd, 0x71, 0x6c, 0xa2, 0x29, 0x05, 0xe5, 0xc2, 0x5f, 0xc4,
- 0xc4, 0x33, 0x31, 0x26, 0x46, 0x43, 0xa2, 0x9e, 0x02, 0x22, 0x0a, 0x66, 0xc1, 0x98, 0xf8, 0x4f,
- 0xb3, 0xbd, 0x2e, 0xb0, 0xd8, 0x76, 0x2f, 0xdd, 0x2d, 0xc2, 0x6b, 0xf8, 0x2c, 0xc6, 0xd7, 0xf1,
- 0x55, 0xcc, 0xce, 0xb6, 0x47, 0x0f, 0x88, 0xff, 0x75, 0x66, 0x3e, 0xf3, 0x9d, 0xd9, 0x99, 0xed,
- 0xc2, 0xe0, 0x24, 0x93, 0xa9, 0xe6, 0x69, 0x34, 0x9e, 0x65, 0x52, 0x4b, 0xd2, 0x4a, 0x45, 0x7a,
- 0xce, 0x36, 0x7e, 0x03, 0xb4, 0x8f, 0x34, 0xd3, 0xb9, 0x22, 0x2f, 0xc1, 0xd5, 0x52, 0xb3, 0x38,
- 0xe0, 0xd1, 0x29, 0x57, 0x5e, 0x6d, 0x54, 0xdb, 0x74, 0x9f, 0x79, 0x63, 0xe4, 0xc6, 0x96, 0x19,
- 0x1f, 0x1b, 0x60, 0xdb, 0xc4, 0x29, 0xe8, 0xf9, 0x37, 0x79, 0x0d, 0xfd, 0x30, 0x17, 0x71, 0x14,
- 0x28, 0xcd, 0x32, 0xcd, 0x23, 0xaf, 0x8e, 0xc9, 0xfe, 0x62, 0xf2, 0xc4, 0x20, 0x47, 0x96, 0xa0,
- 0xbd, 0xb0, 0x62, 0x91, 0x09, 0x0c, 0xac, 0xc0, 0x89, 0x48, 0x85, 0x3a, 0xe3, 0x91, 0xd7, 0x40,
- 0x85, 0xd5, 0x3b, 0x14, 0x76, 0x0a, 0x84, 0xda, 0x9a, 0xa5, 0x49, 0xb6, 0xa0, 0x67, 0x3a, 0x9f,
- 0xf7, 0xd0, 0x44, 0x85, 0x95, 0x45, 0x05, 0xd3, 0x6f, 0xd9, 0x82, 0xcb, 0xaf, 0x0d, 0x73, 0x04,
- 0xcc, 0x9e, 0x37, 0xd0, 0xba, 0xeb, 0x08, 0x26, 0x7d, 0x5e, 0x1f, 0xcb, 0xcd, 0xcb, 0x3f, 0x85,
- 0x4e, 0xc2, 0x95, 0x62, 0xa7, 0xdc, 0x6b, 0x63, 0xea, 0xfd, 0xc5, 0xd4, 0xcf, 0x36, 0x48, 0x4b,
- 0xca, 0x7f, 0x02, 0x70, 0x3d, 0x4e, 0xb2, 0x7e, 0x7b, 0xfa, 0xfd, 0xea, 0x8c, 0xfd, 0x8f, 0xd0,
- 0xab, 0x0e, 0x90, 0x8c, 0xc0, 0x9d, 0xb1, 0x8c, 0xc5, 0x31, 0x8f, 0x85, 0x4a, 0x8a, 0x84, 0xaa,
- 0x8b, 0x78, 0xd0, 0xb9, 0xe0, 0x59, 0x28, 0x15, 0xc7, 0x7d, 0x74, 0x69, 0x69, 0xfa, 0x4b, 0xd0,
- 0x5f, 0x18, 0xa5, 0xff, 0xa7, 0x06, 0x6e, 0x65, 0x34, 0x64, 0x00, 0x75, 0x11, 0x15, 0x9a, 0x75,
- 0x11, 0x91, 0x87, 0x00, 0x38, 0xd6, 0x40, 0x8b, 0xc4, 0xaa, 0xf5, 0xa9, 0x83, 0x9e, 0x63, 0x91,
- 0x70, 0xf2, 0x00, 0xda, 0x22, 0x9d, 0xe5, 0x5a, 0x79, 0x8d, 0x51, 0x63, 0xd3, 0xa1, 0x85, 0x65,
- 0x3a, 0x90, 0xb9, 0xc6, 0x40, 0x13, 0x03, 0xa5, 0x49, 0x08, 0x34, 0x23, 0xae, 0xa6, 0x38, 0x65,
- 0x87, 0xe2, 0xb7, 0xa1, 0xa7, 0x32, 0x49, 0x58, 0x1a, 0xe1, 0x04, 0x1d, 0x5a, 0x9a, 0x36, 0x92,
- 0x2a, 0x19, 0x73, 0xaf, 0x63, 0x4f, 0x52, 0x98, 0xfe, 0xdf, 0x06, 0xf4, 0xaa, 0x4b, 0xb9, 0xd5,
- 0xf9, 0x0a, 0x74, 0x79, 0x1a, 0x55, 0xfb, 0xee, 0xf0, 0x34, 0x2a, 0xbb, 0x56, 0xb8, 0x1b, 0xbc,
- 0x6c, 0xcb, 0xb4, 0xb0, 0x8c, 0xdf, 0xb6, 0x89, 0x57, 0xc8, 0xa1, 0x85, 0x45, 0x56, 0xc1, 0xc9,
- 0x15, 0xcf, 0xac, 0x56, 0x0b, 0xb5, 0xba, 0xc6, 0x81, 0x62, 0xeb, 0xe0, 0xaa, 0x2b, 0xa5, 0x79,
- 0x62, 0xc3, 0x6d, 0xbb, 0x3f, 0xeb, 0x42, 0x60, 0x0d, 0x20, 0x61, 0x97, 0x41, 0xa6, 0x54, 0xf0,
- 0x23, 0xc4, 0x63, 0x34, 0x69, 0x37, 0x61, 0x97, 0x54, 0xa9, 0xfd, 0x90, 0x3c, 0x86, 0xe5, 0x44,
- 0xa4, 0x32, 0x0b, 0x66, 0xcc, 0x5c, 0x42, 0x96, 0xc7, 0x5a, 0x79, 0x5d, 0x84, 0x96, 0x30, 0xf0,
- 0x85, 0x9d, 0xf2, 0x1d, 0x74, 0x23, 0xcb, 0xce, 0x6f, 0xb0, 0x4e, 0xc1, 0x9a, 0x40, 0x85, 0x7d,
- 0x04, 0xae, 0x90, 0x01, 0xae, 0xc3, 0x94, 0x05, 0xa4, 0x1c, 0x21, 0xf7, 0x8c, 0x67, 0x3f, 0x24,
- 0x23, 0xe8, 0x09, 0x19, 0xd8, 0x03, 0x1a, 0xc0, 0x45, 0x00, 0x84, 0x3c, 0x44, 0xd7, 0x7e, 0x48,
- 0xb6, 0xc0, 0xbf, 0x90, 0x71, 0x9e, 0x6a, 0x96, 0x5d, 0x05, 0x53, 0xf3, 0x86, 0x5c, 0xea, 0x40,
- 0xfd, 0x14, 0x7a, 0x7a, 0xc6, 0x95, 0xd7, 0x43, 0xde, 0x9b, 0x13, 0xef, 0x2c, 0x70, 0x54, 0xc4,
- 0xc9, 0x1b, 0x58, 0x13, 0xe9, 0x7f, 0xf2, 0xfb, 0x98, 0xef, 0x57, 0x98, 0x1b, 0x0a, 0xfe, 0xaf,
- 0x1a, 0x74, 0x8a, 0x7f, 0x87, 0xbc, 0x80, 0x56, 0xcc, 0x2f, 0x78, 0x8c, 0xfb, 0x1d, 0xdc, 0x7c,
- 0x1d, 0x0a, 0x6a, 0xfc, 0xc9, 0x20, 0xaf, 0x9a, 0x7b, 0x07, 0x3b, 0x87, 0xd4, 0xf2, 0xe6, 0x02,
- 0x95, 0x3f, 0x67, 0xdd, 0x5e, 0xad, 0xc2, 0xdc, 0x78, 0x0e, 0x2d, 0xe4, 0x49, 0x17, 0x30, 0x63,
- 0x78, 0x8f, 0xb8, 0xd0, 0xf9, 0xf6, 0x96, 0x1e, 0xec, 0x1d, 0xec, 0x0e, 0x6b, 0xc4, 0x81, 0xd6,
- 0x36, 0xa5, 0x87, 0x74, 0x58, 0x37, 0x9f, 0xef, 0xb7, 0x27, 0x5f, 0x77, 0x87, 0x8d, 0x09, 0xf9,
- 0xd0, 0xf8, 0x3e, 0xc0, 0xe2, 0x41, 0xf9, 0xae, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x2f, 0x7a,
- 0x33, 0x13, 0x62, 0x05, 0x00, 0x00,
+var file_frontend_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_frontend_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_frontend_proto_goTypes = []interface{}{
+ (Status_Message_Level)(0), // 0: ninja.Status.Message.Level
+ (*Status)(nil), // 1: ninja.Status
+ (*Status_TotalEdges)(nil), // 2: ninja.Status.TotalEdges
+ (*Status_BuildStarted)(nil), // 3: ninja.Status.BuildStarted
+ (*Status_BuildFinished)(nil), // 4: ninja.Status.BuildFinished
+ (*Status_EdgeStarted)(nil), // 5: ninja.Status.EdgeStarted
+ (*Status_EdgeFinished)(nil), // 6: ninja.Status.EdgeFinished
+ (*Status_Message)(nil), // 7: ninja.Status.Message
+}
+var file_frontend_proto_depIdxs = []int32{
+ 2, // 0: ninja.Status.total_edges:type_name -> ninja.Status.TotalEdges
+ 3, // 1: ninja.Status.build_started:type_name -> ninja.Status.BuildStarted
+ 4, // 2: ninja.Status.build_finished:type_name -> ninja.Status.BuildFinished
+ 5, // 3: ninja.Status.edge_started:type_name -> ninja.Status.EdgeStarted
+ 6, // 4: ninja.Status.edge_finished:type_name -> ninja.Status.EdgeFinished
+ 7, // 5: ninja.Status.message:type_name -> ninja.Status.Message
+ 0, // 6: ninja.Status.Message.level:type_name -> ninja.Status.Message.Level
+ 7, // [7:7] is the sub-list for method output_type
+ 7, // [7:7] is the sub-list for method input_type
+ 7, // [7:7] is the sub-list for extension type_name
+ 7, // [7:7] is the sub-list for extension extendee
+ 0, // [0:7] is the sub-list for field type_name
+}
+
+func init() { file_frontend_proto_init() }
+func file_frontend_proto_init() {
+ if File_frontend_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_frontend_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_frontend_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status_TotalEdges); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_frontend_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status_BuildStarted); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_frontend_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status_BuildFinished); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_frontend_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status_EdgeStarted); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_frontend_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status_EdgeFinished); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_frontend_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Status_Message); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_frontend_proto_rawDesc,
+ NumEnums: 1,
+ NumMessages: 7,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_frontend_proto_goTypes,
+ DependencyIndexes: file_frontend_proto_depIdxs,
+ EnumInfos: file_frontend_proto_enumTypes,
+ MessageInfos: file_frontend_proto_msgTypes,
+ }.Build()
+ File_frontend_proto = out.File
+ file_frontend_proto_rawDesc = nil
+ file_frontend_proto_goTypes = nil
+ file_frontend_proto_depIdxs = nil
}
diff --git a/ui/status/ninja_frontend/frontend.proto b/ui/status/ninja_frontend/frontend.proto
index e5e5d9f..5730388 100644
--- a/ui/status/ninja_frontend/frontend.proto
+++ b/ui/status/ninja_frontend/frontend.proto
@@ -17,7 +17,7 @@
option optimize_for = LITE_RUNTIME;
package ninja;
-option go_package = "ninja_frontend";
+option go_package = "android/soong/ui/status/ninja_frontend";
message Status {
message TotalEdges {
diff --git a/ui/status/ninja_test.go b/ui/status/ninja_test.go
index c400c97..f3638b3 100644
--- a/ui/status/ninja_test.go
+++ b/ui/status/ninja_test.go
@@ -43,3 +43,53 @@
t.Errorf("nr.Close timed out, %s > %s", g, w)
}
}
+
+// Test that error hint is added to output if available
+func TestNinjaReader_CorrectErrorHint(t *testing.T) {
+ errorPattern1 := "pattern-1 in input"
+ errorHint1 := "\n Fix by doing task 1"
+ errorPattern2 := "pattern-2 in input"
+ errorHint2 := "\n Fix by doing task 2"
+ mockErrorHints := make(map[string]string)
+ mockErrorHints[errorPattern1] = errorHint1
+ mockErrorHints[errorPattern2] = errorHint2
+
+ errorHintGenerator := *newErrorHintGenerator(mockErrorHints)
+ testCases := []struct {
+ rawOutput string
+ buildExitCode int
+ expectedFinalOutput string
+ testCaseErrorMessage string
+ }{
+ {
+ rawOutput: "ninja build was successful",
+ buildExitCode: 0,
+ expectedFinalOutput: "ninja build was successful",
+ testCaseErrorMessage: "raw output changed when build was successful",
+ },
+ {
+ rawOutput: "ninja build failed",
+ buildExitCode: 1,
+ expectedFinalOutput: "ninja build failed",
+ testCaseErrorMessage: "raw output changed even when no error hint pattern was found",
+ },
+ {
+ rawOutput: "ninja build failed: " + errorPattern1 + "some footnotes",
+ buildExitCode: 1,
+ expectedFinalOutput: "ninja build failed: " + errorPattern1 + "some footnotes" + errorHint1,
+ testCaseErrorMessage: "error hint not added despite pattern match",
+ },
+ {
+ rawOutput: "ninja build failed: " + errorPattern2 + errorPattern1,
+ buildExitCode: 1,
+ expectedFinalOutput: "ninja build failed: " + errorPattern2 + errorPattern1 + errorHint2,
+ testCaseErrorMessage: "error hint should be added for first pattern match in raw output",
+ },
+ }
+ for _, testCase := range testCases {
+ actualFinalOutput := errorHintGenerator.GetOutputWithErrorHint(testCase.rawOutput, testCase.buildExitCode)
+ if actualFinalOutput != testCase.expectedFinalOutput {
+ t.Errorf(testCase.testCaseErrorMessage+"\nexpected: %s\ngot: %s", testCase.expectedFinalOutput, actualFinalOutput)
+ }
+ }
+}